Passed
Push — master ( 4dab1e...1478cf )
by Marcel
03:10
created

js/advanced.js   B

Complexity

Total Complexity 51
Complexity/F 1.5

Size

Lines of Code 365
Function Count 34

Duplication

Duplicated Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 236
dl 0
loc 365
rs 7.92
c 0
b 0
f 0
wmc 51
mnd 17
bc 17
fnc 34
bpm 0.5
cpm 1.5
noi 0

How to fix   Complexity   

Complexity

Complex classes like js/advanced.js often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

1
/**
2
 * Analytics
3
 *
4
 * This file is licensed under the Affero General Public License version 3 or
5
 * later. See the LICENSE.md file.
6
 *
7
 * @author Marcel Scherello <[email protected]>
8
 * @copyright 2020 Marcel Scherello
9
 */
10
/** global: OCA */
11
/** global: OCP */
12
/** global: OC */
13
'use strict';
14
15
/**
16
 * @namespace OCA.Analytics.Advanced
17
 */
18
OCA.Analytics.Advanced = {};
19
20
/**
21
 * @namespace OCA.Analytics.Advanced.Dataload
22
 */
23
OCA.Analytics.Advanced.Dataload = {
24
    dataloadArray: [],
25
26
    tabContainerDataload: function () {
27
        const datasetId = document.getElementById('app-sidebar').dataset.id;
28
29
        OCA.Analytics.Sidebar.resetView();
30
        document.getElementById('tabHeaderDataload').classList.add('selected');
31
        document.getElementById('tabContainerDataload').classList.remove('hidden');
32
        document.getElementById('tabContainerDataload').innerHTML = '<div style="text-align:center; word-wrap:break-word;" class="get-metadata"><p><img src="' + OC.imagePath('core', 'loading.gif') + '"><br><br></p><p>' + t('analytics', 'Reading data') + '</p></div>';
33
34
        $.ajax({
35
            type: 'GET',
36
            url: OC.generateUrl('apps/analytics/dataload/') + datasetId,
37
            success: function (data) {
38
                // store reulable array
39
                OCA.Analytics.Advanced.Dataload.dataloadArray = data['dataloads'];
40
41
                // clone the DOM template
42
                let table = document.importNode(document.getElementById('templateDataload').content, true);
43
                table.id = 'tableDataload';
44
                document.getElementById('tabContainerDataload').innerHTML = '';
45
                document.getElementById('tabContainerDataload').appendChild(table);
46
                document.getElementById('createDataloadButton').addEventListener('click', OCA.Analytics.Advanced.Dataload.handleCreateButton);
47
                document.getElementById('dataloadList').innerHTML = '';
48
49
                // list all available dataloads for dataset
50
                for (let dataload of data['dataloads']) {
51
                    document.getElementById('dataloadList').appendChild(OCA.Analytics.Advanced.Dataload.buildDataloadRow(dataload));
52
                }
53
54
                // list all available datasources
55
                document.getElementById('datasourceSelect').appendChild(OCA.Analytics.Datasource.buildDropdown());
56
            }
57
        });
58
    },
59
60
    buildDataloadRow: function (dataload) {
61
        let item = document.createElement('div');
62
        item.classList.add('dataloadItem');
63
64
        let typeINT = parseInt(dataload['datasource']);
65
        let typeIcon;
66
        if (typeINT === OCA.Analytics.TYPE_INTERNAL_FILE) {
67
            typeIcon = 'icon-file';
68
        } else if (typeINT === OCA.Analytics.TYPE_INTERNAL_DB) {
69
            typeIcon = 'icon-projects';
70
        } else {
71
            typeIcon = 'icon-external';
72
        }
73
        let a = document.createElement('a');
74
        a.classList.add(typeIcon);
75
        a.innerText = dataload['name'];
76
        a.dataset.id = dataload['id'];
77
        a.dataset.datasourceId = dataload['datasource'];
78
        a.addEventListener('click', OCA.Analytics.Advanced.Dataload.handleDataloadSelect);
79
        item.appendChild(a);
80
        return item;
81
    },
82
83
    handleDataloadSelect: function (evt) {
84
        OCA.Analytics.Advanced.Dataload.buildDataloadOptions(evt);
85
    },
86
87
    buildDataloadOptions: function (evt) {
88
        let dataload = OCA.Analytics.Advanced.Dataload.dataloadArray.find(x => x.id === parseInt(evt.target.dataset.id));
89
90
        document.getElementById('dataloadDetail').dataset.id = dataload['id'];
91
        document.getElementById('dataloadName').value = dataload['name'];
92
        document.getElementById('dataloadDetailHeader').hidden = false;
93
        document.getElementById('dataloadDetailButtons').hidden = false;
94
        document.getElementById('dataloadUpdateButton').addEventListener('click', OCA.Analytics.Advanced.Dataload.handleUpdateButton);
95
        document.getElementById('dataloadDeleteButton').addEventListener('click', OCA.Analytics.Advanced.Dataload.handleDeleteButton);
96
        document.getElementById('dataloadSchedule').value = dataload['schedule'];
97
        document.getElementById('dataloadSchedule').addEventListener('change', OCA.Analytics.Advanced.Dataload.updateDataload);
98
        document.getElementById('dataloadOCC').innerText = 'occ analytics:load ' + dataload['id'];
99
100
        // get all the options for a datasource
101
        document.getElementById('dataloadDetailItems').innerHTML = '';
102
        document.getElementById('dataloadDetailItems').appendChild(OCA.Analytics.Datasource.buildOptionsForm(dataload['datasource']));
103
104
        // set  the options for a datasource
105
        let fieldValues = JSON.parse(dataload['option']);
106
        for (let fieldValue in fieldValues) {
107
            document.getElementById(fieldValue) ? document.getElementById(fieldValue).value = fieldValues[fieldValue] : null;
108
        }
109
110
        if (dataload['datasource'] === OCA.Analytics.TYPE_INTERNAL_FILE) {
111
            document.getElementById('link').addEventListener('click', OCA.Analytics.Sidebar.Dataset.handleFilepicker);
112
        }
113
114
        document.getElementById('dataloadRun').hidden = false;
115
        document.getElementById('dataloadExecuteButton').addEventListener('click', OCA.Analytics.Advanced.Dataload.handleExecuteButton);
116
    },
117
118
    handleCreateButton: function () {
119
        OCA.Analytics.Advanced.Dataload.createDataload();
120
    },
121
122
    createDataload: function () {
123
        $.ajax({
124
            type: 'POST',
125
            url: OC.generateUrl('apps/analytics/dataload'),
126
            data: {
127
                'datasetId': parseInt(document.getElementById('app-sidebar').dataset.id),
128
                'datasourceId': document.getElementById('datasourceSelect').value,
129
            },
130
            success: function () {
131
                document.querySelector('.tabHeader.selected').click();
132
            }
133
        });
134
    },
135
136
    handleUpdateButton: function () {
137
        OCA.Analytics.Advanced.Dataload.updateDataload();
138
    },
139
140
    updateDataload: function () {
141
        const dataloadId = document.getElementById('dataloadDetail').dataset.id;
142
        let option = {};
143
144
        // loop all dynamic options of the selected datasource
145
        let inputFields = document.querySelectorAll('#dataloadDetailItems input, #dataloadDetailItems select, #dataloadDetailDelete select');
146
        for (let inputField of inputFields) {
147
            option[inputField['id']] = inputField['value'];
148
        }
149
        option = JSON.stringify(option);
150
151
        $.ajax({
152
            type: 'PUT',
153
            url: OC.generateUrl('apps/analytics/dataload/') + dataloadId,
154
            data: {
155
                'name': document.getElementById('dataloadName').value,
156
                'schedule': document.getElementById('dataloadSchedule').value,
157
                'option': option,
158
            },
159
            success: function () {
160
                OCA.Analytics.UI.notification('success', t('analytics', 'Dataload saved'));
161
                OCA.Analytics.Advanced.Dataload.dataloadArray.find(x => x.id === parseInt(dataloadId))['schedule'] = document.getElementById('dataloadSchedule').value;
162
                OCA.Analytics.Advanced.Dataload.dataloadArray.find(x => x.id === parseInt(dataloadId))['name'] = document.getElementById('dataloadName').value;
163
                OCA.Analytics.Advanced.Dataload.dataloadArray.find(x => x.id === parseInt(dataloadId))['option'] = option;
164
            }
165
        });
166
    },
167
168
    handleDeleteButton: function () {
169
        OC.dialogs.confirm(
170
            t('analytics', 'Are you sure?'),
171
            t('analytics', 'Delete Dataload'),
172
            function (e) {
173
                if (e === true) {
174
                    OCA.Analytics.Advanced.Dataload.deleteDataload();
175
                }
176
            },
177
            true
178
        );
179
    },
180
181
    deleteDataload: function () {
182
        $.ajax({
183
            type: 'DELETE',
184
            url: OC.generateUrl('apps/analytics/dataload/') + document.getElementById('dataloadDetail').dataset.id,
185
            success: function () {
186
                document.querySelector('.tabHeader.selected').click();
187
            }
188
        });
189
    },
190
191
    handleExecuteButton: function () {
192
        OCA.Analytics.Advanced.Dataload.executeDataload();
193
    },
194
195
    executeDataload: function () {
196
        let mode;
197
        if (document.getElementById('testrunCheckbox').checked) {
198
            mode = 'simulate';
199
        } else {
200
            mode = 'execute';
201
        }
202
203
        $.ajax({
204
            type: 'POST',
205
            url: OC.generateUrl('apps/analytics/dataload/') + mode,
206
            data: {
207
                'dataloadId': document.getElementById('dataloadDetail').dataset.id,
208
            },
209
            success: function (data) {
210
                if (mode === 'simulate') {
211
                    OC.dialogs.message(
212
                        JSON.stringify(data.data),
213
                        t('analytics', 'Datasource simulation'),
214
                        'info',
215
                        OC.dialogs.OK_BUTTON,
216
                        function () {
217
                        },
218
                        true,
219
                        true
220
                    );
221
                } else {
222
                    if (data.error === 0) {
223
                        OCA.Analytics.UI.notification('success', data.insert + t('analytics', ' records inserted, ') + data.update + t('analytics', ' records updated'));
224
                        //document.querySelector('#navigationDatasets [data-id="' + datasetId + '"]').click();
225
                    } else {
226
                        OCA.Analytics.UI.notification('error', data.error);
227
                    }
228
                }
229
            }
230
        });
231
    },
232
233
};
234
235
OCA.Analytics.Advanced.Threshold = {
236
237
    tabContainerThreshold: function () {
238
        const datasetId = document.getElementById('app-sidebar').dataset.id;
239
240
        OCA.Analytics.Sidebar.resetView();
241
        document.getElementById('tabHeaderThreshold').classList.add('selected');
242
        document.getElementById('tabContainerThreshold').classList.remove('hidden');
243
        document.getElementById('tabContainerThreshold').innerHTML = '<div style="text-align:center; word-wrap:break-word;" class="get-metadata"><p><img src="' + OC.imagePath('core', 'loading.gif') + '"><br><br></p><p>' + t('analytics', 'Reading data') + '</p></div>';
244
245
        $.ajax({
246
            type: 'GET',
247
            url: OC.generateUrl('apps/analytics/dataset/') + datasetId,
248
            success: function (data) {
249
                // clone the DOM template
250
                let table = document.importNode(document.getElementById('templateThreshold').content, true);
251
                table.id = 'tableThreshold';
252
                document.getElementById('tabContainerThreshold').innerHTML = '';
253
                document.getElementById('tabContainerThreshold').appendChild(table);
254
                document.getElementById('sidebarThresholdTextDimension1').innerText = data.dimension1 || t('analytics', 'Column 1');
255
                document.getElementById('sidebarThresholdTextValue').innerText = data.value || t('analytics', 'Column 3');
256
                document.getElementById('createThresholdButton').addEventListener('click', OCA.Analytics.Advanced.Threshold.handleThresholdCreateButton);
257
                if (parseInt(data.type) !== OCA.Analytics.TYPE_INTERNAL_DB) {
258
                    document.getElementById('sidebarThresholdSeverity').remove(0);
259
                }
260
261
                $.ajax({
262
                    type: 'GET',
263
                    url: OC.generateUrl('apps/analytics/threshold/') + datasetId,
264
                    success: function (data) {
265
                        if (data !== false) {
266
                            document.getElementById('sidebarThresholdList').innerHTML = '';
267
                            for (let threshold of data) {
268
                                const li = OCA.Analytics.Advanced.Threshold.buildThresholdRow(threshold);
269
                                document.getElementById('sidebarThresholdList').appendChild(li);
270
                            }
271
                        }
272
                    }
273
                });
274
            }
275
        });
276
    },
277
278
    handleThresholdCreateButton: function () {
279
        OCA.Analytics.Advanced.Threshold.createThreashold();
280
    },
281
282
    handleThresholdDeleteButton: function (evt) {
283
        const thresholdId = evt.target.dataset.id;
284
        OCA.Analytics.Advanced.Threshold.deleteThreshold(thresholdId);
285
    },
286
287
    buildThresholdRow: function (data) {
288
289
        let bulletColor, bullet;
290
        data.severity = parseInt(data.severity);
291
        if (data.severity === 2) {
292
            bulletColor = 'red';
293
        } else if (data.severity === 3) {
294
            bulletColor = 'orange';
295
        } else {
296
            bulletColor = 'green';
297
        }
298
299
        if (data.severity === 1) {
300
            bullet = document.createElement('img');
301
            bullet.src = OC.imagePath('notifications', 'notifications-dark.svg');
302
            bullet.classList.add('thresholdBullet');
303
        } else {
304
            bullet = document.createElement('div');
305
            bullet.style.backgroundColor = bulletColor;
306
            bullet.classList.add('thresholdBullet');
307
        }
308
309
        let item = document.createElement('div');
310
        item.classList.add('thresholdItem');
311
312
        let text = document.createElement('div');
313
        text.classList.add('thresholdText');
314
        text.innerText = data.dimension1 + ' ' + data.option + ' ' + data.value;
315
316
        let tDelete = document.createElement('div');
317
        tDelete.classList.add('icon-close');
318
        tDelete.dataset.id = data.id;
319
        tDelete.addEventListener('click', OCA.Analytics.Advanced.Threshold.handleThresholdDeleteButton);
320
321
        item.appendChild(bullet);
322
        item.appendChild(text);
323
        item.appendChild(tDelete);
324
        return item;
325
    },
326
327
    createThreashold: function () {
328
        const datasetId = parseInt(document.getElementById('app-sidebar').dataset.id);
329
        const url = OC.generateUrl('apps/analytics/threshold');
330
331
        $.ajax({
332
            type: 'POST',
333
            url: url,
334
            data: {
335
                'datasetId': datasetId,
336
                'dimension1': document.getElementById('sidebarThresholdDimension1').value,
337
                'option': document.getElementById('sidebarThresholdOption').value,
338
                'value': document.getElementById('sidebarThresholdValue').value,
339
                'severity': document.getElementById('sidebarThresholdSeverity').value,
340
            },
341
            success: function () {
342
                document.querySelector('.tabHeader.selected').click();
343
            }
344
        });
345
    },
346
347
    deleteThreshold: function (thresholdId) {
348
349
        $.ajax({
350
            type: 'DELETE',
351
            url: OC.generateUrl('apps/analytics/threshold/') + thresholdId,
352
            success: function () {
353
                document.querySelector('.tabHeader.selected').click();
354
            }
355
        });
356
    },
357
358
};
359
360
document.addEventListener('DOMContentLoaded', function () {
361
    OCA.Analytics.Sidebar.registerSidebarTab({
362
        id: 'tabHeaderDataload',
363
        class: 'tabContainerDataload',
364
        tabindex: '2',
365
        name: t('analytics', 'Dataload'),
366
        action: OCA.Analytics.Advanced.Dataload.tabContainerDataload,
367
    });
368
369
    OCA.Analytics.Sidebar.registerSidebarTab({
370
        id: 'tabHeaderThreshold',
371
        class: 'tabContainerThreshold',
372
        tabindex: '3',
373
        name: t('analytics', 'Thresholds'),
374
        action: OCA.Analytics.Advanced.Threshold.tabContainerThreshold,
375
    });
376
377
});