Commit 17825b2cb4425a1153718b14b3a0f19243fb241c
Committed by
GitHub
Merge pull request #224 from thingsboard/feature/TB-70
TB-70: Introduce default entity for alias state parameter. Add actio…
Showing
13 changed files
with
239 additions
and
88 deletions
@@ -15,7 +15,7 @@ | @@ -15,7 +15,7 @@ | ||
15 | "resources": [], | 15 | "resources": [], |
16 | "templateHtml": "<tb-alarms-table-widget \n table-id=\"tableId\"\n ctx=\"ctx\">\n</tb-alarms-table-widget>", | 16 | "templateHtml": "<tb-alarms-table-widget \n table-id=\"tableId\"\n ctx=\"ctx\">\n</tb-alarms-table-widget>", |
17 | "templateCss": "", | 17 | "templateCss": "", |
18 | - "controllerScript": "self.onInit = function() {\n var scope = self.ctx.$scope;\n var id = self.ctx.$scope.$injector.get('utils').guid();\n scope.tableId = \"table-\"+id;\n scope.ctx = self.ctx;\n}\n\nself.onDataUpdated = function() {\n self.ctx.$scope.$broadcast('alarms-table-data-updated', self.ctx.$scope.tableId);\n}\n\nself.onDestroy = function() {\n}\n", | 18 | + "controllerScript": "self.onInit = function() {\n var scope = self.ctx.$scope;\n var id = self.ctx.$scope.$injector.get('utils').guid();\n scope.tableId = \"table-\"+id;\n scope.ctx = self.ctx;\n}\n\nself.onDataUpdated = function() {\n self.ctx.$scope.$broadcast('alarms-table-data-updated', self.ctx.$scope.tableId);\n}\n\nself.actionSources = function() {\n return {\n 'actionCellButton': {\n name: 'widget-action.action-cell-button',\n multiple: true\n },\n 'rowClick': {\n name: 'widget-action.row-click',\n multiple: false\n }\n };\n}\n\nself.onDestroy = function() {\n}\n", |
19 | "settingsSchema": "{\n \"schema\": {\n \"type\": \"object\",\n \"title\": \"AlarmTableSettings\",\n \"properties\": {\n \"alarmsTitle\": {\n \"title\": \"Alarms table title\",\n \"type\": \"string\",\n \"default\": \"\"\n },\n \"enableSelection\": {\n \"title\": \"Enable alarms selection\",\n \"type\": \"boolean\",\n \"default\": true\n },\n \"enableSearch\": {\n \"title\": \"Enable alarms search\",\n \"type\": \"boolean\",\n \"default\": true\n },\n \"displayDetails\": {\n \"title\": \"Display alarm details\",\n \"type\": \"boolean\",\n \"default\": true\n },\n \"allowAcknowledgment\": {\n \"title\": \"Allow alarms acknowledgment\",\n \"type\": \"boolean\",\n \"default\": true\n },\n \"allowClear\": {\n \"title\": \"Allow alarms clear\",\n \"type\": \"boolean\",\n \"default\": true\n },\n \"displayPagination\": {\n \"title\": \"Display pagination\",\n \"type\": \"boolean\",\n \"default\": true\n },\n \"defaultPageSize\": {\n \"title\": \"Default page size\",\n \"type\": \"number\",\n \"default\": 10\n },\n \"defaultSortOrder\": {\n \"title\": \"Default sort order\",\n \"type\": \"string\",\n \"default\": \"-createdTime\"\n }\n },\n \"required\": []\n },\n \"form\": [\n \"alarmsTitle\",\n \"enableSelection\",\n \"enableSearch\",\n \"displayDetails\",\n \"allowAcknowledgment\",\n \"allowClear\",\n \"displayPagination\",\n \"defaultPageSize\",\n \"defaultSortOrder\"\n ]\n}", | 19 | "settingsSchema": "{\n \"schema\": {\n \"type\": \"object\",\n \"title\": \"AlarmTableSettings\",\n \"properties\": {\n \"alarmsTitle\": {\n \"title\": \"Alarms table title\",\n \"type\": \"string\",\n \"default\": \"\"\n },\n \"enableSelection\": {\n \"title\": \"Enable alarms selection\",\n \"type\": \"boolean\",\n \"default\": true\n },\n \"enableSearch\": {\n \"title\": \"Enable alarms search\",\n \"type\": \"boolean\",\n \"default\": true\n },\n \"displayDetails\": {\n \"title\": \"Display alarm details\",\n \"type\": \"boolean\",\n \"default\": true\n },\n \"allowAcknowledgment\": {\n \"title\": \"Allow alarms acknowledgment\",\n \"type\": \"boolean\",\n \"default\": true\n },\n \"allowClear\": {\n \"title\": \"Allow alarms clear\",\n \"type\": \"boolean\",\n \"default\": true\n },\n \"displayPagination\": {\n \"title\": \"Display pagination\",\n \"type\": \"boolean\",\n \"default\": true\n },\n \"defaultPageSize\": {\n \"title\": \"Default page size\",\n \"type\": \"number\",\n \"default\": 10\n },\n \"defaultSortOrder\": {\n \"title\": \"Default sort order\",\n \"type\": \"string\",\n \"default\": \"-createdTime\"\n }\n },\n \"required\": []\n },\n \"form\": [\n \"alarmsTitle\",\n \"enableSelection\",\n \"enableSearch\",\n \"displayDetails\",\n \"allowAcknowledgment\",\n \"allowClear\",\n \"displayPagination\",\n \"defaultPageSize\",\n \"defaultSortOrder\"\n ]\n}", |
20 | "dataKeySettingsSchema": "{\n \"schema\": {\n \"type\": \"object\",\n \"title\": \"DataKeySettings\",\n \"properties\": {\n \"columnWidth\": {\n \"title\": \"Column width (px or %)\",\n \"type\": \"string\",\n \"default\": \"0px\"\n },\n \"useCellStyleFunction\": {\n \"title\": \"Use cell style function\",\n \"type\": \"boolean\",\n \"default\": false\n },\n \"cellStyleFunction\": {\n \"title\": \"Cell style function: f(value)\",\n \"type\": \"string\",\n \"default\": \"\"\n },\n \"useCellContentFunction\": {\n \"title\": \"Use cell content function\",\n \"type\": \"boolean\",\n \"default\": false\n },\n \"cellContentFunction\": {\n \"title\": \"Cell content function: f(value, alarm, filter)\",\n \"type\": \"string\",\n \"default\": \"\"\n }\n },\n \"required\": []\n },\n \"form\": [\n \"columnWidth\",\n \"useCellStyleFunction\",\n {\n \"key\": \"cellStyleFunction\",\n \"type\": \"javascript\"\n },\n \"useCellContentFunction\",\n {\n \"key\": \"cellContentFunction\",\n \"type\": \"javascript\"\n }\n ]\n}", | 20 | "dataKeySettingsSchema": "{\n \"schema\": {\n \"type\": \"object\",\n \"title\": \"DataKeySettings\",\n \"properties\": {\n \"columnWidth\": {\n \"title\": \"Column width (px or %)\",\n \"type\": \"string\",\n \"default\": \"0px\"\n },\n \"useCellStyleFunction\": {\n \"title\": \"Use cell style function\",\n \"type\": \"boolean\",\n \"default\": false\n },\n \"cellStyleFunction\": {\n \"title\": \"Cell style function: f(value)\",\n \"type\": \"string\",\n \"default\": \"\"\n },\n \"useCellContentFunction\": {\n \"title\": \"Use cell content function\",\n \"type\": \"boolean\",\n \"default\": false\n },\n \"cellContentFunction\": {\n \"title\": \"Cell content function: f(value, alarm, filter)\",\n \"type\": \"string\",\n \"default\": \"\"\n }\n },\n \"required\": []\n },\n \"form\": [\n \"columnWidth\",\n \"useCellStyleFunction\",\n {\n \"key\": \"cellStyleFunction\",\n \"type\": \"javascript\"\n },\n \"useCellContentFunction\",\n {\n \"key\": \"cellContentFunction\",\n \"type\": \"javascript\"\n }\n ]\n}", |
21 | "defaultConfig": "{\"timewindow\":{\"realtime\":{\"interval\":1000,\"timewindowMs\":86400000},\"aggregation\":{\"type\":\"NONE\",\"limit\":200}},\"showTitle\":true,\"backgroundColor\":\"rgb(255, 255, 255)\",\"color\":\"rgba(0, 0, 0, 0.87)\",\"padding\":\"4px\",\"settings\":{\"enableSelection\":true,\"enableSearch\":true,\"displayDetails\":true,\"allowAcknowledgment\":true,\"allowClear\":true,\"displayPagination\":true,\"defaultPageSize\":10,\"defaultSortOrder\":\"-createdTime\"},\"title\":\"Alarms table\",\"dropShadow\":true,\"enableFullscreen\":true,\"titleStyle\":{\"fontSize\":\"18px\",\"fontWeight\":400,\"padding\":\"5px 10px 5px 10px\"},\"useDashboardTimewindow\":false,\"showLegend\":false,\"alarmSource\":{\"type\":\"function\",\"dataKeys\":[{\"name\":\"createdTime\",\"type\":\"alarm\",\"label\":\"Created time\",\"color\":\"#2196f3\",\"settings\":{\"useCellStyleFunction\":false,\"cellStyleFunction\":\"\",\"useCellContentFunction\":false,\"cellContentFunction\":\"\"},\"_hash\":0.021092237451093787},{\"name\":\"originator\",\"type\":\"alarm\",\"label\":\"Originator\",\"color\":\"#4caf50\",\"settings\":{\"useCellStyleFunction\":false,\"cellStyleFunction\":\"\",\"useCellContentFunction\":false,\"cellContentFunction\":\"\"},\"_hash\":0.2780007688856758},{\"name\":\"type\",\"type\":\"alarm\",\"label\":\"Type\",\"color\":\"#f44336\",\"settings\":{\"useCellStyleFunction\":false,\"cellStyleFunction\":\"\",\"useCellContentFunction\":false,\"cellContentFunction\":\"\"},\"_hash\":0.7323586880398418},{\"name\":\"severity\",\"type\":\"alarm\",\"label\":\"Severity\",\"color\":\"#ffc107\",\"settings\":{\"useCellStyleFunction\":false,\"useCellContentFunction\":false},\"_hash\":0.09927019860088193},{\"name\":\"status\",\"type\":\"alarm\",\"label\":\"Status\",\"color\":\"#607d8b\",\"settings\":{\"useCellStyleFunction\":false,\"cellStyleFunction\":\"\",\"useCellContentFunction\":false,\"cellContentFunction\":\"\"},\"_hash\":0.6588418951443418}],\"entityAliasId\":null,\"name\":\"alarms\"},\"alarmSearchStatus\":\"ANY\",\"alarmsPollingInterval\":5}" | 21 | "defaultConfig": "{\"timewindow\":{\"realtime\":{\"interval\":1000,\"timewindowMs\":86400000},\"aggregation\":{\"type\":\"NONE\",\"limit\":200}},\"showTitle\":true,\"backgroundColor\":\"rgb(255, 255, 255)\",\"color\":\"rgba(0, 0, 0, 0.87)\",\"padding\":\"4px\",\"settings\":{\"enableSelection\":true,\"enableSearch\":true,\"displayDetails\":true,\"allowAcknowledgment\":true,\"allowClear\":true,\"displayPagination\":true,\"defaultPageSize\":10,\"defaultSortOrder\":\"-createdTime\"},\"title\":\"Alarms table\",\"dropShadow\":true,\"enableFullscreen\":true,\"titleStyle\":{\"fontSize\":\"18px\",\"fontWeight\":400,\"padding\":\"5px 10px 5px 10px\"},\"useDashboardTimewindow\":false,\"showLegend\":false,\"alarmSource\":{\"type\":\"function\",\"dataKeys\":[{\"name\":\"createdTime\",\"type\":\"alarm\",\"label\":\"Created time\",\"color\":\"#2196f3\",\"settings\":{\"useCellStyleFunction\":false,\"cellStyleFunction\":\"\",\"useCellContentFunction\":false,\"cellContentFunction\":\"\"},\"_hash\":0.021092237451093787},{\"name\":\"originator\",\"type\":\"alarm\",\"label\":\"Originator\",\"color\":\"#4caf50\",\"settings\":{\"useCellStyleFunction\":false,\"cellStyleFunction\":\"\",\"useCellContentFunction\":false,\"cellContentFunction\":\"\"},\"_hash\":0.2780007688856758},{\"name\":\"type\",\"type\":\"alarm\",\"label\":\"Type\",\"color\":\"#f44336\",\"settings\":{\"useCellStyleFunction\":false,\"cellStyleFunction\":\"\",\"useCellContentFunction\":false,\"cellContentFunction\":\"\"},\"_hash\":0.7323586880398418},{\"name\":\"severity\",\"type\":\"alarm\",\"label\":\"Severity\",\"color\":\"#ffc107\",\"settings\":{\"useCellStyleFunction\":false,\"useCellContentFunction\":false},\"_hash\":0.09927019860088193},{\"name\":\"status\",\"type\":\"alarm\",\"label\":\"Status\",\"color\":\"#607d8b\",\"settings\":{\"useCellStyleFunction\":false,\"cellStyleFunction\":\"\",\"useCellContentFunction\":false,\"cellContentFunction\":\"\"},\"_hash\":0.6588418951443418}],\"entityAliasId\":null,\"name\":\"alarms\"},\"alarmSearchStatus\":\"ANY\",\"alarmsPollingInterval\":5}" |
@@ -353,16 +353,20 @@ function EntityService($http, $q, $filter, $translate, $log, userService, device | @@ -353,16 +353,20 @@ function EntityService($http, $q, $filter, $translate, $log, userService, device | ||
353 | 353 | ||
354 | function entitiesToEntitiesInfo(entities) { | 354 | function entitiesToEntitiesInfo(entities) { |
355 | var entitiesInfo = []; | 355 | var entitiesInfo = []; |
356 | - for (var d = 0; d < entities.length; d++) { | ||
357 | - entitiesInfo.push(entityToEntityInfo(entities[d])); | 356 | + if (entities) { |
357 | + for (var d = 0; d < entities.length; d++) { | ||
358 | + entitiesInfo.push(entityToEntityInfo(entities[d])); | ||
359 | + } | ||
358 | } | 360 | } |
359 | return entitiesInfo; | 361 | return entitiesInfo; |
360 | } | 362 | } |
361 | 363 | ||
362 | function entityRelationInfosToEntitiesInfo(entityRelations, direction) { | 364 | function entityRelationInfosToEntitiesInfo(entityRelations, direction) { |
363 | var entitiesInfo = []; | 365 | var entitiesInfo = []; |
364 | - for (var d = 0; d < entityRelations.length; d++) { | ||
365 | - entitiesInfo.push(entityRelationInfoToEntityInfo(entityRelations[d], direction)); | 366 | + if (entityRelations) { |
367 | + for (var d = 0; d < entityRelations.length; d++) { | ||
368 | + entitiesInfo.push(entityRelationInfoToEntityInfo(entityRelations[d], direction)); | ||
369 | + } | ||
366 | } | 370 | } |
367 | return entitiesInfo; | 371 | return entitiesInfo; |
368 | } | 372 | } |
@@ -371,7 +375,7 @@ function EntityService($http, $q, $filter, $translate, $log, userService, device | @@ -371,7 +375,7 @@ function EntityService($http, $q, $filter, $translate, $log, userService, device | ||
371 | function resolveAlias(entityAlias, stateParams) { | 375 | function resolveAlias(entityAlias, stateParams) { |
372 | var deferred = $q.defer(); | 376 | var deferred = $q.defer(); |
373 | var filter = entityAlias.filter; | 377 | var filter = entityAlias.filter; |
374 | - resolveAliasFilter(filter, stateParams, -1).then( | 378 | + resolveAliasFilter(filter, stateParams, -1, false).then( |
375 | function (result) { | 379 | function (result) { |
376 | var aliasInfo = { | 380 | var aliasInfo = { |
377 | alias: entityAlias.alias, | 381 | alias: entityAlias.alias, |
@@ -404,10 +408,13 @@ function EntityService($http, $q, $filter, $translate, $log, userService, device | @@ -404,10 +408,13 @@ function EntityService($http, $q, $filter, $translate, $log, userService, device | ||
404 | entityId = stateParams.entityId; | 408 | entityId = stateParams.entityId; |
405 | } | 409 | } |
406 | } | 410 | } |
411 | + if (!entityId) { | ||
412 | + entityId = filter.defaultStateEntity; | ||
413 | + } | ||
407 | return entityId; | 414 | return entityId; |
408 | } | 415 | } |
409 | 416 | ||
410 | - function resolveAliasFilter(filter, stateParams, maxItems) { | 417 | + function resolveAliasFilter(filter, stateParams, maxItems, failOnEmpty) { |
411 | var deferred = $q.defer(); | 418 | var deferred = $q.defer(); |
412 | var result = { | 419 | var result = { |
413 | entities: [], | 420 | entities: [], |
@@ -421,7 +428,7 @@ function EntityService($http, $q, $filter, $translate, $log, userService, device | @@ -421,7 +428,7 @@ function EntityService($http, $q, $filter, $translate, $log, userService, device | ||
421 | case types.aliasFilterType.entityList.value: | 428 | case types.aliasFilterType.entityList.value: |
422 | getEntities(filter.entityType, filter.entityList).then( | 429 | getEntities(filter.entityType, filter.entityList).then( |
423 | function success(entities) { | 430 | function success(entities) { |
424 | - if (entities && entities.length) { | 431 | + if (entities && entities.length || !failOnEmpty) { |
425 | result.entities = entitiesToEntitiesInfo(entities); | 432 | result.entities = entitiesToEntitiesInfo(entities); |
426 | deferred.resolve(result); | 433 | deferred.resolve(result); |
427 | } else { | 434 | } else { |
@@ -436,7 +443,7 @@ function EntityService($http, $q, $filter, $translate, $log, userService, device | @@ -436,7 +443,7 @@ function EntityService($http, $q, $filter, $translate, $log, userService, device | ||
436 | case types.aliasFilterType.entityName.value: | 443 | case types.aliasFilterType.entityName.value: |
437 | getEntitiesByNameFilter(filter.entityType, filter.entityNameFilter, maxItems).then( | 444 | getEntitiesByNameFilter(filter.entityType, filter.entityNameFilter, maxItems).then( |
438 | function success(entities) { | 445 | function success(entities) { |
439 | - if (entities && entities.length) { | 446 | + if (entities && entities.length || !failOnEmpty) { |
440 | result.entities = entitiesToEntitiesInfo(entities); | 447 | result.entities = entitiesToEntitiesInfo(entities); |
441 | deferred.resolve(result); | 448 | deferred.resolve(result); |
442 | } else { | 449 | } else { |
@@ -457,7 +464,7 @@ function EntityService($http, $q, $filter, $translate, $log, userService, device | @@ -457,7 +464,7 @@ function EntityService($http, $q, $filter, $translate, $log, userService, device | ||
457 | deferred.resolve(result); | 464 | deferred.resolve(result); |
458 | }, | 465 | }, |
459 | function fail() { | 466 | function fail() { |
460 | - deferred.reject(); | 467 | + deferred.resolve(result); |
461 | } | 468 | } |
462 | ); | 469 | ); |
463 | } else { | 470 | } else { |
@@ -467,7 +474,7 @@ function EntityService($http, $q, $filter, $translate, $log, userService, device | @@ -467,7 +474,7 @@ function EntityService($http, $q, $filter, $translate, $log, userService, device | ||
467 | case types.aliasFilterType.assetType.value: | 474 | case types.aliasFilterType.assetType.value: |
468 | getEntitiesByNameFilter(types.entityType.asset, filter.assetNameFilter, maxItems, null, filter.assetType).then( | 475 | getEntitiesByNameFilter(types.entityType.asset, filter.assetNameFilter, maxItems, null, filter.assetType).then( |
469 | function success(entities) { | 476 | function success(entities) { |
470 | - if (entities && entities.length) { | 477 | + if (entities && entities.length || !failOnEmpty) { |
471 | result.entities = entitiesToEntitiesInfo(entities); | 478 | result.entities = entitiesToEntitiesInfo(entities); |
472 | deferred.resolve(result); | 479 | deferred.resolve(result); |
473 | } else { | 480 | } else { |
@@ -482,7 +489,7 @@ function EntityService($http, $q, $filter, $translate, $log, userService, device | @@ -482,7 +489,7 @@ function EntityService($http, $q, $filter, $translate, $log, userService, device | ||
482 | case types.aliasFilterType.deviceType.value: | 489 | case types.aliasFilterType.deviceType.value: |
483 | getEntitiesByNameFilter(types.entityType.device, filter.deviceNameFilter, maxItems, null, filter.deviceType).then( | 490 | getEntitiesByNameFilter(types.entityType.device, filter.deviceNameFilter, maxItems, null, filter.deviceType).then( |
484 | function success(entities) { | 491 | function success(entities) { |
485 | - if (entities && entities.length) { | 492 | + if (entities && entities.length || !failOnEmpty) { |
486 | result.entities = entitiesToEntitiesInfo(entities); | 493 | result.entities = entitiesToEntitiesInfo(entities); |
487 | deferred.resolve(result); | 494 | deferred.resolve(result); |
488 | } else { | 495 | } else { |
@@ -517,8 +524,8 @@ function EntityService($http, $q, $filter, $translate, $log, userService, device | @@ -517,8 +524,8 @@ function EntityService($http, $q, $filter, $translate, $log, userService, device | ||
517 | searchQuery.parameters.maxLevel = filter.maxLevel && filter.maxLevel > 0 ? filter.maxLevel : -1; | 524 | searchQuery.parameters.maxLevel = filter.maxLevel && filter.maxLevel > 0 ? filter.maxLevel : -1; |
518 | entityRelationService.findInfoByQuery(searchQuery).then( | 525 | entityRelationService.findInfoByQuery(searchQuery).then( |
519 | function success(allRelations) { | 526 | function success(allRelations) { |
520 | - if (allRelations && allRelations.length) { | ||
521 | - if (angular.isDefined(maxItems) && maxItems > 0) { | 527 | + if (allRelations && allRelations.length || !failOnEmpty) { |
528 | + if (angular.isDefined(maxItems) && maxItems > 0 && allRelations) { | ||
522 | var limit = Math.min(allRelations.length, maxItems); | 529 | var limit = Math.min(allRelations.length, maxItems); |
523 | allRelations.length = limit; | 530 | allRelations.length = limit; |
524 | } | 531 | } |
@@ -566,8 +573,8 @@ function EntityService($http, $q, $filter, $translate, $log, userService, device | @@ -566,8 +573,8 @@ function EntityService($http, $q, $filter, $translate, $log, userService, device | ||
566 | } | 573 | } |
567 | findByQueryPromise.then( | 574 | findByQueryPromise.then( |
568 | function success(entities) { | 575 | function success(entities) { |
569 | - if (entities && entities.length) { | ||
570 | - if (angular.isDefined(maxItems) && maxItems > 0) { | 576 | + if (entities && entities.length || !failOnEmpty) { |
577 | + if (angular.isDefined(maxItems) && maxItems > 0 && entities) { | ||
571 | var limit = Math.min(entities.length, maxItems); | 578 | var limit = Math.min(entities.length, maxItems); |
572 | entities.length = limit; | 579 | entities.length = limit; |
573 | } | 580 | } |
@@ -720,7 +727,7 @@ function EntityService($http, $q, $filter, $translate, $log, userService, device | @@ -720,7 +727,7 @@ function EntityService($http, $q, $filter, $translate, $log, userService, device | ||
720 | 727 | ||
721 | function checkEntityAlias(entityAlias) { | 728 | function checkEntityAlias(entityAlias) { |
722 | var deferred = $q.defer(); | 729 | var deferred = $q.defer(); |
723 | - resolveAliasFilter(entityAlias.filter, null, 1).then( | 730 | + resolveAliasFilter(entityAlias.filter, null, 1, true).then( |
724 | function success(result) { | 731 | function success(result) { |
725 | if (result.stateEntity) { | 732 | if (result.stateEntity) { |
726 | deferred.resolve(true); | 733 | deferred.resolve(true); |
@@ -737,7 +737,15 @@ export default class Subscription { | @@ -737,7 +737,15 @@ export default class Subscription { | ||
737 | this.ctx.datasourceService.subscribeToDatasource(listener); | 737 | this.ctx.datasourceService.subscribeToDatasource(listener); |
738 | } | 738 | } |
739 | 739 | ||
740 | - if (datasource.unresolvedStateEntity || !datasource.dataKeys.length) { | 740 | + var forceUpdate = false; |
741 | + if (datasource.unresolvedStateEntity || | ||
742 | + !datasource.dataKeys.length || | ||
743 | + (datasource.type === this.ctx.types.datasourceType.entity && !datasource.entityId) | ||
744 | + ) { | ||
745 | + forceUpdate = true; | ||
746 | + } | ||
747 | + | ||
748 | + if (forceUpdate) { | ||
741 | this.notifyDataLoaded(); | 749 | this.notifyDataLoaded(); |
742 | this.onDataUpdated(); | 750 | this.onDataUpdated(); |
743 | } | 751 | } |
@@ -767,7 +775,14 @@ export default class Subscription { | @@ -767,7 +775,14 @@ export default class Subscription { | ||
767 | 775 | ||
768 | this.ctx.alarmService.subscribeForAlarms(this.alarmSourceListener); | 776 | this.ctx.alarmService.subscribeForAlarms(this.alarmSourceListener); |
769 | 777 | ||
770 | - if (this.alarmSource.unresolvedStateEntity) { | 778 | + var forceUpdate = false; |
779 | + if (this.alarmSource.unresolvedStateEntity || | ||
780 | + (this.alarmSource.type === this.ctx.types.datasourceType.entity && !this.alarmSource.entityId) | ||
781 | + ) { | ||
782 | + forceUpdate = true; | ||
783 | + } | ||
784 | + | ||
785 | + if (forceUpdate) { | ||
771 | this.notifyDataLoaded(); | 786 | this.notifyDataLoaded(); |
772 | this.onDataUpdated(); | 787 | this.onDataUpdated(); |
773 | } | 788 | } |
@@ -282,10 +282,30 @@ export default function EntityStateController($scope, $location, $state, $stateP | @@ -282,10 +282,30 @@ export default function EntityStateController($scope, $location, $state, $stateP | ||
282 | 282 | ||
283 | function updateLocation() { | 283 | function updateLocation() { |
284 | if (vm.stateObject[vm.stateObject.length-1].id) { | 284 | if (vm.stateObject[vm.stateObject.length-1].id) { |
285 | - $location.search({state : utils.objToBase64(vm.stateObject)}); | 285 | + if (isDefaultState()) { |
286 | + $location.search({state : null}); | ||
287 | + } else { | ||
288 | + $location.search({state : utils.objToBase64(vm.stateObject)}); | ||
289 | + } | ||
286 | } | 290 | } |
287 | } | 291 | } |
288 | 292 | ||
293 | + function isDefaultState() { | ||
294 | + if (vm.stateObject.length == 1) { | ||
295 | + var state = vm.stateObject[0]; | ||
296 | + var rootStateId = dashboardUtils.getRootStateId(vm.states); | ||
297 | + if (state.id == rootStateId && (!state.params || isEmpty(state.params))) { | ||
298 | + return true; | ||
299 | + } | ||
300 | + } | ||
301 | + return false; | ||
302 | + } | ||
289 | 303 | ||
304 | + function isEmpty(map) { | ||
305 | + for(var key in map) { | ||
306 | + return !map.hasOwnProperty(key); | ||
307 | + } | ||
308 | + return true; | ||
309 | + } | ||
290 | 310 | ||
291 | } | 311 | } |
@@ -71,7 +71,7 @@ export default function EntityAliasDialogController($scope, $mdDialog, $q, $filt | @@ -71,7 +71,7 @@ export default function EntityAliasDialogController($scope, $mdDialog, $q, $filt | ||
71 | entity: null, | 71 | entity: null, |
72 | stateEntity: false | 72 | stateEntity: false |
73 | } | 73 | } |
74 | - entityService.resolveAliasFilter(vm.alias.filter, null, 1).then( | 74 | + entityService.resolveAliasFilter(vm.alias.filter, null, 1, true).then( |
75 | function success(result) { | 75 | function success(result) { |
76 | validationResult.stateEntity = result.stateEntity; | 76 | validationResult.stateEntity = result.stateEntity; |
77 | var entities = result.entities; | 77 | var entities = result.entities; |
@@ -95,12 +95,16 @@ export default function EntityAutocomplete($compile, $templateCache, $q, $filter | @@ -95,12 +95,16 @@ export default function EntityAutocomplete($compile, $templateCache, $q, $filter | ||
95 | } | 95 | } |
96 | }); | 96 | }); |
97 | 97 | ||
98 | - scope.$watch('entity', function () { | ||
99 | - scope.updateView(); | 98 | + scope.$watch('entity', function (newVal, prevVal) { |
99 | + if (!angular.equals(newVal, prevVal)) { | ||
100 | + scope.updateView(); | ||
101 | + } | ||
100 | }); | 102 | }); |
101 | 103 | ||
102 | - scope.$watch('disabled', function () { | ||
103 | - scope.updateView(); | 104 | + scope.$watch('disabled', function (newVal, prevVal) { |
105 | + if (!angular.equals(newVal, prevVal)) { | ||
106 | + scope.updateView(); | ||
107 | + } | ||
104 | }); | 108 | }); |
105 | 109 | ||
106 | 110 |
@@ -55,6 +55,7 @@ export default function EntityFilterDirective($compile, $templateCache, $q, $doc | @@ -55,6 +55,7 @@ export default function EntityFilterDirective($compile, $templateCache, $q, $doc | ||
55 | break; | 55 | break; |
56 | case types.aliasFilterType.stateEntity.value: | 56 | case types.aliasFilterType.stateEntity.value: |
57 | filter.stateEntityParamName = null; | 57 | filter.stateEntityParamName = null; |
58 | + filter.defaultStateEntity = null; | ||
58 | break; | 59 | break; |
59 | case types.aliasFilterType.assetType.value: | 60 | case types.aliasFilterType.assetType.value: |
60 | filter.assetType = null; | 61 | filter.assetType = null; |
@@ -69,6 +70,7 @@ export default function EntityFilterDirective($compile, $templateCache, $q, $doc | @@ -69,6 +70,7 @@ export default function EntityFilterDirective($compile, $templateCache, $q, $doc | ||
69 | case types.aliasFilterType.deviceSearchQuery.value: | 70 | case types.aliasFilterType.deviceSearchQuery.value: |
70 | filter.rootStateEntity = false; | 71 | filter.rootStateEntity = false; |
71 | filter.stateEntityParamName = null; | 72 | filter.stateEntityParamName = null; |
73 | + filter.defaultStateEntity = null; | ||
72 | filter.rootEntity = null; | 74 | filter.rootEntity = null; |
73 | filter.direction = types.entitySearchDirection.from; | 75 | filter.direction = types.entitySearchDirection.from; |
74 | filter.maxLevel = 1; | 76 | filter.maxLevel = 1; |
@@ -66,6 +66,14 @@ | @@ -66,6 +66,14 @@ | ||
66 | ng-model="filter.stateEntityParamName" | 66 | ng-model="filter.stateEntityParamName" |
67 | aria-label="{{ 'alias.state-entity-parameter-name' | translate }}"> | 67 | aria-label="{{ 'alias.state-entity-parameter-name' | translate }}"> |
68 | </md-input-container> | 68 | </md-input-container> |
69 | + <div layout="column"> | ||
70 | + <label class="tb-small">{{ 'alias.default-state-entity' | translate }}</label> | ||
71 | + <tb-entity-select flex | ||
72 | + the-form="theForm" | ||
73 | + tb-required="false" | ||
74 | + ng-model="filter.defaultStateEntity"> | ||
75 | + </tb-entity-select> | ||
76 | + </div> | ||
69 | </section> | 77 | </section> |
70 | <section layout="column" ng-if="filter.type == types.aliasFilterType.assetType.value" id="assetTypeFilter"> | 78 | <section layout="column" ng-if="filter.type == types.aliasFilterType.assetType.value" id="assetTypeFilter"> |
71 | <tb-entity-subtype-autocomplete | 79 | <tb-entity-subtype-autocomplete |
@@ -97,27 +105,35 @@ | @@ -97,27 +105,35 @@ | ||
97 | </section> | 105 | </section> |
98 | <section layout="column" ng-if="filter.type == types.aliasFilterType.relationsQuery.value" id="relationsQueryFilter"> | 106 | <section layout="column" ng-if="filter.type == types.aliasFilterType.relationsQuery.value" id="relationsQueryFilter"> |
99 | <label class="tb-small">{{ 'alias.root-entity' | translate }}</label> | 107 | <label class="tb-small">{{ 'alias.root-entity' | translate }}</label> |
100 | - <div flex layout="row"> | 108 | + <section class="tb-root-state-entity-switch" layout="row" layout-align="start center" style="padding-left: 0px;"> |
109 | + <md-switch class="root-state-entity-switch" ng-model="filter.rootStateEntity" | ||
110 | + aria-label="{{ 'alias.root-state-entity' | translate }}"> | ||
111 | + </md-switch> | ||
112 | + <label class="tb-small root-state-entity-label" translate>alias.root-state-entity</label> | ||
113 | + </section> | ||
114 | + <div flex layout="row" ng-if="!filter.rootStateEntity"> | ||
101 | <tb-entity-select flex | 115 | <tb-entity-select flex |
102 | the-form="theForm" | 116 | the-form="theForm" |
103 | tb-required="!filter.rootStateEntity" | 117 | tb-required="!filter.rootStateEntity" |
104 | ng-disabled="filter.rootStateEntity" | 118 | ng-disabled="filter.rootStateEntity" |
105 | ng-model="filter.rootEntity"> | 119 | ng-model="filter.rootEntity"> |
106 | </tb-entity-select> | 120 | </tb-entity-select> |
107 | - <div layout="column"> | ||
108 | - <section class="tb-root-state-entity-switch" layout="column" layout-align="start center"> | ||
109 | - <label class="tb-small root-state-entity-label" translate>alias.root-state-entity</label> | ||
110 | - <md-switch class="root-state-entity-switch" ng-model="filter.rootStateEntity" | ||
111 | - aria-label="{{ 'alias.root-state-entity' | translate }}"> | ||
112 | - </md-switch> | ||
113 | - </section> | ||
114 | - <md-input-container ng-if="filter.rootStateEntity" class="md-block"> | ||
115 | - <label translate>alias.state-entity-parameter-name</label> | ||
116 | - <input name="stateEntityParamName" | ||
117 | - placeholder="{{ 'alias.default-entity-parameter-name' | translate }}" | ||
118 | - ng-model="filter.stateEntityParamName" | ||
119 | - aria-label="{{ 'alias.state-entity-parameter-name' | translate }}"> | ||
120 | - </md-input-container> | 121 | + </div> |
122 | + <div flex layout="row" ng-if="filter.rootStateEntity"> | ||
123 | + <md-input-container class="md-block" style="margin-top: 32px;"> | ||
124 | + <label translate>alias.state-entity-parameter-name</label> | ||
125 | + <input name="stateEntityParamName" | ||
126 | + placeholder="{{ 'alias.default-entity-parameter-name' | translate }}" | ||
127 | + ng-model="filter.stateEntityParamName" | ||
128 | + aria-label="{{ 'alias.state-entity-parameter-name' | translate }}"> | ||
129 | + </md-input-container> | ||
130 | + <div flex layout="column"> | ||
131 | + <label class="tb-small">{{ 'alias.default-state-entity' | translate }}</label> | ||
132 | + <tb-entity-select flex | ||
133 | + the-form="theForm" | ||
134 | + tb-required="false" | ||
135 | + ng-model="filter.defaultStateEntity"> | ||
136 | + </tb-entity-select> | ||
121 | </div> | 137 | </div> |
122 | </div> | 138 | </div> |
123 | <div flex layout="row"> | 139 | <div flex layout="row"> |
@@ -148,27 +164,35 @@ | @@ -148,27 +164,35 @@ | ||
148 | </section> | 164 | </section> |
149 | <section layout="column" ng-if="filter.type == types.aliasFilterType.assetSearchQuery.value" id="assetSearchQueryFilter"> | 165 | <section layout="column" ng-if="filter.type == types.aliasFilterType.assetSearchQuery.value" id="assetSearchQueryFilter"> |
150 | <label class="tb-small">{{ 'alias.root-entity' | translate }}</label> | 166 | <label class="tb-small">{{ 'alias.root-entity' | translate }}</label> |
151 | - <div flex layout="row"> | 167 | + <section class="tb-root-state-entity-switch" layout="row" layout-align="start center" style="padding-left: 0px;"> |
168 | + <md-switch class="root-state-entity-switch" ng-model="filter.rootStateEntity" | ||
169 | + aria-label="{{ 'alias.root-state-entity' | translate }}"> | ||
170 | + </md-switch> | ||
171 | + <label class="tb-small root-state-entity-label" translate>alias.root-state-entity</label> | ||
172 | + </section> | ||
173 | + <div flex layout="row" ng-if="!filter.rootStateEntity"> | ||
152 | <tb-entity-select flex | 174 | <tb-entity-select flex |
153 | the-form="theForm" | 175 | the-form="theForm" |
154 | tb-required="!filter.rootStateEntity" | 176 | tb-required="!filter.rootStateEntity" |
155 | ng-disabled="filter.rootStateEntity" | 177 | ng-disabled="filter.rootStateEntity" |
156 | ng-model="filter.rootEntity"> | 178 | ng-model="filter.rootEntity"> |
157 | </tb-entity-select> | 179 | </tb-entity-select> |
158 | - <div layout="column"> | ||
159 | - <section class="tb-root-state-entity-switch" layout="column" layout-align="start center"> | ||
160 | - <label class="tb-small root-state-entity-label" translate>alias.root-state-entity</label> | ||
161 | - <md-switch class="root-state-entity-switch" ng-model="filter.rootStateEntity" | ||
162 | - aria-label="{{ 'alias.root-state-entity' | translate }}"> | ||
163 | - </md-switch> | ||
164 | - </section> | ||
165 | - <md-input-container ng-if="filter.rootStateEntity" class="md-block"> | ||
166 | - <label translate>alias.state-entity-parameter-name</label> | ||
167 | - <input name="stateEntityParamName" | ||
168 | - placeholder="{{ 'alias.default-entity-parameter-name' | translate }}" | ||
169 | - ng-model="filter.stateEntityParamName" | ||
170 | - aria-label="{{ 'alias.state-entity-parameter-name' | translate }}"> | ||
171 | - </md-input-container> | 180 | + </div> |
181 | + <div flex layout="row" ng-if="filter.rootStateEntity"> | ||
182 | + <md-input-container class="md-block" style="margin-top: 32px;"> | ||
183 | + <label translate>alias.state-entity-parameter-name</label> | ||
184 | + <input name="stateEntityParamName" | ||
185 | + placeholder="{{ 'alias.default-entity-parameter-name' | translate }}" | ||
186 | + ng-model="filter.stateEntityParamName" | ||
187 | + aria-label="{{ 'alias.state-entity-parameter-name' | translate }}"> | ||
188 | + </md-input-container> | ||
189 | + <div flex layout="column"> | ||
190 | + <label class="tb-small">{{ 'alias.default-state-entity' | translate }}</label> | ||
191 | + <tb-entity-select flex | ||
192 | + the-form="theForm" | ||
193 | + tb-required="false" | ||
194 | + ng-model="filter.defaultStateEntity"> | ||
195 | + </tb-entity-select> | ||
172 | </div> | 196 | </div> |
173 | </div> | 197 | </div> |
174 | <div flex layout="row"> | 198 | <div flex layout="row"> |
@@ -207,27 +231,35 @@ | @@ -207,27 +231,35 @@ | ||
207 | </section> | 231 | </section> |
208 | <section layout="column" ng-if="filter.type == types.aliasFilterType.deviceSearchQuery.value" id="deviceSearchQueryFilter"> | 232 | <section layout="column" ng-if="filter.type == types.aliasFilterType.deviceSearchQuery.value" id="deviceSearchQueryFilter"> |
209 | <label class="tb-small">{{ 'alias.root-entity' | translate }}</label> | 233 | <label class="tb-small">{{ 'alias.root-entity' | translate }}</label> |
210 | - <div flex layout="row"> | 234 | + <section class="tb-root-state-entity-switch" layout="row" layout-align="start center" style="padding-left: 0px;"> |
235 | + <md-switch class="root-state-entity-switch" ng-model="filter.rootStateEntity" | ||
236 | + aria-label="{{ 'alias.root-state-entity' | translate }}"> | ||
237 | + </md-switch> | ||
238 | + <label class="tb-small root-state-entity-label" translate>alias.root-state-entity</label> | ||
239 | + </section> | ||
240 | + <div flex layout="row" ng-if="!filter.rootStateEntity"> | ||
211 | <tb-entity-select flex | 241 | <tb-entity-select flex |
212 | the-form="theForm" | 242 | the-form="theForm" |
213 | tb-required="!filter.rootStateEntity" | 243 | tb-required="!filter.rootStateEntity" |
214 | ng-disabled="filter.rootStateEntity" | 244 | ng-disabled="filter.rootStateEntity" |
215 | ng-model="filter.rootEntity"> | 245 | ng-model="filter.rootEntity"> |
216 | </tb-entity-select> | 246 | </tb-entity-select> |
217 | - <div layout="column"> | ||
218 | - <section class="tb-root-state-entity-switch" layout="column" layout-align="start center"> | ||
219 | - <label class="tb-small root-state-entity-label" translate>alias.root-state-entity</label> | ||
220 | - <md-switch class="root-state-entity-switch" ng-model="filter.rootStateEntity" | ||
221 | - aria-label="{{ 'alias.root-state-entity' | translate }}"> | ||
222 | - </md-switch> | ||
223 | - </section> | ||
224 | - <md-input-container ng-if="filter.rootStateEntity" class="md-block"> | ||
225 | - <label translate>alias.state-entity-parameter-name</label> | ||
226 | - <input name="stateEntityParamName" | ||
227 | - placeholder="{{ 'alias.default-entity-parameter-name' | translate }}" | ||
228 | - ng-model="filter.stateEntityParamName" | ||
229 | - aria-label="{{ 'alias.state-entity-parameter-name' | translate }}"> | ||
230 | - </md-input-container> | 247 | + </div> |
248 | + <div flex layout="row" ng-if="filter.rootStateEntity"> | ||
249 | + <md-input-container class="md-block" style="margin-top: 32px;"> | ||
250 | + <label translate>alias.state-entity-parameter-name</label> | ||
251 | + <input name="stateEntityParamName" | ||
252 | + placeholder="{{ 'alias.default-entity-parameter-name' | translate }}" | ||
253 | + ng-model="filter.stateEntityParamName" | ||
254 | + aria-label="{{ 'alias.state-entity-parameter-name' | translate }}"> | ||
255 | + </md-input-container> | ||
256 | + <div flex layout="column"> | ||
257 | + <label class="tb-small">{{ 'alias.default-state-entity' | translate }}</label> | ||
258 | + <tb-entity-select flex | ||
259 | + the-form="theForm" | ||
260 | + tb-required="false" | ||
261 | + ng-model="filter.defaultStateEntity"> | ||
262 | + </tb-entity-select> | ||
231 | </div> | 263 | </div> |
232 | </div> | 264 | </div> |
233 | <div flex layout="row"> | 265 | <div flex layout="row"> |
@@ -48,6 +48,7 @@ export default function EntitySelect($compile, $templateCache) { | @@ -48,6 +48,7 @@ export default function EntitySelect($compile, $templateCache) { | ||
48 | } | 48 | } |
49 | 49 | ||
50 | ngModelCtrl.$render = function () { | 50 | ngModelCtrl.$render = function () { |
51 | + destroyWatchers(); | ||
51 | if (ngModelCtrl.$viewValue) { | 52 | if (ngModelCtrl.$viewValue) { |
52 | var value = ngModelCtrl.$viewValue; | 53 | var value = ngModelCtrl.$viewValue; |
53 | scope.model.entityType = value.entityType; | 54 | scope.model.entityType = value.entityType; |
@@ -56,19 +57,43 @@ export default function EntitySelect($compile, $templateCache) { | @@ -56,19 +57,43 @@ export default function EntitySelect($compile, $templateCache) { | ||
56 | scope.model.entityType = null; | 57 | scope.model.entityType = null; |
57 | scope.model.entityId = null; | 58 | scope.model.entityId = null; |
58 | } | 59 | } |
60 | + initWatchers(); | ||
59 | } | 61 | } |
60 | 62 | ||
61 | - scope.$watch('model.entityType', function () { | ||
62 | - scope.updateView(); | ||
63 | - }); | 63 | + function initWatchers() { |
64 | + scope.entityTypeDeregistration = scope.$watch('model.entityType', function (newVal, prevVal) { | ||
65 | + if (!angular.equals(newVal, prevVal)) { | ||
66 | + scope.updateView(); | ||
67 | + } | ||
68 | + }); | ||
69 | + | ||
70 | + scope.entityIdDeregistration = scope.$watch('model.entityId', function (newVal, prevVal) { | ||
71 | + if (!angular.equals(newVal, prevVal)) { | ||
72 | + scope.updateView(); | ||
73 | + } | ||
74 | + }); | ||
64 | 75 | ||
65 | - scope.$watch('model.entityId', function () { | ||
66 | - scope.updateView(); | ||
67 | - }); | 76 | + scope.disabledDeregistration = scope.$watch('disabled', function (newVal, prevVal) { |
77 | + if (!angular.equals(newVal, prevVal)) { | ||
78 | + scope.updateView(); | ||
79 | + } | ||
80 | + }); | ||
81 | + } | ||
68 | 82 | ||
69 | - scope.$watch('disabled', function () { | ||
70 | - scope.updateView(); | ||
71 | - }); | 83 | + function destroyWatchers() { |
84 | + if (scope.entityTypeDeregistration) { | ||
85 | + scope.entityTypeDeregistration(); | ||
86 | + scope.entityTypeDeregistration = null; | ||
87 | + } | ||
88 | + if (scope.entityIdDeregistration) { | ||
89 | + scope.entityIdDeregistration(); | ||
90 | + scope.entityIdDeregistration = null; | ||
91 | + } | ||
92 | + if (scope.disabledDeregistration) { | ||
93 | + scope.disabledDeregistration(); | ||
94 | + scope.disabledDeregistration = null; | ||
95 | + } | ||
96 | + } | ||
72 | 97 | ||
73 | $compile(element.contents())(scope); | 98 | $compile(element.contents())(scope); |
74 | } | 99 | } |
@@ -188,6 +188,7 @@ export default angular.module('thingsboard.locale', []) | @@ -188,6 +188,7 @@ export default angular.module('thingsboard.locale', []) | ||
188 | "root-state-entity": "Use dashboard state entity as root", | 188 | "root-state-entity": "Use dashboard state entity as root", |
189 | "root-entity": "Root entity", | 189 | "root-entity": "Root entity", |
190 | "state-entity-parameter-name": "State entity parameter name", | 190 | "state-entity-parameter-name": "State entity parameter name", |
191 | + "default-state-entity": "Default state entity", | ||
191 | "default-entity-parameter-name": "By default", | 192 | "default-entity-parameter-name": "By default", |
192 | "max-relation-level": "Max relation level", | 193 | "max-relation-level": "Max relation level", |
193 | "unlimited-level": "Unlimited level", | 194 | "unlimited-level": "Unlimited level", |
@@ -69,6 +69,7 @@ function AlarmsTableWidgetController($element, $scope, $filter, $mdMedia, $mdDia | @@ -69,6 +69,7 @@ function AlarmsTableWidgetController($element, $scope, $filter, $mdMedia, $mdDia | ||
69 | vm.displayDetails = true; | 69 | vm.displayDetails = true; |
70 | vm.allowAcknowledgment = true; | 70 | vm.allowAcknowledgment = true; |
71 | vm.allowClear = true; | 71 | vm.allowClear = true; |
72 | + vm.actionCellDescriptors = []; | ||
72 | vm.displayPagination = true; | 73 | vm.displayPagination = true; |
73 | vm.defaultPageSize = 10; | 74 | vm.defaultPageSize = 10; |
74 | vm.defaultSortOrder = '-'+types.alarmFields.createdTime.value; | 75 | vm.defaultSortOrder = '-'+types.alarmFields.createdTime.value; |
@@ -94,6 +95,7 @@ function AlarmsTableWidgetController($element, $scope, $filter, $mdMedia, $mdDia | @@ -94,6 +95,7 @@ function AlarmsTableWidgetController($element, $scope, $filter, $mdMedia, $mdDia | ||
94 | vm.onReorder = onReorder; | 95 | vm.onReorder = onReorder; |
95 | vm.onPaginate = onPaginate; | 96 | vm.onPaginate = onPaginate; |
96 | vm.onRowClick = onRowClick; | 97 | vm.onRowClick = onRowClick; |
98 | + vm.onActionButtonClick = onActionButtonClick; | ||
97 | vm.isCurrent = isCurrent; | 99 | vm.isCurrent = isCurrent; |
98 | vm.openAlarmDetails = openAlarmDetails; | 100 | vm.openAlarmDetails = openAlarmDetails; |
99 | vm.ackAlarms = ackAlarms; | 101 | vm.ackAlarms = ackAlarms; |
@@ -157,6 +159,8 @@ function AlarmsTableWidgetController($element, $scope, $filter, $mdMedia, $mdDia | @@ -157,6 +159,8 @@ function AlarmsTableWidgetController($element, $scope, $filter, $mdMedia, $mdDia | ||
157 | 159 | ||
158 | vm.ctx.widgetActions = [ vm.searchAction ]; | 160 | vm.ctx.widgetActions = [ vm.searchAction ]; |
159 | 161 | ||
162 | + vm.actionCellDescriptors = vm.ctx.actionsApi.getActionDescriptors('actionCellButton'); | ||
163 | + | ||
160 | if (vm.settings.alarmsTitle && vm.settings.alarmsTitle.length) { | 164 | if (vm.settings.alarmsTitle && vm.settings.alarmsTitle.length) { |
161 | vm.alarmsTitle = utils.customTranslation(vm.settings.alarmsTitle, vm.settings.alarmsTitle); | 165 | vm.alarmsTitle = utils.customTranslation(vm.settings.alarmsTitle, vm.settings.alarmsTitle); |
162 | } else { | 166 | } else { |
@@ -280,9 +284,35 @@ function AlarmsTableWidgetController($element, $scope, $filter, $mdMedia, $mdDia | @@ -280,9 +284,35 @@ function AlarmsTableWidgetController($element, $scope, $filter, $mdMedia, $mdDia | ||
280 | } | 284 | } |
281 | 285 | ||
282 | function onRowClick($event, alarm) { | 286 | function onRowClick($event, alarm) { |
287 | + if ($event) { | ||
288 | + $event.stopPropagation(); | ||
289 | + } | ||
283 | if (vm.currentAlarm != alarm) { | 290 | if (vm.currentAlarm != alarm) { |
284 | vm.currentAlarm = alarm; | 291 | vm.currentAlarm = alarm; |
285 | } | 292 | } |
293 | + var descriptors = vm.ctx.actionsApi.getActionDescriptors('rowClick'); | ||
294 | + if (descriptors.length) { | ||
295 | + var entityId; | ||
296 | + var entityName; | ||
297 | + if (vm.currentAlarm && vm.currentAlarm.originator) { | ||
298 | + entityId = vm.currentAlarm.originator; | ||
299 | + entityName = vm.currentAlarm.originatorName; | ||
300 | + } | ||
301 | + vm.ctx.actionsApi.handleWidgetAction($event, descriptors[0], entityId, entityName); | ||
302 | + } | ||
303 | + } | ||
304 | + | ||
305 | + function onActionButtonClick($event, alarm, actionDescriptor) { | ||
306 | + if ($event) { | ||
307 | + $event.stopPropagation(); | ||
308 | + } | ||
309 | + var entityId; | ||
310 | + var entityName; | ||
311 | + if (alarm && alarm.originator) { | ||
312 | + entityId = alarm.originator; | ||
313 | + entityName = alarm.originatorName; | ||
314 | + } | ||
315 | + vm.ctx.actionsApi.handleWidgetAction($event, actionDescriptor, entityId, entityName); | ||
286 | } | 316 | } |
287 | 317 | ||
288 | function isCurrent(alarm) { | 318 | function isCurrent(alarm) { |
@@ -64,6 +64,7 @@ | @@ -64,6 +64,7 @@ | ||
64 | <tr md-row> | 64 | <tr md-row> |
65 | <th md-column md-order-by="{{ key.name }}" ng-repeat="key in vm.alarmSource.dataKeys"><span>{{ key.title }}</span></th> | 65 | <th md-column md-order-by="{{ key.name }}" ng-repeat="key in vm.alarmSource.dataKeys"><span>{{ key.title }}</span></th> |
66 | <th md-column ng-if="vm.displayDetails"><span> </span></th> | 66 | <th md-column ng-if="vm.displayDetails"><span> </span></th> |
67 | + <th md-column ng-if="vm.actionCellDescriptors.length"><span> </span></th> | ||
67 | </tr> | 68 | </tr> |
68 | </thead> | 69 | </thead> |
69 | <tbody md-body> | 70 | <tbody md-body> |
@@ -83,6 +84,19 @@ | @@ -83,6 +84,19 @@ | ||
83 | </md-tooltip> | 84 | </md-tooltip> |
84 | </md-button> | 85 | </md-button> |
85 | </td> | 86 | </td> |
87 | + <td md-cell ng-if="vm.actionCellDescriptors.length" class="tb-action-cell" | ||
88 | + ng-style="{minWidth: vm.actionCellDescriptors.length*36+'px', | ||
89 | + maxWidth: vm.actionCellDescriptors.length*36+'px', | ||
90 | + width: vm.actionCellDescriptors.length*36+'px'}"> | ||
91 | + <md-button class="md-icon-button" ng-repeat="actionDescriptor in vm.actionCellDescriptors" | ||
92 | + aria-label="{{ actionDescriptor.displayName }}" | ||
93 | + ng-click="vm.onActionButtonClick($event, alarm, actionDescriptor)"> | ||
94 | + <md-icon aria-label="{{ actionDescriptor.displayName }}" class="material-icons">{{actionDescriptor.icon}}</md-icon> | ||
95 | + <md-tooltip md-direction="top"> | ||
96 | + {{ actionDescriptor.displayName }} | ||
97 | + </md-tooltip> | ||
98 | + </md-button> | ||
99 | + </td> | ||
86 | </tr> | 100 | </tr> |
87 | </tbody> | 101 | </tbody> |
88 | </table> | 102 | </table> |
@@ -107,6 +107,7 @@ function EntitiesTableWidgetController($element, $scope, $filter, $mdMedia, $tra | @@ -107,6 +107,7 @@ function EntitiesTableWidgetController($element, $scope, $filter, $mdMedia, $tra | ||
107 | vm.datasources = vm.subscription.datasources; | 107 | vm.datasources = vm.subscription.datasources; |
108 | initializeConfig(); | 108 | initializeConfig(); |
109 | updateDatasources(); | 109 | updateDatasources(); |
110 | + updateEntities(); | ||
110 | } | 111 | } |
111 | }); | 112 | }); |
112 | 113 | ||
@@ -276,16 +277,16 @@ function EntitiesTableWidgetController($element, $scope, $filter, $mdMedia, $tra | @@ -276,16 +277,16 @@ function EntitiesTableWidgetController($element, $scope, $filter, $mdMedia, $tra | ||
276 | } | 277 | } |
277 | if (vm.currentEntity != entity) { | 278 | if (vm.currentEntity != entity) { |
278 | vm.currentEntity = entity; | 279 | vm.currentEntity = entity; |
279 | - var descriptors = vm.ctx.actionsApi.getActionDescriptors('rowClick'); | ||
280 | - if (descriptors.length) { | ||
281 | - var entityId; | ||
282 | - var entityName; | ||
283 | - if (vm.currentEntity) { | ||
284 | - entityId = vm.currentEntity.id; | ||
285 | - entityName = vm.currentEntity.entityName; | ||
286 | - } | ||
287 | - vm.ctx.actionsApi.handleWidgetAction($event, descriptors[0], entityId, entityName); | 280 | + } |
281 | + var descriptors = vm.ctx.actionsApi.getActionDescriptors('rowClick'); | ||
282 | + if (descriptors.length) { | ||
283 | + var entityId; | ||
284 | + var entityName; | ||
285 | + if (vm.currentEntity) { | ||
286 | + entityId = vm.currentEntity.id; | ||
287 | + entityName = vm.currentEntity.entityName; | ||
288 | } | 288 | } |
289 | + vm.ctx.actionsApi.handleWidgetAction($event, descriptors[0], entityId, entityName); | ||
289 | } | 290 | } |
290 | } | 291 | } |
291 | 292 |