Passed
Push — master ( 1860eb...71fe99 )
by
unknown
09:58
created

myems-admin/app/controllers/settings/space/spacemeter.controller.js   D

Complexity

Total Complexity 58
Complexity/F 1.87

Size

Lines of Code 334
Function Count 31

Duplication

Duplicated Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
wmc 58
eloc 234
mnd 27
bc 27
fnc 31
dl 0
loc 334
rs 4.5599
bpm 0.8709
cpm 1.8709
noi 2
c 0
b 0
f 0

1 Function

Rating   Name   Duplication   Size   Complexity  
A spacemeter.controller.js ➔ safeApply 0 5 3

How to fix   Complexity   

Complexity

Complex classes like myems-admin/app/controllers/settings/space/spacemeter.controller.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
'use strict';
2
3
app.controller('SpaceMeterController', function(
4
    $scope ,
5
    $window,
6
    $timeout,
7
    $translate,
8
    SpaceService,
9
    MeterService,
10
    VirtualMeterService,
11
    OfflineMeterService, 
12
    SpaceMeterService, 
13
    toaster,
14
    SweetAlert) {
15
    $scope.spaces = [];
16
    $scope.currentSpaceID = 1;
17
    $scope.spacemeters = [];
18
    $scope.cur_user = JSON.parse($window.localStorage.getItem("myems_admin_ui_current_user"));
19
    $scope.isLoadingMeters = false;
20
    $scope.tabInitialized = false;
21
    $scope.isSpaceSelected = false;
22
    $scope.currentmeters = [];
23
    $scope.meters = [];
24
    $scope.virtualmeters = [];
25
    $scope.offlinemeters = [];
26
27
    function safeApply(scope) {
28
        if (!scope.$$phase && !scope.$root.$$phase) {
29
            scope.$apply();
30
        }
31
    }
32
33
    $scope.getAllSpaces = function() {
34
    let headers = { "User-UUID": $scope.cur_user.uuid, "Token": $scope.cur_user.token };
35
    SpaceService.getAllSpaces(headers, function (response) {
36
      if (angular.isDefined(response.status) && response.status === 200) {
37
        $scope.spaces = response.data;
38
      } else {
39
        $scope.spaces = [];
40
      }
41
      //create space tree
42
      var treedata = {'core': {'data': [], "multiple" : false,}, "plugins" : [ "wholerow" ]};
43
      for(var i=0; i < $scope.spaces.length; i++) {
44
          if ($scope.spaces[i].id == 1) {
45
            var node = {"id": $scope.spaces[i].id.toString(),
46
                                "parent": '#',
47
                                "text": $scope.spaces[i].name,
48
                                "state": {  'opened' : true,  'selected' : false },
49
                               };
50
          } else {
51
              var node = {"id": $scope.spaces[i].id.toString(),
52
                                  "parent": $scope.spaces[i].parent_space.id.toString(),
53
                                  "text": $scope.spaces[i].name,
54
                                 };
55
          };
56
          treedata['core']['data'].push(node);
57
      }
58
59
      angular.element(spacetreewithmeter).jstree(treedata);
60
      //space tree selected changed event handler
61
      angular.element(spacetreewithmeter).on("changed.jstree", function (e, data) {
62
          if (data.selected && data.selected.length > 0) {
63
          $scope.currentSpaceID = parseInt(data.selected[0]);
64
              $scope.isSpaceSelected = true;
65
          $scope.spacemeters=[];
66
          $scope.getMetersBySpaceID($scope.currentSpaceID);
67
          } else {
68
              $scope.isSpaceSelected = false;
69
              $scope.spacemeters = [];
70
          }
71
          safeApply($scope);
72
      });
73
    });
74
    };
75
76
	$scope.getMetersBySpaceID = function(id) {
77
	    if ($scope.isLoadingMeters) return;
78
	    $scope.isLoadingMeters = true;
79
	    var metertypes = ['meters', 'virtualmeters', 'offlinemeters'];
80
	    var completedRequests = 0;
81
	    $scope.spacemeters = [];
82
	    let headers = { "User-UUID": $scope.cur_user.uuid, "Token": $scope.cur_user.token };
83
        angular.forEach(metertypes, function(value, index) {
84
            SpaceMeterService.getMetersBySpaceID(id, value, headers, function(response) {
85
                completedRequests++;
86
                if (angular.isDefined(response.status) && response.status === 200) {
87
                    angular.forEach(response.data, function(item, indx) {
88
                        response.data[indx].metertype = value;
89
                    });
90
                    $scope.spacemeters = $scope.spacemeters.concat(response.data);
91
                }
92
                if (completedRequests === metertypes.length) {
93
                    $scope.isLoadingMeters = false;
94
                }
95
            });
96
        });
97
    };
98
99
	$scope.colorMeterType=function(type){
100
		if(type=='meters'){
101
			return 'btn-primary'
102
		}else if(type=='virtualmeters'){
103
			return 'btn-info'
104
		}else{
105
			return 'btn-success'
106
		}
107
	};
108
109
	$scope.changeMeterType=function(){
110
		switch($scope.currentMeterType){
111
			case 'meters':
112
				$scope.currentmeters=$scope.meters || [];
113
				break;
114
			case 'virtualmeters':
115
				$scope.currentmeters=$scope.virtualmeters || [];
116
				break;
117
			case  'offlinemeters':
118
				$scope.currentmeters=$scope.offlinemeters || [];
119
				break;
120
			default:
121
				$scope.currentmeters = [];
122
		}
123
	};
124
125
	$scope.getAllMeters = function() {
126
        let headers = { "User-UUID": $scope.cur_user.uuid, "Token": $scope.cur_user.token };
127
		MeterService.getAllMeters(headers, function (response) {
128
			if (angular.isDefined(response.status) && response.status === 200) {
129
				$scope.meters = response.data;
130
				$scope.currentMeterType="meters";
131
					$scope.changeMeterType();
132
			} else {
133
				$scope.meters = [];
134
			}
135
		});
136
137
	};
138
139
	$scope.getAllOfflineMeters = function() {
140
        let headers = { "User-UUID": $scope.cur_user.uuid, "Token": $scope.cur_user.token };
141
		OfflineMeterService.getAllOfflineMeters(headers, function (response) {
142
			if (angular.isDefined(response.status) && response.status === 200) {
143
				$scope.offlinemeters = response.data;
144
			} else {
145
				$scope.offlinemeters = [];
146
			}
147
		});
148
149
	};
150
151
	$scope.getAllVirtualMeters = function() {
152
        let headers = { "User-UUID": $scope.cur_user.uuid, "Token": $scope.cur_user.token };
153
		VirtualMeterService.getAllVirtualMeters(headers, function (response) {
154
			if (angular.isDefined(response.status) && response.status === 200) {
155
				$scope.virtualmeters = response.data;
156
			} else {
157
				$scope.virtualmeters = [];
158
			}
159
		});
160
161
	};
162
163
	$scope.pairMeter=function(dragEl,dropEl){
164
		if (!$scope.isSpaceSelected) {
165
			toaster.pop({
166
				type: "warning",
167
				body: $translate.instant("SETTING.PLEASE_SELECT_SPACE_FIRST"),
168
				showCloseButton: true,
169
			});
170
			return;
171
		}
172
		var meterid=angular.element('#'+dragEl).scope().meter.id;
173
		var spaceid=angular.element(spacetreewithmeter).jstree(true).get_top_selected();
174
        let headers = { "User-UUID": $scope.cur_user.uuid, "Token": $scope.cur_user.token };
175
		SpaceMeterService.addPair(spaceid,meterid, $scope.currentMeterType, headers, function (response) {
176
			if (angular.isDefined(response.status) && response.status === 201) {
177
					toaster.pop({
178
						type: "success",
179
						title: $translate.instant("TOASTER.SUCCESS_TITLE"),
180
						body: $translate.instant("TOASTER.BIND_METER_SUCCESS"),
181
						showCloseButton: true,
182
					});
183
					$scope.getMetersBySpaceID(spaceid);
184
				} else {
185
          toaster.pop({
186
              type: "error",
187
              title: $translate.instant(response.data.title),
188
              body: $translate.instant(response.data.description),
189
              showCloseButton: true,
190
          });
191
				}
192
		});
193
	};
194
195
	$scope.deleteMeterPair=function(dragEl,dropEl){
196
		if(angular.element('#'+dragEl).hasClass('source')){
197
			return;
198
        }
199
		if (!$scope.isSpaceSelected) {
200
			toaster.pop({
201
				type: "warning",
202
				body: $translate.instant("SETTING.PLEASE_SELECT_SPACE_FIRST"),
203
				showCloseButton: true,
204
			});
205
			return;
206
        }
207
        var spacemeterid = angular.element('#' + dragEl).scope().spacemeter.id;
208
        var spaceid = angular.element(spacetreewithmeter).jstree(true).get_top_selected();
209
        var metertype = angular.element('#' + dragEl).scope().spacemeter.metertype;
210
        let headers = { "User-UUID": $scope.cur_user.uuid, "Token": $scope.cur_user.token };
211
        SpaceMeterService.deletePair(spaceid, spacemeterid, metertype, headers, function (response) {
212
            if (angular.isDefined(response.status) && response.status === 204) {
213
                toaster.pop({
214
                    type: "success",
215
                    title: $translate.instant("TOASTER.SUCCESS_TITLE"),
216
                    body: $translate.instant("TOASTER.UNBIND_METER_SUCCESS"),
217
                    showCloseButton: true,
218
                });
219
                $scope.getMetersBySpaceID(spaceid);
220
            } else {
221
                toaster.pop({
222
                    type: "error",
223
                    title: $translate.instant(response.data.title),
224
                    body: $translate.instant(response.data.description),
225
                    showCloseButton: true,
226
                });
227
            }
228
		});
229
	};
230
231
    $scope.initTab = function() {
232
        if (!$scope.tabInitialized) {
233
            $scope.tabInitialized = true;
234
            $scope.getAllSpaces();
235
            $scope.getAllMeters();
236
            $scope.getAllVirtualMeters();
237
            $scope.getAllOfflineMeters();
238
        }
239
    };
240
241
    // Listen for disabled drop events to show warning
242
    // The directive will only broadcast this event when drop target is disabled
243
    // So we can directly show the warning without checking isSpaceSelected again
244
    $scope.$on('HJC-DROP-DISABLED', function(event) {
245
        // Use $timeout to ensure we're in the right digest cycle
246
        $timeout(function() {
247
            try {
248
                toaster.pop({
249
                    type: "warning",
250
                    body: $translate.instant("SETTING.PLEASE_SELECT_SPACE_FIRST"),
251
                    showCloseButton: true,
252
                });
253
            } catch(err) {
254
                // Fallback if toaster fails
255
                console.error('Error showing toaster:', err);
256
                alert($translate.instant("SETTING.PLEASE_SELECT_SPACE_FIRST"));
0 ignored issues
show
Debugging Code Best Practice introduced by
The alert UI element is often considered obtrusive and is generally only used as a temporary measure. Consider replacing it with another UI element.
Loading history...
257
            }
258
        }, 0);
259
    });
260
261
    // Listen for disabled drag events to show warning
262
    // The directive will broadcast this event when drag is attempted but disabled
263
    $scope.$on('HJC-DRAG-DISABLED', function(event) {
264
        // Use $timeout to ensure we're in the right digest cycle
265
        $timeout(function() {
266
            try {
267
                toaster.pop({
268
                    type: "warning",
269
                    body: $translate.instant("SETTING.PLEASE_SELECT_SPACE_FIRST"),
270
                    showCloseButton: true,
271
                });
272
            } catch(err) {
273
                // Fallback if toaster fails
274
                console.error('Error showing toaster:', err);
275
                alert($translate.instant("SETTING.PLEASE_SELECT_SPACE_FIRST"));
0 ignored issues
show
Debugging Code Best Practice introduced by
The alert UI element is often considered obtrusive and is generally only used as a temporary measure. Consider replacing it with another UI element.
Loading history...
276
            }
277
        }, 0);
278
    });
279
280
    $scope.$on('space.tabSelected', function(event, tabIndex) {
281
        var TAB_INDEXES = ($scope.$parent && $scope.$parent.TAB_INDEXES) || { METER: 1 };
282
        if (tabIndex === TAB_INDEXES.METER && !$scope.tabInitialized) {
283
            $scope.initTab();
284
        }
285
    });
286
287
    $timeout(function() {
288
        var TAB_INDEXES = ($scope.$parent && $scope.$parent.TAB_INDEXES) || { METER: 1 };
289
        if ($scope.$parent && $scope.$parent.activeTabIndex === TAB_INDEXES.METER && !$scope.tabInitialized) {
290
            $scope.initTab();
291
        }
292
    }, 0);
293
294
    $scope.refreshSpaceTree = function() {
295
    let headers = { "User-UUID": $scope.cur_user.uuid, "Token": $scope.cur_user.token };
296
    SpaceService.getAllSpaces(headers, function (response) {
297
      if (angular.isDefined(response.status) && response.status === 200) {
298
        $scope.spaces = response.data;
299
      } else {
300
        $scope.spaces = [];
301
      }
302
      //create space tree
303
      var treedata = {'core': {'data': [], "multiple" : false,}, "plugins" : [ "wholerow" ]};
304
      for(var i=0; i < $scope.spaces.length; i++) {
305
          if ($scope.spaces[i].id == 1) {
306
            var node = {"id": $scope.spaces[i].id.toString(),
307
                                "parent": '#',
308
                                "text": $scope.spaces[i].name,
309
                                "state": {  'opened' : true,  'selected' : false },
310
                               };
311
          } else {
312
              var node = {"id": $scope.spaces[i].id.toString(),
313
                                  "parent": $scope.spaces[i].parent_space.id.toString(),
314
                                  "text": $scope.spaces[i].name,
315
                                 };
316
          };
317
          treedata['core']['data'].push(node);
318
      }
319
320
      angular.element(spacetreewithmeter).jstree(true).settings.core.data = treedata['core']['data'];
321
      angular.element(spacetreewithmeter).jstree(true).refresh();
322
      // Reset selection state after tree refresh
323
      $scope.isSpaceSelected = false;
324
      $scope.spacemeters = [];
325
      safeApply($scope);
326
    });
327
    };
328
329
	$scope.$on('handleBroadcastSpaceChanged', function(event) {
330
    $scope.spacemeters = [];
331
    $scope.refreshSpaceTree();
332
	});
333
334
});
335