Passed
Push — master ( 0c4439...aa6908 )
by Marcel
02:17
created

js/advanced.js   C

Complexity

Total Complexity 53
Complexity/F 1.56

Size

Lines of Code 384
Function Count 34

Duplication

Duplicated Lines 0
Ratio 0 %

Importance

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