Commit c36af7311ef46d64a0396525045ac88d17ff048e

Authored by Vladyslav
Committed by Igor Kulikov
1 parent 9f266cd2

Add bulk provision support label (#2096)

* Add to asset support label

* Add support import label

* Add support update entity type and label

* Add translate asset label
Showing 27 changed files with 127 additions and 29 deletions
@@ -119,6 +119,11 @@ public class ThingsboardInstallService { @@ -119,6 +119,11 @@ public class ThingsboardInstallService {
119 case "2.4.0": 119 case "2.4.0":
120 log.info("Upgrading ThingsBoard from version 2.4.0 to 2.4.1 ..."); 120 log.info("Upgrading ThingsBoard from version 2.4.0 to 2.4.1 ...");
121 121
  122 + case "2.4.1":
  123 + log.info("Upgrading ThingsBoard from version 2.4.1 to 2.4.2 ...");
  124 +
  125 + databaseUpgradeService.upgradeDatabase("2.4.1");
  126 +
122 log.info("Updating system data..."); 127 log.info("Updating system data...");
123 128
124 systemDataLoaderService.deleteSystemWidgetBundle("charts"); 129 systemDataLoaderService.deleteSystemWidgetBundle("charts");
@@ -267,6 +267,15 @@ public class CassandraDatabaseUpgradeService implements DatabaseUpgradeService { @@ -267,6 +267,15 @@ public class CassandraDatabaseUpgradeService implements DatabaseUpgradeService {
267 } catch (InvalidQueryException e) {} 267 } catch (InvalidQueryException e) {}
268 log.info("Schema updated."); 268 log.info("Schema updated.");
269 break; 269 break;
  270 + case "2.4.1":
  271 + log.info("Updating schema ...");
  272 + String updateAssetTableStmt = "alter table asset add label text";
  273 + try {
  274 + cluster.getSession().execute(updateAssetTableStmt);
  275 + Thread.sleep(2500);
  276 + } catch (InvalidQueryException e) {}
  277 + log.info("Schema updated.");
  278 + break;
270 default: 279 default:
271 throw new RuntimeException("Unable to upgrade Cassandra database, unsupported fromVersion: " + fromVersion); 280 throw new RuntimeException("Unable to upgrade Cassandra database, unsupported fromVersion: " + fromVersion);
272 } 281 }
@@ -176,6 +176,15 @@ public class SqlDatabaseUpgradeService implements DatabaseUpgradeService { @@ -176,6 +176,15 @@ public class SqlDatabaseUpgradeService implements DatabaseUpgradeService {
176 log.info("Schema updated."); 176 log.info("Schema updated.");
177 } 177 }
178 break; 178 break;
  179 + case "2.4.1":
  180 + try (Connection conn = DriverManager.getConnection(dbUrl, dbUserName, dbPassword)) {
  181 + log.info("Updating schema ...");
  182 + try {
  183 + conn.createStatement().execute("ALTER TABLE asset ADD COLUMN label varchar(255)"); //NOSONAR, ignoring because method used to execute thingsboard database upgrade script
  184 + } catch (Exception e) {}
  185 + log.info("Schema updated.");
  186 + }
  187 + break;
179 default: 188 default:
180 throw new RuntimeException("Unable to upgrade SQL database, unsupported fromVersion: " + fromVersion); 189 throw new RuntimeException("Unable to upgrade SQL database, unsupported fromVersion: " + fromVersion);
181 } 190 }
@@ -31,6 +31,7 @@ public class Asset extends SearchTextBasedWithAdditionalInfo<AssetId> implements @@ -31,6 +31,7 @@ public class Asset extends SearchTextBasedWithAdditionalInfo<AssetId> implements
31 private CustomerId customerId; 31 private CustomerId customerId;
32 private String name; 32 private String name;
33 private String type; 33 private String type;
  34 + private String label;
34 35
35 public Asset() { 36 public Asset() {
36 super(); 37 super();
@@ -46,6 +47,7 @@ public class Asset extends SearchTextBasedWithAdditionalInfo<AssetId> implements @@ -46,6 +47,7 @@ public class Asset extends SearchTextBasedWithAdditionalInfo<AssetId> implements
46 this.customerId = asset.getCustomerId(); 47 this.customerId = asset.getCustomerId();
47 this.name = asset.getName(); 48 this.name = asset.getName();
48 this.type = asset.getType(); 49 this.type = asset.getType();
  50 + this.label = asset.getLabel();
49 } 51 }
50 52
51 public TenantId getTenantId() { 53 public TenantId getTenantId() {
@@ -81,6 +83,14 @@ public class Asset extends SearchTextBasedWithAdditionalInfo<AssetId> implements @@ -81,6 +83,14 @@ public class Asset extends SearchTextBasedWithAdditionalInfo<AssetId> implements
81 this.type = type; 83 this.type = type;
82 } 84 }
83 85
  86 + public String getLabel() {
  87 + return label;
  88 + }
  89 +
  90 + public void setLabel(String label) {
  91 + this.label = label;
  92 + }
  93 +
84 @Override 94 @Override
85 public String getSearchText() { 95 public String getSearchText() {
86 return getName(); 96 return getName();
@@ -97,6 +107,8 @@ public class Asset extends SearchTextBasedWithAdditionalInfo<AssetId> implements @@ -97,6 +107,8 @@ public class Asset extends SearchTextBasedWithAdditionalInfo<AssetId> implements
97 builder.append(name); 107 builder.append(name);
98 builder.append(", type="); 108 builder.append(", type=");
99 builder.append(type); 109 builder.append(type);
  110 + builder.append(", label=");
  111 + builder.append(label);
100 builder.append(", additionalInfo="); 112 builder.append(", additionalInfo=");
101 builder.append(getAdditionalInfo()); 113 builder.append(getAdditionalInfo());
102 builder.append(", createdTime="); 114 builder.append(", createdTime=");
@@ -197,6 +197,7 @@ public class ModelConstants { @@ -197,6 +197,7 @@ public class ModelConstants {
197 public static final String ASSET_CUSTOMER_ID_PROPERTY = CUSTOMER_ID_PROPERTY; 197 public static final String ASSET_CUSTOMER_ID_PROPERTY = CUSTOMER_ID_PROPERTY;
198 public static final String ASSET_NAME_PROPERTY = "name"; 198 public static final String ASSET_NAME_PROPERTY = "name";
199 public static final String ASSET_TYPE_PROPERTY = "type"; 199 public static final String ASSET_TYPE_PROPERTY = "type";
  200 + public static final String ASSET_LABEL_PROPERTY = "label";
200 public static final String ASSET_ADDITIONAL_INFO_PROPERTY = ADDITIONAL_INFO_PROPERTY; 201 public static final String ASSET_ADDITIONAL_INFO_PROPERTY = ADDITIONAL_INFO_PROPERTY;
201 202
202 public static final String ASSET_BY_TENANT_AND_SEARCH_TEXT_COLUMN_FAMILY_NAME = "asset_by_tenant_and_search_text"; 203 public static final String ASSET_BY_TENANT_AND_SEARCH_TEXT_COLUMN_FAMILY_NAME = "asset_by_tenant_and_search_text";
@@ -37,6 +37,7 @@ import static org.thingsboard.server.dao.model.ModelConstants.ASSET_CUSTOMER_ID_ @@ -37,6 +37,7 @@ import static org.thingsboard.server.dao.model.ModelConstants.ASSET_CUSTOMER_ID_
37 import static org.thingsboard.server.dao.model.ModelConstants.ASSET_NAME_PROPERTY; 37 import static org.thingsboard.server.dao.model.ModelConstants.ASSET_NAME_PROPERTY;
38 import static org.thingsboard.server.dao.model.ModelConstants.ASSET_TENANT_ID_PROPERTY; 38 import static org.thingsboard.server.dao.model.ModelConstants.ASSET_TENANT_ID_PROPERTY;
39 import static org.thingsboard.server.dao.model.ModelConstants.ASSET_TYPE_PROPERTY; 39 import static org.thingsboard.server.dao.model.ModelConstants.ASSET_TYPE_PROPERTY;
  40 +import static org.thingsboard.server.dao.model.ModelConstants.ASSET_LABEL_PROPERTY;
40 import static org.thingsboard.server.dao.model.ModelConstants.ID_PROPERTY; 41 import static org.thingsboard.server.dao.model.ModelConstants.ID_PROPERTY;
41 import static org.thingsboard.server.dao.model.ModelConstants.SEARCH_TEXT_PROPERTY; 42 import static org.thingsboard.server.dao.model.ModelConstants.SEARCH_TEXT_PROPERTY;
42 43
@@ -64,6 +65,9 @@ public final class AssetEntity implements SearchTextEntity<Asset> { @@ -64,6 +65,9 @@ public final class AssetEntity implements SearchTextEntity<Asset> {
64 @Column(name = ASSET_NAME_PROPERTY) 65 @Column(name = ASSET_NAME_PROPERTY)
65 private String name; 66 private String name;
66 67
  68 + @Column(name = ASSET_LABEL_PROPERTY)
  69 + private String label;
  70 +
67 @Column(name = SEARCH_TEXT_PROPERTY) 71 @Column(name = SEARCH_TEXT_PROPERTY)
68 private String searchText; 72 private String searchText;
69 73
@@ -86,6 +90,7 @@ public final class AssetEntity implements SearchTextEntity<Asset> { @@ -86,6 +90,7 @@ public final class AssetEntity implements SearchTextEntity<Asset> {
86 } 90 }
87 this.name = asset.getName(); 91 this.name = asset.getName();
88 this.type = asset.getType(); 92 this.type = asset.getType();
  93 + this.label = asset.getLabel();
89 this.additionalInfo = asset.getAdditionalInfo(); 94 this.additionalInfo = asset.getAdditionalInfo();
90 } 95 }
91 96
@@ -163,8 +168,9 @@ public final class AssetEntity implements SearchTextEntity<Asset> { @@ -163,8 +168,9 @@ public final class AssetEntity implements SearchTextEntity<Asset> {
163 } 168 }
164 asset.setName(name); 169 asset.setName(name);
165 asset.setType(type); 170 asset.setType(type);
  171 + asset.setLabel(label);
166 asset.setAdditionalInfo(additionalInfo); 172 asset.setAdditionalInfo(additionalInfo);
167 return asset; 173 return asset;
168 } 174 }
169 175
170 -}  
  176 +}
@@ -40,6 +40,7 @@ import static org.thingsboard.server.dao.model.ModelConstants.ASSET_CUSTOMER_ID_ @@ -40,6 +40,7 @@ import static org.thingsboard.server.dao.model.ModelConstants.ASSET_CUSTOMER_ID_
40 import static org.thingsboard.server.dao.model.ModelConstants.ASSET_NAME_PROPERTY; 40 import static org.thingsboard.server.dao.model.ModelConstants.ASSET_NAME_PROPERTY;
41 import static org.thingsboard.server.dao.model.ModelConstants.ASSET_TENANT_ID_PROPERTY; 41 import static org.thingsboard.server.dao.model.ModelConstants.ASSET_TENANT_ID_PROPERTY;
42 import static org.thingsboard.server.dao.model.ModelConstants.ASSET_TYPE_PROPERTY; 42 import static org.thingsboard.server.dao.model.ModelConstants.ASSET_TYPE_PROPERTY;
  43 +import static org.thingsboard.server.dao.model.ModelConstants.ASSET_LABEL_PROPERTY;
43 import static org.thingsboard.server.dao.model.ModelConstants.SEARCH_TEXT_PROPERTY; 44 import static org.thingsboard.server.dao.model.ModelConstants.SEARCH_TEXT_PROPERTY;
44 45
45 @Data 46 @Data
@@ -61,6 +62,9 @@ public final class AssetEntity extends BaseSqlEntity<Asset> implements SearchTex @@ -61,6 +62,9 @@ public final class AssetEntity extends BaseSqlEntity<Asset> implements SearchTex
61 @Column(name = ASSET_TYPE_PROPERTY) 62 @Column(name = ASSET_TYPE_PROPERTY)
62 private String type; 63 private String type;
63 64
  65 + @Column(name = ASSET_LABEL_PROPERTY)
  66 + private String label;
  67 +
64 @Column(name = SEARCH_TEXT_PROPERTY) 68 @Column(name = SEARCH_TEXT_PROPERTY)
65 private String searchText; 69 private String searchText;
66 70
@@ -84,6 +88,7 @@ public final class AssetEntity extends BaseSqlEntity<Asset> implements SearchTex @@ -84,6 +88,7 @@ public final class AssetEntity extends BaseSqlEntity<Asset> implements SearchTex
84 } 88 }
85 this.name = asset.getName(); 89 this.name = asset.getName();
86 this.type = asset.getType(); 90 this.type = asset.getType();
  91 + this.label = asset.getLabel();
87 this.additionalInfo = asset.getAdditionalInfo(); 92 this.additionalInfo = asset.getAdditionalInfo();
88 } 93 }
89 94
@@ -113,8 +118,9 @@ public final class AssetEntity extends BaseSqlEntity<Asset> implements SearchTex @@ -113,8 +118,9 @@ public final class AssetEntity extends BaseSqlEntity<Asset> implements SearchTex
113 } 118 }
114 asset.setName(name); 119 asset.setName(name);
115 asset.setType(type); 120 asset.setType(type);
  121 + asset.setLabel(label);
116 asset.setAdditionalInfo(additionalInfo); 122 asset.setAdditionalInfo(additionalInfo);
117 return asset; 123 return asset;
118 } 124 }
119 125
120 -}  
  126 +}
@@ -244,6 +244,7 @@ CREATE TABLE IF NOT EXISTS thingsboard.asset ( @@ -244,6 +244,7 @@ CREATE TABLE IF NOT EXISTS thingsboard.asset (
244 customer_id timeuuid, 244 customer_id timeuuid,
245 name text, 245 name text,
246 type text, 246 type text,
  247 + label text,
247 search_text text, 248 search_text text,
248 additional_info text, 249 additional_info text,
249 PRIMARY KEY (id, tenant_id, customer_id, type) 250 PRIMARY KEY (id, tenant_id, customer_id, type)
@@ -711,4 +712,4 @@ CREATE MATERIALIZED VIEW IF NOT EXISTS thingsboard.entity_view_by_tenant_and_ent @@ -711,4 +712,4 @@ CREATE MATERIALIZED VIEW IF NOT EXISTS thingsboard.entity_view_by_tenant_and_ent
711 AND search_text IS NOT NULL 712 AND search_text IS NOT NULL
712 AND id IS NOT NULL 713 AND id IS NOT NULL
713 PRIMARY KEY (tenant_id, entity_id, customer_id, search_text, id, type) 714 PRIMARY KEY (tenant_id, entity_id, customer_id, search_text, id, type)
714 - WITH CLUSTERING ORDER BY (entity_id DESC, customer_id DESC, search_text ASC, id DESC);  
  715 + WITH CLUSTERING ORDER BY (entity_id DESC, customer_id DESC, search_text ASC, id DESC);
@@ -42,6 +42,7 @@ CREATE TABLE IF NOT EXISTS asset ( @@ -42,6 +42,7 @@ CREATE TABLE IF NOT EXISTS asset (
42 additional_info varchar, 42 additional_info varchar,
43 customer_id varchar(31), 43 customer_id varchar(31),
44 name varchar(255), 44 name varchar(255),
  45 + label varchar(255),
45 search_text varchar(255), 46 search_text varchar(255),
46 tenant_id varchar(31), 47 tenant_id varchar(31),
47 type varchar(255) 48 type varchar(255)
@@ -1130,19 +1130,12 @@ function EntityService($http, $q, $filter, $translate, $log, userService, device @@ -1130,19 +1130,12 @@ function EntityService($http, $q, $filter, $translate, $log, userService, device
1130 let statisticalInfo = {}; 1130 let statisticalInfo = {};
1131 let newEntity = { 1131 let newEntity = {
1132 name: entityParameters.name, 1132 name: entityParameters.name,
1133 - type: entityParameters.type 1133 + type: entityParameters.type,
  1134 + label: entityParameters.label
1134 }; 1135 };
1135 - let promise;  
1136 - switch (entityType) {  
1137 - case types.entityType.device:  
1138 - promise = deviceService.saveDevice(newEntity, config);  
1139 - break;  
1140 - case types.entityType.asset:  
1141 - promise = assetService.saveAsset(newEntity, true, config);  
1142 - break;  
1143 - } 1136 + let saveEntityPromise = getEntitySavePromise(entityType, newEntity, config);
1144 1137
1145 - promise.then(function success(response) { 1138 + saveEntityPromise.then(function success(response) {
1146 saveEntityRelation(entityType, response.id, entityParameters, config).then(function success() { 1139 saveEntityRelation(entityType, response.id, entityParameters, config).then(function success() {
1147 statisticalInfo.create = { 1140 statisticalInfo.create = {
1148 entity: 1 1141 entity: 1
@@ -1166,7 +1159,15 @@ function EntityService($http, $q, $filter, $translate, $log, userService, device @@ -1166,7 +1159,15 @@ function EntityService($http, $q, $filter, $translate, $log, userService, device
1166 break; 1159 break;
1167 } 1160 }
1168 findIdEntity.then(function success(response) { 1161 findIdEntity.then(function success(response) {
1169 - saveEntityRelation(entityType, response.id, entityParameters, config).then(function success() { 1162 + let promises = [];
  1163 + if(response.label !== entityParameters.label || response.type !== entityParameters.type){
  1164 + response.label = entityParameters.label;
  1165 + response.type = entityParameters.type;
  1166 + promises.push(getEntitySavePromise(entityType, response, config));
  1167 + }
  1168 + promises.push(saveEntityRelation(entityType, response.id, entityParameters, config));
  1169 +
  1170 + $q.all(promises).then(function success() {
1170 statisticalInfo.update = { 1171 statisticalInfo.update = {
1171 entity: 1 1172 entity: 1
1172 }; 1173 };
@@ -1193,6 +1194,19 @@ function EntityService($http, $q, $filter, $translate, $log, userService, device @@ -1193,6 +1194,19 @@ function EntityService($http, $q, $filter, $translate, $log, userService, device
1193 return deferred.promise; 1194 return deferred.promise;
1194 } 1195 }
1195 1196
  1197 + function getEntitySavePromise(entityType, newEntity, config) {
  1198 + let promise;
  1199 + switch (entityType) {
  1200 + case types.entityType.device:
  1201 + promise = deviceService.saveDevice(newEntity, config);
  1202 + break;
  1203 + case types.entityType.asset:
  1204 + promise = assetService.saveAsset(newEntity, true, config);
  1205 + break;
  1206 + }
  1207 + return promise;
  1208 + }
  1209 +
1196 function getRelatedEntity(entityId, keys, typeTranslatePrefix) { 1210 function getRelatedEntity(entityId, keys, typeTranslatePrefix) {
1197 var deferred = $q.defer(); 1211 var deferred = $q.defer();
1198 getEntityPromise(entityId.entityType, entityId.id, {ignoreLoading: true}).then( 1212 getEntityPromise(entityId.entityType, entityId.id, {ignoreLoading: true}).then(
@@ -64,6 +64,10 @@ @@ -64,6 +64,10 @@
64 entity-type="types.entityType.asset"> 64 entity-type="types.entityType.asset">
65 </tb-entity-subtype-autocomplete> 65 </tb-entity-subtype-autocomplete>
66 <md-input-container class="md-block"> 66 <md-input-container class="md-block">
  67 + <label translate>asset.label</label>
  68 + <input name="label" ng-model="asset.label">
  69 + </md-input-container>
  70 + <md-input-container class="md-block">
67 <label translate>asset.description</label> 71 <label translate>asset.description</label>
68 <textarea ng-model="asset.additionalInfo.description" rows="2"></textarea> 72 <textarea ng-model="asset.additionalInfo.description" rows="2"></textarea>
69 </md-input-container> 73 </md-input-container>
@@ -369,6 +369,10 @@ export default angular.module('thingsboard.types', []) @@ -369,6 +369,10 @@ export default angular.module('thingsboard.types', [])
369 name: 'import.column-type.type', 369 name: 'import.column-type.type',
370 value: 'type' 370 value: 'type'
371 }, 371 },
  372 + label: {
  373 + name: 'import.column-type.label',
  374 + value: 'label'
  375 + },
372 clientAttribute: { 376 clientAttribute: {
373 name: 'import.column-type.client-attribute', 377 name: 'import.column-type.client-attribute',
374 value: 'CLIENT_ATTRIBUTE' 378 value: 'CLIENT_ATTRIBUTE'
@@ -98,7 +98,7 @@ export default function ImportDialogCsvController($scope, $mdDialog, toast, impo @@ -98,7 +98,7 @@ export default function ImportDialogCsvController($scope, $mdDialog, toast, impo
98 vm.columnsParam = []; 98 vm.columnsParam = [];
99 var columnParam = {}; 99 var columnParam = {};
100 for (var i = 0; i < parseData.headers.length; i++) { 100 for (var i = 0; i < parseData.headers.length; i++) {
101 - if (vm.importParameters.isHeader && parseData.headers[i].search(/^(name|type)$/im) === 0) { 101 + if (vm.importParameters.isHeader && parseData.headers[i].search(/^(name|type|label)$/im) === 0) {
102 columnParam = { 102 columnParam = {
103 type: types.importEntityColumnType[parseData.headers[i].toLowerCase()].value, 103 type: types.importEntityColumnType[parseData.headers[i].toLowerCase()].value,
104 key: parseData.headers[i].toLowerCase(), 104 key: parseData.headers[i].toLowerCase(),
@@ -126,6 +126,7 @@ export default function ImportDialogCsvController($scope, $mdDialog, toast, impo @@ -126,6 +126,7 @@ export default function ImportDialogCsvController($scope, $mdDialog, toast, impo
126 var entityData = { 126 var entityData = {
127 name: "", 127 name: "",
128 type: "", 128 type: "",
  129 + label: "",
129 accessToken: "", 130 accessToken: "",
130 attributes: { 131 attributes: {
131 server: [], 132 server: [],
@@ -162,6 +163,9 @@ export default function ImportDialogCsvController($scope, $mdDialog, toast, impo @@ -162,6 +163,9 @@ export default function ImportDialogCsvController($scope, $mdDialog, toast, impo
162 case types.importEntityColumnType.type.value: 163 case types.importEntityColumnType.type.value:
163 entityData.type = importData.rows[i][j]; 164 entityData.type = importData.rows[i][j];
164 break; 165 break;
  166 + case types.importEntityColumnType.label.value:
  167 + entityData.label = importData.rows[i][j];
  168 + break;
165 } 169 }
166 } 170 }
167 entitiesData.push(entityData); 171 entitiesData.push(entityData);
@@ -44,6 +44,7 @@ function TableColumnsAssignmentController($scope, types, $timeout) { @@ -44,6 +44,7 @@ function TableColumnsAssignmentController($scope, types, $timeout) {
44 44
45 vm.columnTypes.name = types.importEntityColumnType.name; 45 vm.columnTypes.name = types.importEntityColumnType.name;
46 vm.columnTypes.type = types.importEntityColumnType.type; 46 vm.columnTypes.type = types.importEntityColumnType.type;
  47 + vm.columnTypes.label = types.importEntityColumnType.label;
47 48
48 switch (vm.entityType) { 49 switch (vm.entityType) {
49 case types.entityType.device: 50 case types.entityType.device:
@@ -62,6 +63,7 @@ function TableColumnsAssignmentController($scope, types, $timeout) { @@ -62,6 +63,7 @@ function TableColumnsAssignmentController($scope, types, $timeout) {
62 if (newVal) { 63 if (newVal) {
63 var isSelectName = false; 64 var isSelectName = false;
64 var isSelectType = false; 65 var isSelectType = false;
  66 + var isSelectLabel = false;
65 var isSelectCredentials = false; 67 var isSelectCredentials = false;
66 for (var i = 0; i < newVal.length; i++) { 68 for (var i = 0; i < newVal.length; i++) {
67 switch (newVal[i].type) { 69 switch (newVal[i].type) {
@@ -71,6 +73,9 @@ function TableColumnsAssignmentController($scope, types, $timeout) { @@ -71,6 +73,9 @@ function TableColumnsAssignmentController($scope, types, $timeout) {
71 case types.importEntityColumnType.type.value: 73 case types.importEntityColumnType.type.value:
72 isSelectType = true; 74 isSelectType = true;
73 break; 75 break;
  76 + case types.importEntityColumnType.label.value:
  77 + isSelectLabel = true;
  78 + break;
74 case types.importEntityColumnType.accessToken.value: 79 case types.importEntityColumnType.accessToken.value:
75 isSelectCredentials = true; 80 isSelectCredentials = true;
76 break; 81 break;
@@ -84,6 +89,7 @@ function TableColumnsAssignmentController($scope, types, $timeout) { @@ -84,6 +89,7 @@ function TableColumnsAssignmentController($scope, types, $timeout) {
84 $timeout(function () { 89 $timeout(function () {
85 vm.columnTypes.name.disable = isSelectName; 90 vm.columnTypes.name.disable = isSelectName;
86 vm.columnTypes.type.disable = isSelectType; 91 vm.columnTypes.type.disable = isSelectType;
  92 + vm.columnTypes.label.disable = isSelectLabel;
87 if (angular.isDefined(vm.columnTypes.accessToken)) { 93 if (angular.isDefined(vm.columnTypes.accessToken)) {
88 vm.columnTypes.accessToken.disable = isSelectCredentials; 94 vm.columnTypes.accessToken.disable = isSelectCredentials;
89 } 95 }
@@ -41,6 +41,7 @@ @@ -41,6 +41,7 @@
41 <md-input-container md-no-float 41 <md-input-container md-no-float
42 ng-if="column.type != vm.columnTypes.name.value && 42 ng-if="column.type != vm.columnTypes.name.value &&
43 column.type != vm.columnTypes.type.value && 43 column.type != vm.columnTypes.type.value &&
  44 + column.type != vm.columnTypes.label.value &&
44 column.type != vm.columnTypes.accessToken.value"> 45 column.type != vm.columnTypes.accessToken.value">
45 <input required name="columnKeyName" 46 <input required name="columnKeyName"
46 placeholder="{{ 'import.column-value' | translate }}" 47 placeholder="{{ 'import.column-value' | translate }}"
@@ -246,7 +246,8 @@ @@ -246,7 +246,8 @@
246 "select-asset": "Vybrat aktivum", 246 "select-asset": "Vybrat aktivum",
247 "no-assets-matching": "Žádná aktiva odpovídající '{{entity}}' nebyla nalezena.", 247 "no-assets-matching": "Žádná aktiva odpovídající '{{entity}}' nebyla nalezena.",
248 "asset-required": "Aktivum je povinné", 248 "asset-required": "Aktivum je povinné",
249 - "name-starts-with": "Název aktiva začíná" 249 + "name-starts-with": "Název aktiva začíná",
  250 + "label": "Název"
250 }, 251 },
251 "attribute": { 252 "attribute": {
252 "attributes": "Atributy", 253 "attributes": "Atributy",
@@ -267,7 +267,8 @@ @@ -267,7 +267,8 @@
267 "select-asset": "Objekt auswählen", 267 "select-asset": "Objekt auswählen",
268 "no-assets-matching": "Es wurden keine zu '{{entity}}' passenden Objekte gefunden.", 268 "no-assets-matching": "Es wurden keine zu '{{entity}}' passenden Objekte gefunden.",
269 "asset-required": "Objekt ist erforderlich", 269 "asset-required": "Objekt ist erforderlich",
270 - "name-starts-with": "Name des Objekts beginnt mit" 270 + "name-starts-with": "Name des Objekts beginnt mit",
  271 + "label": "Bezeichnung"
271 }, 272 },
272 "attribute": { 273 "attribute": {
273 "attributes": "Eigenschaften", 274 "attributes": "Eigenschaften",
@@ -271,7 +271,8 @@ @@ -271,7 +271,8 @@
271 "asset-required": "Asset is required", 271 "asset-required": "Asset is required",
272 "name-starts-with": "Asset name starts with", 272 "name-starts-with": "Asset name starts with",
273 "import": "Import assets", 273 "import": "Import assets",
274 - "asset-file": "Asset file" 274 + "asset-file": "Asset file",
  275 + "label": "Label"
275 }, 276 },
276 "attribute": { 277 "attribute": {
277 "attributes": "Attributes", 278 "attributes": "Attributes",
@@ -1139,6 +1140,7 @@ @@ -1139,6 +1140,7 @@
1139 "column-type": { 1140 "column-type": {
1140 "name": "Name", 1141 "name": "Name",
1141 "type": "Type", 1142 "type": "Type",
  1143 + "label": "Label",
1142 "column-type": "Column type", 1144 "column-type": "Column type",
1143 "client-attribute": "Client attribute", 1145 "client-attribute": "Client attribute",
1144 "shared-attribute": "Shared attribute", 1146 "shared-attribute": "Shared attribute",
@@ -271,7 +271,8 @@ @@ -271,7 +271,8 @@
271 "asset-required": "El activo es requerido", 271 "asset-required": "El activo es requerido",
272 "name-starts-with": "El nombre del activo comienza con", 272 "name-starts-with": "El nombre del activo comienza con",
273 "import": "Importar activos", 273 "import": "Importar activos",
274 - "asset-file": "Archivo del activo" 274 + "asset-file": "Archivo del activo",
  275 + "label": "Etiqueta"
275 }, 276 },
276 "attribute": { 277 "attribute": {
277 "attributes": "Atributos", 278 "attributes": "Atributos",
@@ -246,7 +246,8 @@ @@ -246,7 +246,8 @@
246 "select-asset": "انتخاب دارايي", 246 "select-asset": "انتخاب دارايي",
247 "no-assets-matching": ".يافت نشد '{{entity}}' هيچ دارايي منطبق بر", 247 "no-assets-matching": ".يافت نشد '{{entity}}' هيچ دارايي منطبق بر",
248 "asset-required": "دارايي مود نياز است", 248 "asset-required": "دارايي مود نياز است",
249 - "name-starts-with": "نام دارايي شروع مي شود با" 249 + "name-starts-with": "نام دارايي شروع مي شود با",
  250 + "label": "برچسب"
250 }, 251 },
251 "attribute": { 252 "attribute": {
252 "attributes": "ويژگي ها", 253 "attributes": "ويژگي ها",
@@ -271,7 +271,8 @@ @@ -271,7 +271,8 @@
271 "unassign-assets-text": "Après la confirmation, tous les actifs sélectionnés ne seront pas attribués et ne seront pas accessibles au client.", 271 "unassign-assets-text": "Après la confirmation, tous les actifs sélectionnés ne seront pas attribués et ne seront pas accessibles au client.",
272 "unassign-assets-title": "Êtes-vous sûr de vouloir retirer l'attribution de {count, plural, 1 {1 asset} other {# assets}}?", 272 "unassign-assets-title": "Êtes-vous sûr de vouloir retirer l'attribution de {count, plural, 1 {1 asset} other {# assets}}?",
273 "unassign-from-customer": "Retirer du client", 273 "unassign-from-customer": "Retirer du client",
274 - "view-assets": "Afficher les actifs" 274 + "view-assets": "Afficher les actifs",
  275 + "label": "Label"
275 }, 276 },
276 "attribute": { 277 "attribute": {
277 "add": "Ajouter un attribut", 278 "add": "Ajouter un attribut",
@@ -268,7 +268,8 @@ @@ -268,7 +268,8 @@
268 "select-asset": "Seleziona asset", 268 "select-asset": "Seleziona asset",
269 "no-assets-matching": "Nessun asset corrispondente a '{{entity}}' è stato trovato.", 269 "no-assets-matching": "Nessun asset corrispondente a '{{entity}}' è stato trovato.",
270 "asset-required": "Asset obbligatorio", 270 "asset-required": "Asset obbligatorio",
271 - "name-starts-with": "Asset con nome che inizia per" 271 + "name-starts-with": "Asset con nome che inizia per",
  272 + "label": "Etichetta"
272 }, 273 },
273 "attribute": { 274 "attribute": {
274 "attributes": "Attributi", 275 "attributes": "Attributi",
@@ -236,7 +236,8 @@ @@ -236,7 +236,8 @@
236 "select-asset": "アセットを選択", 236 "select-asset": "アセットを選択",
237 "no-assets-matching": "'{{entity}}'発見されました。", 237 "no-assets-matching": "'{{entity}}'発見されました。",
238 "asset-required": "資産が必要です", 238 "asset-required": "資産が必要です",
239 - "name-starts-with": "アセット名はで始まります" 239 + "name-starts-with": "アセット名はで始まります",
  240 + "label": "ラベル"
240 }, 241 },
241 "attribute": { 242 "attribute": {
242 "attributes": "属性", 243 "attributes": "属性",
@@ -250,7 +250,8 @@ @@ -250,7 +250,8 @@
250 "asset-required": "Актив обязателен", 250 "asset-required": "Актив обязателен",
251 "name-starts-with": "Название актива, начинающееся с", 251 "name-starts-with": "Название актива, начинающееся с",
252 "import": "Импортировать активы", 252 "import": "Импортировать активы",
253 - "asset-file": "Файл с активами" 253 + "asset-file": "Файл с активами",
  254 + "label": "Метка"
254 }, 255 },
255 "attribute": { 256 "attribute": {
256 "attributes": "Атрибуты", 257 "attributes": "Атрибуты",
@@ -1113,6 +1114,7 @@ @@ -1113,6 +1114,7 @@
1113 "column-type": { 1114 "column-type": {
1114 "name": "Название", 1115 "name": "Название",
1115 "type": "Тип", 1116 "type": "Тип",
  1117 + "label": "Метка",
1116 "column-type": "Тип колонки", 1118 "column-type": "Тип колонки",
1117 "client-attribute": "Клиентский атрибут", 1119 "client-attribute": "Клиентский атрибут",
1118 "shared-attribute": "Общий атрибут", 1120 "shared-attribute": "Общий атрибут",
@@ -236,7 +236,8 @@ @@ -236,7 +236,8 @@
236 "select-asset": "Varlık seç", 236 "select-asset": "Varlık seç",
237 "no-assets-matching": "'{{entity}}' isimli varlık bulunamadı.", 237 "no-assets-matching": "'{{entity}}' isimli varlık bulunamadı.",
238 "asset-required": "Varlık gerekli", 238 "asset-required": "Varlık gerekli",
239 - "name-starts-with": "... ile başlayan varlık adı" 239 + "name-starts-with": "... ile başlayan varlık adı",
  240 + "label": "Etiket"
240 }, 241 },
241 "attribute": { 242 "attribute": {
242 "attributes": "Öznitelikler", 243 "attributes": "Öznitelikler",
@@ -280,7 +280,8 @@ @@ -280,7 +280,8 @@
280 "list-of-groups": "{ count, plural, 1 {Одна група активів} other {Список # груп активів} }", 280 "list-of-groups": "{ count, plural, 1 {Одна група активів} other {Список # груп активів} }",
281 "group-name-starts-with": "Групи активів, чиї імена починаються з '{{prefix}}'", 281 "group-name-starts-with": "Групи активів, чиї імена починаються з '{{prefix}}'",
282 "import": "Імпортувати активи", 282 "import": "Імпортувати активи",
283 - "asset-file": "Файл з активами" 283 + "asset-file": "Файл з активами",
  284 + "label": "Мітка"
284 }, 285 },
285 "attribute": { 286 "attribute": {
286 "attributes": "Атрибути", 287 "attributes": "Атрибути",
@@ -1365,6 +1366,7 @@ @@ -1365,6 +1366,7 @@
1365 "column-type": { 1366 "column-type": {
1366 "name": "Назва", 1367 "name": "Назва",
1367 "type": "Тип", 1368 "type": "Тип",
  1369 + "label": "Мітка",
1368 "column-type": "Тип колонки", 1370 "column-type": "Тип колонки",
1369 "client-attribute": "Атрибут клієнта", 1371 "client-attribute": "Атрибут клієнта",
1370 "shared-attribute": "Спільний атрибут", 1372 "shared-attribute": "Спільний атрибут",
@@ -2343,4 +2345,4 @@ @@ -2343,4 +2345,4 @@
2343 "cs_CZ": "Чеська" 2345 "cs_CZ": "Чеська"
2344 } 2346 }
2345 } 2347 }
2346 -} 2348 +}
@@ -241,7 +241,8 @@ @@ -241,7 +241,8 @@
241 "select-asset": "选择资产", 241 "select-asset": "选择资产",
242 "no-assets-matching": "没有找到匹配 '{{entity}}' 的资产。", 242 "no-assets-matching": "没有找到匹配 '{{entity}}' 的资产。",
243 "asset-required": "资产必填", 243 "asset-required": "资产必填",
244 - "name-starts-with": "资产名称以此开头" 244 + "name-starts-with": "资产名称以此开头",
  245 + "label": "标签"
245 }, 246 },
246 "attribute": { 247 "attribute": {
247 "attributes": "属性", 248 "attributes": "属性",