Commit 9ef646765e4bf4e07396b55f70534ca37671cd36
1 parent
0a83091a
TB-61: Improve Aliases management. Implement Asset type and Device type alias filter.
Showing
25 changed files
with
784 additions
and
457 deletions
@@ -95,8 +95,7 @@ export default class AliasController { | @@ -95,8 +95,7 @@ export default class AliasController { | ||
95 | this.entityService.resolveAlias(entityAlias, this.stateController.getStateParams()).then( | 95 | this.entityService.resolveAlias(entityAlias, this.stateController.getStateParams()).then( |
96 | function success(aliasInfo) { | 96 | function success(aliasInfo) { |
97 | aliasCtrl.resolvedAliases[aliasId] = aliasInfo; | 97 | aliasCtrl.resolvedAliases[aliasId] = aliasInfo; |
98 | - if (entityAlias.filter.stateEntity) { | ||
99 | - aliasInfo.stateEntity = true; | 98 | + if (aliasInfo.stateEntity) { |
100 | aliasCtrl.resolvedAliasesToStateEntities[aliasId] = | 99 | aliasCtrl.resolvedAliasesToStateEntities[aliasId] = |
101 | aliasCtrl.stateController.getStateParams().entityId; | 100 | aliasCtrl.stateController.getStateParams().entityId; |
102 | } | 101 | } |
@@ -31,6 +31,7 @@ function EntityService($http, $q, $filter, $translate, $log, userService, device | @@ -31,6 +31,7 @@ function EntityService($http, $q, $filter, $translate, $log, userService, device | ||
31 | resolveAliasFilter: resolveAliasFilter, | 31 | resolveAliasFilter: resolveAliasFilter, |
32 | checkEntityAlias: checkEntityAlias, | 32 | checkEntityAlias: checkEntityAlias, |
33 | filterAliasByEntityTypes: filterAliasByEntityTypes, | 33 | filterAliasByEntityTypes: filterAliasByEntityTypes, |
34 | + getAliasFilterTypesByEntityTypes: getAliasFilterTypesByEntityTypes, | ||
34 | getEntityKeys: getEntityKeys, | 35 | getEntityKeys: getEntityKeys, |
35 | createDatasourcesFromSubscriptionsInfo: createDatasourcesFromSubscriptionsInfo, | 36 | createDatasourcesFromSubscriptionsInfo: createDatasourcesFromSubscriptionsInfo, |
36 | getRelatedEntities: getRelatedEntities, | 37 | getRelatedEntities: getRelatedEntities, |
@@ -223,17 +224,21 @@ function EntityService($http, $q, $filter, $translate, $log, userService, device | @@ -223,17 +224,21 @@ function EntityService($http, $q, $filter, $translate, $log, userService, device | ||
223 | return promise; | 224 | return promise; |
224 | } | 225 | } |
225 | 226 | ||
226 | - function getEntitiesByNameFilter(entityType, entityNameFilter, limit, config, subType) { | ||
227 | - var deferred = $q.defer(); | ||
228 | - var pageLink = {limit: limit, textSearch: entityNameFilter}; | 227 | + function getEntitiesByPageLink(entityType, pageLink, config, subType, data, deferred) { |
229 | var promise = getEntitiesByPageLinkPromise(entityType, pageLink, config, subType); | 228 | var promise = getEntitiesByPageLinkPromise(entityType, pageLink, config, subType); |
230 | if (promise) { | 229 | if (promise) { |
231 | promise.then( | 230 | promise.then( |
232 | function success(result) { | 231 | function success(result) { |
233 | - if (result.data && result.data.length > 0) { | ||
234 | - deferred.resolve(result.data); | 232 | + data = data.concat(result.data); |
233 | + if (result.hasNext) { | ||
234 | + pageLink = result.nextPageLink; | ||
235 | + getEntitiesByPageLink(entityType, pageLink, config, subType, data, deferred); | ||
235 | } else { | 236 | } else { |
236 | - deferred.resolve(null); | 237 | + if (data && data.length > 0) { |
238 | + deferred.resolve(data); | ||
239 | + } else { | ||
240 | + deferred.resolve(null); | ||
241 | + } | ||
237 | } | 242 | } |
238 | }, | 243 | }, |
239 | function fail() { | 244 | function fail() { |
@@ -243,6 +248,34 @@ function EntityService($http, $q, $filter, $translate, $log, userService, device | @@ -243,6 +248,34 @@ function EntityService($http, $q, $filter, $translate, $log, userService, device | ||
243 | } else { | 248 | } else { |
244 | deferred.resolve(null); | 249 | deferred.resolve(null); |
245 | } | 250 | } |
251 | + } | ||
252 | + | ||
253 | + function getEntitiesByNameFilter(entityType, entityNameFilter, limit, config, subType) { | ||
254 | + var deferred = $q.defer(); | ||
255 | + var pageLink = {limit: limit, textSearch: entityNameFilter}; | ||
256 | + if (limit == -1) { // all | ||
257 | + var data = []; | ||
258 | + pageLink.limit = 100; | ||
259 | + getEntitiesByPageLink(entityType, pageLink, config, subType, data, deferred); | ||
260 | + } else { | ||
261 | + var promise = getEntitiesByPageLinkPromise(entityType, pageLink, config, subType); | ||
262 | + if (promise) { | ||
263 | + promise.then( | ||
264 | + function success(result) { | ||
265 | + if (result.data && result.data.length > 0) { | ||
266 | + deferred.resolve(result.data); | ||
267 | + } else { | ||
268 | + deferred.resolve(null); | ||
269 | + } | ||
270 | + }, | ||
271 | + function fail() { | ||
272 | + deferred.resolve(null); | ||
273 | + } | ||
274 | + ); | ||
275 | + } else { | ||
276 | + deferred.resolve(null); | ||
277 | + } | ||
278 | + } | ||
246 | return deferred.promise; | 279 | return deferred.promise; |
247 | } | 280 | } |
248 | 281 | ||
@@ -261,11 +294,12 @@ function EntityService($http, $q, $filter, $translate, $log, userService, device | @@ -261,11 +294,12 @@ function EntityService($http, $q, $filter, $translate, $log, userService, device | ||
261 | function resolveAlias(entityAlias, stateParams) { | 294 | function resolveAlias(entityAlias, stateParams) { |
262 | var deferred = $q.defer(); | 295 | var deferred = $q.defer(); |
263 | var filter = entityAlias.filter; | 296 | var filter = entityAlias.filter; |
264 | - resolveAliasFilter(filter, stateParams, 100).then( | 297 | + resolveAliasFilter(filter, stateParams, -1).then( |
265 | function (result) { | 298 | function (result) { |
266 | var entities = result.entities; | 299 | var entities = result.entities; |
267 | var aliasInfo = { | 300 | var aliasInfo = { |
268 | alias: entityAlias.alias, | 301 | alias: entityAlias.alias, |
302 | + stateEntity: result.stateEntity, | ||
269 | resolveMultiple: filter.resolveMultiple | 303 | resolveMultiple: filter.resolveMultiple |
270 | }; | 304 | }; |
271 | var resolvedEntities = entitiesToEntitiesInfo(entities); | 305 | var resolvedEntities = entitiesToEntitiesInfo(entities); |
@@ -291,39 +325,68 @@ function EntityService($http, $q, $filter, $translate, $log, userService, device | @@ -291,39 +325,68 @@ function EntityService($http, $q, $filter, $translate, $log, userService, device | ||
291 | }; | 325 | }; |
292 | switch (filter.type) { | 326 | switch (filter.type) { |
293 | case types.aliasFilterType.entityList.value: | 327 | case types.aliasFilterType.entityList.value: |
294 | - if (filter.stateEntity) { | ||
295 | - result.stateEntity = true; | ||
296 | - if (stateParams && stateParams.entityId) { | ||
297 | - getEntity(stateParams.entityId.entityType, stateParams.entityId.id).then( | ||
298 | - function success(entity) { | ||
299 | - result.entities = [entity]; | ||
300 | - deferred.resolve(result); | ||
301 | - }, | ||
302 | - function fail() { | ||
303 | - deferred.reject(); | ||
304 | - } | ||
305 | - ); | ||
306 | - } else { | ||
307 | - deferred.resolve(result); | 328 | + getEntities(filter.entityType, filter.entityList).then( |
329 | + function success(entities) { | ||
330 | + if (entities && entities.length) { | ||
331 | + result.entities = entities; | ||
332 | + deferred.resolve(result); | ||
333 | + } else { | ||
334 | + deferred.reject(); | ||
335 | + } | ||
336 | + }, | ||
337 | + function fail() { | ||
338 | + deferred.reject(); | ||
308 | } | 339 | } |
309 | - } else { | ||
310 | - getEntities(filter.entityType, filter.entityList).then( | ||
311 | - function success(entities) { | ||
312 | - if (entities && entities.length) { | ||
313 | - result.entities = entities; | ||
314 | - deferred.resolve(result); | ||
315 | - } else { | ||
316 | - deferred.reject(); | ||
317 | - } | 340 | + ); |
341 | + break; | ||
342 | + case types.aliasFilterType.entityName.value: | ||
343 | + getEntitiesByNameFilter(filter.entityType, filter.entityNameFilter, maxItems).then( | ||
344 | + function success(entities) { | ||
345 | + if (entities && entities.length) { | ||
346 | + result.entities = entities; | ||
347 | + deferred.resolve(result); | ||
348 | + } else { | ||
349 | + deferred.reject(); | ||
350 | + } | ||
351 | + }, | ||
352 | + function fail() { | ||
353 | + deferred.reject(); | ||
354 | + } | ||
355 | + ); | ||
356 | + break; | ||
357 | + case types.aliasFilterType.stateEntity.value: | ||
358 | + result.stateEntity = true; | ||
359 | + if (stateParams && stateParams.entityId) { | ||
360 | + getEntity(stateParams.entityId.entityType, stateParams.entityId.id).then( | ||
361 | + function success(entity) { | ||
362 | + result.entities = [entity]; | ||
363 | + deferred.resolve(result); | ||
318 | }, | 364 | }, |
319 | function fail() { | 365 | function fail() { |
320 | deferred.reject(); | 366 | deferred.reject(); |
321 | } | 367 | } |
322 | ); | 368 | ); |
369 | + } else { | ||
370 | + deferred.resolve(result); | ||
323 | } | 371 | } |
324 | break; | 372 | break; |
325 | - case types.aliasFilterType.entityName.value: | ||
326 | - getEntitiesByNameFilter(filter.entityType, filter.entityNameFilter, maxItems).then( | 373 | + case types.aliasFilterType.assetType.value: |
374 | + getEntitiesByNameFilter(types.entityType.asset, filter.assetNameFilter, maxItems, null, filter.assetType).then( | ||
375 | + function success(entities) { | ||
376 | + if (entities && entities.length) { | ||
377 | + result.entities = entities; | ||
378 | + deferred.resolve(result); | ||
379 | + } else { | ||
380 | + deferred.reject(); | ||
381 | + } | ||
382 | + }, | ||
383 | + function fail() { | ||
384 | + deferred.reject(); | ||
385 | + } | ||
386 | + ); | ||
387 | + break; | ||
388 | + case types.aliasFilterType.deviceType.value: | ||
389 | + getEntitiesByNameFilter(types.entityType.device, filter.deviceNameFilter, maxItems, null, filter.deviceType).then( | ||
327 | function success(entities) { | 390 | function success(entities) { |
328 | if (entities && entities.length) { | 391 | if (entities && entities.length) { |
329 | result.entities = entities; | 392 | result.entities = entities; |
@@ -337,27 +400,81 @@ function EntityService($http, $q, $filter, $translate, $log, userService, device | @@ -337,27 +400,81 @@ function EntityService($http, $q, $filter, $translate, $log, userService, device | ||
337 | } | 400 | } |
338 | ); | 401 | ); |
339 | break; | 402 | break; |
340 | - //TODO: | 403 | + |
404 | + //TODO: Alias filter | ||
341 | } | 405 | } |
342 | return deferred.promise; | 406 | return deferred.promise; |
343 | } | 407 | } |
344 | 408 | ||
345 | function filterAliasByEntityTypes(entityAlias, entityTypes) { | 409 | function filterAliasByEntityTypes(entityAlias, entityTypes) { |
346 | var filter = entityAlias.filter; | 410 | var filter = entityAlias.filter; |
347 | - switch (filter.type) { | ||
348 | - case types.aliasFilterType.entityList.value: | ||
349 | - if (filter.stateEntity) { | ||
350 | - return true; | ||
351 | - } else { | 411 | + if (filterAliasFilterTypeByEntityTypes(filter.type, entityTypes)) { |
412 | + switch (filter.type) { | ||
413 | + case types.aliasFilterType.entityList.value: | ||
352 | return entityTypes.indexOf(filter.entityType) > -1 ? true : false; | 414 | return entityTypes.indexOf(filter.entityType) > -1 ? true : false; |
353 | - } | 415 | + case types.aliasFilterType.entityName.value: |
416 | + return entityTypes.indexOf(filter.entityType) > -1 ? true : false; | ||
417 | + case types.aliasFilterType.stateEntity.value: | ||
418 | + return true; | ||
419 | + case types.aliasFilterType.assetType.value: | ||
420 | + return entityTypes.indexOf(types.entityType.asset) > -1 ? true : false; | ||
421 | + case types.aliasFilterType.deviceType.value: | ||
422 | + return entityTypes.indexOf(types.entityType.device) > -1 ? true : false; | ||
423 | + } | ||
424 | + } | ||
425 | + //TODO: Alias filter | ||
426 | + return false; | ||
427 | + } | ||
428 | + | ||
429 | + function filterAliasFilterTypeByEntityType(aliasFilterType, entityType) { | ||
430 | + switch (aliasFilterType) { | ||
431 | + case types.aliasFilterType.entityList.value: | ||
432 | + return true; | ||
354 | case types.aliasFilterType.entityName.value: | 433 | case types.aliasFilterType.entityName.value: |
355 | - return entityTypes.indexOf(filter.entityType) > -1 ? true : false; | 434 | + return true; |
435 | + case types.aliasFilterType.stateEntity.value: | ||
436 | + return true; | ||
437 | + case types.aliasFilterType.assetType.value: | ||
438 | + return entityType === types.entityType.asset; | ||
439 | + case types.aliasFilterType.deviceType.value: | ||
440 | + return entityType === types.entityType.device; | ||
441 | + case types.aliasFilterType.relationsQuery.value: | ||
442 | + return true; | ||
443 | + case types.aliasFilterType.assetSearchQuery.value: | ||
444 | + return entityType === types.entityType.asset; | ||
445 | + case types.aliasFilterType.deviceSearchQuery.value: | ||
446 | + return entityType === types.entityType.device; | ||
356 | } | 447 | } |
357 | - //TODO: | ||
358 | return false; | 448 | return false; |
359 | } | 449 | } |
360 | 450 | ||
451 | + function filterAliasFilterTypeByEntityTypes(aliasFilterType, entityTypes) { | ||
452 | + if (!entityTypes || !entityTypes.length) { | ||
453 | + return true; | ||
454 | + } | ||
455 | + var valid = false; | ||
456 | + entityTypes.forEach(function(entityType) { | ||
457 | + valid = valid || filterAliasFilterTypeByEntityType(aliasFilterType, entityType); | ||
458 | + }); | ||
459 | + return valid; | ||
460 | + } | ||
461 | + | ||
462 | + function getAliasFilterTypesByEntityTypes(entityTypes) { | ||
463 | + var allAliasFilterTypes = types.aliasFilterType; | ||
464 | + if (!entityTypes || !entityTypes.length) { | ||
465 | + return allAliasFilterTypes; | ||
466 | + } | ||
467 | + var result = {}; | ||
468 | + for (var type in allAliasFilterTypes) { | ||
469 | + var aliasFilterType = allAliasFilterTypes[type]; | ||
470 | + if (filterAliasFilterTypeByEntityTypes(aliasFilterType.value, entityTypes)) { | ||
471 | + result[type] = aliasFilterType; | ||
472 | + } | ||
473 | + } | ||
474 | + return result; | ||
475 | + } | ||
476 | + | ||
477 | + | ||
361 | function checkEntityAlias(entityAlias) { | 478 | function checkEntityAlias(entityAlias) { |
362 | var deferred = $q.defer(); | 479 | var deferred = $q.defer(); |
363 | resolveAliasFilter(entityAlias.filter, null, 1).then( | 480 | resolveAliasFilter(entityAlias.filter, null, 1).then( |
@@ -380,50 +497,6 @@ function EntityService($http, $q, $filter, $translate, $log, userService, device | @@ -380,50 +497,6 @@ function EntityService($http, $q, $filter, $translate, $log, userService, device | ||
380 | return deferred.promise; | 497 | return deferred.promise; |
381 | } | 498 | } |
382 | 499 | ||
383 | - /*function processEntityAlias(index, aliasIds, entityAliases, stateParams, resolution, deferred) { | ||
384 | - if (index < aliasIds.length) { | ||
385 | - var aliasId = aliasIds[index]; | ||
386 | - var entityAlias = entityAliases[aliasId]; | ||
387 | - var alias = entityAlias.alias; | ||
388 | - var filter = entityAlias.filter; | ||
389 | - resolveAliasFilter(filter, stateParams).then( | ||
390 | - function (entities) { | ||
391 | - if (entities && entities.length) { | ||
392 | - var entity = entities[0]; | ||
393 | - var resolvedAlias = {alias: alias, entityType: entity.id.entityType, entityId: entity.id.id}; | ||
394 | - resolution.aliasesInfo.entityAliases[aliasId] = resolvedAlias; | ||
395 | - resolution.aliasesInfo.entityAliasesInfo[aliasId] = entitiesToEntitiesInfo(entities); | ||
396 | - index++; | ||
397 | - processEntityAlias(index, aliasIds, entityAliases, stateParams, resolution, deferred); | ||
398 | - } else { | ||
399 | - if (!resolution.error) { | ||
400 | - resolution.error = 'dashboard.invalid-aliases-config'; | ||
401 | - } | ||
402 | - index++; | ||
403 | - processEntityAlias(index, aliasIds, entityAliases, stateParams, resolution, deferred); | ||
404 | - } | ||
405 | - } | ||
406 | - ); | ||
407 | - } else { | ||
408 | - deferred.resolve(resolution); | ||
409 | - } | ||
410 | - }*/ | ||
411 | - | ||
412 | - /*function processEntityAliases(entityAliases, stateParams) { | ||
413 | - var deferred = $q.defer(); | ||
414 | - var resolution = { | ||
415 | - aliasesInfo: {} | ||
416 | - }; | ||
417 | - var aliasIds = []; | ||
418 | - if (entityAliases) { | ||
419 | - for (var aliasId in entityAliases) { | ||
420 | - aliasIds.push(aliasId); | ||
421 | - } | ||
422 | - } | ||
423 | - processEntityAlias(0, aliasIds, entityAliases, stateParams, resolution, deferred); | ||
424 | - return deferred.promise; | ||
425 | - }*/ | ||
426 | - | ||
427 | function getEntityKeys(entityType, entityId, query, type) { | 500 | function getEntityKeys(entityType, entityId, query, type) { |
428 | var deferred = $q.defer(); | 501 | var deferred = $q.defer(); |
429 | var url = '/api/plugins/telemetry/' + entityType + '/' + entityId + '/keys/'; | 502 | var url = '/api/plugins/telemetry/' + entityType + '/' + entityId + '/keys/'; |
@@ -889,4 +962,4 @@ function EntityService($http, $q, $filter, $translate, $log, userService, device | @@ -889,4 +962,4 @@ function EntityService($http, $q, $filter, $translate, $log, userService, device | ||
889 | } | 962 | } |
890 | } | 963 | } |
891 | 964 | ||
892 | -} | ||
965 | +} |
@@ -258,17 +258,17 @@ export default class Subscription { | @@ -258,17 +258,17 @@ export default class Subscription { | ||
258 | } else { | 258 | } else { |
259 | subscription.rpcEnabled = subscription.ctx.$scope.widgetEditMode ? true : false; | 259 | subscription.rpcEnabled = subscription.ctx.$scope.widgetEditMode ? true : false; |
260 | } | 260 | } |
261 | - subscription.callbacks.rpcStateChanged(this); | 261 | + subscription.callbacks.rpcStateChanged(subscription); |
262 | deferred.resolve(); | 262 | deferred.resolve(); |
263 | } else { | 263 | } else { |
264 | subscription.rpcEnabled = false; | 264 | subscription.rpcEnabled = false; |
265 | - subscription.callbacks.rpcStateChanged(this); | 265 | + subscription.callbacks.rpcStateChanged(subscription); |
266 | deferred.resolve(); | 266 | deferred.resolve(); |
267 | } | 267 | } |
268 | }, | 268 | }, |
269 | function fail () { | 269 | function fail () { |
270 | subscription.rpcEnabled = false; | 270 | subscription.rpcEnabled = false; |
271 | - subscription.callbacks.rpcStateChanged(this); | 271 | + subscription.callbacks.rpcStateChanged(subscription); |
272 | deferred.resolve(); | 272 | deferred.resolve(); |
273 | } | 273 | } |
274 | ); | 274 | ); |
@@ -110,14 +110,12 @@ function DashboardUtils(types, utils, timeService) { | @@ -110,14 +110,12 @@ function DashboardUtils(types, utils, timeService) { | ||
110 | deviceAlias.deviceFilter.useFilter ? types.aliasFilterType.entityName.value : types.aliasFilterType.entityList.value; | 110 | deviceAlias.deviceFilter.useFilter ? types.aliasFilterType.entityName.value : types.aliasFilterType.entityList.value; |
111 | if (entityAlias.filter.type == types.aliasFilterType.entityList.value) { | 111 | if (entityAlias.filter.type == types.aliasFilterType.entityList.value) { |
112 | entityAlias.filter.entityList = deviceAlias.deviceFilter.deviceList; | 112 | entityAlias.filter.entityList = deviceAlias.deviceFilter.deviceList; |
113 | - entityAlias.filter.stateEntity = false; | ||
114 | } else { | 113 | } else { |
115 | entityAlias.filter.entityNameFilter = deviceAlias.deviceFilter.deviceNameFilter; | 114 | entityAlias.filter.entityNameFilter = deviceAlias.deviceFilter.deviceNameFilter; |
116 | } | 115 | } |
117 | } else { | 116 | } else { |
118 | entityAlias.filter.type = types.aliasFilterType.entityList.value; | 117 | entityAlias.filter.type = types.aliasFilterType.entityList.value; |
119 | entityAlias.filter.entityList = [deviceAlias.deviceId]; | 118 | entityAlias.filter.entityList = [deviceAlias.deviceId]; |
120 | - entityAlias.filter.stateEntity = false; | ||
121 | } | 119 | } |
122 | return entityAlias; | 120 | return entityAlias; |
123 | } | 121 | } |
@@ -132,7 +130,6 @@ function DashboardUtils(types, utils, timeService) { | @@ -132,7 +130,6 @@ function DashboardUtils(types, utils, timeService) { | ||
132 | } | 130 | } |
133 | if (entityAlias.filter.type == types.aliasFilterType.entityList.value) { | 131 | if (entityAlias.filter.type == types.aliasFilterType.entityList.value) { |
134 | entityAlias.filter.entityList = entityAlias.entityFilter.entityList; | 132 | entityAlias.filter.entityList = entityAlias.entityFilter.entityList; |
135 | - entityAlias.filter.stateEntity = false; | ||
136 | } else { | 133 | } else { |
137 | entityAlias.filter.entityNameFilter = entityAlias.entityFilter.entityNameFilter; | 134 | entityAlias.filter.entityNameFilter = entityAlias.entityFilter.entityNameFilter; |
138 | } | 135 | } |
@@ -342,7 +339,6 @@ function DashboardUtils(types, utils, timeService) { | @@ -342,7 +339,6 @@ function DashboardUtils(types, utils, timeService) { | ||
342 | function createSingleEntityFilter(entityType, entityId) { | 339 | function createSingleEntityFilter(entityType, entityId) { |
343 | return { | 340 | return { |
344 | type: types.aliasFilterType.entityList.value, | 341 | type: types.aliasFilterType.entityList.value, |
345 | - stateEntity: false, | ||
346 | entityList: [entityId], | 342 | entityList: [entityId], |
347 | entityType: entityType, | 343 | entityType: entityType, |
348 | resolveMultiple: false | 344 | resolveMultiple: false |
@@ -74,6 +74,10 @@ export default angular.module('thingsboard.types', []) | @@ -74,6 +74,10 @@ export default angular.module('thingsboard.types', []) | ||
74 | value: 'entityName', | 74 | value: 'entityName', |
75 | name: 'alias.filter-type-entity-name' | 75 | name: 'alias.filter-type-entity-name' |
76 | }, | 76 | }, |
77 | + stateEntity: { | ||
78 | + value: 'stateEntity', | ||
79 | + name: 'alias.filter-type-state-entity' | ||
80 | + }, | ||
77 | assetType: { | 81 | assetType: { |
78 | value: 'assetType', | 82 | value: 'assetType', |
79 | name: 'alias.filter-type-asset-type' | 83 | name: 'alias.filter-type-asset-type' |
@@ -139,6 +143,53 @@ export default angular.module('thingsboard.types', []) | @@ -139,6 +143,53 @@ export default angular.module('thingsboard.types', []) | ||
139 | dashboard: "DASHBOARD", | 143 | dashboard: "DASHBOARD", |
140 | alarm: "ALARM" | 144 | alarm: "ALARM" |
141 | }, | 145 | }, |
146 | + entityTypeTranslations: { | ||
147 | + "DEVICE": { | ||
148 | + type: 'entity.type-device', | ||
149 | + list: 'entity.list-of-devices', | ||
150 | + nameStartsWith: 'entity.device-name-starts-with' | ||
151 | + }, | ||
152 | + "ASSET": { | ||
153 | + type: 'entity.type-asset', | ||
154 | + list: 'entity.list-of-assets', | ||
155 | + nameStartsWith: 'entity.asset-name-starts-with' | ||
156 | + }, | ||
157 | + "RULE": { | ||
158 | + type: 'entity.type-rule', | ||
159 | + list: 'entity.list-of-rules', | ||
160 | + nameStartsWith: 'entity.rule-name-starts-with' | ||
161 | + }, | ||
162 | + "PLUGIN": { | ||
163 | + type: 'entity.type-plugin', | ||
164 | + list: 'entity.list-of-plugins', | ||
165 | + nameStartsWith: 'entity.plugin-name-starts-with' | ||
166 | + }, | ||
167 | + "TENANT": { | ||
168 | + type: 'entity.type-tenant', | ||
169 | + list: 'entity.list-of-tenants', | ||
170 | + nameStartsWith: 'entity.tenant-name-starts-with' | ||
171 | + }, | ||
172 | + "CUSTOMER": { | ||
173 | + type: 'entity.type-customer', | ||
174 | + list: 'entity.list-of-customers', | ||
175 | + nameStartsWith: 'entity.customer-name-starts-with' | ||
176 | + }, | ||
177 | + "USER": { | ||
178 | + type: 'entity.type-user', | ||
179 | + list: 'entity.list-of-users', | ||
180 | + nameStartsWith: 'entity.user-name-starts-with' | ||
181 | + }, | ||
182 | + "DASHBOARD": { | ||
183 | + type: 'entity.type-dashboard', | ||
184 | + list: 'entity.list-of-dashboards', | ||
185 | + nameStartsWith: 'entity.dashboard-name-starts-with' | ||
186 | + }, | ||
187 | + "ALARM": { | ||
188 | + type: 'entity.type-alarm', | ||
189 | + list: 'entity.list-of-alarms', | ||
190 | + nameStartsWith: 'entity.alarm-name-starts-with' | ||
191 | + } | ||
192 | + }, | ||
142 | entitySearchDirection: { | 193 | entitySearchDirection: { |
143 | from: "FROM", | 194 | from: "FROM", |
144 | to: "TO" | 195 | to: "TO" |
@@ -109,8 +109,7 @@ function Utils($mdColorPalette, $rootScope, $window, types) { | @@ -109,8 +109,7 @@ function Utils($mdColorPalette, $rootScope, $window, types) { | ||
109 | cleanCopy: cleanCopy, | 109 | cleanCopy: cleanCopy, |
110 | isLocalUrl: isLocalUrl, | 110 | isLocalUrl: isLocalUrl, |
111 | validateDatasources: validateDatasources, | 111 | validateDatasources: validateDatasources, |
112 | - createKey: createKey, | ||
113 | - entityTypeName: entityTypeName | 112 | + createKey: createKey |
114 | } | 113 | } |
115 | 114 | ||
116 | return service; | 115 | return service; |
@@ -358,27 +357,4 @@ function Utils($mdColorPalette, $rootScope, $window, types) { | @@ -358,27 +357,4 @@ function Utils($mdColorPalette, $rootScope, $window, types) { | ||
358 | return dataKey; | 357 | return dataKey; |
359 | } | 358 | } |
360 | 359 | ||
361 | - function entityTypeName (type) { | ||
362 | - switch (type) { | ||
363 | - case types.entityType.device: | ||
364 | - return 'entity.type-device'; | ||
365 | - case types.entityType.asset: | ||
366 | - return 'entity.type-asset'; | ||
367 | - case types.entityType.rule: | ||
368 | - return 'entity.type-rule'; | ||
369 | - case types.entityType.plugin: | ||
370 | - return 'entity.type-plugin'; | ||
371 | - case types.entityType.tenant: | ||
372 | - return 'entity.type-tenant'; | ||
373 | - case types.entityType.customer: | ||
374 | - return 'entity.type-customer'; | ||
375 | - case types.entityType.user: | ||
376 | - return 'entity.type-user'; | ||
377 | - case types.entityType.dashboard: | ||
378 | - return 'entity.type-dashboard'; | ||
379 | - case types.entityType.alarm: | ||
380 | - return 'entity.type-alarm'; | ||
381 | - } | ||
382 | - } | ||
383 | - | ||
384 | } | 360 | } |
@@ -15,7 +15,7 @@ | @@ -15,7 +15,7 @@ | ||
15 | */ | 15 | */ |
16 | /* eslint-disable import/no-unresolved, import/default */ | 16 | /* eslint-disable import/no-unresolved, import/default */ |
17 | 17 | ||
18 | -import entityAliasesTemplate from '../entity/entity-aliases.tpl.html'; | 18 | +import entityAliasDialogTemplate from '../entity/entity-alias-dialog.tpl.html'; |
19 | 19 | ||
20 | /* eslint-enable import/no-unresolved, import/default */ | 20 | /* eslint-enable import/no-unresolved, import/default */ |
21 | 21 | ||
@@ -130,17 +130,14 @@ export default function AddWidgetController($scope, widgetService, entityService | @@ -130,17 +130,14 @@ export default function AddWidgetController($scope, widgetService, entityService | ||
130 | var singleEntityAlias = {id: null, alias: alias, filter: {}}; | 130 | var singleEntityAlias = {id: null, alias: alias, filter: {}}; |
131 | 131 | ||
132 | $mdDialog.show({ | 132 | $mdDialog.show({ |
133 | - controller: 'EntityAliasesController', | 133 | + controller: 'EntityAliasDialogController', |
134 | controllerAs: 'vm', | 134 | controllerAs: 'vm', |
135 | - templateUrl: entityAliasesTemplate, | 135 | + templateUrl: entityAliasDialogTemplate, |
136 | locals: { | 136 | locals: { |
137 | - config: { | ||
138 | - entityAliases: angular.copy(vm.dashboard.configuration.entityAliases), | ||
139 | - widgets: null, | ||
140 | - isSingleEntityAlias: true, | ||
141 | - singleEntityAlias: singleEntityAlias, | ||
142 | - allowedEntityTypes: allowedEntityTypes | ||
143 | - } | 137 | + isAdd: true, |
138 | + allowedEntityTypes: allowedEntityTypes, | ||
139 | + entityAliases: vm.dashboard.configuration.entityAliases, | ||
140 | + alias: singleEntityAlias | ||
144 | }, | 141 | }, |
145 | parent: angular.element($document[0].body), | 142 | parent: angular.element($document[0].body), |
146 | fullscreen: true, | 143 | fullscreen: true, |
@@ -15,7 +15,7 @@ | @@ -15,7 +15,7 @@ | ||
15 | */ | 15 | */ |
16 | /* eslint-disable import/no-unresolved, import/default */ | 16 | /* eslint-disable import/no-unresolved, import/default */ |
17 | 17 | ||
18 | -import entityAliasesTemplate from '../entity/entity-aliases.tpl.html'; | 18 | +import entityAliasDialogTemplate from '../entity/entity-alias-dialog.tpl.html'; |
19 | import editWidgetTemplate from './edit-widget.tpl.html'; | 19 | import editWidgetTemplate from './edit-widget.tpl.html'; |
20 | 20 | ||
21 | /* eslint-enable import/no-unresolved, import/default */ | 21 | /* eslint-enable import/no-unresolved, import/default */ |
@@ -98,17 +98,14 @@ export default function EditWidgetDirective($compile, $templateCache, types, wid | @@ -98,17 +98,14 @@ export default function EditWidgetDirective($compile, $templateCache, types, wid | ||
98 | var singleEntityAlias = {id: null, alias: alias, filter: {}}; | 98 | var singleEntityAlias = {id: null, alias: alias, filter: {}}; |
99 | 99 | ||
100 | $mdDialog.show({ | 100 | $mdDialog.show({ |
101 | - controller: 'EntityAliasesController', | 101 | + controller: 'EntityAliasDialogController', |
102 | controllerAs: 'vm', | 102 | controllerAs: 'vm', |
103 | - templateUrl: entityAliasesTemplate, | 103 | + templateUrl: entityAliasDialogTemplate, |
104 | locals: { | 104 | locals: { |
105 | - config: { | ||
106 | - entityAliases: angular.copy(scope.dashboard.configuration.entityAliases), | ||
107 | - widgets: null, | ||
108 | - isSingleEntityAlias: true, | ||
109 | - singleEntityAlias: singleEntityAlias, | ||
110 | - allowedEntityTypes: allowedEntityTypes | ||
111 | - } | 105 | + isAdd: true, |
106 | + allowedEntityTypes: allowedEntityTypes, | ||
107 | + entityAliases: scope.dashboard.configuration.entityAliases, | ||
108 | + alias: singleEntityAlias | ||
112 | }, | 109 | }, |
113 | parent: angular.element($document[0].body), | 110 | parent: angular.element($document[0].body), |
114 | fullscreen: true, | 111 | fullscreen: true, |
ui/src/app/entity/entity-alias-dialog.controller.js
renamed from
ui/src/app/entity/entity-filter-dialog.controller.js
@@ -14,22 +14,48 @@ | @@ -14,22 +14,48 @@ | ||
14 | * limitations under the License. | 14 | * limitations under the License. |
15 | */ | 15 | */ |
16 | 16 | ||
17 | +import './entity-alias-dialog.scss'; | ||
18 | + | ||
17 | /*@ngInject*/ | 19 | /*@ngInject*/ |
18 | -export default function EntityFilterDialogController($scope, $mdDialog, $q, entityService, types, isAdd, allowedEntityTypes, filter) { | 20 | +export default function EntityAliasDialogController($scope, $mdDialog, $q, $filter, utils, entityService, types, isAdd, allowedEntityTypes, entityAliases, alias) { |
19 | 21 | ||
20 | var vm = this; | 22 | var vm = this; |
21 | 23 | ||
22 | vm.types = types; | 24 | vm.types = types; |
23 | vm.isAdd = isAdd; | 25 | vm.isAdd = isAdd; |
24 | vm.allowedEntityTypes = allowedEntityTypes; | 26 | vm.allowedEntityTypes = allowedEntityTypes; |
25 | - vm.filter = filter; | 27 | + if (angular.isArray(entityAliases)) { |
28 | + vm.entityAliases = entityAliases; | ||
29 | + } else { | ||
30 | + vm.entityAliases = []; | ||
31 | + for (var aliasId in entityAliases) { | ||
32 | + vm.entityAliases.push(entityAliases[aliasId]); | ||
33 | + } | ||
34 | + } | ||
35 | + if (vm.isAdd && !alias) { | ||
36 | + vm.alias = { | ||
37 | + alias: '', | ||
38 | + filter: { | ||
39 | + resolveMultiple: false | ||
40 | + } | ||
41 | + }; | ||
42 | + } else { | ||
43 | + vm.alias = alias; | ||
44 | + } | ||
26 | 45 | ||
27 | vm.cancel = cancel; | 46 | vm.cancel = cancel; |
28 | vm.save = save; | 47 | vm.save = save; |
29 | 48 | ||
30 | - $scope.$watch('vm.filter.type', function (newType, prevType) { | ||
31 | - if (newType && newType != prevType) { | ||
32 | - updateFilter(); | 49 | + $scope.$watch('vm.alias.alias', function (newAlias) { |
50 | + if (newAlias) { | ||
51 | + var valid = true; | ||
52 | + var result = $filter('filter')(vm.entityAliases, {alias: newAlias}, true); | ||
53 | + if (result && result.length) { | ||
54 | + if (vm.isAdd || vm.alias.id != result[0].id) { | ||
55 | + valid = false; | ||
56 | + } | ||
57 | + } | ||
58 | + $scope.theForm.aliasName.$setValidity('duplicateAliasName', valid); | ||
33 | } | 59 | } |
34 | }); | 60 | }); |
35 | 61 | ||
@@ -39,32 +65,13 @@ export default function EntityFilterDialogController($scope, $mdDialog, $q, enti | @@ -39,32 +65,13 @@ export default function EntityFilterDialogController($scope, $mdDialog, $q, enti | ||
39 | } | 65 | } |
40 | }); | 66 | }); |
41 | 67 | ||
42 | - function updateFilter() { | ||
43 | - var filter = {}; | ||
44 | - filter.type = vm.filter.type; | ||
45 | - filter.resolveMultiple = vm.filter.resolveMultiple; | ||
46 | - switch (filter.type) { | ||
47 | - case types.aliasFilterType.entityList.value: | ||
48 | - filter.entityType = null; | ||
49 | - filter.entityList = []; | ||
50 | - filter.stateEntity = false; | ||
51 | - break; | ||
52 | - case types.aliasFilterType.entityName.value: | ||
53 | - filter.entityType = null; | ||
54 | - filter.entityNameFilter = ''; | ||
55 | - break; | ||
56 | - //TODO: | ||
57 | - } | ||
58 | - vm.filter = filter; | ||
59 | - } | ||
60 | - | ||
61 | function validate() { | 68 | function validate() { |
62 | var deferred = $q.defer(); | 69 | var deferred = $q.defer(); |
63 | var validationResult = { | 70 | var validationResult = { |
64 | entity: null, | 71 | entity: null, |
65 | stateEntity: false | 72 | stateEntity: false |
66 | } | 73 | } |
67 | - entityService.resolveAliasFilter(vm.filter, null, 1).then( | 74 | + entityService.resolveAliasFilter(vm.alias.filter, null, 1).then( |
68 | function success(result) { | 75 | function success(result) { |
69 | validationResult.stateEntity = result.stateEntity; | 76 | validationResult.stateEntity = result.stateEntity; |
70 | var entities = result.entities; | 77 | var entities = result.entities; |
@@ -87,12 +94,11 @@ export default function EntityFilterDialogController($scope, $mdDialog, $q, enti | @@ -87,12 +94,11 @@ export default function EntityFilterDialogController($scope, $mdDialog, $q, enti | ||
87 | function save() { | 94 | function save() { |
88 | $scope.theForm.$setPristine(); | 95 | $scope.theForm.$setPristine(); |
89 | validate().then( | 96 | validate().then( |
90 | - function success(validationResult) { | ||
91 | - $mdDialog.hide({ | ||
92 | - filter: vm.filter, | ||
93 | - entity: validationResult.entity, | ||
94 | - stateEntity: validationResult.stateEntity | ||
95 | - }); | 97 | + function success() { |
98 | + if (vm.isAdd) { | ||
99 | + vm.alias.id = utils.guid(); | ||
100 | + } | ||
101 | + $mdDialog.hide(vm.alias); | ||
96 | }, | 102 | }, |
97 | function fail() { | 103 | function fail() { |
98 | $scope.theForm.$setValidity('entityFilter', false); | 104 | $scope.theForm.$setValidity('entityFilter', false); |
@@ -101,4 +107,3 @@ export default function EntityFilterDialogController($scope, $mdDialog, $q, enti | @@ -101,4 +107,3 @@ export default function EntityFilterDialogController($scope, $mdDialog, $q, enti | ||
101 | } | 107 | } |
102 | 108 | ||
103 | } | 109 | } |
104 | - |
ui/src/app/entity/entity-alias-dialog.scss
0 → 100644
1 | +/** | ||
2 | + * Copyright © 2016-2017 The Thingsboard Authors | ||
3 | + * | ||
4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | + * you may not use this file except in compliance with the License. | ||
6 | + * You may obtain a copy of the License at | ||
7 | + * | ||
8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | + * | ||
10 | + * Unless required by applicable law or agreed to in writing, software | ||
11 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | + * See the License for the specific language governing permissions and | ||
14 | + * limitations under the License. | ||
15 | + */ | ||
16 | + | ||
17 | +.tb-entity-alias-dialog { | ||
18 | + .tb-resolve-multiple-switch { | ||
19 | + padding-left: 10px; | ||
20 | + .resolve-multiple-switch { | ||
21 | + margin: 0; | ||
22 | + } | ||
23 | + .resolve-multiple-label { | ||
24 | + margin: 5px 0; | ||
25 | + } | ||
26 | + } | ||
27 | +} |
ui/src/app/entity/entity-alias-dialog.tpl.html
renamed from
ui/src/app/entity/entity-filter-dialog.tpl.html
@@ -15,11 +15,11 @@ | @@ -15,11 +15,11 @@ | ||
15 | limitations under the License. | 15 | limitations under the License. |
16 | 16 | ||
17 | --> | 17 | --> |
18 | -<md-dialog class="tb-entity-filter-dialog" style="width: 600px;" aria-label="{{ 'alias.entity-filter' | translate }}"> | 18 | +<md-dialog class="tb-entity-alias-dialog" style="width: 600px;" aria-label="{{ (vm.isAdd ? 'alias.add' : 'alias.edit') | translate }}"> |
19 | <form name="theForm" ng-submit="vm.save()"> | 19 | <form name="theForm" ng-submit="vm.save()"> |
20 | <md-toolbar> | 20 | <md-toolbar> |
21 | <div class="md-toolbar-tools"> | 21 | <div class="md-toolbar-tools"> |
22 | - <h2>{{ (vm.isAdd ? 'alias.create-entity-filter' : 'alias.edit-entity-filter') | translate }}</h2> | 22 | + <h2>{{ (vm.isAdd ? 'alias.add' : 'alias.edit') | translate }}</h2> |
23 | <span flex></span> | 23 | <span flex></span> |
24 | <md-button class="md-icon-button" ng-click="vm.cancel()"> | 24 | <md-button class="md-icon-button" ng-click="vm.cancel()"> |
25 | <ng-md-icon icon="close" aria-label="{{ 'dialog.close' | translate }}"></ng-md-icon> | 25 | <ng-md-icon icon="close" aria-label="{{ 'dialog.close' | translate }}"></ng-md-icon> |
@@ -32,56 +32,29 @@ | @@ -32,56 +32,29 @@ | ||
32 | <div class="md-dialog-content"> | 32 | <div class="md-dialog-content"> |
33 | <fieldset ng-disabled="loading"> | 33 | <fieldset ng-disabled="loading"> |
34 | <div flex layout="column"> | 34 | <div flex layout="column"> |
35 | - <md-input-container> | ||
36 | - <label>{{ 'alias.filter-type' | translate }}</label> | ||
37 | - <md-select required name="filterType" | ||
38 | - ng-model="vm.filter.type" aria-label="{{ 'alias.filter-type' | translate }}"> | ||
39 | - <md-option ng-repeat="type in vm.types.aliasFilterType" ng-value="type.value"> | ||
40 | - {{type.name | translate}} | ||
41 | - </md-option> | ||
42 | - </md-select> | ||
43 | - <div ng-messages="theForm.filterType.$error"> | ||
44 | - <div ng-message="required" translate>alias.filter-type-required</div> | ||
45 | - </div> | ||
46 | - </md-input-container> | ||
47 | - <section layout="column" ng-if="vm.filter.type == vm.types.aliasFilterType.entityList.value" id="entityListFilter"> | ||
48 | - <md-checkbox flex aria-label="{{ 'alias.use-state-entity' | translate }}" | ||
49 | - ng-model="vm.filter.stateEntity">{{ 'alias.use-state-entity' | translate }} | ||
50 | - </md-checkbox> | ||
51 | - <tb-entity-type-select | ||
52 | - ng-if="!vm.filter.stateEntity" | ||
53 | - ng-model="vm.filter.entityType" | ||
54 | - the-form="theForm" | ||
55 | - ng-disabled="vm.filter.stateEntity" | ||
56 | - tb-required="!vm.filter.stateEntity" | ||
57 | - allowed-entity-types="vm.allowedEntityTypes"> | ||
58 | - </tb-entity-type-select> | ||
59 | - <tb-entity-list | ||
60 | - ng-if="!vm.filter.stateEntity" | ||
61 | - ng-model="vm.filter.entityList" | ||
62 | - ng-disabled="vm.filter.stateEntity" | ||
63 | - tb-required="!vm.filter.stateEntity" | ||
64 | - entity-type="vm.filter.entityType"> | ||
65 | - </tb-entity-list> | ||
66 | - </section> | ||
67 | - <section flex layout="column" ng-if="vm.filter.type == vm.types.aliasFilterType.entityName.value" id="entityNameFilter"> | ||
68 | - <tb-entity-type-select | ||
69 | - ng-model="vm.filter.entityType" | ||
70 | - the-form="theForm" | ||
71 | - tb-required="true" | ||
72 | - allowed-entity-types="vm.allowedEntityTypes"> | ||
73 | - </tb-entity-type-select> | ||
74 | - <md-input-container flex> | ||
75 | - <label translate>entity.name-starts-with</label> | ||
76 | - <input required name="entityNameFilter" | ||
77 | - ng-model="vm.filter.entityNameFilter" | ||
78 | - aria-label="{{ 'entity.name-starts-with' | translate }}"> | ||
79 | - <div ng-messages="theForm.entityNameFilter.$error"> | ||
80 | - <div ng-message="required" translate>entity.entity-name-filter-required</div> | 35 | + <div layout="row"> |
36 | + <md-input-container flex class="md-block"> | ||
37 | + <label translate>alias.name</label> | ||
38 | + <input required name="aliasName" | ||
39 | + ng-model="vm.alias.alias" | ||
40 | + aria-label="{{ 'alias.name' | translate }}"> | ||
41 | + <div ng-messages="theForm.aliasName.$error"> | ||
42 | + <div ng-message="required" translate>alias.name-required</div> | ||
43 | + <div ng-message="duplicateAliasName" translate>alias.duplicate-alias</div> | ||
81 | </div> | 44 | </div> |
82 | - | ||
83 | </md-input-container> | 45 | </md-input-container> |
84 | - </section> | 46 | + <section class="tb-resolve-multiple-switch" layout="column" layout-align="start center"> |
47 | + <label class="tb-small resolve-multiple-label" translate>alias.resolve-multiple</label> | ||
48 | + <md-switch class="resolve-multiple-switch" ng-model="vm.alias.filter.resolveMultiple" | ||
49 | + aria-label="{{ 'alias.resolve-multiple' | translate }}"> | ||
50 | + </md-switch> | ||
51 | + </section> | ||
52 | + </div> | ||
53 | + <tb-entity-filter | ||
54 | + ng-model="vm.alias.filter" | ||
55 | + allowed-entity-types="vm.allowedEntityTypes" | ||
56 | + the-form="theForm"> | ||
57 | + </tb-entity-filter> | ||
85 | <div class="tb-error-messages" ng-messages="theForm.$error" role="alert"> | 58 | <div class="tb-error-messages" ng-messages="theForm.$error" role="alert"> |
86 | <div translate ng-message="entityFilter" class="tb-error-message">alias.entity-filter-no-entity-matched</div> | 59 | <div translate ng-message="entityFilter" class="tb-error-message">alias.entity-filter-no-entity-matched</div> |
87 | </div> | 60 | </div> |
@@ -92,9 +65,9 @@ | @@ -92,9 +65,9 @@ | ||
92 | <md-dialog-actions layout="row"> | 65 | <md-dialog-actions layout="row"> |
93 | <span flex></span> | 66 | <span flex></span> |
94 | <md-button ng-disabled="loading || theForm.$invalid || !theForm.$dirty" type="submit" class="md-raised md-primary"> | 67 | <md-button ng-disabled="loading || theForm.$invalid || !theForm.$dirty" type="submit" class="md-raised md-primary"> |
95 | - {{ 'action.save' | translate }} | 68 | + {{ (vm.isAdd ? 'action.add' : 'action.save') | translate }} |
96 | </md-button> | 69 | </md-button> |
97 | <md-button ng-disabled="loading" ng-click="vm.cancel()" style="margin-right:20px;">{{ 'action.cancel' | translate }}</md-button> | 70 | <md-button ng-disabled="loading" ng-click="vm.cancel()" style="margin-right:20px;">{{ 'action.cancel' | translate }}</md-button> |
98 | </md-dialog-actions> | 71 | </md-dialog-actions> |
99 | </form> | 72 | </form> |
100 | -</md-dialog> | ||
73 | +</md-dialog> |
@@ -15,22 +15,27 @@ | @@ -15,22 +15,27 @@ | ||
15 | */ | 15 | */ |
16 | import './entity-aliases.scss'; | 16 | import './entity-aliases.scss'; |
17 | 17 | ||
18 | +/* eslint-disable import/no-unresolved, import/default */ | ||
19 | + | ||
20 | +import entityAliasDialogTemplate from './entity-alias-dialog.tpl.html'; | ||
21 | + | ||
22 | +/* eslint-enable import/no-unresolved, import/default */ | ||
23 | + | ||
18 | /*@ngInject*/ | 24 | /*@ngInject*/ |
19 | export default function EntityAliasesController(utils, entityService, toast, $scope, $mdDialog, $document, $q, $translate, | 25 | export default function EntityAliasesController(utils, entityService, toast, $scope, $mdDialog, $document, $q, $translate, |
20 | types, config) { | 26 | types, config) { |
21 | 27 | ||
22 | var vm = this; | 28 | var vm = this; |
23 | 29 | ||
24 | - vm.isSingleEntityAlias = config.isSingleEntityAlias; | ||
25 | - vm.singleEntityAlias = config.singleEntityAlias; | 30 | + vm.types = types; |
26 | vm.entityAliases = []; | 31 | vm.entityAliases = []; |
27 | vm.title = config.customTitle ? config.customTitle : 'entity.aliases'; | 32 | vm.title = config.customTitle ? config.customTitle : 'entity.aliases'; |
28 | vm.disableAdd = config.disableAdd; | 33 | vm.disableAdd = config.disableAdd; |
29 | vm.aliasToWidgetsMap = {}; | 34 | vm.aliasToWidgetsMap = {}; |
30 | vm.allowedEntityTypes = config.allowedEntityTypes; | 35 | vm.allowedEntityTypes = config.allowedEntityTypes; |
31 | 36 | ||
32 | - vm.onFilterEntityChanged = onFilterEntityChanged; | ||
33 | vm.addAlias = addAlias; | 37 | vm.addAlias = addAlias; |
38 | + vm.editAlias = editAlias; | ||
34 | vm.removeAlias = removeAlias; | 39 | vm.removeAlias = removeAlias; |
35 | 40 | ||
36 | vm.cancel = cancel; | 41 | vm.cancel = cancel; |
@@ -79,42 +84,61 @@ export default function EntityAliasesController(utils, entityService, toast, $sc | @@ -79,42 +84,61 @@ export default function EntityAliasesController(utils, entityService, toast, $sc | ||
79 | } | 84 | } |
80 | } | 85 | } |
81 | 86 | ||
82 | - if (vm.isSingleEntityAlias) { | ||
83 | - checkEntityAlias(vm.singleEntityAlias); | ||
84 | - } | ||
85 | - | ||
86 | for (aliasId in config.entityAliases) { | 87 | for (aliasId in config.entityAliases) { |
87 | var entityAlias = config.entityAliases[aliasId]; | 88 | var entityAlias = config.entityAliases[aliasId]; |
88 | - var result = {id: aliasId, alias: entityAlias.alias, filter: entityAlias.filter, changed: true}; | ||
89 | - checkEntityAlias(result); | 89 | + var filter = entityAlias.filter; |
90 | + if (!filter) { | ||
91 | + filter = { | ||
92 | + resolveMultiple: false | ||
93 | + }; | ||
94 | + } | ||
95 | + if (!filter.resolveMultiple) { | ||
96 | + filter.resolveMultiple = false; | ||
97 | + } | ||
98 | + var result = {id: aliasId, alias: entityAlias.alias, filter: filter}; | ||
90 | vm.entityAliases.push(result); | 99 | vm.entityAliases.push(result); |
91 | } | 100 | } |
92 | } | 101 | } |
93 | 102 | ||
94 | - function checkEntityAlias(entityAlias) { | ||
95 | - if (!entityAlias.filter || entityAlias.filter == null) { | ||
96 | - entityAlias.filter = {}; | ||
97 | - } | 103 | + function addAlias($event) { |
104 | + openAliasDialog($event); | ||
98 | } | 105 | } |
99 | 106 | ||
100 | - function onFilterEntityChanged(entity, stateEntity, entityAlias) { | ||
101 | - if (entityAlias) { | ||
102 | - if (!entityAlias.alias || entityAlias.alias.length == 0) { | ||
103 | - entityAlias.changed = false; | ||
104 | - } | ||
105 | - if (!entityAlias.changed && entityAlias.filter && entityAlias.filter.type) { | ||
106 | - if (stateEntity) { | ||
107 | - entityAlias.alias = $translate.instant('alias.state-entity'); | ||
108 | - } else { | ||
109 | - entityAlias.alias = entity.name; | ||
110 | - } | ||
111 | - } | ||
112 | - } | 107 | + function editAlias($event, entityAlias) { |
108 | + openAliasDialog($event, entityAlias); | ||
113 | } | 109 | } |
114 | 110 | ||
115 | - function addAlias() { | ||
116 | - var entityAlias = {id: utils.guid(), alias: '', filter: {}, changed: false}; | ||
117 | - vm.entityAliases.push(entityAlias); | 111 | + function openAliasDialog($event, entityAlias) { |
112 | + var isAdd = entityAlias ? false : true; | ||
113 | + var aliasIndex; | ||
114 | + if (!isAdd) { | ||
115 | + aliasIndex = vm.entityAliases.indexOf(entityAlias); | ||
116 | + } | ||
117 | + $mdDialog.show({ | ||
118 | + controller: 'EntityAliasDialogController', | ||
119 | + controllerAs: 'vm', | ||
120 | + templateUrl: entityAliasDialogTemplate, | ||
121 | + locals: { | ||
122 | + isAdd: isAdd, | ||
123 | + allowedEntityTypes: vm.allowedEntityTypes, | ||
124 | + entityAliases: vm.entityAliases, | ||
125 | + alias: isAdd ? null : angular.copy(entityAlias) | ||
126 | + }, | ||
127 | + parent: angular.element($document[0].body), | ||
128 | + fullscreen: true, | ||
129 | + skipHide: true, | ||
130 | + targetEvent: $event | ||
131 | + }).then(function (alias) { | ||
132 | + if (isAdd) { | ||
133 | + vm.entityAliases.push(alias); | ||
134 | + } else { | ||
135 | + vm.entityAliases[aliasIndex] = alias; | ||
136 | + } | ||
137 | + if ($scope.theForm) { | ||
138 | + $scope.theForm.$setDirty(); | ||
139 | + } | ||
140 | + }, function () { | ||
141 | + }); | ||
118 | } | 142 | } |
119 | 143 | ||
120 | function removeAlias($event, entityAlias) { | 144 | function removeAlias($event, entityAlias) { |
@@ -157,43 +181,30 @@ export default function EntityAliasesController(utils, entityService, toast, $sc | @@ -157,43 +181,30 @@ export default function EntityAliasesController(utils, entityService, toast, $sc | ||
157 | var uniqueAliasList = {}; | 181 | var uniqueAliasList = {}; |
158 | 182 | ||
159 | var valid = true; | 183 | var valid = true; |
160 | - var aliasId; | ||
161 | - var alias; | ||
162 | - var i; | ||
163 | - | ||
164 | - if (vm.isSingleEntityAlias) { | ||
165 | - if (!vm.singleEntityAlias.id) { | ||
166 | - vm.singleEntityAlias.id = utils.guid(); | ||
167 | - } | ||
168 | - for (i = 0; i < vm.entityAliases.length; i ++) { | ||
169 | - alias = vm.entityAliases[i].alias; | ||
170 | - if (alias === vm.singleEntityAlias.alias) { | ||
171 | - valid = false; | ||
172 | - break; | ||
173 | - } | ||
174 | - } | ||
175 | - } else { | ||
176 | - for (i = 0; i < vm.entityAliases.length; i++) { | ||
177 | - aliasId = vm.entityAliases[i].id; | ||
178 | - alias = vm.entityAliases[i].alias; | ||
179 | - if (!uniqueAliasList[alias]) { | ||
180 | - uniqueAliasList[alias] = alias; | ||
181 | - entityAliases[aliasId] = {id: aliasId, alias: alias, filter: vm.entityAliases[i].filter}; | ||
182 | - } else { | ||
183 | - valid = false; | ||
184 | - break; | ||
185 | - } | 184 | + var message, aliasId, alias, filter; |
185 | + | ||
186 | + for (var i = 0; i < vm.entityAliases.length; i++) { | ||
187 | + aliasId = vm.entityAliases[i].id; | ||
188 | + alias = vm.entityAliases[i].alias; | ||
189 | + filter = vm.entityAliases[i].filter; | ||
190 | + if (uniqueAliasList[alias]) { | ||
191 | + valid = false; | ||
192 | + message = $translate.instant('entity.duplicate-alias-error', {alias: alias}); | ||
193 | + break; | ||
194 | + } else if (!filter || !filter.type) { | ||
195 | + valid = false; | ||
196 | + message = $translate.instant('entity.missing-entity-filter-error', {alias: alias}); | ||
197 | + break; | ||
198 | + } else { | ||
199 | + uniqueAliasList[alias] = alias; | ||
200 | + entityAliases[aliasId] = {id: aliasId, alias: alias, filter: filter}; | ||
186 | } | 201 | } |
187 | } | 202 | } |
188 | if (valid) { | 203 | if (valid) { |
189 | $scope.theForm.$setPristine(); | 204 | $scope.theForm.$setPristine(); |
190 | - if (vm.isSingleEntityAlias) { | ||
191 | - $mdDialog.hide(vm.singleEntityAlias); | ||
192 | - } else { | ||
193 | - $mdDialog.hide(entityAliases); | ||
194 | - } | 205 | + $mdDialog.hide(entityAliases); |
195 | } else { | 206 | } else { |
196 | - toast.showError($translate.instant('entity.duplicate-alias-error', {alias: alias})); | 207 | + toast.showError(message); |
197 | } | 208 | } |
198 | } | 209 | } |
199 | 210 |
@@ -17,6 +17,7 @@ | @@ -17,6 +17,7 @@ | ||
17 | .tb-aliases-dialog { | 17 | .tb-aliases-dialog { |
18 | .md-dialog-content { | 18 | .md-dialog-content { |
19 | padding-bottom: 0px; | 19 | padding-bottom: 0px; |
20 | + padding-top: 0px; | ||
20 | } | 21 | } |
21 | .tb-aliases-header { | 22 | .tb-aliases-header { |
22 | min-height: 40px; | 23 | min-height: 40px; |
@@ -33,5 +34,16 @@ | @@ -33,5 +34,16 @@ | ||
33 | md-input-container { | 34 | md-input-container { |
34 | margin: 0px; | 35 | margin: 0px; |
35 | } | 36 | } |
37 | + .tb-resolve-multiple-switch { | ||
38 | + padding-left: 10px; | ||
39 | + .resolve-multiple-switch { | ||
40 | + margin: 0; | ||
41 | + } | ||
42 | + } | ||
43 | + .md-button { | ||
44 | + &.md-icon-button { | ||
45 | + margin: 0px; | ||
46 | + } | ||
47 | + } | ||
36 | } | 48 | } |
37 | } | 49 | } |
@@ -19,7 +19,7 @@ | @@ -19,7 +19,7 @@ | ||
19 | <form name="theForm" ng-submit="vm.save()"> | 19 | <form name="theForm" ng-submit="vm.save()"> |
20 | <md-toolbar> | 20 | <md-toolbar> |
21 | <div class="md-toolbar-tools"> | 21 | <div class="md-toolbar-tools"> |
22 | - <h2>{{ vm.isSingleEntityAlias ? ('entity.configure-alias' | translate:vm.singleEntityAlias ) : (vm.title | translate) }}</h2> | 22 | + <h2>{{ vm.title | translate }}</h2> |
23 | <span flex></span> | 23 | <span flex></span> |
24 | <md-button class="md-icon-button" ng-click="vm.cancel()"> | 24 | <md-button class="md-icon-button" ng-click="vm.cancel()"> |
25 | <ng-md-icon icon="close" aria-label="{{ 'dialog.close' | translate }}"></ng-md-icon> | 25 | <ng-md-icon icon="close" aria-label="{{ 'dialog.close' | translate }}"></ng-md-icon> |
@@ -28,66 +28,72 @@ | @@ -28,66 +28,72 @@ | ||
28 | </md-toolbar> | 28 | </md-toolbar> |
29 | <md-progress-linear class="md-warn" md-mode="indeterminate" ng-disabled="!loading" ng-show="loading"></md-progress-linear> | 29 | <md-progress-linear class="md-warn" md-mode="indeterminate" ng-disabled="!loading" ng-show="loading"></md-progress-linear> |
30 | <span style="min-height: 5px;" flex="" ng-show="!loading"></span> | 30 | <span style="min-height: 5px;" flex="" ng-show="!loading"></span> |
31 | - <div class="tb-aliases-header" ng-show="!vm.isSingleEntityAlias" flex layout="row" layout-align="start center"> | 31 | + <div class="tb-aliases-header" flex layout="row" layout-align="start center"> |
32 | <span flex="5"></span> | 32 | <span flex="5"></span> |
33 | <div flex layout="row" layout-align="start center"> | 33 | <div flex layout="row" layout-align="start center"> |
34 | - <span class="tb-header-label" translate flex="20" style="min-width: 150px;">entity.alias</span> | ||
35 | - <div flex="80" layout="row" layout-align="start center" style="min-width: 240px; padding-left: 10px;"> | ||
36 | - <span class="tb-header-label" translate flex="70">alias.entity-filter</span> | ||
37 | - <span class="tb-header-label" translate flex="30" style="padding-left: 10px;" >alias.resolve-multiple</span> | ||
38 | - </div> | ||
39 | - <span style="min-width: 40px; margin: 0 6px;"></span> | 34 | + <span class="tb-header-label" translate flex="20" style="min-width: 150px;">alias.name</span> |
35 | + <span class="tb-header-label" translate flex="70" style="padding-left: 10px;">alias.entity-filter</span> | ||
36 | + <span class="tb-header-label" translate flex="10" style="padding-left: 10px; min-width: 120px;">alias.resolve-multiple</span> | ||
37 | + <span style="min-width: 80px;"></span> | ||
40 | </div> | 38 | </div> |
41 | </div> | 39 | </div> |
42 | - <md-divider ng-show="!vm.isSingleEntityAlias"></md-divider> | 40 | + <md-divider></md-divider> |
43 | <md-dialog-content> | 41 | <md-dialog-content> |
44 | <div class="md-dialog-content"> | 42 | <div class="md-dialog-content"> |
45 | <fieldset ng-disabled="loading"> | 43 | <fieldset ng-disabled="loading"> |
46 | - <div ng-show="vm.isSingleEntityAlias" layout="row"> | ||
47 | - <tb-entity-filter flex | ||
48 | - allowed-entity-types="vm.allowedEntityTypes" | ||
49 | - ng-model="vm.singleEntityAlias.filter"> | ||
50 | - </tb-entity-filter> | ||
51 | - </div> | ||
52 | - <div ng-show="!vm.isSingleEntityAlias" style="height: 100%; overflow: auto; padding-bottom: 20px;"> | ||
53 | - <div ng-form name="aliasForm" flex layout="row" layout-align="start center" ng-repeat="entityAlias in vm.entityAliases track by $index"> | ||
54 | - <span flex="5">{{$index + 1}}.</span> | ||
55 | - <div class="md-whiteframe-4dp tb-alias" flex layout="row" layout-align="start center"> | ||
56 | - <md-input-container flex="20" style="min-width: 150px;" md-no-float class="md-block"> | ||
57 | - <input required ng-change="entityAlias.changed=true" name="alias" placeholder="{{ 'entity.alias' | translate }}" ng-model="entityAlias.alias"> | ||
58 | - <div ng-messages="aliasForm.alias.$error"> | ||
59 | - <div translate ng-message="required">entity.alias-required</div> | ||
60 | - </div> | ||
61 | - </md-input-container> | ||
62 | - <tb-entity-filter flex="80" style="min-width: 240px; padding-left: 10px;" | ||
63 | - hide-labels | ||
64 | - allowed-entity-types="vm.allowedEntityTypes" | ||
65 | - ng-model="entityAlias.filter" | ||
66 | - on-matching-entity-change="vm.onFilterEntityChanged(entity, stateEntity, entityAlias)"> | ||
67 | - </tb-entity-filter> | ||
68 | - <md-button ng-disabled="loading" class="md-icon-button md-primary" style="min-width: 40px;" | ||
69 | - ng-click="vm.removeAlias($event, entityAlias)" aria-label="{{ 'action.remove' | translate }}"> | ||
70 | - <md-tooltip md-direction="top"> | ||
71 | - {{ 'entity.remove-alias' | translate }} | ||
72 | - </md-tooltip> | ||
73 | - <md-icon aria-label="{{ 'action.delete' | translate }}" class="material-icons"> | ||
74 | - close | ||
75 | - </md-icon> | ||
76 | - </md-button> | ||
77 | - </div> | ||
78 | - </div> | 44 | + <div ng-form name="aliasForm" flex layout="row" layout-align="start center" ng-repeat="entityAlias in vm.entityAliases track by $index"> |
45 | + <span flex="5">{{$index + 1}}.</span> | ||
46 | + <di class="md-whiteframe-4dp tb-alias" flex layout="row" layout-align="start center"> | ||
47 | + <md-input-container flex="20" style="min-width: 150px;" md-no-float class="md-block"> | ||
48 | + <input required name="alias" placeholder="{{ 'entity.alias' | translate }}" ng-model="entityAlias.alias"> | ||
49 | + <div ng-messages="aliasForm.alias.$error"> | ||
50 | + <div translate ng-message="required">entity.alias-required</div> | ||
51 | + </div> | ||
52 | + </md-input-container> | ||
53 | + <tb-entity-filter-view | ||
54 | + flex="70" style="padding-left: 10px;" | ||
55 | + ng-model="entityAlias.filter"> | ||
56 | + </tb-entity-filter-view> | ||
57 | + <section flex="10" style="padding-left: 10px; min-width: 120px;" | ||
58 | + class="tb-resolve-multiple-switch" | ||
59 | + layout="column" | ||
60 | + layout-align="center center"> | ||
61 | + <md-switch class="resolve-multiple-switch" | ||
62 | + ng-model="entityAlias.filter.resolveMultiple" | ||
63 | + aria-label="resolve-multiple-switcher"> | ||
64 | + </md-switch> | ||
65 | + </section> | ||
66 | + <md-button ng-disabled="loading" class="md-icon-button md-primary" style="min-width: 40px;" | ||
67 | + ng-click="vm.editAlias($event, entityAlias)" aria-label="{{ 'action.edit' | translate }}"> | ||
68 | + <md-tooltip md-direction="top"> | ||
69 | + {{ 'alias.edit' | translate }} | ||
70 | + </md-tooltip> | ||
71 | + <md-icon aria-label="{{ 'alias.edit' | translate }}" class="material-icons"> | ||
72 | + edit | ||
73 | + </md-icon> | ||
74 | + </md-button> | ||
75 | + <md-button ng-disabled="loading" class="md-icon-button md-primary" style="min-width: 40px;" | ||
76 | + ng-click="vm.removeAlias($event, entityAlias)" aria-label="{{ 'action.remove' | translate }}"> | ||
77 | + <md-tooltip md-direction="top"> | ||
78 | + {{ 'entity.remove-alias' | translate }} | ||
79 | + </md-tooltip> | ||
80 | + <md-icon aria-label="{{ 'action.delete' | translate }}" class="material-icons"> | ||
81 | + close | ||
82 | + </md-icon> | ||
83 | + </md-button> | ||
84 | + </di> | ||
79 | </div> | 85 | </div> |
80 | </fieldset> | 86 | </fieldset> |
81 | </div> | 87 | </div> |
82 | </md-dialog-content> | 88 | </md-dialog-content> |
83 | <md-dialog-actions layout="row"> | 89 | <md-dialog-actions layout="row"> |
84 | - <md-button ng-show="!vm.isSingleEntityAlias && !vm.disableAdd" ng-disabled="loading" class="md-primary md-raised" | 90 | + <md-button ng-show="!vm.disableAdd" ng-disabled="loading" class="md-primary md-raised" |
85 | ng-click="vm.addAlias($event)" | 91 | ng-click="vm.addAlias($event)" |
86 | - aria-label="{{ 'action.add' | translate }}"> | 92 | + aria-label="{{ 'alias.add' | translate }}"> |
87 | <md-tooltip md-direction="top"> | 93 | <md-tooltip md-direction="top"> |
88 | - {{ 'entity.add-alias' | translate }} | 94 | + {{ 'alias.add' | translate }} |
89 | </md-tooltip> | 95 | </md-tooltip> |
90 | - <span translate>action.add</span> | 96 | + <span translate>alias.add</span> |
91 | </md-button> | 97 | </md-button> |
92 | <span flex></span> | 98 | <span flex></span> |
93 | <md-button ng-disabled="loading || theForm.$invalid || !theForm.$dirty" type="submit" class="md-raised md-primary"> | 99 | <md-button ng-disabled="loading || theForm.$invalid || !theForm.$dirty" type="submit" class="md-raised md-primary"> |
1 | +/* | ||
2 | + * Copyright © 2016-2017 The Thingsboard Authors | ||
3 | + * | ||
4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | + * you may not use this file except in compliance with the License. | ||
6 | + * You may obtain a copy of the License at | ||
7 | + * | ||
8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | + * | ||
10 | + * Unless required by applicable law or agreed to in writing, software | ||
11 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | + * See the License for the specific language governing permissions and | ||
14 | + * limitations under the License. | ||
15 | + */ | ||
16 | + | ||
17 | +/* eslint-disable import/no-unresolved, import/default */ | ||
18 | + | ||
19 | +import entityFilterViewTemplate from './entity-filter-view.tpl.html'; | ||
20 | + | ||
21 | +/* eslint-enable import/no-unresolved, import/default */ | ||
22 | + | ||
23 | +import './entity-filter-view.scss'; | ||
24 | + | ||
25 | +/*@ngInject*/ | ||
26 | +export default function EntityFilterViewDirective($compile, $templateCache, $q, $document, $mdDialog, $translate, types/*, entityService*/) { | ||
27 | + | ||
28 | + var linker = function (scope, element, attrs, ngModelCtrl) { | ||
29 | + | ||
30 | + var template = $templateCache.get(entityFilterViewTemplate); | ||
31 | + element.html(template); | ||
32 | + | ||
33 | + scope.ngModelCtrl = ngModelCtrl; | ||
34 | + scope.types = types; | ||
35 | + scope.filterDisplayValue = ''; | ||
36 | + | ||
37 | + scope.$watch('filter', function () { | ||
38 | + scope.updateDisplayValue(); | ||
39 | + }); | ||
40 | + | ||
41 | + scope.updateDisplayValue = function() { | ||
42 | + if (scope.filter && scope.filter.type) { | ||
43 | + var entityType; | ||
44 | + var prefix; | ||
45 | + switch (scope.filter.type) { | ||
46 | + case types.aliasFilterType.entityList.value: | ||
47 | + entityType = scope.filter.entityType; | ||
48 | + var count = scope.filter.entityList.length; | ||
49 | + scope.filterDisplayValue = $translate.instant(types.entityTypeTranslations[entityType].list, {count: count}, 'messageformat'); | ||
50 | + break; | ||
51 | + case types.aliasFilterType.entityName.value: | ||
52 | + entityType = scope.filter.entityType; | ||
53 | + prefix = scope.filter.entityNameFilter; | ||
54 | + scope.filterDisplayValue = $translate.instant(types.entityTypeTranslations[entityType].nameStartsWith, {prefix: prefix}); | ||
55 | + break; | ||
56 | + case types.aliasFilterType.stateEntity.value: | ||
57 | + scope.filterDisplayValue = $translate.instant('alias.filter-type-state-entity-description'); | ||
58 | + break; | ||
59 | + case types.aliasFilterType.assetType.value: | ||
60 | + var assetType = scope.filter.assetType; | ||
61 | + prefix = scope.filter.assetNameFilter; | ||
62 | + if (prefix && prefix.length) { | ||
63 | + scope.filterDisplayValue = $translate.instant('alias.filter-type-asset-type-and-name-description', {assetType: assetType, prefix: prefix}); | ||
64 | + } else { | ||
65 | + scope.filterDisplayValue = $translate.instant('alias.filter-type-asset-type-description', {assetType: assetType}); | ||
66 | + } | ||
67 | + break; | ||
68 | + case types.aliasFilterType.deviceType.value: | ||
69 | + var deviceType = scope.filter.deviceType; | ||
70 | + prefix = scope.filter.deviceNameFilter; | ||
71 | + if (prefix && prefix.length) { | ||
72 | + scope.filterDisplayValue = $translate.instant('alias.filter-type-device-type-and-name-description', {deviceType: deviceType, prefix: prefix}); | ||
73 | + } else { | ||
74 | + scope.filterDisplayValue = $translate.instant('alias.filter-type-device-type-description', {deviceType: deviceType}); | ||
75 | + } | ||
76 | + break; | ||
77 | + //TODO: Alias filter | ||
78 | + default: | ||
79 | + scope.filterDisplayValue = scope.filter.type; | ||
80 | + break; | ||
81 | + } | ||
82 | + } else { | ||
83 | + scope.filterDisplayValue = ''; | ||
84 | + } | ||
85 | + } | ||
86 | + | ||
87 | + ngModelCtrl.$render = function () { | ||
88 | + if (ngModelCtrl.$viewValue) { | ||
89 | + scope.filter = ngModelCtrl.$viewValue; | ||
90 | + } else { | ||
91 | + scope.filter = null; | ||
92 | + } | ||
93 | + } | ||
94 | + | ||
95 | + $compile(element.contents())(scope); | ||
96 | + | ||
97 | + } | ||
98 | + | ||
99 | + return { | ||
100 | + restrict: "E", | ||
101 | + require: "^ngModel", | ||
102 | + link: linker, | ||
103 | + scope: true | ||
104 | + }; | ||
105 | + | ||
106 | +} |
ui/src/app/entity/entity-filter-view.scss
0 → 100644
1 | +/** | ||
2 | + * Copyright © 2016-2017 The Thingsboard Authors | ||
3 | + * | ||
4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | + * you may not use this file except in compliance with the License. | ||
6 | + * You may obtain a copy of the License at | ||
7 | + * | ||
8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | + * | ||
10 | + * Unless required by applicable law or agreed to in writing, software | ||
11 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | + * See the License for the specific language governing permissions and | ||
14 | + * limitations under the License. | ||
15 | + */ | ||
16 | + | ||
17 | +.tb-entity-filter-view { | ||
18 | + .entity-filter-empty { | ||
19 | + color: rgba(221, 44, 0, 0.87); | ||
20 | + font-size: 14px; | ||
21 | + line-height: 16px; | ||
22 | + } | ||
23 | + .entity-filter-type { | ||
24 | + font-size: 14px; | ||
25 | + line-height: 16px; | ||
26 | + color: rgba(0, 0, 0, 0.570588); | ||
27 | + } | ||
28 | + .entity-filter-value { | ||
29 | + font-size: 14px; | ||
30 | + line-height: 16px; | ||
31 | + color: rgba(0, 0, 0, 0.570588); | ||
32 | + } | ||
33 | +} |
1 | +<!-- | ||
2 | + | ||
3 | + Copyright © 2016-2017 The Thingsboard Authors | ||
4 | + | ||
5 | + Licensed under the Apache License, Version 2.0 (the "License"); | ||
6 | + you may not use this file except in compliance with the License. | ||
7 | + You may obtain a copy of the License at | ||
8 | + | ||
9 | + http://www.apache.org/licenses/LICENSE-2.0 | ||
10 | + | ||
11 | + Unless required by applicable law or agreed to in writing, software | ||
12 | + distributed under the License is distributed on an "AS IS" BASIS, | ||
13 | + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
14 | + See the License for the specific language governing permissions and | ||
15 | + limitations under the License. | ||
16 | + | ||
17 | +--> | ||
18 | + | ||
19 | +<div layout='column' class="tb-entity-filter-view"> | ||
20 | + <div ng-if="!filter || !filter.type" class="entity-filter-empty" translate>alias.no-entity-filter-specified</div> | ||
21 | + <div ng-if="filter && filter.type" layout="column"> | ||
22 | + <div class="entity-filter-value">{{ filterDisplayValue }}</div> | ||
23 | + </div> | ||
24 | +</div> |
@@ -17,16 +17,13 @@ | @@ -17,16 +17,13 @@ | ||
17 | /* eslint-disable import/no-unresolved, import/default */ | 17 | /* eslint-disable import/no-unresolved, import/default */ |
18 | 18 | ||
19 | import entityFilterTemplate from './entity-filter.tpl.html'; | 19 | import entityFilterTemplate from './entity-filter.tpl.html'; |
20 | -import entityFilterDialogTemplate from './entity-filter-dialog.tpl.html'; | ||
21 | 20 | ||
22 | /* eslint-enable import/no-unresolved, import/default */ | 21 | /* eslint-enable import/no-unresolved, import/default */ |
23 | 22 | ||
24 | -import EntityFilterDialogController from './entity-filter-dialog.controller'; | ||
25 | - | ||
26 | import './entity-filter.scss'; | 23 | import './entity-filter.scss'; |
27 | 24 | ||
28 | /*@ngInject*/ | 25 | /*@ngInject*/ |
29 | -export default function EntityFilterDirective($compile, $templateCache, $q, $document, $mdDialog, types) { | 26 | +export default function EntityFilterDirective($compile, $templateCache, $q, $document, $mdDialog, types, entityService) { |
30 | 27 | ||
31 | var linker = function (scope, element, attrs, ngModelCtrl) { | 28 | var linker = function (scope, element, attrs, ngModelCtrl) { |
32 | 29 | ||
@@ -35,66 +32,59 @@ export default function EntityFilterDirective($compile, $templateCache, $q, $doc | @@ -35,66 +32,59 @@ export default function EntityFilterDirective($compile, $templateCache, $q, $doc | ||
35 | 32 | ||
36 | scope.ngModelCtrl = ngModelCtrl; | 33 | scope.ngModelCtrl = ngModelCtrl; |
37 | scope.types = types; | 34 | scope.types = types; |
38 | - scope.hideLabels = angular.isDefined(attrs.hideLabels); | 35 | + scope.aliasFilterTypes = entityService.getAliasFilterTypesByEntityTypes(scope.allowedEntityTypes); |
39 | 36 | ||
40 | - scope.updateValidity = function() { | ||
41 | - if (ngModelCtrl.$viewValue) { | ||
42 | - var value = ngModelCtrl.$viewValue; | ||
43 | - ngModelCtrl.$setValidity('filter', value.type ? true : false); | 37 | + scope.$watch('filter.type', function (newType, prevType) { |
38 | + if (newType && newType != prevType) { | ||
39 | + updateFilter(); | ||
44 | } | 40 | } |
45 | - } | 41 | + }); |
46 | 42 | ||
47 | - ngModelCtrl.$render = function () { | ||
48 | - if (ngModelCtrl.$viewValue) { | ||
49 | - scope.model = angular.copy(ngModelCtrl.$viewValue); | ||
50 | - } else { | ||
51 | - scope.model = { | ||
52 | - type: null, | ||
53 | - resolveMultiple: false | ||
54 | - } | 43 | + function updateFilter() { |
44 | + var filter = {}; | ||
45 | + filter.type = scope.filter.type; | ||
46 | + filter.resolveMultiple = scope.filter.resolveMultiple; | ||
47 | + switch (filter.type) { | ||
48 | + case types.aliasFilterType.entityList.value: | ||
49 | + filter.entityType = null; | ||
50 | + filter.entityList = []; | ||
51 | + break; | ||
52 | + case types.aliasFilterType.entityName.value: | ||
53 | + filter.entityType = null; | ||
54 | + filter.entityNameFilter = ''; | ||
55 | + break; | ||
56 | + case types.aliasFilterType.stateEntity.value: | ||
57 | + break; | ||
58 | + case types.aliasFilterType.assetType.value: | ||
59 | + filter.assetType = null; | ||
60 | + filter.assetNameFilter = ''; | ||
61 | + break; | ||
62 | + case types.aliasFilterType.deviceType.value: | ||
63 | + filter.deviceType = null; | ||
64 | + filter.deviceNameFilter = ''; | ||
65 | + break; | ||
66 | + //TODO: Alias filter | ||
55 | } | 67 | } |
68 | + scope.filter = filter; | ||
56 | } | 69 | } |
57 | 70 | ||
58 | - scope.$watch('model.resolveMultiple', function () { | ||
59 | - if (ngModelCtrl.$viewValue) { | ||
60 | - var value = ngModelCtrl.$viewValue; | ||
61 | - value.resolveMultiple = scope.model.resolveMultiple; | ||
62 | - ngModelCtrl.$setViewValue(value); | ||
63 | - scope.updateValidity(); | ||
64 | - } | 71 | + scope.$watch('filter', function () { |
72 | + scope.updateView(); | ||
65 | }); | 73 | }); |
66 | 74 | ||
67 | - scope.editFilter = function($event) { | ||
68 | - openEntityFilterDialog($event, false); | 75 | + scope.updateView = function() { |
76 | + ngModelCtrl.$setViewValue(scope.filter); | ||
69 | } | 77 | } |
70 | 78 | ||
71 | - scope.createFilter = function($event) { | ||
72 | - openEntityFilterDialog($event, true); | ||
73 | - } | ||
74 | - | ||
75 | - function openEntityFilterDialog($event, isAdd) { | ||
76 | - $mdDialog.show({ | ||
77 | - controller: EntityFilterDialogController, | ||
78 | - controllerAs: 'vm', | ||
79 | - templateUrl: entityFilterDialogTemplate, | ||
80 | - locals: { | ||
81 | - isAdd: isAdd, | ||
82 | - allowedEntityTypes: scope.allowedEntityTypes, | ||
83 | - filter: angular.copy(scope.model) | ||
84 | - }, | ||
85 | - parent: angular.element($document[0].body), | ||
86 | - fullscreen: true, | ||
87 | - skipHide: true, | ||
88 | - targetEvent: $event | ||
89 | - }).then(function (result) { | ||
90 | - scope.model = result.filter; | ||
91 | - ngModelCtrl.$setViewValue(result.filter); | ||
92 | - scope.updateValidity(); | ||
93 | - if (scope.onMatchingEntityChange) { | ||
94 | - scope.onMatchingEntityChange({entity: result.entity, stateEntity: result.stateEntity}); | 79 | + ngModelCtrl.$render = function () { |
80 | + if (ngModelCtrl.$viewValue) { | ||
81 | + scope.filter = ngModelCtrl.$viewValue; | ||
82 | + } else { | ||
83 | + scope.filter = { | ||
84 | + type: null, | ||
85 | + resolveMultiple: false | ||
95 | } | 86 | } |
96 | - }, function () { | ||
97 | - }); | 87 | + } |
98 | } | 88 | } |
99 | 89 | ||
100 | $compile(element.contents())(scope); | 90 | $compile(element.contents())(scope); |
@@ -106,8 +96,8 @@ export default function EntityFilterDirective($compile, $templateCache, $q, $doc | @@ -106,8 +96,8 @@ export default function EntityFilterDirective($compile, $templateCache, $q, $doc | ||
106 | require: "^ngModel", | 96 | require: "^ngModel", |
107 | link: linker, | 97 | link: linker, |
108 | scope: { | 98 | scope: { |
109 | - allowedEntityTypes: '=?', | ||
110 | - onMatchingEntityChange: '&' | 99 | + theForm: '=', |
100 | + allowedEntityTypes: '=?' | ||
111 | } | 101 | } |
112 | }; | 102 | }; |
113 | 103 |
@@ -13,22 +13,7 @@ | @@ -13,22 +13,7 @@ | ||
13 | * See the License for the specific language governing permissions and | 13 | * See the License for the specific language governing permissions and |
14 | * limitations under the License. | 14 | * limitations under the License. |
15 | */ | 15 | */ |
16 | + | ||
16 | .tb-entity-filter { | 17 | .tb-entity-filter { |
17 | - .tb-filter-switch { | ||
18 | - padding-left: 10px; | ||
19 | - .filter-switch { | ||
20 | - margin: 0; | ||
21 | - } | ||
22 | - .filter-label { | ||
23 | - margin: 5px 0; | ||
24 | - } | ||
25 | - } | ||
26 | - .tb-error-messages { | ||
27 | - margin-top: -11px; | ||
28 | - height: 35px; | ||
29 | - .tb-error-message { | ||
30 | - padding-left: 8px; | ||
31 | - padding-top: 14px; | ||
32 | - } | ||
33 | - } | 18 | + |
34 | } | 19 | } |
@@ -15,37 +15,77 @@ | @@ -15,37 +15,77 @@ | ||
15 | limitations under the License. | 15 | limitations under the License. |
16 | 16 | ||
17 | --> | 17 | --> |
18 | -<section layout='row' class="tb-entity-filter"> | ||
19 | - <section layout="row" flex="70"> | ||
20 | - <section flex layout="column" layout-align="center start"> | ||
21 | - <div ng-if="model.type">{{ types.aliasFilterType[model.type].name | translate }}</div> | ||
22 | - <md-button ng-if="!model.type" | ||
23 | - ng-disabled="loading" class="md-primary" | ||
24 | - ng-click="createFilter($event)" | ||
25 | - aria-label="{{ 'alias.create-entity-filter' | translate }}"> | ||
26 | - <md-icon aria-label="{{ 'alias.create-entity-filter' | translate }}" | ||
27 | - class="material-icons"> | ||
28 | - add | ||
29 | - </md-icon> | ||
30 | - {{ 'alias.create-entity-filter' | translate }} | ||
31 | - </md-button> | ||
32 | - </section> | ||
33 | - <md-button ng-if="model.type" ng-disabled="loading" class="md-icon-button md-primary" | ||
34 | - style="min-width: 40px;" | ||
35 | - ng-click="editFilter($event)" | ||
36 | - aria-label="{{ 'alias.edit-entity-filter' | translate }}"> | ||
37 | - <md-tooltip md-direction="top"> | ||
38 | - {{ 'alias.edit-entity-filter' | translate }} | ||
39 | - </md-tooltip> | ||
40 | - <md-icon aria-label="{{ 'alias.edit-entity-filter' | translate }}" | ||
41 | - class="material-icons"> | ||
42 | - edit | ||
43 | - </md-icon> | ||
44 | - </md-button> | 18 | +<div layout='column' class="tb-entity-filter"> |
19 | + <md-input-container class="md-block"> | ||
20 | + <label>{{ 'alias.filter-type' | translate }}</label> | ||
21 | + <md-select required name="filterType" | ||
22 | + ng-model="filter.type" aria-label="{{ 'alias.filter-type' | translate }}"> | ||
23 | + <md-option ng-repeat="type in aliasFilterTypes" ng-value="type.value"> | ||
24 | + {{type.name | translate}} | ||
25 | + </md-option> | ||
26 | + </md-select> | ||
27 | + <div ng-messages="theForm.filterType.$error"> | ||
28 | + <div ng-message="required" translate>alias.filter-type-required</div> | ||
29 | + </div> | ||
30 | + </md-input-container> | ||
31 | + <section layout="column" ng-if="filter.type == types.aliasFilterType.entityList.value" id="entityListFilter"> | ||
32 | + <tb-entity-type-select | ||
33 | + ng-model="filter.entityType" | ||
34 | + the-form="theForm" | ||
35 | + tb-required="true" | ||
36 | + allowed-entity-types="allowedEntityTypes"> | ||
37 | + </tb-entity-type-select> | ||
38 | + <tb-entity-list | ||
39 | + ng-model="filter.entityList" | ||
40 | + tb-required="true" | ||
41 | + entity-type="filter.entityType"> | ||
42 | + </tb-entity-list> | ||
45 | </section> | 43 | </section> |
46 | - <section class="tb-filter-switch" layout="column" flex="30" layout-align="center center"> | ||
47 | - <label ng-if="!hideLabels" class="tb-small filter-label" translate>alias.resolve-multiple</label> | ||
48 | - <md-switch class="filter-switch" ng-model="model.resolveMultiple" aria-label="resolve-multiple-switcher"> | ||
49 | - </md-switch> | 44 | + <section flex layout="column" ng-if="filter.type == types.aliasFilterType.entityName.value" id="entityNameFilter"> |
45 | + <tb-entity-type-select | ||
46 | + ng-model="filter.entityType" | ||
47 | + the-form="theForm" | ||
48 | + tb-required="true" | ||
49 | + allowed-entity-types="allowedEntityTypes"> | ||
50 | + </tb-entity-type-select> | ||
51 | + <md-input-container class="md-block"> | ||
52 | + <label translate>entity.name-starts-with</label> | ||
53 | + <input required name="entityNameFilter" | ||
54 | + ng-model="filter.entityNameFilter" | ||
55 | + aria-label="{{ 'entity.name-starts-with' | translate }}"> | ||
56 | + <div ng-messages="theForm.entityNameFilter.$error"> | ||
57 | + <div ng-message="required" translate>entity.entity-name-filter-required</div> | ||
58 | + </div> | ||
59 | + </md-input-container> | ||
50 | </section> | 60 | </section> |
51 | -</section> | 61 | + <section layout="column" ng-if="filter.type == types.aliasFilterType.stateEntity.value" id="stateEntityFilter"> |
62 | + </section> | ||
63 | + <section layout="column" ng-if="filter.type == types.aliasFilterType.assetType.value" id="assetTypeFilter"> | ||
64 | + <tb-entity-subtype-autocomplete | ||
65 | + tb-required="true" | ||
66 | + the-form="theForm" | ||
67 | + ng-model="filter.assetType" | ||
68 | + entity-type="types.entityType.asset"> | ||
69 | + </tb-entity-subtype-autocomplete> | ||
70 | + <md-input-container class="md-block"> | ||
71 | + <label translate>asset.name-starts-with</label> | ||
72 | + <input name="assetNameFilter" | ||
73 | + ng-model="filter.assetNameFilter" | ||
74 | + aria-label="{{ 'asset.name-starts-with' | translate }}"> | ||
75 | + </md-input-container> | ||
76 | + </section> | ||
77 | + <section layout="column" ng-if="filter.type == types.aliasFilterType.deviceType.value" id="deviceTypeFilter"> | ||
78 | + <tb-entity-subtype-autocomplete | ||
79 | + tb-required="true" | ||
80 | + the-form="theForm" | ||
81 | + ng-model="filter.deviceType" | ||
82 | + entity-type="types.entityType.device"> | ||
83 | + </tb-entity-subtype-autocomplete> | ||
84 | + <md-input-container class="md-block"> | ||
85 | + <label translate>device.name-starts-with</label> | ||
86 | + <input name="deviceNameFilter" | ||
87 | + ng-model="filter.deviceNameFilter" | ||
88 | + aria-label="{{ 'device.name-starts-with' | translate }}"> | ||
89 | + </md-input-container> | ||
90 | + </section> | ||
91 | +</div> |
@@ -71,7 +71,7 @@ export default function EntityTypeSelect($compile, $templateCache, utils, userSe | @@ -71,7 +71,7 @@ export default function EntityTypeSelect($compile, $templateCache, utils, userSe | ||
71 | } | 71 | } |
72 | 72 | ||
73 | scope.typeName = function(type) { | 73 | scope.typeName = function(type) { |
74 | - return utils.entityTypeName(type); | 74 | + return type ? types.entityTypeTranslations[type].type : ''; |
75 | } | 75 | } |
76 | 76 | ||
77 | scope.updateValidity = function () { | 77 | scope.updateValidity = function () { |
@@ -15,6 +15,7 @@ | @@ -15,6 +15,7 @@ | ||
15 | */ | 15 | */ |
16 | 16 | ||
17 | import EntityAliasesController from './entity-aliases.controller'; | 17 | import EntityAliasesController from './entity-aliases.controller'; |
18 | +import EntityAliasDialogController from './entity-alias-dialog.controller'; | ||
18 | import EntityTypeSelectDirective from './entity-type-select.directive'; | 19 | import EntityTypeSelectDirective from './entity-type-select.directive'; |
19 | import EntitySubtypeSelectDirective from './entity-subtype-select.directive'; | 20 | import EntitySubtypeSelectDirective from './entity-subtype-select.directive'; |
20 | import EntitySubtypeAutocompleteDirective from './entity-subtype-autocomplete.directive'; | 21 | import EntitySubtypeAutocompleteDirective from './entity-subtype-autocomplete.directive'; |
@@ -22,6 +23,7 @@ import EntityAutocompleteDirective from './entity-autocomplete.directive'; | @@ -22,6 +23,7 @@ import EntityAutocompleteDirective from './entity-autocomplete.directive'; | ||
22 | import EntityListDirective from './entity-list.directive'; | 23 | import EntityListDirective from './entity-list.directive'; |
23 | import EntitySelectDirective from './entity-select.directive'; | 24 | import EntitySelectDirective from './entity-select.directive'; |
24 | import EntityFilterDirective from './entity-filter.directive'; | 25 | import EntityFilterDirective from './entity-filter.directive'; |
26 | +import EntityFilterViewDirective from './entity-filter-view.directive'; | ||
25 | import AliasesEntitySelectPanelController from './aliases-entity-select-panel.controller'; | 27 | import AliasesEntitySelectPanelController from './aliases-entity-select-panel.controller'; |
26 | import AliasesEntitySelectDirective from './aliases-entity-select.directive'; | 28 | import AliasesEntitySelectDirective from './aliases-entity-select.directive'; |
27 | import AddAttributeDialogController from './attribute/add-attribute-dialog.controller'; | 29 | import AddAttributeDialogController from './attribute/add-attribute-dialog.controller'; |
@@ -32,6 +34,7 @@ import RelationTypeAutocompleteDirective from './relation/relation-type-autocomp | @@ -32,6 +34,7 @@ import RelationTypeAutocompleteDirective from './relation/relation-type-autocomp | ||
32 | 34 | ||
33 | export default angular.module('thingsboard.entity', []) | 35 | export default angular.module('thingsboard.entity', []) |
34 | .controller('EntityAliasesController', EntityAliasesController) | 36 | .controller('EntityAliasesController', EntityAliasesController) |
37 | + .controller('EntityAliasDialogController', EntityAliasDialogController) | ||
35 | .controller('AliasesEntitySelectPanelController', AliasesEntitySelectPanelController) | 38 | .controller('AliasesEntitySelectPanelController', AliasesEntitySelectPanelController) |
36 | .controller('AddAttributeDialogController', AddAttributeDialogController) | 39 | .controller('AddAttributeDialogController', AddAttributeDialogController) |
37 | .controller('AddWidgetToDashboardDialogController', AddWidgetToDashboardDialogController) | 40 | .controller('AddWidgetToDashboardDialogController', AddWidgetToDashboardDialogController) |
@@ -42,6 +45,7 @@ export default angular.module('thingsboard.entity', []) | @@ -42,6 +45,7 @@ export default angular.module('thingsboard.entity', []) | ||
42 | .directive('tbEntityList', EntityListDirective) | 45 | .directive('tbEntityList', EntityListDirective) |
43 | .directive('tbEntitySelect', EntitySelectDirective) | 46 | .directive('tbEntitySelect', EntitySelectDirective) |
44 | .directive('tbEntityFilter', EntityFilterDirective) | 47 | .directive('tbEntityFilter', EntityFilterDirective) |
48 | + .directive('tbEntityFilterView', EntityFilterViewDirective) | ||
45 | .directive('tbAliasesEntitySelect', AliasesEntitySelectDirective) | 49 | .directive('tbAliasesEntitySelect', AliasesEntitySelectDirective) |
46 | .directive('tbAttributeTable', AttributeTableDirective) | 50 | .directive('tbAttributeTable', AttributeTableDirective) |
47 | .directive('tbRelationTable', RelationTableDirective) | 51 | .directive('tbRelationTable', RelationTableDirective) |
@@ -218,9 +218,9 @@ function RelationTableController($scope, $q, $mdDialog, $document, $translate, $ | @@ -218,9 +218,9 @@ function RelationTableController($scope, $q, $mdDialog, $document, $translate, $ | ||
218 | function success(allRelations) { | 218 | function success(allRelations) { |
219 | allRelations.forEach(function(relation) { | 219 | allRelations.forEach(function(relation) { |
220 | if (vm.direction == vm.types.entitySearchDirection.from) { | 220 | if (vm.direction == vm.types.entitySearchDirection.from) { |
221 | - relation.toEntityTypeName = $translate.instant(utils.entityTypeName(relation.to.entityType)); | 221 | + relation.toEntityTypeName = $translate.instant(types.entityTypeTranslations[relation.to.entityType].type); |
222 | } else { | 222 | } else { |
223 | - relation.fromEntityTypeName = $translate.instant(utils.entityTypeName(relation.from.entityType)); | 223 | + relation.fromEntityTypeName = $translate.instant(types.entityTypeTranslations[relation.from.entityType].type); |
224 | } | 224 | } |
225 | }); | 225 | }); |
226 | vm.allRelations = allRelations; | 226 | vm.allRelations = allRelations; |
@@ -365,7 +365,6 @@ export default function ImportExport($log, $translate, $q, $mdDialog, $document, | @@ -365,7 +365,6 @@ export default function ImportExport($log, $translate, $q, $mdDialog, $document, | ||
365 | alias = aliasInfo.aliasName; | 365 | alias = aliasInfo.aliasName; |
366 | filter = { | 366 | filter = { |
367 | type: types.aliasFilterType.entityList.value, | 367 | type: types.aliasFilterType.entityList.value, |
368 | - stateEntity: false, | ||
369 | entityType: types.entityType.device, | 368 | entityType: types.entityType.device, |
370 | entityList: [aliasInfo.deviceId], | 369 | entityList: [aliasInfo.deviceId], |
371 | resolveMultiple: false | 370 | resolveMultiple: false |
@@ -378,7 +377,6 @@ export default function ImportExport($log, $translate, $q, $mdDialog, $document, | @@ -378,7 +377,6 @@ export default function ImportExport($log, $translate, $q, $mdDialog, $document, | ||
378 | resolveMultiple: false | 377 | resolveMultiple: false |
379 | } | 378 | } |
380 | if (filter.type == types.aliasFilterType.entityList.value) { | 379 | if (filter.type == types.aliasFilterType.entityList.value) { |
381 | - filter.stateEntity = false; | ||
382 | filter.entityList = aliasInfo.deviceFilter.deviceList | 380 | filter.entityList = aliasInfo.deviceFilter.deviceList |
383 | } else { | 381 | } else { |
384 | filter.entityNameFilter = aliasInfo.deviceFilter.deviceNameFilter; | 382 | filter.entityNameFilter = aliasInfo.deviceFilter.deviceNameFilter; |
@@ -391,7 +389,6 @@ export default function ImportExport($log, $translate, $q, $mdDialog, $document, | @@ -391,7 +389,6 @@ export default function ImportExport($log, $translate, $q, $mdDialog, $document, | ||
391 | resolveMultiple: false | 389 | resolveMultiple: false |
392 | } | 390 | } |
393 | if (filter.type == types.aliasFilterType.entityList.value) { | 391 | if (filter.type == types.aliasFilterType.entityList.value) { |
394 | - filter.stateEntity = false; | ||
395 | filter.entityList = aliasInfo.entityFilter.entityList; | 392 | filter.entityList = aliasInfo.entityFilter.entityList; |
396 | } else { | 393 | } else { |
397 | filter.entityNameFilter = aliasInfo.entityFilter.entityNameFilter; | 394 | filter.entityNameFilter = aliasInfo.entityFilter.entityNameFilter; |
@@ -662,8 +659,6 @@ export default function ImportExport($log, $translate, $q, $mdDialog, $document, | @@ -662,8 +659,6 @@ export default function ImportExport($log, $translate, $q, $mdDialog, $document, | ||
662 | entityAliases: missingEntityAliases, | 659 | entityAliases: missingEntityAliases, |
663 | widgets: widgets, | 660 | widgets: widgets, |
664 | isSingleWidget: isSingleWidget, | 661 | isSingleWidget: isSingleWidget, |
665 | - isSingleEntityAlias: false, | ||
666 | - singleEntityAlias: null, | ||
667 | customTitle: customTitle, | 662 | customTitle: customTitle, |
668 | disableAdd: true | 663 | disableAdd: true |
669 | } | 664 | } |
@@ -113,23 +113,30 @@ export default angular.module('thingsboard.locale', []) | @@ -113,23 +113,30 @@ export default angular.module('thingsboard.locale', []) | ||
113 | "alarm-required": "Alarm is required" | 113 | "alarm-required": "Alarm is required" |
114 | }, | 114 | }, |
115 | "alias": { | 115 | "alias": { |
116 | + "add": "Add alias", | ||
117 | + "edit": "Edit alias", | ||
118 | + "name": "Alias name", | ||
119 | + "name-required": "Alias name is required", | ||
120 | + "duplicate-alias": "Alias with same name is already exists.", | ||
116 | "filter-type-entity-list": "Entity list", | 121 | "filter-type-entity-list": "Entity list", |
117 | "filter-type-entity-name": "Entity name", | 122 | "filter-type-entity-name": "Entity name", |
123 | + "filter-type-state-entity": "Entity from dashboard state", | ||
124 | + "filter-type-state-entity-description": "Entity taken from dashboard state parameters", | ||
118 | "filter-type-asset-type": "Asset type", | 125 | "filter-type-asset-type": "Asset type", |
126 | + "filter-type-asset-type-description": "Assets of type '{{assetType}}'", | ||
127 | + "filter-type-asset-type-and-name-description": "Assets of type '{{assetType}}' and with name starting with '{{prefix}}'", | ||
119 | "filter-type-device-type": "Device type", | 128 | "filter-type-device-type": "Device type", |
129 | + "filter-type-device-type-description": "Devices of type '{{deviceType}}'", | ||
130 | + "filter-type-device-type-and-name-description": "Devices of type '{{deviceType}}' and with name starting with '{{prefix}}'", | ||
120 | "filter-type-relations-query": "Relations query", | 131 | "filter-type-relations-query": "Relations query", |
121 | "filter-type-asset-search-query": "Asset search query", | 132 | "filter-type-asset-search-query": "Asset search query", |
122 | "filter-type-device-search-query": "Device search query", | 133 | "filter-type-device-search-query": "Device search query", |
123 | "entity-filter": "Entity filter", | 134 | "entity-filter": "Entity filter", |
124 | - "create-entity-filter": "Create entity filter", | ||
125 | - "edit-entity-filter": "Edit entity filter", | ||
126 | - "entity-filter-required": "Entity filter is required.", | ||
127 | "resolve-multiple": "Resolve as multiple entities", | 135 | "resolve-multiple": "Resolve as multiple entities", |
128 | "filter-type": "Filter type", | 136 | "filter-type": "Filter type", |
129 | "filter-type-required": "Filter type is required.", | 137 | "filter-type-required": "Filter type is required.", |
130 | - "use-state-entity": "Use state entity", | ||
131 | - "state-entity": "State entity", | ||
132 | "entity-filter-no-entity-matched": "No entities matching specified filter were found.", | 138 | "entity-filter-no-entity-matched": "No entities matching specified filter were found.", |
139 | + "no-entity-filter-specified": "No entity filter specified" | ||
133 | }, | 140 | }, |
134 | "asset": { | 141 | "asset": { |
135 | "asset": "Asset", | 142 | "asset": "Asset", |
@@ -185,7 +192,8 @@ export default angular.module('thingsboard.locale', []) | @@ -185,7 +192,8 @@ export default angular.module('thingsboard.locale', []) | ||
185 | "idCopiedMessage": "Asset Id has been copied to clipboard", | 192 | "idCopiedMessage": "Asset Id has been copied to clipboard", |
186 | "select-asset": "Select asset", | 193 | "select-asset": "Select asset", |
187 | "no-assets-matching": "No assets matching '{{entity}}' were found.", | 194 | "no-assets-matching": "No assets matching '{{entity}}' were found.", |
188 | - "asset-required": "Asset is required" | 195 | + "asset-required": "Asset is required", |
196 | + "name-starts-with": "Asset name starts with" | ||
189 | }, | 197 | }, |
190 | "attribute": { | 198 | "attribute": { |
191 | "attributes": "Attributes", | 199 | "attributes": "Attributes", |
@@ -463,7 +471,7 @@ export default angular.module('thingsboard.locale', []) | @@ -463,7 +471,7 @@ export default angular.module('thingsboard.locale', []) | ||
463 | "alias-required": "Device alias is required.", | 471 | "alias-required": "Device alias is required.", |
464 | "remove-alias": "Remove device alias", | 472 | "remove-alias": "Remove device alias", |
465 | "add-alias": "Add device alias", | 473 | "add-alias": "Add device alias", |
466 | - "name-starts-with": "Name starts with", | 474 | + "name-starts-with": "Device name starts with", |
467 | "device-list": "Device list", | 475 | "device-list": "Device list", |
468 | "use-device-name-filter": "Use filter", | 476 | "use-device-name-filter": "Use filter", |
469 | "device-list-empty": "No devices selected.", | 477 | "device-list-empty": "No devices selected.", |
@@ -549,6 +557,7 @@ export default angular.module('thingsboard.locale', []) | @@ -549,6 +557,7 @@ export default angular.module('thingsboard.locale', []) | ||
549 | "unable-delete-entity-alias-title": "Unable to delete entity alias", | 557 | "unable-delete-entity-alias-title": "Unable to delete entity alias", |
550 | "unable-delete-entity-alias-text": "Entity alias '{{entityAlias}}' can't be deleted as it used by the following widget(s):<br/>{{widgetsList}}", | 558 | "unable-delete-entity-alias-text": "Entity alias '{{entityAlias}}' can't be deleted as it used by the following widget(s):<br/>{{widgetsList}}", |
551 | "duplicate-alias-error": "Duplicate alias found '{{alias}}'.<br>Entity aliases must be unique whithin the dashboard.", | 559 | "duplicate-alias-error": "Duplicate alias found '{{alias}}'.<br>Entity aliases must be unique whithin the dashboard.", |
560 | + "missing-entity-filter-error": "Filter is missing for alias '{{alias}}'.", | ||
552 | "configure-alias": "Configure '{{alias}}' alias", | 561 | "configure-alias": "Configure '{{alias}}' alias", |
553 | "alias": "Alias", | 562 | "alias": "Alias", |
554 | "alias-required": "Entity alias is required.", | 563 | "alias-required": "Entity alias is required.", |
@@ -562,24 +571,42 @@ export default angular.module('thingsboard.locale', []) | @@ -562,24 +571,42 @@ export default angular.module('thingsboard.locale', []) | ||
562 | "entity-name-filter-required": "Entity name filter is required.", | 571 | "entity-name-filter-required": "Entity name filter is required.", |
563 | "entity-name-filter-no-entity-matched": "No entities starting with '{{entity}}' were found.", | 572 | "entity-name-filter-no-entity-matched": "No entities starting with '{{entity}}' were found.", |
564 | "all-subtypes": "All", | 573 | "all-subtypes": "All", |
574 | + "select-entities": "Select entities", | ||
575 | + "no-aliases-found": "No aliases found.", | ||
576 | + "no-alias-matching": "'{{alias}}' not found.", | ||
577 | + "create-new-alias": "Create a new one!", | ||
578 | + "no-keys-found": "No keys found.", | ||
579 | + "no-key-matching": "'{{key}}' not found.", | ||
580 | + "create-new-key": "Create a new one!", | ||
565 | "type": "Type", | 581 | "type": "Type", |
566 | "type-required": "Entity type is required.", | 582 | "type-required": "Entity type is required.", |
567 | "type-device": "Device", | 583 | "type-device": "Device", |
584 | + "list-of-devices": "{ count, select, 1 {One device} other {List of # devices} }", | ||
585 | + "device-name-starts-with": "Devices whose names start with '{{prefix}}'", | ||
568 | "type-asset": "Asset", | 586 | "type-asset": "Asset", |
587 | + "list-of-assets": "{ count, select, 1 {One asset} other {List of # assets} }", | ||
588 | + "asset-name-starts-with": "Assets whose names start with '{{prefix}}'", | ||
569 | "type-rule": "Rule", | 589 | "type-rule": "Rule", |
590 | + "list-of-rules": "{ count, select, 1 {One rule} other {List of # rules} }", | ||
591 | + "rule-name-starts-with": "Rules whose names start with '{{prefix}}'", | ||
570 | "type-plugin": "Plugin", | 592 | "type-plugin": "Plugin", |
593 | + "list-of-plugins": "{ count, select, 1 {One plugin} other {List of # plugins} }", | ||
594 | + "plugin-name-starts-with": "Plugins whose names start with '{{prefix}}'", | ||
571 | "type-tenant": "Tenant", | 595 | "type-tenant": "Tenant", |
596 | + "list-of-tenants": "{ count, select, 1 {One tenant} other {List of # tenants} }", | ||
597 | + "tenant-name-starts-with": "Tenants whose names start with '{{prefix}}'", | ||
572 | "type-customer": "Customer", | 598 | "type-customer": "Customer", |
599 | + "list-of-customers": "{ count, select, 1 {One customer} other {List of # customers} }", | ||
600 | + "customer-name-starts-with": "Customers whose names start with '{{prefix}}'", | ||
573 | "type-user": "User", | 601 | "type-user": "User", |
602 | + "list-of-users": "{ count, select, 1 {One user} other {List of # users} }", | ||
603 | + "user-name-starts-with": "Users whose names start with '{{prefix}}'", | ||
574 | "type-dashboard": "Dashboard", | 604 | "type-dashboard": "Dashboard", |
605 | + "list-of-dashboards": "{ count, select, 1 {One dashboard} other {List of # dashboards} }", | ||
606 | + "dashboard-name-starts-with": "Dashboards whose names start with '{{prefix}}'", | ||
575 | "type-alarm": "Alarm", | 607 | "type-alarm": "Alarm", |
576 | - "select-entities": "Select entities", | ||
577 | - "no-aliases-found": "No aliases found.", | ||
578 | - "no-alias-matching": "'{{alias}}' not found.", | ||
579 | - "create-new-alias": "Create a new one!", | ||
580 | - "no-keys-found": "No keys found.", | ||
581 | - "no-key-matching": "'{{key}}' not found.", | ||
582 | - "create-new-key": "Create a new one!" | 608 | + "list-of-alarms": "{ count, select, 1 {One alarms} other {List of # alarms} }", |
609 | + "alarm-name-starts-with": "Alarms whose names start with '{{prefix}}'" | ||
583 | }, | 610 | }, |
584 | "event": { | 611 | "event": { |
585 | "event-type": "Event type", | 612 | "event-type": "Event type", |