Showing
8 changed files
with
533 additions
and
60 deletions
@@ -30,7 +30,9 @@ function AttributeService($http, $q, $filter, types, telemetryWebsocketService) | @@ -30,7 +30,9 @@ function AttributeService($http, $q, $filter, types, telemetryWebsocketService) | ||
30 | subscribeForEntityAttributes: subscribeForEntityAttributes, | 30 | subscribeForEntityAttributes: subscribeForEntityAttributes, |
31 | unsubscribeForEntityAttributes: unsubscribeForEntityAttributes, | 31 | unsubscribeForEntityAttributes: unsubscribeForEntityAttributes, |
32 | saveEntityAttributes: saveEntityAttributes, | 32 | saveEntityAttributes: saveEntityAttributes, |
33 | - deleteEntityAttributes: deleteEntityAttributes | 33 | + deleteEntityAttributes: deleteEntityAttributes, |
34 | + saveEntityTimeseries: saveEntityTimeseries, | ||
35 | + deleteEntityTimeseries: deleteEntityTimeseries | ||
34 | } | 36 | } |
35 | 37 | ||
36 | return service; | 38 | return service; |
@@ -212,7 +214,8 @@ function AttributeService($http, $q, $filter, types, telemetryWebsocketService) | @@ -212,7 +214,8 @@ function AttributeService($http, $q, $filter, types, telemetryWebsocketService) | ||
212 | } | 214 | } |
213 | } | 215 | } |
214 | 216 | ||
215 | - function saveEntityAttributes(entityType, entityId, attributeScope, attributes) { | 217 | + function saveEntityAttributes(entityType, entityId, attributeScope, attributes, config) { |
218 | + config = config || {}; | ||
216 | var deferred = $q.defer(); | 219 | var deferred = $q.defer(); |
217 | var attributesData = {}; | 220 | var attributesData = {}; |
218 | var deleteAttributes = []; | 221 | var deleteAttributes = []; |
@@ -229,7 +232,7 @@ function AttributeService($http, $q, $filter, types, telemetryWebsocketService) | @@ -229,7 +232,7 @@ function AttributeService($http, $q, $filter, types, telemetryWebsocketService) | ||
229 | } | 232 | } |
230 | if (Object.keys(attributesData).length) { | 233 | if (Object.keys(attributesData).length) { |
231 | var url = '/api/plugins/telemetry/' + entityType + '/' + entityId + '/' + attributeScope; | 234 | var url = '/api/plugins/telemetry/' + entityType + '/' + entityId + '/' + attributeScope; |
232 | - $http.post(url, attributesData).then(function success(response) { | 235 | + $http.post(url, attributesData, config).then(function success(response) { |
233 | if (deleteEntityAttributesPromise) { | 236 | if (deleteEntityAttributesPromise) { |
234 | deleteEntityAttributesPromise.then( | 237 | deleteEntityAttributesPromise.then( |
235 | function success() { | 238 | function success() { |
@@ -260,6 +263,55 @@ function AttributeService($http, $q, $filter, types, telemetryWebsocketService) | @@ -260,6 +263,55 @@ function AttributeService($http, $q, $filter, types, telemetryWebsocketService) | ||
260 | return deferred.promise; | 263 | return deferred.promise; |
261 | } | 264 | } |
262 | 265 | ||
266 | + function saveEntityTimeseries(entityType, entityId, timeseriesScope, timeseries, config) { | ||
267 | + config = config || {}; | ||
268 | + var deferred = $q.defer(); | ||
269 | + var timeseriesData = {}; | ||
270 | + var deleteTimeseries = []; | ||
271 | + for (var a=0; a<timeseries.length;a++) { | ||
272 | + if (angular.isDefined(timeseries[a].value) && timeseries[a].value !== null) { | ||
273 | + timeseriesData[timeseries[a].key] = timeseries[a].value; | ||
274 | + } else { | ||
275 | + deleteTimeseries.push(timeseries[a]); | ||
276 | + } | ||
277 | + } | ||
278 | + var deleteEntityTimeseriesPromise; | ||
279 | + if (deleteTimeseries.length) { | ||
280 | + deleteEntityTimeseriesPromise = deleteEntityTimeseries(entityType, entityId, deleteTimeseries); | ||
281 | + } | ||
282 | + if (Object.keys(timeseriesData).length) { | ||
283 | + var url = '/api/plugins/telemetry/' + entityType + '/' + entityId + '/timeseries/' + timeseriesScope; | ||
284 | + $http.post(url, timeseriesData, config).then(function success(response) { | ||
285 | + if (deleteEntityTimeseriesPromise) { | ||
286 | + deleteEntityTimeseriesPromise.then( | ||
287 | + function success() { | ||
288 | + deferred.resolve(response.data); | ||
289 | + }, | ||
290 | + function fail() { | ||
291 | + deferred.reject(); | ||
292 | + } | ||
293 | + ) | ||
294 | + } else { | ||
295 | + deferred.resolve(response.data); | ||
296 | + } | ||
297 | + }, function fail() { | ||
298 | + deferred.reject(); | ||
299 | + }); | ||
300 | + } else if (deleteEntityTimeseriesPromise) { | ||
301 | + deleteEntityTimeseriesPromise.then( | ||
302 | + function success() { | ||
303 | + deferred.resolve(); | ||
304 | + }, | ||
305 | + function fail() { | ||
306 | + deferred.reject(); | ||
307 | + } | ||
308 | + ) | ||
309 | + } else { | ||
310 | + deferred.resolve(); | ||
311 | + } | ||
312 | + return deferred.promise; | ||
313 | + } | ||
314 | + | ||
263 | function deleteEntityAttributes(entityType, entityId, attributeScope, attributes) { | 315 | function deleteEntityAttributes(entityType, entityId, attributeScope, attributes) { |
264 | var deferred = $q.defer(); | 316 | var deferred = $q.defer(); |
265 | var keys = ''; | 317 | var keys = ''; |
@@ -278,5 +330,22 @@ function AttributeService($http, $q, $filter, types, telemetryWebsocketService) | @@ -278,5 +330,22 @@ function AttributeService($http, $q, $filter, types, telemetryWebsocketService) | ||
278 | return deferred.promise; | 330 | return deferred.promise; |
279 | } | 331 | } |
280 | 332 | ||
333 | + function deleteEntityTimeseries(entityType, entityId, timeseries) { | ||
334 | + var deferred = $q.defer(); | ||
335 | + var keys = ''; | ||
336 | + for (var i = 0; i < timeseries.length; i++) { | ||
337 | + if (i > 0) { | ||
338 | + keys += ','; | ||
339 | + } | ||
340 | + keys += timeseries[i].key; | ||
341 | + } | ||
342 | + var url = '/api/plugins/telemetry/' + entityType + '/' + entityId + '/timeseries/delete' + '?keys=' + keys; | ||
343 | + $http.delete(url).then(function success() { | ||
344 | + deferred.resolve(); | ||
345 | + }, function fail() { | ||
346 | + deferred.reject(); | ||
347 | + }); | ||
348 | + return deferred.promise; | ||
349 | + } | ||
281 | 350 | ||
282 | } | 351 | } |
@@ -31,6 +31,7 @@ function DeviceService($http, $q, $window, userService, attributeService, custom | @@ -31,6 +31,7 @@ function DeviceService($http, $q, $window, userService, attributeService, custom | ||
31 | getDeviceCredentials: getDeviceCredentials, | 31 | getDeviceCredentials: getDeviceCredentials, |
32 | getTenantDevices: getTenantDevices, | 32 | getTenantDevices: getTenantDevices, |
33 | saveDevice: saveDevice, | 33 | saveDevice: saveDevice, |
34 | + saveDeviceParameters: saveDeviceParameters, | ||
34 | saveDeviceCredentials: saveDeviceCredentials, | 35 | saveDeviceCredentials: saveDeviceCredentials, |
35 | unassignDeviceFromCustomer: unassignDeviceFromCustomer, | 36 | unassignDeviceFromCustomer: unassignDeviceFromCustomer, |
36 | makeDevicePublic: makeDevicePublic, | 37 | makeDevicePublic: makeDevicePublic, |
@@ -42,7 +43,8 @@ function DeviceService($http, $q, $window, userService, attributeService, custom | @@ -42,7 +43,8 @@ function DeviceService($http, $q, $window, userService, attributeService, custom | ||
42 | sendOneWayRpcCommand: sendOneWayRpcCommand, | 43 | sendOneWayRpcCommand: sendOneWayRpcCommand, |
43 | sendTwoWayRpcCommand: sendTwoWayRpcCommand, | 44 | sendTwoWayRpcCommand: sendTwoWayRpcCommand, |
44 | findByQuery: findByQuery, | 45 | findByQuery: findByQuery, |
45 | - getDeviceTypes: getDeviceTypes | 46 | + getDeviceTypes: getDeviceTypes, |
47 | + findByName: findByName | ||
46 | } | 48 | } |
47 | 49 | ||
48 | return service; | 50 | return service; |
@@ -124,7 +126,7 @@ function DeviceService($http, $q, $window, userService, attributeService, custom | @@ -124,7 +126,7 @@ function DeviceService($http, $q, $window, userService, attributeService, custom | ||
124 | if (!config) { | 126 | if (!config) { |
125 | config = {}; | 127 | config = {}; |
126 | } | 128 | } |
127 | - config = Object.assign(config, { ignoreErrors: ignoreErrors }); | 129 | + config = Object.assign(config, {ignoreErrors: ignoreErrors}); |
128 | $http.get(url, config).then(function success(response) { | 130 | $http.get(url, config).then(function success(response) { |
129 | deferred.resolve(response.data); | 131 | deferred.resolve(response.data); |
130 | }, function fail(response) { | 132 | }, function fail(response) { |
@@ -136,8 +138,8 @@ function DeviceService($http, $q, $window, userService, attributeService, custom | @@ -136,8 +138,8 @@ function DeviceService($http, $q, $window, userService, attributeService, custom | ||
136 | function getDevices(deviceIds, config) { | 138 | function getDevices(deviceIds, config) { |
137 | var deferred = $q.defer(); | 139 | var deferred = $q.defer(); |
138 | var ids = ''; | 140 | var ids = ''; |
139 | - for (var i=0;i<deviceIds.length;i++) { | ||
140 | - if (i>0) { | 141 | + for (var i = 0; i < deviceIds.length; i++) { |
142 | + if (i > 0) { | ||
141 | ids += ','; | 143 | ids += ','; |
142 | } | 144 | } |
143 | ids += deviceIds[i]; | 145 | ids += deviceIds[i]; |
@@ -146,11 +148,11 @@ function DeviceService($http, $q, $window, userService, attributeService, custom | @@ -146,11 +148,11 @@ function DeviceService($http, $q, $window, userService, attributeService, custom | ||
146 | $http.get(url, config).then(function success(response) { | 148 | $http.get(url, config).then(function success(response) { |
147 | var devices = response.data; | 149 | var devices = response.data; |
148 | devices.sort(function (device1, device2) { | 150 | devices.sort(function (device1, device2) { |
149 | - var id1 = device1.id.id; | ||
150 | - var id2 = device2.id.id; | ||
151 | - var index1 = deviceIds.indexOf(id1); | ||
152 | - var index2 = deviceIds.indexOf(id2); | ||
153 | - return index1 - index2; | 151 | + var id1 = device1.id.id; |
152 | + var id2 = device2.id.id; | ||
153 | + var index1 = deviceIds.indexOf(id1); | ||
154 | + var index2 = deviceIds.indexOf(id2); | ||
155 | + return index1 - index2; | ||
154 | }); | 156 | }); |
155 | deferred.resolve(devices); | 157 | deferred.resolve(devices); |
156 | }, function fail(response) { | 158 | }, function fail(response) { |
@@ -159,10 +161,11 @@ function DeviceService($http, $q, $window, userService, attributeService, custom | @@ -159,10 +161,11 @@ function DeviceService($http, $q, $window, userService, attributeService, custom | ||
159 | return deferred.promise; | 161 | return deferred.promise; |
160 | } | 162 | } |
161 | 163 | ||
162 | - function saveDevice(device) { | 164 | + function saveDevice(device, config) { |
165 | + config = config || {}; | ||
163 | var deferred = $q.defer(); | 166 | var deferred = $q.defer(); |
164 | var url = '/api/device'; | 167 | var url = '/api/device'; |
165 | - $http.post(url, device).then(function success(response) { | 168 | + $http.post(url, device, config).then(function success(response) { |
166 | deferred.resolve(response.data); | 169 | deferred.resolve(response.data); |
167 | }, function fail() { | 170 | }, function fail() { |
168 | deferred.reject(); | 171 | deferred.reject(); |
@@ -170,6 +173,54 @@ function DeviceService($http, $q, $window, userService, attributeService, custom | @@ -170,6 +173,54 @@ function DeviceService($http, $q, $window, userService, attributeService, custom | ||
170 | return deferred.promise; | 173 | return deferred.promise; |
171 | } | 174 | } |
172 | 175 | ||
176 | + function saveDeviceRelarion(deviceId, deviceRelation, config) { | ||
177 | + var deferred = $q.defer(); | ||
178 | + var attributesType = Object.keys(types.attributesScope); | ||
179 | + var allPromise = []; | ||
180 | + var promise = ""; | ||
181 | + for (var i = 0; i < attributesType.length; i++) { | ||
182 | + if (deviceRelation.attributes[attributesType[i]] && deviceRelation.attributes[attributesType[i]].length !== 0) { | ||
183 | + promise = attributeService.saveEntityAttributes(types.entityType.device, deviceId, types.attributesScope[attributesType[i]].value, deviceRelation.attributes[attributesType[i]], config).then(function success() {}); | ||
184 | + allPromise.push(promise); | ||
185 | + } | ||
186 | + } | ||
187 | + if (deviceRelation.timeseries.length !== 0) { | ||
188 | + promise = attributeService.saveEntityTimeseries(types.entityType.device, deviceId, "time", deviceRelation.timeseries, config).then(function success() { | ||
189 | + }); | ||
190 | + allPromise.push(promise); | ||
191 | + } | ||
192 | + $q.all(allPromise).then(function success() { | ||
193 | + deferred.resolve(); | ||
194 | + }); | ||
195 | + return deferred.promise; | ||
196 | + } | ||
197 | + | ||
198 | + function saveDeviceParameters(deviceParameters, update, config) { | ||
199 | + config = config || {}; | ||
200 | + var deferred = $q.defer(); | ||
201 | + var newDevice = { | ||
202 | + name: deviceParameters.name, | ||
203 | + type: deviceParameters.type | ||
204 | + }; | ||
205 | + saveDevice(newDevice, config).then(function success(response) { | ||
206 | + saveDeviceRelarion(response.id.id, deviceParameters, config).then(function success() { | ||
207 | + deferred.resolve(); | ||
208 | + }); | ||
209 | + }, function fail() { | ||
210 | + if (update) { | ||
211 | + findByName(deviceParameters.name, config).then(function success(response) { | ||
212 | + saveDeviceRelarion(response.id.id, deviceParameters, config).then(function success() { | ||
213 | + deferred.resolve(); | ||
214 | + }); | ||
215 | + }); | ||
216 | + } else { | ||
217 | + deferred.resolve(); | ||
218 | + } | ||
219 | + console.log("error"); // eslint-disable-line | ||
220 | + }); | ||
221 | + return deferred.promise; | ||
222 | + } | ||
223 | + | ||
173 | function deleteDevice(deviceId) { | 224 | function deleteDevice(deviceId) { |
174 | var deferred = $q.defer(); | 225 | var deferred = $q.defer(); |
175 | var url = '/api/device/' + deviceId; | 226 | var url = '/api/device/' + deviceId; |
@@ -297,7 +348,7 @@ function DeviceService($http, $q, $window, userService, attributeService, custom | @@ -297,7 +348,7 @@ function DeviceService($http, $q, $window, userService, attributeService, custom | ||
297 | if (!config) { | 348 | if (!config) { |
298 | config = {}; | 349 | config = {}; |
299 | } | 350 | } |
300 | - config = Object.assign(config, { ignoreErrors: ignoreErrors }); | 351 | + config = Object.assign(config, {ignoreErrors: ignoreErrors}); |
301 | $http.post(url, query, config).then(function success(response) { | 352 | $http.post(url, query, config).then(function success(response) { |
302 | deferred.resolve(response.data); | 353 | deferred.resolve(response.data); |
303 | }, function fail() { | 354 | }, function fail() { |
@@ -317,4 +368,15 @@ function DeviceService($http, $q, $window, userService, attributeService, custom | @@ -317,4 +368,15 @@ function DeviceService($http, $q, $window, userService, attributeService, custom | ||
317 | return deferred.promise; | 368 | return deferred.promise; |
318 | } | 369 | } |
319 | 370 | ||
371 | + function findByName(deviceName, config) { | ||
372 | + config = config || {}; | ||
373 | + var deferred = $q.defer(); | ||
374 | + var url = '/api/tenant/devices?deviceName=' + deviceName; | ||
375 | + $http.get(url, config).then(function success(response) { | ||
376 | + deferred.resolve(response.data); | ||
377 | + }, function fail() { | ||
378 | + deferred.reject(); | ||
379 | + }); | ||
380 | + return deferred.promise; | ||
381 | + } | ||
320 | } | 382 | } |
@@ -350,6 +350,40 @@ export default angular.module('thingsboard.types', []) | @@ -350,6 +350,40 @@ export default angular.module('thingsboard.types', []) | ||
350 | rulenode: "RULE_NODE", | 350 | rulenode: "RULE_NODE", |
351 | entityView: "ENTITY_VIEW" | 351 | entityView: "ENTITY_VIEW" |
352 | }, | 352 | }, |
353 | + entityGroup: { | ||
354 | + columnType: { | ||
355 | + sharedAttribute: { | ||
356 | + name: 'entity-group.column-type.shared-attribute', | ||
357 | + value: 'SHARED_ATTRIBUTE' | ||
358 | + }, | ||
359 | + serverAttribute: { | ||
360 | + name: 'entity-group.column-type.server-attribute', | ||
361 | + value: 'SERVER_ATTRIBUTE' | ||
362 | + }, | ||
363 | + timeseries: { | ||
364 | + name: 'entity-group.column-type.timeseries', | ||
365 | + value: 'TIMESERIES' | ||
366 | + }, | ||
367 | + entityField: { | ||
368 | + name: 'entity-group.column-type.entity-field', | ||
369 | + value: 'ENTITY_FIELD' | ||
370 | + } | ||
371 | + }, | ||
372 | + entityField: { | ||
373 | + name: { | ||
374 | + name: 'entity-group.entity-field.name', | ||
375 | + value: 'name' | ||
376 | + }, | ||
377 | + type: { | ||
378 | + name: 'entity-group.entity-field.type', | ||
379 | + value: 'type' | ||
380 | + }, | ||
381 | + assigned_customer: { | ||
382 | + name: 'entity-group.entity-field.assigned_customer', | ||
383 | + value: 'assigned_customer' | ||
384 | + } | ||
385 | + } | ||
386 | + }, | ||
353 | aliasEntityType: { | 387 | aliasEntityType: { |
354 | current_customer: "CURRENT_CUSTOMER" | 388 | current_customer: "CURRENT_CUSTOMER" |
355 | }, | 389 | }, |
@@ -16,7 +16,7 @@ | @@ -16,7 +16,7 @@ | ||
16 | import './import-dialog.scss'; | 16 | import './import-dialog.scss'; |
17 | 17 | ||
18 | /*@ngInject*/ | 18 | /*@ngInject*/ |
19 | -export default function ImportDialogCsvController($scope, $mdDialog, toast, importTitle, importFileLabel) { | 19 | +export default function ImportDialogCsvController($scope, $mdDialog, toast, importTitle, importFileLabel, importExport, types, $timeout) { |
20 | 20 | ||
21 | var vm = this; | 21 | var vm = this; |
22 | 22 | ||
@@ -25,9 +25,58 @@ export default function ImportDialogCsvController($scope, $mdDialog, toast, impo | @@ -25,9 +25,58 @@ export default function ImportDialogCsvController($scope, $mdDialog, toast, impo | ||
25 | vm.fileAdded = fileAdded; | 25 | vm.fileAdded = fileAdded; |
26 | vm.clearFile = clearFile; | 26 | vm.clearFile = clearFile; |
27 | 27 | ||
28 | + vm.addDevices = addDevices; | ||
29 | + vm.importParams = { | ||
30 | + isUpdate: true | ||
31 | + }; | ||
32 | + | ||
28 | vm.importTitle = importTitle; | 33 | vm.importTitle = importTitle; |
29 | vm.importFileLabel = importFileLabel; | 34 | vm.importFileLabel = importFileLabel; |
30 | 35 | ||
36 | + vm.columnsParam = []; | ||
37 | + | ||
38 | + vm.entityType = types.entityType.device; | ||
39 | + vm.columnTypes = {}; | ||
40 | + vm.entityField = {}; | ||
41 | + | ||
42 | + var parseData = {}; | ||
43 | + | ||
44 | + switch (vm.entityType) { | ||
45 | + case types.entityType.device: | ||
46 | + vm.columnTypes = types.entityGroup.columnType; | ||
47 | + break; | ||
48 | + } | ||
49 | + | ||
50 | + vm.entityField.name = types.entityGroup.entityField.name; | ||
51 | + | ||
52 | + switch (vm.entityType) { | ||
53 | + case types.entityType.device: | ||
54 | + vm.entityField.type = types.entityGroup.entityField.type; | ||
55 | + // vm.entityField.assigned_customer = types.entityGroup.entityField.assigned_customer; | ||
56 | + break; | ||
57 | + } | ||
58 | + | ||
59 | + $scope.$watch('vm.columnsParam', function(newVal, prevVal){ | ||
60 | + if (newVal && !angular.equals(newVal, prevVal)) { | ||
61 | + var isSelectName = false; | ||
62 | + var isSelectType = false; | ||
63 | + for (var i = 0; i < newVal.length; i++) { | ||
64 | + if (newVal[i].type === types.entityGroup.columnType.entityField.value && | ||
65 | + newVal[i].key === types.entityGroup.entityField.name.value) { | ||
66 | + isSelectName = true; | ||
67 | + } | ||
68 | + if (newVal[i].type === types.entityGroup.columnType.entityField.value && | ||
69 | + newVal[i].key === types.entityGroup.entityField.type.value) { | ||
70 | + isSelectType = true; | ||
71 | + } | ||
72 | + } | ||
73 | + $timeout(function () { | ||
74 | + vm.entityField.name.disable = isSelectName; | ||
75 | + vm.entityField.type.disable = isSelectType; | ||
76 | + }); | ||
77 | + } | ||
78 | + }, true); | ||
79 | + | ||
31 | 80 | ||
32 | function cancel() { | 81 | function cancel() { |
33 | $mdDialog.cancel(); | 82 | $mdDialog.cancel(); |
@@ -36,16 +85,16 @@ export default function ImportDialogCsvController($scope, $mdDialog, toast, impo | @@ -36,16 +85,16 @@ export default function ImportDialogCsvController($scope, $mdDialog, toast, impo | ||
36 | function fileAdded($file) { | 85 | function fileAdded($file) { |
37 | if ($file.getExtension() === 'csv') { | 86 | if ($file.getExtension() === 'csv') { |
38 | var reader = new FileReader(); | 87 | var reader = new FileReader(); |
39 | - reader.onload = function(event) { | ||
40 | - $scope.$apply(function() { | 88 | + reader.onload = function (event) { |
89 | + $scope.$apply(function () { | ||
41 | if (event.target.result) { | 90 | if (event.target.result) { |
42 | $scope.theForm.$setDirty(); | 91 | $scope.theForm.$setDirty(); |
43 | var importCSV = event.target.result; | 92 | var importCSV = event.target.result; |
44 | if (importCSV && importCSV.length > 0) { | 93 | if (importCSV && importCSV.length > 0) { |
45 | try { | 94 | try { |
46 | vm.importData = importCSV; | 95 | vm.importData = importCSV; |
47 | - console.log(vm.importData); // eslint-disable-line | ||
48 | vm.fileName = $file.name; | 96 | vm.fileName = $file.name; |
97 | + parseCSVData(vm.importData); | ||
49 | } catch (err) { | 98 | } catch (err) { |
50 | vm.fileName = null; | 99 | vm.fileName = null; |
51 | toast.showError(err.message); | 100 | toast.showError(err.message); |
@@ -58,10 +107,89 @@ export default function ImportDialogCsvController($scope, $mdDialog, toast, impo | @@ -58,10 +107,89 @@ export default function ImportDialogCsvController($scope, $mdDialog, toast, impo | ||
58 | } | 107 | } |
59 | } | 108 | } |
60 | 109 | ||
110 | + function parseCSVData(importData) { | ||
111 | + var config = { | ||
112 | + delim: vm.importParams.delim, | ||
113 | + header: vm.importParams.isHeader | ||
114 | + }; | ||
115 | + parseData = importExport.convertCSVToJson(importData, config); | ||
116 | + for (var i = 0; i < parseData.headers.length; i++) { | ||
117 | + var columnParam = { | ||
118 | + type: types.entityGroup.columnType.serverAttribute.value, | ||
119 | + key: vm.importParams.isHeader ? parseData.headers[i] : "", | ||
120 | + sampleData: parseData.rows[0][i] | ||
121 | + }; | ||
122 | + vm.columnsParam.push(columnParam); | ||
123 | + } | ||
124 | + } | ||
125 | + | ||
126 | + function addDevices () { | ||
127 | + var arrayParam = [{type: "ENTITY_FIELD", key: "name", sampleData: "Device 1"}, {type: "ENTITY_FIELD", key: "type", sampleData: "test"}, {type: "SERVER_ATTRIBUTE", key: "test", sampleData: "test"}, {type: "TIMESERIES", key: "testBoolean", sampleData: false}, {type: "SHARED_ATTRIBUTE", key: "testNumber", sampleData: 123}]; // eslint-disable-line | ||
128 | + var data = {headers: ["Device 1", "test", "test", "FALSE", "123"], | ||
129 | + rows:[["Device 1", "test", "test", false, 123.5]]}; | ||
130 | + // rows:[["Device 1", "test", "test", false, 123], | ||
131 | + // ["Device 2", "test", "test", false, 124], | ||
132 | + // ["Device 3", "test", "test", false, 125], | ||
133 | + // ["Device 4", "test", "test", false, 126], | ||
134 | + // ["Device 5", "test", "test", false, 127]]}; | ||
135 | + var arrayData = []; | ||
136 | + var config = { | ||
137 | + ignoreErrors: true | ||
138 | + }; | ||
139 | + for (var i = 0; i < data.rows.length; i ++) { | ||
140 | + var obj = { | ||
141 | + name: "", | ||
142 | + type: "", | ||
143 | + attributes: { | ||
144 | + server: [], | ||
145 | + shared: [] | ||
146 | + }, | ||
147 | + timeseries: [] | ||
148 | + }; | ||
149 | + for(var j = 0; j < arrayParam.length; j++){ | ||
150 | + switch (arrayParam[j].type) { | ||
151 | + case types.entityGroup.columnType.serverAttribute.value: | ||
152 | + obj.attributes.server.push({ | ||
153 | + key: arrayParam[j].key, | ||
154 | + value: data.rows[i][j] | ||
155 | + }); | ||
156 | + break; | ||
157 | + case types.entityGroup.columnType.sharedAttribute.value: | ||
158 | + obj.attributes.shared.push({ | ||
159 | + key: arrayParam[j].key, | ||
160 | + value: data.rows[i][j] | ||
161 | + }); | ||
162 | + break; | ||
163 | + case types.entityGroup.columnType.timeseries.value: | ||
164 | + obj.timeseries.push({ | ||
165 | + key: arrayParam[j].key, | ||
166 | + value: data.rows[i][j] | ||
167 | + }); | ||
168 | + break; | ||
169 | + case types.entityGroup.columnType.entityField.value: | ||
170 | + switch (arrayParam[j].key) { | ||
171 | + case types.entityGroup.entityField.name.value: | ||
172 | + obj.name = data.rows[i][j]; | ||
173 | + break; | ||
174 | + case types.entityGroup.entityField.type.value: | ||
175 | + obj.type = data.rows[i][j]; | ||
176 | + break; | ||
177 | + } | ||
178 | + break; | ||
179 | + } | ||
180 | + } | ||
181 | + arrayData.push(obj); | ||
182 | + } | ||
183 | + importExport.createMultiEntity(arrayData, vm.entityType, vm.importParams.isUpdate, config).then(function () { | ||
184 | + $mdDialog.hide(); | ||
185 | + }); | ||
186 | + } | ||
187 | + | ||
61 | function clearFile() { | 188 | function clearFile() { |
62 | $scope.theForm.$setDirty(); | 189 | $scope.theForm.$setDirty(); |
63 | vm.fileName = null; | 190 | vm.fileName = null; |
64 | vm.importData = null; | 191 | vm.importData = null; |
192 | + vm.columnsParam = []; | ||
65 | } | 193 | } |
66 | 194 | ||
67 | function importFromJson() { | 195 | function importFromJson() { |
@@ -26,7 +26,8 @@ | @@ -26,7 +26,8 @@ | ||
26 | </md-button> | 26 | </md-button> |
27 | </div> | 27 | </div> |
28 | </md-toolbar> | 28 | </md-toolbar> |
29 | - <md-progress-linear class="md-warn" md-mode="indeterminate" ng-disabled="!$root.loading" ng-show="$root.loading"></md-progress-linear> | 29 | + <md-progress-linear class="md-warn" md-mode="indeterminate" ng-disabled="!$root.loading" |
30 | + ng-show="$root.loading"></md-progress-linear> | ||
30 | <span style="min-height: 5px;" flex="" ng-show="!$root.loading"></span> | 31 | <span style="min-height: 5px;" flex="" ng-show="!$root.loading"></span> |
31 | <md-dialog-content> | 32 | <md-dialog-content> |
32 | <div class="md-dialog-content"> | 33 | <div class="md-dialog-content"> |
@@ -38,7 +39,8 @@ | @@ -38,7 +39,8 @@ | ||
38 | flow-file-added="vm.fileAdded( $file )" class="tb-file-select-container"> | 39 | flow-file-added="vm.fileAdded( $file )" class="tb-file-select-container"> |
39 | <div class="tb-file-clear-container"> | 40 | <div class="tb-file-clear-container"> |
40 | <md-button ng-click="vm.clearFile()" | 41 | <md-button ng-click="vm.clearFile()" |
41 | - class="tb-file-clear-btn md-icon-button md-primary" aria-label="{{ 'action.remove' | translate }}"> | 42 | + class="tb-file-clear-btn md-icon-button md-primary" |
43 | + aria-label="{{ 'action.remove' | translate }}"> | ||
42 | <md-tooltip md-direction="top"> | 44 | <md-tooltip md-direction="top"> |
43 | {{ 'action.remove' | translate }} | 45 | {{ 'action.remove' | translate }} |
44 | </md-tooltip> | 46 | </md-tooltip> |
@@ -49,7 +51,8 @@ | @@ -49,7 +51,8 @@ | ||
49 | </div> | 51 | </div> |
50 | <div class="alert tb-flow-drop" flow-drop> | 52 | <div class="alert tb-flow-drop" flow-drop> |
51 | <label for="select" translate>import.drop-file-csv</label> | 53 | <label for="select" translate>import.drop-file-csv</label> |
52 | - <input class="file-input" flow-btn flow-attrs="{accept:'.csv,application/csv,text/csv'}" id="select"> | 54 | + <input class="file-input" flow-btn |
55 | + flow-attrs="{accept:'.csv,application/csv,text/csv'}" id="select"> | ||
53 | </div> | 56 | </div> |
54 | </div> | 57 | </div> |
55 | </div> | 58 | </div> |
@@ -59,14 +62,81 @@ | @@ -59,14 +62,81 @@ | ||
59 | </div> | 62 | </div> |
60 | </div> | 63 | </div> |
61 | </fieldset> | 64 | </fieldset> |
65 | + <div flex layout="row"> | ||
66 | + <md-input-container class="md-block"> | ||
67 | + <label translate>CSV delimiter parametr</label> | ||
68 | + <input ng-model="vm.importParams.delim"> | ||
69 | + </md-input-container> | ||
70 | + <md-input-container class="md-block"> | ||
71 | + <md-checkbox ng-model="vm.importParams.isHeader" aria-label="Checkbox 1"> | ||
72 | + Use first line is header | ||
73 | + </md-checkbox> | ||
74 | + </md-input-container> | ||
75 | + <md-input-container class="md-block"> | ||
76 | + <md-checkbox ng-model="vm.importParams.isUpdate" aria-label="Checkbox 1"> | ||
77 | + Update parameter device | ||
78 | + </md-checkbox> | ||
79 | + </md-input-container> | ||
80 | + </div> | ||
81 | + <md-table-container flex class="tb-table-select"> | ||
82 | + <table md-table> | ||
83 | + <thead md-head> | ||
84 | + <tr md-row> | ||
85 | + <th md-column> </th> | ||
86 | + <th md-column>Example value data</th> | ||
87 | + <th md-column style="min-width: 140px">Column type</th> | ||
88 | + <th md-column style="min-width: 140px">Value</th> | ||
89 | + </tr> | ||
90 | + </thead> | ||
91 | + <tbody md-body> | ||
92 | + <tr md-row ng-repeat="column in vm.columnsParam"> | ||
93 | + <td md-cell>{{$index + 1}}</td> | ||
94 | + <td md-cell>{{column.sampleData}}</td> | ||
95 | + <td md-cell> | ||
96 | + <md-select ng-model="column.type" required name="columnType" | ||
97 | + aria-label="{{ 'entity-group.column-type' | translate }}"> | ||
98 | + <md-option ng-repeat="type in vm.columnTypes" ng-value="type.value"> | ||
99 | + {{type.name | translate}} | ||
100 | + </md-option> | ||
101 | + </md-select> | ||
102 | + </td> | ||
103 | + <td md-cell> | ||
104 | + <md-select ng-if="column.type == vm.columnTypes.entityField.value" | ||
105 | + required name="columnKey" ng-model="column.key" | ||
106 | + aria-label="{{ 'entity-group.column-value' | translate }}"> | ||
107 | + <md-option ng-repeat="field in vm.entityField" ng-value="field.value" ng-disabled="field.disable"> | ||
108 | + {{field.name | translate}} | ||
109 | + </md-option> | ||
110 | + </md-select> | ||
111 | + <md-input-container md-no-float | ||
112 | + ng-if="column.type != vm.columnTypes.entityField.value && | ||
113 | + column.type != vm.columnTypes.name.value && | ||
114 | + column.type != vm.columnTypes.type.value"> | ||
115 | + <input required name="columnKeyName" | ||
116 | + placeholder="{{ 'entity-group.column-value' | translate }}" | ||
117 | + ng-model="column.key" | ||
118 | + aria-label="{{ 'entity-group.column-value' | translate }}"> | ||
119 | + </md-input-container> | ||
120 | + </td> | ||
121 | + </tr> | ||
122 | + </tbody> | ||
123 | + </table> | ||
124 | + <md-divider></md-divider> | ||
125 | + </md-table-container> | ||
62 | </div> | 126 | </div> |
63 | </md-dialog-content> | 127 | </md-dialog-content> |
64 | <md-dialog-actions layout="row"> | 128 | <md-dialog-actions layout="row"> |
65 | <span flex></span> | 129 | <span flex></span> |
66 | - <md-button ng-disabled="$root.loading || !theForm.$dirty || !theForm.$valid || !vm.importData" type="submit" class="md-raised md-primary"> | 130 | + <md-button ng-disabled="$root.loading" ng-click="vm.addDevices()" style="margin-right:20px;"> |
131 | + Add Device | ||
132 | + </md-button> | ||
133 | + <md-button ng-disabled="$root.loading || !theForm.$dirty || !theForm.$valid || !vm.importData" type="submit" | ||
134 | + class="md-raised md-primary"> | ||
67 | {{ 'action.import' | translate }} | 135 | {{ 'action.import' | translate }} |
68 | </md-button> | 136 | </md-button> |
69 | - <md-button ng-disabled="$root.loading" ng-click="vm.cancel()" style="margin-right:20px;">{{ 'action.cancel' | translate }}</md-button> | 137 | + <md-button ng-disabled="$root.loading" ng-click="vm.cancel()" style="margin-right:20px;">{{ 'action.cancel' |
138 | + | translate }} | ||
139 | + </md-button> | ||
70 | </md-dialog-actions> | 140 | </md-dialog-actions> |
71 | </form> | 141 | </form> |
72 | </md-dialog> | 142 | </md-dialog> |
@@ -40,3 +40,13 @@ $previewSize: 100px !default; | @@ -40,3 +40,13 @@ $previewSize: 100px !default; | ||
40 | top: 50%; | 40 | top: 50%; |
41 | transform: translate(0%, -50%) !important; | 41 | transform: translate(0%, -50%) !important; |
42 | } | 42 | } |
43 | + | ||
44 | +.tb-table-select{ | ||
45 | + md-input-container{ | ||
46 | + margin: 0; | ||
47 | + | ||
48 | + .md-errors-spacer{ | ||
49 | + min-height: 0; | ||
50 | + } | ||
51 | + } | ||
52 | +} |
@@ -25,7 +25,7 @@ import entityAliasesTemplate from '../entity/alias/entity-aliases.tpl.html'; | @@ -25,7 +25,7 @@ import entityAliasesTemplate from '../entity/alias/entity-aliases.tpl.html'; | ||
25 | /* eslint-disable no-undef, angular/window-service, angular/document-service */ | 25 | /* eslint-disable no-undef, angular/window-service, angular/document-service */ |
26 | 26 | ||
27 | /*@ngInject*/ | 27 | /*@ngInject*/ |
28 | -export default function ImportExport($log, $translate, $q, $mdDialog, $document, $http, itembuffer, utils, types, | 28 | +export default function ImportExport($log, $translate, $q, $mdDialog, $document, $http, itembuffer, utils, types, $timeout, deviceService, |
29 | dashboardUtils, entityService, dashboardService, ruleChainService, widgetService, toast, attributeService) { | 29 | dashboardUtils, entityService, dashboardService, ruleChainService, widgetService, toast, attributeService) { |
30 | 30 | ||
31 | 31 | ||
@@ -43,7 +43,9 @@ export default function ImportExport($log, $translate, $q, $mdDialog, $document, | @@ -43,7 +43,9 @@ export default function ImportExport($log, $translate, $q, $mdDialog, $document, | ||
43 | exportExtension: exportExtension, | 43 | exportExtension: exportExtension, |
44 | importExtension: importExtension, | 44 | importExtension: importExtension, |
45 | importDevices: importDevices, | 45 | importDevices: importDevices, |
46 | - exportToPc: exportToPc | 46 | + convertCSVToJson: convertCSVToJson, |
47 | + exportToPc: exportToPc, | ||
48 | + createMultiEntity: createMultiEntity | ||
47 | }; | 49 | }; |
48 | 50 | ||
49 | return service; | 51 | return service; |
@@ -56,11 +58,11 @@ export default function ImportExport($log, $translate, $q, $mdDialog, $document, | @@ -56,11 +58,11 @@ export default function ImportExport($log, $translate, $q, $mdDialog, $document, | ||
56 | var bundleAlias = widgetsBundle.alias; | 58 | var bundleAlias = widgetsBundle.alias; |
57 | var isSystem = widgetsBundle.tenantId.id === types.id.nullUid; | 59 | var isSystem = widgetsBundle.tenantId.id === types.id.nullUid; |
58 | widgetService.getBundleWidgetTypes(bundleAlias, isSystem).then( | 60 | widgetService.getBundleWidgetTypes(bundleAlias, isSystem).then( |
59 | - function success (widgetTypes) { | 61 | + function success(widgetTypes) { |
60 | prepareExport(widgetsBundle); | 62 | prepareExport(widgetsBundle); |
61 | var widgetsBundleItem = { | 63 | var widgetsBundleItem = { |
62 | - widgetsBundle: prepareExport(widgetsBundle), | ||
63 | - widgetTypes: [] | 64 | + widgetsBundle: prepareExport(widgetsBundle), |
65 | + widgetTypes: [] | ||
64 | }; | 66 | }; |
65 | for (var t in widgetTypes) { | 67 | for (var t in widgetTypes) { |
66 | var widgetType = widgetTypes[t]; | 68 | var widgetType = widgetTypes[t]; |
@@ -70,10 +72,10 @@ export default function ImportExport($log, $translate, $q, $mdDialog, $document, | @@ -70,10 +72,10 @@ export default function ImportExport($log, $translate, $q, $mdDialog, $document, | ||
70 | widgetsBundleItem.widgetTypes.push(prepareExport(widgetType)); | 72 | widgetsBundleItem.widgetTypes.push(prepareExport(widgetType)); |
71 | } | 73 | } |
72 | var name = widgetsBundle.title; | 74 | var name = widgetsBundle.title; |
73 | - name = name.toLowerCase().replace(/\W/g,"_"); | 75 | + name = name.toLowerCase().replace(/\W/g, "_"); |
74 | exportToPc(widgetsBundleItem, name + '.json'); | 76 | exportToPc(widgetsBundleItem, name + '.json'); |
75 | }, | 77 | }, |
76 | - function fail (rejection) { | 78 | + function fail(rejection) { |
77 | var message = rejection; | 79 | var message = rejection; |
78 | if (!message) { | 80 | if (!message) { |
79 | message = $translate.instant('error.unknown-error'); | 81 | message = $translate.instant('error.unknown-error'); |
@@ -170,7 +172,7 @@ export default function ImportExport($log, $translate, $q, $mdDialog, $document, | @@ -170,7 +172,7 @@ export default function ImportExport($log, $translate, $q, $mdDialog, $document, | ||
170 | delete widgetType.bundleAlias; | 172 | delete widgetType.bundleAlias; |
171 | } | 173 | } |
172 | var name = widgetType.name; | 174 | var name = widgetType.name; |
173 | - name = name.toLowerCase().replace(/\W/g,"_"); | 175 | + name = name.toLowerCase().replace(/\W/g, "_"); |
174 | exportToPc(prepareExport(widgetType), name + '.json'); | 176 | exportToPc(prepareExport(widgetType), name + '.json'); |
175 | }, | 177 | }, |
176 | function fail(rejection) { | 178 | function fail(rejection) { |
@@ -211,8 +213,7 @@ export default function ImportExport($log, $translate, $q, $mdDialog, $document, | @@ -211,8 +213,7 @@ export default function ImportExport($log, $translate, $q, $mdDialog, $document, | ||
211 | 213 | ||
212 | function validateImportedWidgetType(widgetType) { | 214 | function validateImportedWidgetType(widgetType) { |
213 | if (angular.isUndefined(widgetType.name) | 215 | if (angular.isUndefined(widgetType.name) |
214 | - || angular.isUndefined(widgetType.descriptor)) | ||
215 | - { | 216 | + || angular.isUndefined(widgetType.descriptor)) { |
216 | return false; | 217 | return false; |
217 | } | 218 | } |
218 | return true; | 219 | return true; |
@@ -230,7 +231,7 @@ export default function ImportExport($log, $translate, $q, $mdDialog, $document, | @@ -230,7 +231,7 @@ export default function ImportExport($log, $translate, $q, $mdDialog, $document, | ||
230 | metadata: prepareRuleChainMetaData(ruleChainMetaData) | 231 | metadata: prepareRuleChainMetaData(ruleChainMetaData) |
231 | }; | 232 | }; |
232 | var name = ruleChain.name; | 233 | var name = ruleChain.name; |
233 | - name = name.toLowerCase().replace(/\W/g,"_"); | 234 | + name = name.toLowerCase().replace(/\W/g, "_"); |
234 | exportToPc(ruleChainExport, name + '.json'); | 235 | exportToPc(ruleChainExport, name + '.json'); |
235 | }, | 236 | }, |
236 | (rejection) => { | 237 | (rejection) => { |
@@ -255,7 +256,7 @@ export default function ImportExport($log, $translate, $q, $mdDialog, $document, | @@ -255,7 +256,7 @@ export default function ImportExport($log, $translate, $q, $mdDialog, $document, | ||
255 | 256 | ||
256 | function prepareRuleChainMetaData(ruleChainMetaData) { | 257 | function prepareRuleChainMetaData(ruleChainMetaData) { |
257 | delete ruleChainMetaData.ruleChainId; | 258 | delete ruleChainMetaData.ruleChainId; |
258 | - for (var i=0;i<ruleChainMetaData.nodes.length;i++) { | 259 | + for (var i = 0; i < ruleChainMetaData.nodes.length; i++) { |
259 | var node = ruleChainMetaData.nodes[i]; | 260 | var node = ruleChainMetaData.nodes[i]; |
260 | delete node.ruleChainId; | 261 | delete node.ruleChainId; |
261 | ruleChainMetaData.nodes[i] = prepareExport(node); | 262 | ruleChainMetaData.nodes[i] = prepareExport(node); |
@@ -307,7 +308,7 @@ export default function ImportExport($log, $translate, $q, $mdDialog, $document, | @@ -307,7 +308,7 @@ export default function ImportExport($log, $translate, $q, $mdDialog, $document, | ||
307 | function exportWidget(dashboard, sourceState, sourceLayout, widget) { | 308 | function exportWidget(dashboard, sourceState, sourceLayout, widget) { |
308 | var widgetItem = itembuffer.prepareWidgetItem(dashboard, sourceState, sourceLayout, widget); | 309 | var widgetItem = itembuffer.prepareWidgetItem(dashboard, sourceState, sourceLayout, widget); |
309 | var name = widgetItem.widget.config.title; | 310 | var name = widgetItem.widget.config.title; |
310 | - name = name.toLowerCase().replace(/\W/g,"_"); | 311 | + name = name.toLowerCase().replace(/\W/g, "_"); |
311 | exportToPc(prepareExport(widgetItem), name + '.json'); | 312 | exportToPc(prepareExport(widgetItem), name + '.json'); |
312 | } | 313 | } |
313 | 314 | ||
@@ -417,10 +418,10 @@ export default function ImportExport($log, $translate, $q, $mdDialog, $document, | @@ -417,10 +418,10 @@ export default function ImportExport($log, $translate, $q, $mdDialog, $document, | ||
417 | var aliasIds = Object.keys(entityAliases); | 418 | var aliasIds = Object.keys(entityAliases); |
418 | if (aliasIds.length > 0) { | 419 | if (aliasIds.length > 0) { |
419 | processEntityAliases(entityAliases, aliasIds).then( | 420 | processEntityAliases(entityAliases, aliasIds).then( |
420 | - function(missingEntityAliases) { | 421 | + function (missingEntityAliases) { |
421 | if (Object.keys(missingEntityAliases).length > 0) { | 422 | if (Object.keys(missingEntityAliases).length > 0) { |
422 | - editMissingAliases($event, [ widget ], | ||
423 | - true, 'dashboard.widget-import-missing-aliases-title', missingEntityAliases).then( | 423 | + editMissingAliases($event, [widget], |
424 | + true, 'dashboard.widget-import-missing-aliases-title', missingEntityAliases).then( | ||
424 | function success(updatedEntityAliases) { | 425 | function success(updatedEntityAliases) { |
425 | for (var aliasId in updatedEntityAliases) { | 426 | for (var aliasId in updatedEntityAliases) { |
426 | var entityAlias = updatedEntityAliases[aliasId]; | 427 | var entityAlias = updatedEntityAliases[aliasId]; |
@@ -485,14 +486,14 @@ export default function ImportExport($log, $translate, $q, $mdDialog, $document, | @@ -485,14 +486,14 @@ export default function ImportExport($log, $translate, $q, $mdDialog, $document, | ||
485 | function success(targetLayout) { | 486 | function success(targetLayout) { |
486 | itembuffer.addWidgetToDashboard(dashboard, targetState, targetLayout, widget, | 487 | itembuffer.addWidgetToDashboard(dashboard, targetState, targetLayout, widget, |
487 | aliasesInfo, onAliasesUpdateFunction, originalColumns, originalSize, -1, -1).then( | 488 | aliasesInfo, onAliasesUpdateFunction, originalColumns, originalSize, -1, -1).then( |
488 | - function() { | ||
489 | - deferred.resolve( | ||
490 | - { | ||
491 | - widget: widget, | ||
492 | - layoutId: targetLayout | ||
493 | - } | ||
494 | - ); | ||
495 | - } | 489 | + function () { |
490 | + deferred.resolve( | ||
491 | + { | ||
492 | + widget: widget, | ||
493 | + layoutId: targetLayout | ||
494 | + } | ||
495 | + ); | ||
496 | + } | ||
496 | ); | 497 | ); |
497 | }, | 498 | }, |
498 | function fail() { | 499 | function fail() { |
@@ -507,7 +508,7 @@ export default function ImportExport($log, $translate, $q, $mdDialog, $document, | @@ -507,7 +508,7 @@ export default function ImportExport($log, $translate, $q, $mdDialog, $document, | ||
507 | dashboardService.getDashboard(dashboardId).then( | 508 | dashboardService.getDashboard(dashboardId).then( |
508 | function success(dashboard) { | 509 | function success(dashboard) { |
509 | var name = dashboard.title; | 510 | var name = dashboard.title; |
510 | - name = name.toLowerCase().replace(/\W/g,"_"); | 511 | + name = name.toLowerCase().replace(/\W/g, "_"); |
511 | exportToPc(prepareDashboardExport(dashboard), name + '.json'); | 512 | exportToPc(prepareDashboardExport(dashboard), name + '.json'); |
512 | }, | 513 | }, |
513 | function fail(rejection) { | 514 | function fail(rejection) { |
@@ -540,13 +541,13 @@ export default function ImportExport($log, $translate, $q, $mdDialog, $document, | @@ -540,13 +541,13 @@ export default function ImportExport($log, $translate, $q, $mdDialog, $document, | ||
540 | dashboard = dashboardUtils.validateAndUpdateDashboard(dashboard); | 541 | dashboard = dashboardUtils.validateAndUpdateDashboard(dashboard); |
541 | var entityAliases = dashboard.configuration.entityAliases; | 542 | var entityAliases = dashboard.configuration.entityAliases; |
542 | if (entityAliases) { | 543 | if (entityAliases) { |
543 | - var aliasIds = Object.keys( entityAliases ); | 544 | + var aliasIds = Object.keys(entityAliases); |
544 | if (aliasIds.length > 0) { | 545 | if (aliasIds.length > 0) { |
545 | processEntityAliases(entityAliases, aliasIds).then( | 546 | processEntityAliases(entityAliases, aliasIds).then( |
546 | - function(missingEntityAliases) { | ||
547 | - if (Object.keys( missingEntityAliases ).length > 0) { | 547 | + function (missingEntityAliases) { |
548 | + if (Object.keys(missingEntityAliases).length > 0) { | ||
548 | editMissingAliases($event, dashboard.configuration.widgets, | 549 | editMissingAliases($event, dashboard.configuration.widgets, |
549 | - false, 'dashboard.dashboard-import-missing-aliases-title', missingEntityAliases).then( | 550 | + false, 'dashboard.dashboard-import-missing-aliases-title', missingEntityAliases).then( |
550 | function success(updatedEntityAliases) { | 551 | function success(updatedEntityAliases) { |
551 | for (var aliasId in updatedEntityAliases) { | 552 | for (var aliasId in updatedEntityAliases) { |
552 | entityAliases[aliasId] = updatedEntityAliases[aliasId]; | 553 | entityAliases[aliasId] = updatedEntityAliases[aliasId]; |
@@ -617,6 +618,7 @@ export default function ImportExport($log, $translate, $q, $mdDialog, $document, | @@ -617,6 +618,7 @@ export default function ImportExport($log, $translate, $q, $mdDialog, $document, | ||
617 | // saveImportedDashboard(dashboard, deferred); | 618 | // saveImportedDashboard(dashboard, deferred); |
618 | // } | 619 | // } |
619 | // } | 620 | // } |
621 | + deferred.resolve(); | ||
620 | }, | 622 | }, |
621 | function fail() { | 623 | function fail() { |
622 | deferred.reject(); | 624 | deferred.reject(); |
@@ -644,14 +646,13 @@ export default function ImportExport($log, $translate, $q, $mdDialog, $document, | @@ -644,14 +646,13 @@ export default function ImportExport($log, $translate, $q, $mdDialog, $document, | ||
644 | } | 646 | } |
645 | 647 | ||
646 | 648 | ||
647 | - | ||
648 | function exportExtension(extensionId) { | 649 | function exportExtension(extensionId) { |
649 | 650 | ||
650 | getExtension(extensionId) | 651 | getExtension(extensionId) |
651 | .then( | 652 | .then( |
652 | function success(extension) { | 653 | function success(extension) { |
653 | var name = extension.title; | 654 | var name = extension.title; |
654 | - name = name.toLowerCase().replace(/\W/g,"_"); | 655 | + name = name.toLowerCase().replace(/\W/g, "_"); |
655 | exportToPc(prepareExport(extension), name + '.json'); | 656 | exportToPc(prepareExport(extension), name + '.json'); |
656 | }, | 657 | }, |
657 | function fail(rejection) { | 658 | function fail(rejection) { |
@@ -711,7 +712,7 @@ export default function ImportExport($log, $translate, $q, $mdDialog, $document, | @@ -711,7 +712,7 @@ export default function ImportExport($log, $translate, $q, $mdDialog, $document, | ||
711 | function validateImportedExtension(configuration) { | 712 | function validateImportedExtension(configuration) { |
712 | if (configuration.length) { | 713 | if (configuration.length) { |
713 | for (let i = 0; i < configuration.length; i++) { | 714 | for (let i = 0; i < configuration.length; i++) { |
714 | - if (angular.isUndefined(configuration[i].configuration) || angular.isUndefined(configuration[i].id )|| angular.isUndefined(configuration[i].type)) { | 715 | + if (angular.isUndefined(configuration[i].configuration) || angular.isUndefined(configuration[i].id) || angular.isUndefined(configuration[i].type)) { |
715 | return false; | 716 | return false; |
716 | } | 717 | } |
717 | } | 718 | } |
@@ -742,7 +743,7 @@ export default function ImportExport($log, $translate, $q, $mdDialog, $document, | @@ -742,7 +743,7 @@ export default function ImportExport($log, $translate, $q, $mdDialog, $document, | ||
742 | var aliasId = aliasIds[index]; | 743 | var aliasId = aliasIds[index]; |
743 | var entityAlias = entityAliases[aliasId]; | 744 | var entityAlias = entityAliases[aliasId]; |
744 | entityService.checkEntityAlias(entityAlias).then( | 745 | entityService.checkEntityAlias(entityAlias).then( |
745 | - function(result) { | 746 | + function (result) { |
746 | if (result) { | 747 | if (result) { |
747 | checkNextEntityAliasOrComplete(index, aliasIds, entityAliases, missingEntityAliases, deferred); | 748 | checkNextEntityAliasOrComplete(index, aliasIds, entityAliases, missingEntityAliases, deferred); |
748 | } else { | 749 | } else { |
@@ -782,6 +783,91 @@ export default function ImportExport($log, $translate, $q, $mdDialog, $document, | @@ -782,6 +783,91 @@ export default function ImportExport($log, $translate, $q, $mdDialog, $document, | ||
782 | return deferred.promise; | 783 | return deferred.promise; |
783 | } | 784 | } |
784 | 785 | ||
786 | + /** | ||
787 | + * splitCSV function (c) 2009 Brian Huisman, see http://www.greywyvern.com/?post=258 | ||
788 | + * Works by spliting on seperators first, then patching together quoted values | ||
789 | + */ | ||
790 | + function splitCSV(str, sep) { | ||
791 | + for (var foo = str.split(sep = sep || ","), x = foo.length - 1, tl; x >= 0; x--) { | ||
792 | + if (foo[x].replace(/"\s+$/, '"').charAt(foo[x].length - 1) == '"') { | ||
793 | + if ((tl = foo[x].replace(/^\s+"/, '"')).length > 1 && tl.charAt(0) == '"') { | ||
794 | + foo[x] = foo[x].replace(/^\s*"|"\s*$/g, '').replace(/""/g, '"'); | ||
795 | + } else if (x) { | ||
796 | + foo.splice(x - 1, 2, [foo[x - 1], foo[x]].join(sep)); | ||
797 | + } else foo = foo.shift().split(sep).concat(foo); | ||
798 | + } else foo[x].replace(/""/g, '"'); | ||
799 | + } | ||
800 | + return foo; | ||
801 | + } | ||
802 | + | ||
803 | + function isNumeric(str) { | ||
804 | + str = str.replace(',', '.'); | ||
805 | + return !isNaN(parseFloat(str)) && isFinite(str); | ||
806 | + } | ||
807 | + | ||
808 | + function parseStringToFormatJS(str) { | ||
809 | + if (isNumeric(str.replace(',', '.'))) { | ||
810 | + return parseFloat(str.replace(',', '.')); | ||
811 | + } | ||
812 | + if (str.search(/^(true|false)$/im) === 0) { | ||
813 | + return str.toLowerCase() === 'true'; | ||
814 | + } | ||
815 | + if (str === "") { | ||
816 | + return null; | ||
817 | + } | ||
818 | + return str; | ||
819 | + } | ||
820 | + | ||
821 | + function convertCSVToJson(csvdata, config) { | ||
822 | + config = config || {}; | ||
823 | + const delim = config.delim || ","; | ||
824 | + const header = config.header || false; | ||
825 | + | ||
826 | + let csvlines = csvdata.split(/[\r\n]+/); | ||
827 | + let csvheaders = splitCSV(csvlines[0], delim); | ||
828 | + let csvrows = header ? csvlines.slice(1, csvlines.length) : csvlines; | ||
829 | + | ||
830 | + let result = {}; | ||
831 | + result.headers = csvheaders; | ||
832 | + result.rows = []; | ||
833 | + | ||
834 | + for (let r in csvrows) { | ||
835 | + if (csvrows.hasOwnProperty(r)) { | ||
836 | + let row = csvrows[r]; | ||
837 | + | ||
838 | + if (row.length === 0) | ||
839 | + break; | ||
840 | + | ||
841 | + let rowitems = splitCSV(row, delim); | ||
842 | + for (let i = 0; i < rowitems.length; i++) { | ||
843 | + rowitems[i] = parseStringToFormatJS(rowitems[i]); | ||
844 | + } | ||
845 | + result.rows.push(rowitems); | ||
846 | + } | ||
847 | + } | ||
848 | + return result; | ||
849 | + } | ||
850 | + | ||
851 | + function createMultiEntity(arrayData, entityType, update, config) { | ||
852 | + var deferred = $q.defer(); | ||
853 | + var allPromise = []; | ||
854 | + switch (entityType) { | ||
855 | + case types.entityType.device: | ||
856 | + for(var i = 0; i < arrayData.length; i++){ | ||
857 | + var promise = deviceService.saveDeviceParameters(arrayData[i], update, config); | ||
858 | + allPromise.push(promise); | ||
859 | + } | ||
860 | + break; | ||
861 | + } | ||
862 | + $q.all(allPromise).then(function success() { | ||
863 | + deferred.resolve(); | ||
864 | + $timeout(function () { | ||
865 | + console.log("1"); // eslint-disable-line | ||
866 | + }, 1000); | ||
867 | + }); | ||
868 | + return deferred.promise; | ||
869 | + } | ||
870 | + | ||
785 | // Common functions | 871 | // Common functions |
786 | 872 | ||
787 | function prepareExport(data) { | 873 | function prepareExport(data) { |
@@ -821,8 +907,7 @@ export default function ImportExport($log, $translate, $q, $mdDialog, $document, | @@ -821,8 +907,7 @@ export default function ImportExport($log, $translate, $q, $mdDialog, $document, | ||
821 | 907 | ||
822 | if (window.navigator && window.navigator.msSaveOrOpenBlob) { | 908 | if (window.navigator && window.navigator.msSaveOrOpenBlob) { |
823 | window.navigator.msSaveOrOpenBlob(blob, filename); | 909 | window.navigator.msSaveOrOpenBlob(blob, filename); |
824 | - } | ||
825 | - else{ | 910 | + } else { |
826 | var e = document.createEvent('MouseEvents'), | 911 | var e = document.createEvent('MouseEvents'), |
827 | a = document.createElement('a'); | 912 | a = document.createElement('a'); |
828 | 913 | ||
@@ -873,7 +958,6 @@ export default function ImportExport($log, $translate, $q, $mdDialog, $document, | @@ -873,7 +958,6 @@ export default function ImportExport($log, $translate, $q, $mdDialog, $document, | ||
873 | targetEvent: $event | 958 | targetEvent: $event |
874 | }).then(function (importData) { | 959 | }).then(function (importData) { |
875 | deferred.resolve(importData); | 960 | deferred.resolve(importData); |
876 | - | ||
877 | }, function () { | 961 | }, function () { |
878 | deferred.reject(); | 962 | deferred.reject(); |
879 | }); | 963 | }); |
@@ -778,6 +778,22 @@ | @@ -778,6 +778,22 @@ | ||
778 | "no-data": "No data to display", | 778 | "no-data": "No data to display", |
779 | "columns-to-display": "Columns to Display" | 779 | "columns-to-display": "Columns to Display" |
780 | }, | 780 | }, |
781 | + "entity-group": { | ||
782 | + "column-value": "Value", | ||
783 | + "column-title": "Title", | ||
784 | + "column-type": { | ||
785 | + "column-type": "Column type", | ||
786 | + "shared-attribute": "Shared attribute", | ||
787 | + "server-attribute": "Server attribute", | ||
788 | + "timeseries": "Timeseries", | ||
789 | + "entity-field": "Entity field" | ||
790 | + }, | ||
791 | + "entity-field": { | ||
792 | + "name": "Name", | ||
793 | + "type": "Type", | ||
794 | + "assigned_customer": "Assigned Customer" | ||
795 | + } | ||
796 | + }, | ||
781 | "entity-view": { | 797 | "entity-view": { |
782 | "entity-view": "Entity View", | 798 | "entity-view": "Entity View", |
783 | "entity-view-required": "Entity view is required.", | 799 | "entity-view-required": "Entity view is required.", |