Browse Source

Fix dashboard device button, clear code and counted all statistical info

pull/1776/head
Vladyslav_Prykhodko 7 years ago
parent
commit
07cd8b9978
  1. 32
      ui/src/app/api/attribute.service.js
  2. 61
      ui/src/app/api/device.service.js
  3. 4
      ui/src/app/common/types.constant.js
  4. 5
      ui/src/app/device/device.controller.js
  5. 118
      ui/src/app/import-export/import-dialog-csv.controller.js
  6. 60
      ui/src/app/import-export/import-dialog-csv.tpl.html
  7. 52
      ui/src/app/import-export/import-export.service.js
  8. 2
      ui/src/app/import-export/index.js
  9. 91
      ui/src/app/import-export/table-columns-assignment.directive.js
  10. 62
      ui/src/app/import-export/table-columns-assignment.tpl.html
  11. 5
      ui/src/app/locale/locale.constant-en_US.json

32
ui/src/app/api/attribute.service.js

@ -238,23 +238,23 @@ function AttributeService($http, $q, $filter, types, telemetryWebsocketService)
function success() {
deferred.resolve(response.data);
},
function fail(response) {
deferred.reject(response);
function fail() {
deferred.reject();
}
)
} else {
deferred.resolve(response.data);
}
}, function fail(response) {
deferred.reject(response);
}, function fail() {
deferred.reject();
});
} else if (deleteEntityAttributesPromise) {
deleteEntityAttributesPromise.then(
function success() {
deferred.resolve();
},
function fail(response) {
deferred.reject(response);
function fail() {
deferred.reject();
}
)
} else {
@ -287,23 +287,23 @@ function AttributeService($http, $q, $filter, types, telemetryWebsocketService)
function success() {
deferred.resolve(response.data);
},
function fail(response) {
deferred.reject(response);
function fail() {
deferred.reject();
}
)
} else {
deferred.resolve(response.data);
}
}, function fail(response) {
deferred.reject(response);
}, function fail() {
deferred.reject();
});
} else if (deleteEntityTimeseriesPromise) {
deleteEntityTimeseriesPromise.then(
function success() {
deferred.resolve();
},
function fail(response) {
deferred.reject(response);
function fail() {
deferred.reject();
}
)
} else {
@ -325,8 +325,8 @@ function AttributeService($http, $q, $filter, types, telemetryWebsocketService)
var url = '/api/plugins/telemetry/' + entityType + '/' + entityId + '/' + attributeScope + '?keys=' + keys;
$http.delete(url, config).then(function success() {
deferred.resolve();
}, function fail(response) {
deferred.reject(response);
}, function fail() {
deferred.reject();
});
return deferred.promise;
}
@ -344,8 +344,8 @@ function AttributeService($http, $q, $filter, types, telemetryWebsocketService)
var url = '/api/plugins/telemetry/' + entityType + '/' + entityId + '/timeseries/delete' + '?keys=' + keys;
$http.delete(url, config).then(function success() {
deferred.resolve();
}, function fail(response) {
deferred.reject(response);
}, function fail() {
deferred.reject();
});
return deferred.promise;
}

61
ui/src/app/api/device.service.js

@ -43,8 +43,7 @@ function DeviceService($http, $q, $window, userService, attributeService, custom
sendOneWayRpcCommand: sendOneWayRpcCommand,
sendTwoWayRpcCommand: sendTwoWayRpcCommand,
findByQuery: findByQuery,
getDeviceTypes: getDeviceTypes,
findByName: findByName
getDeviceTypes: getDeviceTypes
}
return service;
@ -167,8 +166,8 @@ function DeviceService($http, $q, $window, userService, attributeService, custom
var url = '/api/device';
$http.post(url, device, config).then(function success(response) {
deferred.resolve(response.data);
}, function fail(response) {
deferred.reject(response);
}, function fail() {
deferred.reject();
});
return deferred.promise;
}
@ -178,18 +177,36 @@ function DeviceService($http, $q, $window, userService, attributeService, custom
let attributesType = Object.keys(types.attributesScope);
let allPromise = [];
let promise = "";
let statisticalInfo = {};
for (let 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);
let attrribute = attributesType[i];
if (deviceRelation.attributes[attrribute] && deviceRelation.attributes[attrribute].length !== 0) {
promise = attributeService.saveEntityAttributes(types.entityType.device, deviceId, types.attributesScope[attrribute].value, deviceRelation.attributes[attrribute], config).then(function () {
statisticalInfo.create = {
[attrribute]: deviceRelation.attributes[attributesType[i]].length
};
}, function () {
statisticalInfo.error = {
[attrribute]: deviceRelation.attributes[attributesType[i]].length
};
});
allPromise.push(promise);
}
}
if (deviceRelation.timeseries.length !== 0) {
promise = attributeService.saveEntityTimeseries(types.entityType.device, deviceId, "time", deviceRelation.timeseries, config);
promise = attributeService.saveEntityTimeseries(types.entityType.device, deviceId, "time", deviceRelation.timeseries, config).then(function () {
statisticalInfo.create = {
timeseries: deviceRelation.timeseries.length
};
}, function () {
statisticalInfo.error = {
timeseries: deviceRelation.timeseries.length
};
});
allPromise.push(promise);
}
$q.all(allPromise).then(function success() {
deferred.resolve();
deferred.resolve(statisticalInfo);
});
return deferred.promise;
}
@ -197,26 +214,28 @@ function DeviceService($http, $q, $window, userService, attributeService, custom
function saveDeviceParameters(deviceParameters, update, config) {
config = config || {};
const deferred = $q.defer();
let statisticalInfo = {
create: {},
update: {},
error: {}
};
let statisticalInfo = {};
let newDevice = {
name: deviceParameters.name,
type: deviceParameters.type
};
saveDevice(newDevice, config).then(function success(response) {
statisticalInfo.create.device = 1;
saveDeviceRelarion(response.id.id, deviceParameters, config).then(function success() {
statisticalInfo.create={
device: 1
};
saveDeviceRelarion(response.id.id, deviceParameters, config).then(function success(response) {
angular.merge(statisticalInfo, response, statisticalInfo);
deferred.resolve(statisticalInfo);
});
}, function fail(response) {
console.log(response); // eslint-disable-line
}, function fail() {
if (update) {
findByName(deviceParameters.name, config).then(function success(response) {
statisticalInfo.update.device = 1;
saveDeviceRelarion(response.id.id, deviceParameters, config).then(function success() {
statisticalInfo.update = {
device: 1
};
saveDeviceRelarion(response.id.id, deviceParameters, config).then(function success(response) {
delete Object.assign(response, {update: response.create}).create;
angular.merge(statisticalInfo, response);
deferred.resolve(statisticalInfo);
});
}, function fail() {
@ -384,8 +403,8 @@ function DeviceService($http, $q, $window, userService, attributeService, custom
var url = '/api/tenant/devices?deviceName=' + deviceName;
$http.get(url, config).then(function success(response) {
deferred.resolve(response.data);
}, function fail(response) {
deferred.reject(response);
}, function fail() {
deferred.reject();
});
return deferred.promise;
}

4
ui/src/app/common/types.constant.js

@ -352,6 +352,10 @@ export default angular.module('thingsboard.types', [])
},
entityGroup: {
columnType: {
clientAttribute: {
name: 'entity-group.column-type.client-attribute',
value: 'CLIENT_ATTRIBUTE'
},
sharedAttribute: {
name: 'entity-group.column-type.shared-attribute',
value: 'SHARED_ATTRIBUTE'

5
ui/src/app/device/device.controller.js

@ -68,7 +68,7 @@ export function DeviceController($rootScope, userService, deviceService, custome
},
{
onAction: function ($event) {
importExport.importDevices($event).then(
importExport.importDevices($event, types.entityType.device).then(
function() {
vm.grid.refreshList();
}
@ -107,7 +107,6 @@ export function DeviceController($rootScope, userService, deviceService, custome
addItemTemplateUrl: addDeviceTemplate,
// addItemText: function() { return $translate.instant('device.add-device-text') },
noItemsText: function() { return $translate.instant('device.no-devices-text') },
itemDetailsText: function() { return $translate.instant('device.device-details') },
isDetailsReadOnly: isCustomerUser,
@ -338,6 +337,7 @@ export function DeviceController($rootScope, userService, deviceService, custome
icon: "add"
};
vm.deviceGridConfig.addItemActions = [];
} else if (vm.devicesScope === 'customer_user') {
deviceActionsList.push(
@ -352,6 +352,7 @@ export function DeviceController($rootScope, userService, deviceService, custome
);
vm.deviceGridConfig.addItemAction = {};
vm.deviceGridConfig.addItemActions = [];
}
}

118
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, importExport, types, $timeout) {
export default function ImportDialogCsvController($scope, $mdDialog, toast, importTitle, importFileLabel, entityType, importExport, types, $timeout, $q) {
var vm = this;
@ -27,63 +27,80 @@ export default function ImportDialogCsvController($scope, $mdDialog, toast, impo
vm.addDevices = addDevices;
vm.importParams = {
delim: ',',
isUpdate: true,
isHeader: true
};
vm.selectedStep = 0;
vm.stepProgress = 1;
vm.maxStep = 3;
vm.showBusyText = false;
vm.stepData = [
{ step: 1, completed: false, optional: false, data: {} },
{ step: 2, completed: false, optional: false, data: {} },
{ step: 3, completed: false, optional: false, data: {} },
];
vm.enableNextStep = function nextStep() {
//do not exceed into max step
if (vm.selectedStep >= vm.maxStep) {
return;
}
//do not increment vm.stepProgress when submitting from previously completed step
if (vm.selectedStep === vm.stepProgress - 1) {
vm.stepProgress = vm.stepProgress + 1;
}
vm.selectedStep = vm.selectedStep + 1;
};
vm.moveToPreviousStep = function moveToPreviousStep() {
if (vm.selectedStep > 0) {
vm.selectedStep = vm.selectedStep - 1;
}
};
vm.submitCurrentStep = function submitCurrentStep(stepData, isSkip) {
var deferred = $q.defer();
vm.showBusyText = true;
if (!stepData.completed && !isSkip) {
//simulate $http
$timeout(function () {
vm.showBusyText = false;
deferred.resolve({ status: 200, statusText: 'success', data: {} });
//move to next step when success
stepData.completed = true;
vm.enableNextStep();
}, 1000)
} else {
vm.showBusyText = false;
vm.enableNextStep();
}
};
vm.importTitle = importTitle;
vm.importFileLabel = importFileLabel;
vm.entityType = entityType;
vm.columnsParam = [];
vm.parseData = [];
vm.entityType = types.entityType.device;
vm.columnTypes = {};
vm.entityField = {};
vm.delimiters = [{
key: ',',
value: ','
},{
key: ';',
value: ';'
},{
key: '|',
value: '|'
},{
key: '\t',
value: 'Tab'
}];
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();
}
function fileAdded($file) {
if ($file.getExtension() === 'csv') {
var reader = new FileReader();
@ -94,9 +111,8 @@ export default function ImportDialogCsvController($scope, $mdDialog, toast, impo
var importCSV = event.target.result;
if (importCSV && importCSV.length > 0) {
try {
vm.importData = importCSV;
parseCSV(importCSV);
vm.fileName = $file.name;
parseCSVData(vm.importData);
} catch (err) {
vm.fileName = null;
toast.showError(err.message);
@ -109,7 +125,7 @@ export default function ImportDialogCsvController($scope, $mdDialog, toast, impo
}
}
function parseCSVData(importData) {
function parseCSV(importData) {
var columnParam = {};
var config = {
delim: vm.importParams.delim,
@ -202,10 +218,14 @@ export default function ImportDialogCsvController($scope, $mdDialog, toast, impo
function clearFile() {
$scope.theForm.$setDirty();
vm.fileName = null;
vm.importData = null;
parseData = null;
vm.columnsParam = [];
}
function cancel() {
$mdDialog.cancel();
}
function importFromJson() {
$scope.theForm.$setPristine();
$mdDialog.hide(vm.importData);

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

@ -63,66 +63,26 @@
</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 class="md-block" style="min-width: 120px">
<label translate>CSV delimiter</label>
<md-select ng-model="vm.importParams.delim">
<md-option ng-repeat="delimiter in vm.delimiters" ng-value="delimiter.key">
{{delimiter.value}}
</md-option>
</md-select>
</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
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
Update parameters
</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>
<tb-table-columns-assignment the-form="theForm" columns="vm.columnsParam" entityType="vm.entityType"></tb-table-columns-assignment>
</div>
</md-dialog-content>
<md-dialog-actions layout="row">

52
ui/src/app/import-export/import-export.service.js

@ -578,9 +578,9 @@ export default function ImportExport($log, $translate, $q, $mdDialog, $document,
return deferred.promise;
}
function importDevices($event) {
function importDevices($event, entityType) {
var deferred = $q.defer();
openImportDialogCSV($event, 'device.import', 'device.device-file').then(
openImportDialogCSV($event, entityType,'device.import', 'device.device-file').then(
function success() {
// if (!validateImportedDashboard(dashboard)) {
// toast.showError($translate.instant('dashboard.invalid-dashboard-file-error'));
@ -783,10 +783,6 @@ 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) == '"') {
@ -805,7 +801,7 @@ export default function ImportExport($log, $translate, $q, $mdDialog, $document,
return !isNaN(parseFloat(str)) && isFinite(str);
}
function parseStringToFormatJS(str) {
function convertStringToJSType(str) {
if (isNumeric(str.replace(',', '.'))) {
return parseFloat(str.replace(',', '.'));
}
@ -827,7 +823,7 @@ export default function ImportExport($log, $translate, $q, $mdDialog, $document,
let csvlines = csvdata.split(/[\r\n]+/);
let csvheaders = splitCSV(csvlines[0], delim);
if (csvheaders.length < 2) {
toast.showError('A file should contain at least two columns');
toast.showError($translate.instant('entity.import-csv-number-columns-error'));
return -1;
}
let csvrows = header ? csvlines.slice(1, csvlines.length) : csvlines;
@ -844,34 +840,47 @@ export default function ImportExport($log, $translate, $q, $mdDialog, $document,
let rowitems = splitCSV(row, delim);
if (rowitems.length !== result.headers.length) {
toast.showError('Invalid file format. Row:' + (header ? result.rows.length + 2: result.rows.length + 1));
toast.showError($translate.instant('entity.import-csv-invalid-format-error', {line: (header ? result.rows.length + 2: result.rows.length + 1)}));
return -1;
}
for (let i = 0; i < rowitems.length; i++) {
rowitems[i] = parseStringToFormatJS(rowitems[i]);
rowitems[i] = convertStringToJSType(rowitems[i]);
}
result.rows.push(rowitems);
}
}
return result;
}
function sumObject(obj1, obj2){
Object.keys(obj2).map(function(key) {
if (angular.isObject(obj2[key])) {
obj1[key] = obj1[key] || {};
angular.merge(obj1[key], sumObject(obj1[key], obj2[key]));
} else {
obj1[key] = (obj1[key] || 0) + obj2[key];
}
});
return obj1;
}
function createMultiEntity(arrayData, entityType, update, config) {
var deferred = $q.defer();
var allPromise = [];
let deferred = $q.defer();
let allPromise = [];
let statisticalInfo = {};
switch (entityType) {
case types.entityType.device:
for(var i = 0; i < arrayData.length; i++){
var promise = deviceService.saveDeviceParameters(arrayData[i], update, config);
for(let i = 0; i < arrayData.length; i++){
const 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);
$q.all(allPromise).then(function success(response) {
for (let i = 0; i < response.length; i++){
statisticalInfo = sumObject(statisticalInfo, response[i]);
}
deferred.resolve(statisticalInfo);
});
return deferred.promise;
}
@ -950,7 +959,7 @@ export default function ImportExport($log, $translate, $q, $mdDialog, $document,
return deferred.promise;
}
function openImportDialogCSV($event, importTitle, importFileLabel) {
function openImportDialogCSV($event, entityType, importTitle, importFileLabel) {
var deferred = $q.defer();
$mdDialog.show({
controller: 'ImportDialogCSVController',
@ -958,7 +967,8 @@ export default function ImportExport($log, $translate, $q, $mdDialog, $document,
templateUrl: importDialogCSVTemplate,
locals: {
importTitle: importTitle,
importFileLabel: importFileLabel
importFileLabel: importFileLabel,
entityType: entityType
},
parent: angular.element($document[0].body),
multiple: true,

2
ui/src/app/import-export/index.js

@ -16,10 +16,12 @@
import ImportExport from './import-export.service';
import ImportDialogController from './import-dialog.controller';
import ImportDialogCSVController from './import-dialog-csv.controller';
import TableColumnsAssignment from './table-columns-assignment.directive';
export default angular.module('thingsboard.importexport', [])
.factory('importExport', ImportExport)
.controller('ImportDialogController', ImportDialogController)
.controller('ImportDialogCSVController', ImportDialogCSVController)
.directive('tbTableColumnsAssignment', TableColumnsAssignment)
.name;

91
ui/src/app/import-export/table-columns-assignment.directive.js

@ -0,0 +1,91 @@
/*
* Copyright © 2016-2019 The Thingsboard Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
// import './timeinterval.scss';
/* eslint-disable import/no-unresolved, import/default */
import tableColumnsAssignment from './table-columns-assignment.tpl.html';
/* eslint-enable import/no-unresolved, import/default */
/*@ngInject*/
export default function TableColumnsAssignment() {
return {
restrict: "E",
scope: true,
bindToController: {
theForm: '=?',
columns: '=',
entityType: '=',
},
templateUrl: tableColumnsAssignment,
controller: TableColumnsAssignmentController,
controllerAs: 'vm'
};
}
/*@ngInject*/
function TableColumnsAssignmentController($scope, types, $timeout) {
var vm = this;
vm.columnTypes = {};
vm.entityField = {};
switch (vm.entityType) {
case types.entityType.device:
vm.columnTypes.sharedAttribute = types.entityGroup.columnType.sharedAttribute;
vm.columnTypes.serverAttribute = types.entityGroup.columnType.serverAttribute;
vm.columnTypes.timeseries = types.entityGroup.columnType.timeseries;
vm.columnTypes.entityField = types.entityGroup.columnType.entityField;
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.columns', 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);
$scope.$watch('vm.columns', function(newVal, prevVal) {
if (vm.isEdit && !angular.equals(newVal, prevVal)) {
vm.theForm.$setDirty();
}
}, true);
}

62
ui/src/app/import-export/table-columns-assignment.tpl.html

@ -0,0 +1,62 @@
<!--
Copyright © 2016-2019 The Thingsboard Authors
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<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.columns track by $index">
<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>

5
ui/src/app/locale/locale.constant-en_US.json

@ -776,13 +776,16 @@
"details": "Entity details",
"no-entities-prompt": "No entities found",
"no-data": "No data to display",
"columns-to-display": "Columns to Display"
"columns-to-display": "Columns to Display",
"import-csv-number-columns-error": "A file should contain at least two columns",
"import-csv-invalid-format-error": "Invalid file format. Line: '{{line}}'"
},
"entity-group": {
"column-value": "Value",
"column-title": "Title",
"column-type": {
"column-type": "Column type",
"client-attribute": "Client attribute",
"shared-attribute": "Shared attribute",
"server-attribute": "Server attribute",
"timeseries": "Timeseries",

Loading…
Cancel
Save