From 68e9844f535c7ec6e5527143d696157319b11389 Mon Sep 17 00:00:00 2001 From: Vladyslav_Prykhodko Date: Mon, 20 May 2019 11:57:43 +0300 Subject: [PATCH] Add device --- ui/src/app/api/attribute.service.js | 75 ++++++++- ui/src/app/api/device.service.js | 86 ++++++++-- ui/src/app/common/types.constant.js | 34 ++++ .../import-dialog-csv.controller.js | 136 ++++++++++++++- .../import-export/import-dialog-csv.tpl.html | 80 ++++++++- ui/src/app/import-export/import-dialog.scss | 10 ++ .../import-export/import-export.service.js | 156 ++++++++++++++---- ui/src/app/locale/locale.constant-en_US.json | 16 ++ 8 files changed, 533 insertions(+), 60 deletions(-) diff --git a/ui/src/app/api/attribute.service.js b/ui/src/app/api/attribute.service.js index 599f44c59e..df34674f48 100644 --- a/ui/src/app/api/attribute.service.js +++ b/ui/src/app/api/attribute.service.js @@ -30,7 +30,9 @@ function AttributeService($http, $q, $filter, types, telemetryWebsocketService) subscribeForEntityAttributes: subscribeForEntityAttributes, unsubscribeForEntityAttributes: unsubscribeForEntityAttributes, saveEntityAttributes: saveEntityAttributes, - deleteEntityAttributes: deleteEntityAttributes + deleteEntityAttributes: deleteEntityAttributes, + saveEntityTimeseries: saveEntityTimeseries, + deleteEntityTimeseries: deleteEntityTimeseries } return service; @@ -212,7 +214,8 @@ function AttributeService($http, $q, $filter, types, telemetryWebsocketService) } } - function saveEntityAttributes(entityType, entityId, attributeScope, attributes) { + function saveEntityAttributes(entityType, entityId, attributeScope, attributes, config) { + config = config || {}; var deferred = $q.defer(); var attributesData = {}; var deleteAttributes = []; @@ -229,7 +232,7 @@ function AttributeService($http, $q, $filter, types, telemetryWebsocketService) } if (Object.keys(attributesData).length) { var url = '/api/plugins/telemetry/' + entityType + '/' + entityId + '/' + attributeScope; - $http.post(url, attributesData).then(function success(response) { + $http.post(url, attributesData, config).then(function success(response) { if (deleteEntityAttributesPromise) { deleteEntityAttributesPromise.then( function success() { @@ -260,6 +263,55 @@ function AttributeService($http, $q, $filter, types, telemetryWebsocketService) return deferred.promise; } + function saveEntityTimeseries(entityType, entityId, timeseriesScope, timeseries, config) { + config = config || {}; + var deferred = $q.defer(); + var timeseriesData = {}; + var deleteTimeseries = []; + for (var a=0; a 0) { + keys += ','; + } + keys += timeseries[i].key; + } + var url = '/api/plugins/telemetry/' + entityType + '/' + entityId + '/timeseries/delete' + '?keys=' + keys; + $http.delete(url).then(function success() { + deferred.resolve(); + }, function fail() { + deferred.reject(); + }); + return deferred.promise; + } } \ No newline at end of file diff --git a/ui/src/app/api/device.service.js b/ui/src/app/api/device.service.js index 1a25d70eb7..3df99cb7cd 100644 --- a/ui/src/app/api/device.service.js +++ b/ui/src/app/api/device.service.js @@ -31,6 +31,7 @@ function DeviceService($http, $q, $window, userService, attributeService, custom getDeviceCredentials: getDeviceCredentials, getTenantDevices: getTenantDevices, saveDevice: saveDevice, + saveDeviceParameters: saveDeviceParameters, saveDeviceCredentials: saveDeviceCredentials, unassignDeviceFromCustomer: unassignDeviceFromCustomer, makeDevicePublic: makeDevicePublic, @@ -42,7 +43,8 @@ function DeviceService($http, $q, $window, userService, attributeService, custom sendOneWayRpcCommand: sendOneWayRpcCommand, sendTwoWayRpcCommand: sendTwoWayRpcCommand, findByQuery: findByQuery, - getDeviceTypes: getDeviceTypes + getDeviceTypes: getDeviceTypes, + findByName: findByName } return service; @@ -124,7 +126,7 @@ function DeviceService($http, $q, $window, userService, attributeService, custom if (!config) { config = {}; } - config = Object.assign(config, { ignoreErrors: ignoreErrors }); + config = Object.assign(config, {ignoreErrors: ignoreErrors}); $http.get(url, config).then(function success(response) { deferred.resolve(response.data); }, function fail(response) { @@ -136,8 +138,8 @@ function DeviceService($http, $q, $window, userService, attributeService, custom function getDevices(deviceIds, config) { var deferred = $q.defer(); var ids = ''; - for (var i=0;i0) { + for (var i = 0; i < deviceIds.length; i++) { + if (i > 0) { ids += ','; } ids += deviceIds[i]; @@ -146,11 +148,11 @@ function DeviceService($http, $q, $window, userService, attributeService, custom $http.get(url, config).then(function success(response) { var devices = response.data; devices.sort(function (device1, device2) { - var id1 = device1.id.id; - var id2 = device2.id.id; - var index1 = deviceIds.indexOf(id1); - var index2 = deviceIds.indexOf(id2); - return index1 - index2; + var id1 = device1.id.id; + var id2 = device2.id.id; + var index1 = deviceIds.indexOf(id1); + var index2 = deviceIds.indexOf(id2); + return index1 - index2; }); deferred.resolve(devices); }, function fail(response) { @@ -159,10 +161,11 @@ function DeviceService($http, $q, $window, userService, attributeService, custom return deferred.promise; } - function saveDevice(device) { + function saveDevice(device, config) { + config = config || {}; var deferred = $q.defer(); var url = '/api/device'; - $http.post(url, device).then(function success(response) { + $http.post(url, device, config).then(function success(response) { deferred.resolve(response.data); }, function fail() { deferred.reject(); @@ -170,6 +173,54 @@ function DeviceService($http, $q, $window, userService, attributeService, custom return deferred.promise; } + function saveDeviceRelarion(deviceId, deviceRelation, config) { + var deferred = $q.defer(); + var attributesType = Object.keys(types.attributesScope); + var allPromise = []; + var promise = ""; + for (var i = 0; i < attributesType.length; i++) { + if (deviceRelation.attributes[attributesType[i]] && deviceRelation.attributes[attributesType[i]].length !== 0) { + promise = attributeService.saveEntityAttributes(types.entityType.device, deviceId, types.attributesScope[attributesType[i]].value, deviceRelation.attributes[attributesType[i]], config).then(function success() {}); + allPromise.push(promise); + } + } + if (deviceRelation.timeseries.length !== 0) { + promise = attributeService.saveEntityTimeseries(types.entityType.device, deviceId, "time", deviceRelation.timeseries, config).then(function success() { + }); + allPromise.push(promise); + } + $q.all(allPromise).then(function success() { + deferred.resolve(); + }); + return deferred.promise; + } + + function saveDeviceParameters(deviceParameters, update, config) { + config = config || {}; + var deferred = $q.defer(); + var newDevice = { + name: deviceParameters.name, + type: deviceParameters.type + }; + saveDevice(newDevice, config).then(function success(response) { + saveDeviceRelarion(response.id.id, deviceParameters, config).then(function success() { + deferred.resolve(); + }); + }, function fail() { + if (update) { + findByName(deviceParameters.name, config).then(function success(response) { + saveDeviceRelarion(response.id.id, deviceParameters, config).then(function success() { + deferred.resolve(); + }); + }); + } else { + deferred.resolve(); + } + console.log("error"); // eslint-disable-line + }); + return deferred.promise; + } + function deleteDevice(deviceId) { var deferred = $q.defer(); var url = '/api/device/' + deviceId; @@ -297,7 +348,7 @@ function DeviceService($http, $q, $window, userService, attributeService, custom if (!config) { config = {}; } - config = Object.assign(config, { ignoreErrors: ignoreErrors }); + config = Object.assign(config, {ignoreErrors: ignoreErrors}); $http.post(url, query, config).then(function success(response) { deferred.resolve(response.data); }, function fail() { @@ -317,4 +368,15 @@ function DeviceService($http, $q, $window, userService, attributeService, custom return deferred.promise; } + function findByName(deviceName, config) { + config = config || {}; + var deferred = $q.defer(); + var url = '/api/tenant/devices?deviceName=' + deviceName; + $http.get(url, config).then(function success(response) { + deferred.resolve(response.data); + }, function fail() { + deferred.reject(); + }); + return deferred.promise; + } } diff --git a/ui/src/app/common/types.constant.js b/ui/src/app/common/types.constant.js index 8e85e1a054..08d16b40c9 100644 --- a/ui/src/app/common/types.constant.js +++ b/ui/src/app/common/types.constant.js @@ -350,6 +350,40 @@ export default angular.module('thingsboard.types', []) rulenode: "RULE_NODE", entityView: "ENTITY_VIEW" }, + entityGroup: { + columnType: { + sharedAttribute: { + name: 'entity-group.column-type.shared-attribute', + value: 'SHARED_ATTRIBUTE' + }, + serverAttribute: { + name: 'entity-group.column-type.server-attribute', + value: 'SERVER_ATTRIBUTE' + }, + timeseries: { + name: 'entity-group.column-type.timeseries', + value: 'TIMESERIES' + }, + entityField: { + name: 'entity-group.column-type.entity-field', + value: 'ENTITY_FIELD' + } + }, + entityField: { + name: { + name: 'entity-group.entity-field.name', + value: 'name' + }, + type: { + name: 'entity-group.entity-field.type', + value: 'type' + }, + assigned_customer: { + name: 'entity-group.entity-field.assigned_customer', + value: 'assigned_customer' + } + } + }, aliasEntityType: { current_customer: "CURRENT_CUSTOMER" }, diff --git a/ui/src/app/import-export/import-dialog-csv.controller.js b/ui/src/app/import-export/import-dialog-csv.controller.js index 91596c4399..b45d73b816 100644 --- a/ui/src/app/import-export/import-dialog-csv.controller.js +++ b/ui/src/app/import-export/import-dialog-csv.controller.js @@ -16,7 +16,7 @@ import './import-dialog.scss'; /*@ngInject*/ -export default function ImportDialogCsvController($scope, $mdDialog, toast, importTitle, importFileLabel) { +export default function ImportDialogCsvController($scope, $mdDialog, toast, importTitle, importFileLabel, importExport, types, $timeout) { var vm = this; @@ -25,9 +25,58 @@ export default function ImportDialogCsvController($scope, $mdDialog, toast, impo vm.fileAdded = fileAdded; vm.clearFile = clearFile; + vm.addDevices = addDevices; + vm.importParams = { + isUpdate: true + }; + vm.importTitle = importTitle; vm.importFileLabel = importFileLabel; + vm.columnsParam = []; + + vm.entityType = types.entityType.device; + vm.columnTypes = {}; + vm.entityField = {}; + + var parseData = {}; + + switch (vm.entityType) { + case types.entityType.device: + vm.columnTypes = types.entityGroup.columnType; + break; + } + + vm.entityField.name = types.entityGroup.entityField.name; + + switch (vm.entityType) { + case types.entityType.device: + vm.entityField.type = types.entityGroup.entityField.type; + // vm.entityField.assigned_customer = types.entityGroup.entityField.assigned_customer; + break; + } + + $scope.$watch('vm.columnsParam', function(newVal, prevVal){ + if (newVal && !angular.equals(newVal, prevVal)) { + var isSelectName = false; + var isSelectType = false; + for (var i = 0; i < newVal.length; i++) { + if (newVal[i].type === types.entityGroup.columnType.entityField.value && + newVal[i].key === types.entityGroup.entityField.name.value) { + isSelectName = true; + } + if (newVal[i].type === types.entityGroup.columnType.entityField.value && + newVal[i].key === types.entityGroup.entityField.type.value) { + isSelectType = true; + } + } + $timeout(function () { + vm.entityField.name.disable = isSelectName; + vm.entityField.type.disable = isSelectType; + }); + } + }, true); + function cancel() { $mdDialog.cancel(); @@ -36,16 +85,16 @@ export default function ImportDialogCsvController($scope, $mdDialog, toast, impo function fileAdded($file) { if ($file.getExtension() === 'csv') { var reader = new FileReader(); - reader.onload = function(event) { - $scope.$apply(function() { + reader.onload = function (event) { + $scope.$apply(function () { if (event.target.result) { $scope.theForm.$setDirty(); var importCSV = event.target.result; if (importCSV && importCSV.length > 0) { try { vm.importData = importCSV; - console.log(vm.importData); // eslint-disable-line vm.fileName = $file.name; + parseCSVData(vm.importData); } catch (err) { vm.fileName = null; toast.showError(err.message); @@ -58,10 +107,89 @@ export default function ImportDialogCsvController($scope, $mdDialog, toast, impo } } + function parseCSVData(importData) { + var config = { + delim: vm.importParams.delim, + header: vm.importParams.isHeader + }; + parseData = importExport.convertCSVToJson(importData, config); + for (var i = 0; i < parseData.headers.length; i++) { + var columnParam = { + type: types.entityGroup.columnType.serverAttribute.value, + key: vm.importParams.isHeader ? parseData.headers[i] : "", + sampleData: parseData.rows[0][i] + }; + vm.columnsParam.push(columnParam); + } + } + + function addDevices () { + 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 + var data = {headers: ["Device 1", "test", "test", "FALSE", "123"], + rows:[["Device 1", "test", "test", false, 123.5]]}; + // rows:[["Device 1", "test", "test", false, 123], + // ["Device 2", "test", "test", false, 124], + // ["Device 3", "test", "test", false, 125], + // ["Device 4", "test", "test", false, 126], + // ["Device 5", "test", "test", false, 127]]}; + var arrayData = []; + var config = { + ignoreErrors: true + }; + for (var i = 0; i < data.rows.length; i ++) { + var obj = { + name: "", + type: "", + attributes: { + server: [], + shared: [] + }, + timeseries: [] + }; + for(var j = 0; j < arrayParam.length; j++){ + switch (arrayParam[j].type) { + case types.entityGroup.columnType.serverAttribute.value: + obj.attributes.server.push({ + key: arrayParam[j].key, + value: data.rows[i][j] + }); + break; + case types.entityGroup.columnType.sharedAttribute.value: + obj.attributes.shared.push({ + key: arrayParam[j].key, + value: data.rows[i][j] + }); + break; + case types.entityGroup.columnType.timeseries.value: + obj.timeseries.push({ + key: arrayParam[j].key, + value: data.rows[i][j] + }); + break; + case types.entityGroup.columnType.entityField.value: + switch (arrayParam[j].key) { + case types.entityGroup.entityField.name.value: + obj.name = data.rows[i][j]; + break; + case types.entityGroup.entityField.type.value: + obj.type = data.rows[i][j]; + break; + } + break; + } + } + arrayData.push(obj); + } + importExport.createMultiEntity(arrayData, vm.entityType, vm.importParams.isUpdate, config).then(function () { + $mdDialog.hide(); + }); + } + function clearFile() { $scope.theForm.$setDirty(); vm.fileName = null; vm.importData = null; + vm.columnsParam = []; } function importFromJson() { diff --git a/ui/src/app/import-export/import-dialog-csv.tpl.html b/ui/src/app/import-export/import-dialog-csv.tpl.html index 0bc2e6448b..a275c5c7e4 100644 --- a/ui/src/app/import-export/import-dialog-csv.tpl.html +++ b/ui/src/app/import-export/import-dialog-csv.tpl.html @@ -26,7 +26,8 @@ - +
@@ -38,7 +39,8 @@ flow-file-added="vm.fileAdded( $file )" class="tb-file-select-container">
+ class="tb-file-clear-btn md-icon-button md-primary" + aria-label="{{ 'action.remove' | translate }}"> {{ 'action.remove' | translate }} @@ -49,7 +51,8 @@
- +
@@ -59,14 +62,81 @@ +
+ + + + + + + Use first line is header + + + + + Update parameter device + + +
+ + + + + + + + + + + + + + + + + + +
 Example value dataColumn typeValue
{{$index + 1}}{{column.sampleData}} + + + {{type.name | translate}} + + + + + + {{field.name | translate}} + + + + + +
+ +
- + + Add Device + + {{ 'action.import' | translate }} - {{ 'action.cancel' | translate }} + {{ 'action.cancel' + | translate }} + diff --git a/ui/src/app/import-export/import-dialog.scss b/ui/src/app/import-export/import-dialog.scss index 44e2802f31..7e8e203050 100644 --- a/ui/src/app/import-export/import-dialog.scss +++ b/ui/src/app/import-export/import-dialog.scss @@ -40,3 +40,13 @@ $previewSize: 100px !default; top: 50%; transform: translate(0%, -50%) !important; } + +.tb-table-select{ + md-input-container{ + margin: 0; + + .md-errors-spacer{ + min-height: 0; + } + } +} diff --git a/ui/src/app/import-export/import-export.service.js b/ui/src/app/import-export/import-export.service.js index ffa9527651..6ebfbdeaff 100644 --- a/ui/src/app/import-export/import-export.service.js +++ b/ui/src/app/import-export/import-export.service.js @@ -25,7 +25,7 @@ import entityAliasesTemplate from '../entity/alias/entity-aliases.tpl.html'; /* eslint-disable no-undef, angular/window-service, angular/document-service */ /*@ngInject*/ -export default function ImportExport($log, $translate, $q, $mdDialog, $document, $http, itembuffer, utils, types, +export default function ImportExport($log, $translate, $q, $mdDialog, $document, $http, itembuffer, utils, types, $timeout, deviceService, dashboardUtils, entityService, dashboardService, ruleChainService, widgetService, toast, attributeService) { @@ -43,7 +43,9 @@ export default function ImportExport($log, $translate, $q, $mdDialog, $document, exportExtension: exportExtension, importExtension: importExtension, importDevices: importDevices, - exportToPc: exportToPc + convertCSVToJson: convertCSVToJson, + exportToPc: exportToPc, + createMultiEntity: createMultiEntity }; return service; @@ -56,11 +58,11 @@ export default function ImportExport($log, $translate, $q, $mdDialog, $document, var bundleAlias = widgetsBundle.alias; var isSystem = widgetsBundle.tenantId.id === types.id.nullUid; widgetService.getBundleWidgetTypes(bundleAlias, isSystem).then( - function success (widgetTypes) { + function success(widgetTypes) { prepareExport(widgetsBundle); var widgetsBundleItem = { - widgetsBundle: prepareExport(widgetsBundle), - widgetTypes: [] + widgetsBundle: prepareExport(widgetsBundle), + widgetTypes: [] }; for (var t in widgetTypes) { var widgetType = widgetTypes[t]; @@ -70,10 +72,10 @@ export default function ImportExport($log, $translate, $q, $mdDialog, $document, widgetsBundleItem.widgetTypes.push(prepareExport(widgetType)); } var name = widgetsBundle.title; - name = name.toLowerCase().replace(/\W/g,"_"); + name = name.toLowerCase().replace(/\W/g, "_"); exportToPc(widgetsBundleItem, name + '.json'); }, - function fail (rejection) { + function fail(rejection) { var message = rejection; if (!message) { message = $translate.instant('error.unknown-error'); @@ -170,7 +172,7 @@ export default function ImportExport($log, $translate, $q, $mdDialog, $document, delete widgetType.bundleAlias; } var name = widgetType.name; - name = name.toLowerCase().replace(/\W/g,"_"); + name = name.toLowerCase().replace(/\W/g, "_"); exportToPc(prepareExport(widgetType), name + '.json'); }, function fail(rejection) { @@ -211,8 +213,7 @@ export default function ImportExport($log, $translate, $q, $mdDialog, $document, function validateImportedWidgetType(widgetType) { if (angular.isUndefined(widgetType.name) - || angular.isUndefined(widgetType.descriptor)) - { + || angular.isUndefined(widgetType.descriptor)) { return false; } return true; @@ -230,7 +231,7 @@ export default function ImportExport($log, $translate, $q, $mdDialog, $document, metadata: prepareRuleChainMetaData(ruleChainMetaData) }; var name = ruleChain.name; - name = name.toLowerCase().replace(/\W/g,"_"); + name = name.toLowerCase().replace(/\W/g, "_"); exportToPc(ruleChainExport, name + '.json'); }, (rejection) => { @@ -255,7 +256,7 @@ export default function ImportExport($log, $translate, $q, $mdDialog, $document, function prepareRuleChainMetaData(ruleChainMetaData) { delete ruleChainMetaData.ruleChainId; - for (var i=0;i 0) { processEntityAliases(entityAliases, aliasIds).then( - function(missingEntityAliases) { + function (missingEntityAliases) { if (Object.keys(missingEntityAliases).length > 0) { - editMissingAliases($event, [ widget ], - true, 'dashboard.widget-import-missing-aliases-title', missingEntityAliases).then( + editMissingAliases($event, [widget], + true, 'dashboard.widget-import-missing-aliases-title', missingEntityAliases).then( function success(updatedEntityAliases) { for (var aliasId in updatedEntityAliases) { var entityAlias = updatedEntityAliases[aliasId]; @@ -485,14 +486,14 @@ export default function ImportExport($log, $translate, $q, $mdDialog, $document, function success(targetLayout) { itembuffer.addWidgetToDashboard(dashboard, targetState, targetLayout, widget, aliasesInfo, onAliasesUpdateFunction, originalColumns, originalSize, -1, -1).then( - function() { - deferred.resolve( - { - widget: widget, - layoutId: targetLayout - } - ); - } + function () { + deferred.resolve( + { + widget: widget, + layoutId: targetLayout + } + ); + } ); }, function fail() { @@ -507,7 +508,7 @@ export default function ImportExport($log, $translate, $q, $mdDialog, $document, dashboardService.getDashboard(dashboardId).then( function success(dashboard) { var name = dashboard.title; - name = name.toLowerCase().replace(/\W/g,"_"); + name = name.toLowerCase().replace(/\W/g, "_"); exportToPc(prepareDashboardExport(dashboard), name + '.json'); }, function fail(rejection) { @@ -540,13 +541,13 @@ export default function ImportExport($log, $translate, $q, $mdDialog, $document, dashboard = dashboardUtils.validateAndUpdateDashboard(dashboard); var entityAliases = dashboard.configuration.entityAliases; if (entityAliases) { - var aliasIds = Object.keys( entityAliases ); + var aliasIds = Object.keys(entityAliases); if (aliasIds.length > 0) { processEntityAliases(entityAliases, aliasIds).then( - function(missingEntityAliases) { - if (Object.keys( missingEntityAliases ).length > 0) { + function (missingEntityAliases) { + if (Object.keys(missingEntityAliases).length > 0) { editMissingAliases($event, dashboard.configuration.widgets, - false, 'dashboard.dashboard-import-missing-aliases-title', missingEntityAliases).then( + false, 'dashboard.dashboard-import-missing-aliases-title', missingEntityAliases).then( function success(updatedEntityAliases) { for (var aliasId in updatedEntityAliases) { entityAliases[aliasId] = updatedEntityAliases[aliasId]; @@ -617,6 +618,7 @@ export default function ImportExport($log, $translate, $q, $mdDialog, $document, // saveImportedDashboard(dashboard, deferred); // } // } + deferred.resolve(); }, function fail() { deferred.reject(); @@ -644,14 +646,13 @@ export default function ImportExport($log, $translate, $q, $mdDialog, $document, } - function exportExtension(extensionId) { getExtension(extensionId) .then( function success(extension) { var name = extension.title; - name = name.toLowerCase().replace(/\W/g,"_"); + name = name.toLowerCase().replace(/\W/g, "_"); exportToPc(prepareExport(extension), name + '.json'); }, function fail(rejection) { @@ -711,7 +712,7 @@ export default function ImportExport($log, $translate, $q, $mdDialog, $document, function validateImportedExtension(configuration) { if (configuration.length) { for (let i = 0; i < configuration.length; i++) { - if (angular.isUndefined(configuration[i].configuration) || angular.isUndefined(configuration[i].id )|| angular.isUndefined(configuration[i].type)) { + if (angular.isUndefined(configuration[i].configuration) || angular.isUndefined(configuration[i].id) || angular.isUndefined(configuration[i].type)) { return false; } } @@ -742,7 +743,7 @@ export default function ImportExport($log, $translate, $q, $mdDialog, $document, var aliasId = aliasIds[index]; var entityAlias = entityAliases[aliasId]; entityService.checkEntityAlias(entityAlias).then( - function(result) { + function (result) { if (result) { checkNextEntityAliasOrComplete(index, aliasIds, entityAliases, missingEntityAliases, deferred); } else { @@ -782,6 +783,91 @@ export default function ImportExport($log, $translate, $q, $mdDialog, $document, return deferred.promise; } + /** + * splitCSV function (c) 2009 Brian Huisman, see http://www.greywyvern.com/?post=258 + * Works by spliting on seperators first, then patching together quoted values + */ + function splitCSV(str, sep) { + for (var foo = str.split(sep = sep || ","), x = foo.length - 1, tl; x >= 0; x--) { + if (foo[x].replace(/"\s+$/, '"').charAt(foo[x].length - 1) == '"') { + if ((tl = foo[x].replace(/^\s+"/, '"')).length > 1 && tl.charAt(0) == '"') { + foo[x] = foo[x].replace(/^\s*"|"\s*$/g, '').replace(/""/g, '"'); + } else if (x) { + foo.splice(x - 1, 2, [foo[x - 1], foo[x]].join(sep)); + } else foo = foo.shift().split(sep).concat(foo); + } else foo[x].replace(/""/g, '"'); + } + return foo; + } + + function isNumeric(str) { + str = str.replace(',', '.'); + return !isNaN(parseFloat(str)) && isFinite(str); + } + + function parseStringToFormatJS(str) { + if (isNumeric(str.replace(',', '.'))) { + return parseFloat(str.replace(',', '.')); + } + if (str.search(/^(true|false)$/im) === 0) { + return str.toLowerCase() === 'true'; + } + if (str === "") { + return null; + } + return str; + } + + function convertCSVToJson(csvdata, config) { + config = config || {}; + const delim = config.delim || ","; + const header = config.header || false; + + let csvlines = csvdata.split(/[\r\n]+/); + let csvheaders = splitCSV(csvlines[0], delim); + let csvrows = header ? csvlines.slice(1, csvlines.length) : csvlines; + + let result = {}; + result.headers = csvheaders; + result.rows = []; + + for (let r in csvrows) { + if (csvrows.hasOwnProperty(r)) { + let row = csvrows[r]; + + if (row.length === 0) + break; + + let rowitems = splitCSV(row, delim); + for (let i = 0; i < rowitems.length; i++) { + rowitems[i] = parseStringToFormatJS(rowitems[i]); + } + result.rows.push(rowitems); + } + } + return result; + } + + function createMultiEntity(arrayData, entityType, update, config) { + var deferred = $q.defer(); + var allPromise = []; + switch (entityType) { + case types.entityType.device: + for(var i = 0; i < arrayData.length; i++){ + var promise = deviceService.saveDeviceParameters(arrayData[i], update, config); + allPromise.push(promise); + } + break; + } + $q.all(allPromise).then(function success() { + deferred.resolve(); + $timeout(function () { + console.log("1"); // eslint-disable-line + }, 1000); + }); + return deferred.promise; + } + // Common functions function prepareExport(data) { @@ -821,8 +907,7 @@ export default function ImportExport($log, $translate, $q, $mdDialog, $document, if (window.navigator && window.navigator.msSaveOrOpenBlob) { window.navigator.msSaveOrOpenBlob(blob, filename); - } - else{ + } else { var e = document.createEvent('MouseEvents'), a = document.createElement('a'); @@ -873,7 +958,6 @@ export default function ImportExport($log, $translate, $q, $mdDialog, $document, targetEvent: $event }).then(function (importData) { deferred.resolve(importData); - }, function () { deferred.reject(); }); diff --git a/ui/src/app/locale/locale.constant-en_US.json b/ui/src/app/locale/locale.constant-en_US.json index 57281150bd..ba82eb8e13 100644 --- a/ui/src/app/locale/locale.constant-en_US.json +++ b/ui/src/app/locale/locale.constant-en_US.json @@ -778,6 +778,22 @@ "no-data": "No data to display", "columns-to-display": "Columns to Display" }, + "entity-group": { + "column-value": "Value", + "column-title": "Title", + "column-type": { + "column-type": "Column type", + "shared-attribute": "Shared attribute", + "server-attribute": "Server attribute", + "timeseries": "Timeseries", + "entity-field": "Entity field" + }, + "entity-field": { + "name": "Name", + "type": "Type", + "assigned_customer": "Assigned Customer" + } + }, "entity-view": { "entity-view": "Entity View", "entity-view-required": "Entity view is required.",