Browse Source

Add device

pull/1776/head
Vladyslav_Prykhodko 8 years ago
parent
commit
68e9844f53
  1. 75
      ui/src/app/api/attribute.service.js
  2. 86
      ui/src/app/api/device.service.js
  3. 34
      ui/src/app/common/types.constant.js
  4. 136
      ui/src/app/import-export/import-dialog-csv.controller.js
  5. 80
      ui/src/app/import-export/import-dialog-csv.tpl.html
  6. 10
      ui/src/app/import-export/import-dialog.scss
  7. 156
      ui/src/app/import-export/import-export.service.js
  8. 16
      ui/src/app/locale/locale.constant-en_US.json

75
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<timeseries.length;a++) {
if (angular.isDefined(timeseries[a].value) && timeseries[a].value !== null) {
timeseriesData[timeseries[a].key] = timeseries[a].value;
} else {
deleteTimeseries.push(timeseries[a]);
}
}
var deleteEntityTimeseriesPromise;
if (deleteTimeseries.length) {
deleteEntityTimeseriesPromise = deleteEntityTimeseries(entityType, entityId, deleteTimeseries);
}
if (Object.keys(timeseriesData).length) {
var url = '/api/plugins/telemetry/' + entityType + '/' + entityId + '/timeseries/' + timeseriesScope;
$http.post(url, timeseriesData, config).then(function success(response) {
if (deleteEntityTimeseriesPromise) {
deleteEntityTimeseriesPromise.then(
function success() {
deferred.resolve(response.data);
},
function fail() {
deferred.reject();
}
)
} else {
deferred.resolve(response.data);
}
}, function fail() {
deferred.reject();
});
} else if (deleteEntityTimeseriesPromise) {
deleteEntityTimeseriesPromise.then(
function success() {
deferred.resolve();
},
function fail() {
deferred.reject();
}
)
} else {
deferred.resolve();
}
return deferred.promise;
}
function deleteEntityAttributes(entityType, entityId, attributeScope, attributes) {
var deferred = $q.defer();
var keys = '';
@ -278,5 +330,22 @@ function AttributeService($http, $q, $filter, types, telemetryWebsocketService)
return deferred.promise;
}
function deleteEntityTimeseries(entityType, entityId, timeseries) {
var deferred = $q.defer();
var keys = '';
for (var i = 0; i < timeseries.length; i++) {
if (i > 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;
}
}

86
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;i<deviceIds.length;i++) {
if (i>0) {
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;
}
}

34
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"
},

136
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() {

80
ui/src/app/import-export/import-dialog-csv.tpl.html

@ -26,7 +26,8 @@
</md-button>
</div>
</md-toolbar>
<md-progress-linear class="md-warn" md-mode="indeterminate" ng-disabled="!$root.loading" ng-show="$root.loading"></md-progress-linear>
<md-progress-linear class="md-warn" md-mode="indeterminate" ng-disabled="!$root.loading"
ng-show="$root.loading"></md-progress-linear>
<span style="min-height: 5px;" flex="" ng-show="!$root.loading"></span>
<md-dialog-content>
<div class="md-dialog-content">
@ -38,7 +39,8 @@
flow-file-added="vm.fileAdded( $file )" class="tb-file-select-container">
<div class="tb-file-clear-container">
<md-button ng-click="vm.clearFile()"
class="tb-file-clear-btn md-icon-button md-primary" aria-label="{{ 'action.remove' | translate }}">
class="tb-file-clear-btn md-icon-button md-primary"
aria-label="{{ 'action.remove' | translate }}">
<md-tooltip md-direction="top">
{{ 'action.remove' | translate }}
</md-tooltip>
@ -49,7 +51,8 @@
</div>
<div class="alert tb-flow-drop" flow-drop>
<label for="select" translate>import.drop-file-csv</label>
<input class="file-input" flow-btn flow-attrs="{accept:'.csv,application/csv,text/csv'}" id="select">
<input class="file-input" flow-btn
flow-attrs="{accept:'.csv,application/csv,text/csv'}" id="select">
</div>
</div>
</div>
@ -59,14 +62,81 @@
</div>
</div>
</fieldset>
<div flex layout="row">
<md-input-container class="md-block">
<label translate>CSV delimiter parametr</label>
<input ng-model="vm.importParams.delim">
</md-input-container>
<md-input-container class="md-block">
<md-checkbox ng-model="vm.importParams.isHeader" aria-label="Checkbox 1">
Use first line is header
</md-checkbox>
</md-input-container>
<md-input-container class="md-block">
<md-checkbox ng-model="vm.importParams.isUpdate" aria-label="Checkbox 1">
Update parameter device
</md-checkbox>
</md-input-container>
</div>
<md-table-container flex class="tb-table-select">
<table md-table>
<thead md-head>
<tr md-row>
<th md-column>&nbsp</th>
<th md-column>Example value data</th>
<th md-column style="min-width: 140px">Column type</th>
<th md-column style="min-width: 140px">Value</th>
</tr>
</thead>
<tbody md-body>
<tr md-row ng-repeat="column in vm.columnsParam">
<td md-cell>{{$index + 1}}</td>
<td md-cell>{{column.sampleData}}</td>
<td md-cell>
<md-select ng-model="column.type" required name="columnType"
aria-label="{{ 'entity-group.column-type' | translate }}">
<md-option ng-repeat="type in vm.columnTypes" ng-value="type.value">
{{type.name | translate}}
</md-option>
</md-select>
</td>
<td md-cell>
<md-select ng-if="column.type == vm.columnTypes.entityField.value"
required name="columnKey" ng-model="column.key"
aria-label="{{ 'entity-group.column-value' | translate }}">
<md-option ng-repeat="field in vm.entityField" ng-value="field.value" ng-disabled="field.disable">
{{field.name | translate}}
</md-option>
</md-select>
<md-input-container md-no-float
ng-if="column.type != vm.columnTypes.entityField.value &&
column.type != vm.columnTypes.name.value &&
column.type != vm.columnTypes.type.value">
<input required name="columnKeyName"
placeholder="{{ 'entity-group.column-value' | translate }}"
ng-model="column.key"
aria-label="{{ 'entity-group.column-value' | translate }}">
</md-input-container>
</td>
</tr>
</tbody>
</table>
<md-divider></md-divider>
</md-table-container>
</div>
</md-dialog-content>
<md-dialog-actions layout="row">
<span flex></span>
<md-button ng-disabled="$root.loading || !theForm.$dirty || !theForm.$valid || !vm.importData" type="submit" class="md-raised md-primary">
<md-button ng-disabled="$root.loading" ng-click="vm.addDevices()" style="margin-right:20px;">
Add Device
</md-button>
<md-button ng-disabled="$root.loading || !theForm.$dirty || !theForm.$valid || !vm.importData" type="submit"
class="md-raised md-primary">
{{ 'action.import' | translate }}
</md-button>
<md-button ng-disabled="$root.loading" ng-click="vm.cancel()" style="margin-right:20px;">{{ 'action.cancel' | translate }}</md-button>
<md-button ng-disabled="$root.loading" ng-click="vm.cancel()" style="margin-right:20px;">{{ 'action.cancel'
| translate }}
</md-button>
</md-dialog-actions>
</form>
</md-dialog>

10
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;
}
}
}

156
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<ruleChainMetaData.nodes.length;i++) {
for (var i = 0; i < ruleChainMetaData.nodes.length; i++) {
var node = ruleChainMetaData.nodes[i];
delete node.ruleChainId;
ruleChainMetaData.nodes[i] = prepareExport(node);
@ -307,7 +308,7 @@ export default function ImportExport($log, $translate, $q, $mdDialog, $document,
function exportWidget(dashboard, sourceState, sourceLayout, widget) {
var widgetItem = itembuffer.prepareWidgetItem(dashboard, sourceState, sourceLayout, widget);
var name = widgetItem.widget.config.title;
name = name.toLowerCase().replace(/\W/g,"_");
name = name.toLowerCase().replace(/\W/g, "_");
exportToPc(prepareExport(widgetItem), name + '.json');
}
@ -417,10 +418,10 @@ export default function ImportExport($log, $translate, $q, $mdDialog, $document,
var aliasIds = Object.keys(entityAliases);
if (aliasIds.length > 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();
});

16
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.",

Loading…
Cancel
Save