From 8e16a1562a62c87f0e321c3729c7cdd7d434c2a1 Mon Sep 17 00:00:00 2001 From: devaskim Date: Sat, 17 Feb 2024 18:58:11 +0500 Subject: [PATCH 1/3] Implemented cell click action for table widgets. --- .../widget_types/asset_admin_table.json | 2 +- .../widget_types/device_admin_table.json | 2 +- .../system/widget_types/entities_table.json | 2 +- .../entities-table-widget.component.html | 38 ++++++++++++++----- .../entity/entities-table-widget.component.ts | 30 +++++++++++++++ .../assets/locale/locale.constant-en_US.json | 2 + 6 files changed, 63 insertions(+), 13 deletions(-) diff --git a/application/src/main/data/json/system/widget_types/asset_admin_table.json b/application/src/main/data/json/system/widget_types/asset_admin_table.json index 0a2eb2c37a..6e1dc45660 100644 --- a/application/src/main/data/json/system/widget_types/asset_admin_table.json +++ b/application/src/main/data/json/system/widget_types/asset_admin_table.json @@ -11,7 +11,7 @@ "resources": [], "templateHtml": "\n", "templateCss": "", - "controllerScript": "self.onInit = function() {\n}\n\nself.onDataUpdated = function() {\n self.ctx.$scope.entitiesTableWidget.onDataUpdated();\n}\n\nself.typeParameters = function() {\n return {\n maxDatasources: 1,\n hasDataPageLink: true,\n warnOnPageDataOverflow: false,\n dataKeysOptional: true\n };\n}\n\nself.actionSources = function() {\n return {\n 'actionCellButton': {\n name: 'widget-action.action-cell-button',\n multiple: true,\n hasShowCondition: true\n },\n 'rowClick': {\n name: 'widget-action.row-click',\n multiple: false\n },\n 'rowDoubleClick': {\n name: 'widget-action.row-double-click',\n multiple: false\n }\n };\n}\n\nself.onDestroy = function() {\n}\n", + "controllerScript": "self.onInit = function() {\n}\n\nself.onDataUpdated = function() {\n self.ctx.$scope.entitiesTableWidget.onDataUpdated();\n}\n\nself.typeParameters = function() {\n return {\n maxDatasources: 1,\n hasDataPageLink: true,\n warnOnPageDataOverflow: false,\n dataKeysOptional: true\n };\n}\n\nself.actionSources = function() {\n return {\n 'actionCellButton': {\n name: 'widget-action.action-cell-button',\n multiple: true,\n hasShowCondition: true\n },\n 'rowClick': {\n name: 'widget-action.row-click',\n multiple: false\n },\n 'rowDoubleClick': {\n name: 'widget-action.row-double-click',\n multiple: false\n },\n 'cellClick': {\n name: 'widget-action.cell-click',\n multiple: false\n },\n 'cellDoubleClick': {\n name: 'widget-action.cell-double-click',\n multiple: false\n }\n };\n}\n\nself.onDestroy = function() {\n}\n", "settingsSchema": "", "dataKeySettingsSchema": "", "settingsDirective": "tb-entities-table-widget-settings", diff --git a/application/src/main/data/json/system/widget_types/device_admin_table.json b/application/src/main/data/json/system/widget_types/device_admin_table.json index af460a286c..61aecb377d 100644 --- a/application/src/main/data/json/system/widget_types/device_admin_table.json +++ b/application/src/main/data/json/system/widget_types/device_admin_table.json @@ -11,7 +11,7 @@ "resources": [], "templateHtml": "\n", "templateCss": "", - "controllerScript": "self.onInit = function() {\n}\n\nself.onDataUpdated = function() {\n self.ctx.$scope.entitiesTableWidget.onDataUpdated();\n}\n\nself.typeParameters = function() {\n return {\n maxDatasources: 1,\n hasDataPageLink: true,\n warnOnPageDataOverflow: false,\n dataKeysOptional: true\n };\n}\n\nself.actionSources = function() {\n return {\n 'actionCellButton': {\n name: 'widget-action.action-cell-button',\n multiple: true,\n hasShowCondition: true\n },\n 'rowClick': {\n name: 'widget-action.row-click',\n multiple: false\n },\n 'rowDoubleClick': {\n name: 'widget-action.row-double-click',\n multiple: false\n }\n };\n}\n\nself.onDestroy = function() {\n}\n", + "controllerScript": "self.onInit = function() {\n}\n\nself.onDataUpdated = function() {\n self.ctx.$scope.entitiesTableWidget.onDataUpdated();\n}\n\nself.typeParameters = function() {\n return {\n maxDatasources: 1,\n hasDataPageLink: true,\n warnOnPageDataOverflow: false,\n dataKeysOptional: true\n };\n}\n\nself.actionSources = function() {\n return {\n 'actionCellButton': {\n name: 'widget-action.action-cell-button',\n multiple: true,\n hasShowCondition: true\n },\n 'rowClick': {\n name: 'widget-action.row-click',\n multiple: false\n },\n 'rowDoubleClick': {\n name: 'widget-action.row-double-click',\n multiple: false\n },\n 'cellClick': {\n name: 'widget-action.cell-click',\n multiple: false\n },\n 'cellDoubleClick': {\n name: 'widget-action.cell-double-click',\n multiple: false\n }\n };\n}\n\nself.onDestroy = function() {\n}\n", "settingsSchema": "", "dataKeySettingsSchema": "", "settingsDirective": "tb-entities-table-widget-settings", diff --git a/application/src/main/data/json/system/widget_types/entities_table.json b/application/src/main/data/json/system/widget_types/entities_table.json index 1ebf8d4fde..5b8ccc1d50 100644 --- a/application/src/main/data/json/system/widget_types/entities_table.json +++ b/application/src/main/data/json/system/widget_types/entities_table.json @@ -11,7 +11,7 @@ "resources": [], "templateHtml": "\n", "templateCss": "", - "controllerScript": "self.onInit = function() {\n}\n\nself.onDataUpdated = function() {\n self.ctx.$scope.entitiesTableWidget.onDataUpdated();\n}\n\nself.typeParameters = function() {\n return {\n maxDatasources: 1,\n hasDataPageLink: true,\n warnOnPageDataOverflow: false,\n dataKeysOptional: true,\n defaultDataKeysFunction: function() {\n return [{ name: 'name', type: 'entityField' }];\n }\n };\n}\n\nself.actionSources = function() {\n return {\n 'actionCellButton': {\n name: 'widget-action.action-cell-button',\n multiple: true,\n hasShowCondition: true\n },\n 'rowClick': {\n name: 'widget-action.row-click',\n multiple: false\n },\n 'rowDoubleClick': {\n name: 'widget-action.row-double-click',\n multiple: false\n }\n };\n}\n\nself.onDestroy = function() {\n}\n", + "controllerScript": "self.onInit = function() {\n}\n\nself.onDataUpdated = function() {\n self.ctx.$scope.entitiesTableWidget.onDataUpdated();\n}\n\nself.typeParameters = function() {\n return {\n maxDatasources: 1,\n hasDataPageLink: true,\n warnOnPageDataOverflow: false,\n dataKeysOptional: true,\n defaultDataKeysFunction: function() {\n return [{ name: 'name', type: 'entityField' }];\n }\n };\n}\n\nself.actionSources = function() {\n return {\n 'actionCellButton': {\n name: 'widget-action.action-cell-button',\n multiple: true,\n hasShowCondition: true\n },\n 'rowClick': {\n name: 'widget-action.row-click',\n multiple: false\n },\n 'rowDoubleClick': {\n name: 'widget-action.row-double-click',\n multiple: false\n },\n 'cellClick': {\n name: 'widget-action.cell-click',\n multiple: false\n },\n 'cellDoubleClick': {\n name: 'widget-action.cell-double-click',\n multiple: false\n }\n };\n}\n\nself.onDestroy = function() {\n}\n", "settingsSchema": "", "dataKeySettingsSchema": "", "settingsDirective": "tb-entities-table-widget-settings", diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/entity/entities-table-widget.component.html b/ui-ngx/src/app/modules/home/components/widget/lib/entity/entities-table-widget.component.html index 22e79fd526..46ea65141c 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/entity/entities-table-widget.component.html +++ b/ui-ngx/src/app/modules/home/components/widget/lib/entity/entities-table-widget.component.html @@ -42,10 +42,19 @@ matSort [matSortActive]="sortOrderProperty" [matSortDirection]="pageLinkSortDirection()" matSortDisableClear> {{ column.title }} - - + + + + + + + + - + + + + + + ): boolean { + let configured = false; + actionSourceIds.forEach(id => configured = configured || this.ctx.actionsApi.getActionDescriptors(id).length > 0 ); + return configured; + } + ngOnDestroy(): void { if (this.widgetResize$) { this.widgetResize$.disconnect(); @@ -310,6 +317,9 @@ export class EntitiesTableWidgetComponent extends PageComponent implements OnIni cssParser.cssPreviewNamespace = namespace; cssParser.createStyleElement(namespace, cssString); $(this.elementRef.nativeElement).addClass(namespace); + + this.useCellClickAction = this.isActionsConfigured(['cellClick', 'cellDoubleClick']) && + !this.isActionsConfigured(['rowClick', 'rowDoubleClick']); } private updateDatasources() { @@ -687,6 +697,26 @@ export class EntitiesTableWidgetComponent extends PageComponent implements OnIni } } + public onCellClick($event: Event, entity: EntityData, key: EntityColumn, isDouble?: boolean) { + if ($event) { + $event.stopPropagation(); + } + this.entityDatasource.toggleCurrentEntity(entity); + const actionSourceId = isDouble ? 'cellDoubleClick' : 'cellClick'; + const descriptors = this.ctx.actionsApi.getActionDescriptors(actionSourceId); + if (descriptors.length) { + let entityId; + let entityName; + let entityLabel; + if (entity) { + entityId = entity.id; + entityName = entity.entityName; + entityLabel = entity.entityLabel; + } + this.ctx.actionsApi.handleWidgetAction($event, descriptors[0], entityId, entityName, {entity, key}, entityLabel); + } + } + public onRowClick($event: Event, entity: EntityData, isDouble?: boolean) { if ($event) { $event.stopPropagation(); diff --git a/ui-ngx/src/assets/locale/locale.constant-en_US.json b/ui-ngx/src/assets/locale/locale.constant-en_US.json index 288db8c9d2..aca909ad88 100644 --- a/ui-ngx/src/assets/locale/locale.constant-en_US.json +++ b/ui-ngx/src/assets/locale/locale.constant-en_US.json @@ -6911,6 +6911,7 @@ "widget-action": { "action-cell-button": "Action cell button", "row-click": "On row click", + "cell-click": "On cell click", "polygon-click": "On polygon click", "marker-click": "On marker click", "circle-click": "On circle click", @@ -6919,6 +6920,7 @@ "element-click": "On HTML element click", "pie-slice-click": "On slice click", "row-double-click": "On row double click", + "cell-double-click": "On cell double click", "card-click": "On card click", "click": "On click" } From c823a74e20ba02cd47fe5011f4a7d3cb69c4baba Mon Sep 17 00:00:00 2001 From: rusikv Date: Fri, 19 Apr 2024 16:22:39 +0300 Subject: [PATCH 2/3] UI: cell click action type implementation --- .../system/widget_types/alarms_table.json | 2 +- .../widget_types/asset_admin_table.json | 2 +- .../widget_types/device_admin_table.json | 2 +- .../system/widget_types/entities_table.json | 2 +- .../manage-widget-actions.component.models.ts | 2 + .../widget-action-dialog.component.html | 21 +++++++ .../action/widget-action-dialog.component.ts | 58 ++++++++++++++++++- .../alarm/alarms-table-widget.component.html | 6 +- .../alarm/alarms-table-widget.component.ts | 29 ++++++++++ .../entities-table-widget.component.html | 34 +++-------- .../entity/entities-table-widget.component.ts | 27 +++++---- .../widget/widget-config.component.ts | 28 ++++++++- ui-ngx/src/app/shared/models/widget.models.ts | 4 ++ .../assets/locale/locale.constant-en_US.json | 4 ++ ui-ngx/src/styles.scss | 3 + 15 files changed, 178 insertions(+), 46 deletions(-) diff --git a/application/src/main/data/json/system/widget_types/alarms_table.json b/application/src/main/data/json/system/widget_types/alarms_table.json index 5a360bcc32..428bdbd02b 100644 --- a/application/src/main/data/json/system/widget_types/alarms_table.json +++ b/application/src/main/data/json/system/widget_types/alarms_table.json @@ -11,7 +11,7 @@ "resources": [], "templateHtml": "\n", "templateCss": "", - "controllerScript": "self.onInit = function() {\n}\n\nself.onDataUpdated = function() {\n self.ctx.$scope.alarmsTableWidget.onDataUpdated();\n}\n\nself.actionSources = function() {\n return {\n 'actionCellButton': {\n name: 'widget-action.action-cell-button',\n multiple: true,\n hasShowCondition: true\n },\n 'rowClick': {\n name: 'widget-action.row-click',\n multiple: false\n }\n };\n}\n\nself.onDestroy = function() {\n}\n", + "controllerScript": "self.onInit = function() {\n}\n\nself.onDataUpdated = function() {\n self.ctx.$scope.alarmsTableWidget.onDataUpdated();\n}\n\nself.actionSources = function() {\n return {\n 'actionCellButton': {\n name: 'widget-action.action-cell-button',\n multiple: true,\n hasShowCondition: true\n },\n 'rowClick': {\n name: 'widget-action.row-click',\n multiple: false\n },\n 'cellClick': {\n name: 'widget-action.cell-click',\n multiple: true\n }\n };\n}\n\nself.onDestroy = function() {\n}\n", "settingsSchema": "", "dataKeySettingsSchema": "", "settingsDirective": "tb-alarms-table-widget-settings", diff --git a/application/src/main/data/json/system/widget_types/asset_admin_table.json b/application/src/main/data/json/system/widget_types/asset_admin_table.json index 6e1dc45660..1aa671c06b 100644 --- a/application/src/main/data/json/system/widget_types/asset_admin_table.json +++ b/application/src/main/data/json/system/widget_types/asset_admin_table.json @@ -11,7 +11,7 @@ "resources": [], "templateHtml": "\n", "templateCss": "", - "controllerScript": "self.onInit = function() {\n}\n\nself.onDataUpdated = function() {\n self.ctx.$scope.entitiesTableWidget.onDataUpdated();\n}\n\nself.typeParameters = function() {\n return {\n maxDatasources: 1,\n hasDataPageLink: true,\n warnOnPageDataOverflow: false,\n dataKeysOptional: true\n };\n}\n\nself.actionSources = function() {\n return {\n 'actionCellButton': {\n name: 'widget-action.action-cell-button',\n multiple: true,\n hasShowCondition: true\n },\n 'rowClick': {\n name: 'widget-action.row-click',\n multiple: false\n },\n 'rowDoubleClick': {\n name: 'widget-action.row-double-click',\n multiple: false\n },\n 'cellClick': {\n name: 'widget-action.cell-click',\n multiple: false\n },\n 'cellDoubleClick': {\n name: 'widget-action.cell-double-click',\n multiple: false\n }\n };\n}\n\nself.onDestroy = function() {\n}\n", + "controllerScript": "self.onInit = function() {\n}\n\nself.onDataUpdated = function() {\n self.ctx.$scope.entitiesTableWidget.onDataUpdated();\n}\n\nself.typeParameters = function() {\n return {\n maxDatasources: 1,\n hasDataPageLink: true,\n warnOnPageDataOverflow: false,\n dataKeysOptional: true\n };\n}\n\nself.actionSources = function() {\n return {\n 'actionCellButton': {\n name: 'widget-action.action-cell-button',\n multiple: true,\n hasShowCondition: true\n },\n 'rowClick': {\n name: 'widget-action.row-click',\n multiple: false\n },\n 'rowDoubleClick': {\n name: 'widget-action.row-double-click',\n multiple: false\n },\n 'cellClick': {\n name: 'widget-action.cell-click',\n multiple: true\n }\n };\n}\n\nself.onDestroy = function() {\n}\n", "settingsSchema": "", "dataKeySettingsSchema": "", "settingsDirective": "tb-entities-table-widget-settings", diff --git a/application/src/main/data/json/system/widget_types/device_admin_table.json b/application/src/main/data/json/system/widget_types/device_admin_table.json index 61aecb377d..1e4bcd1373 100644 --- a/application/src/main/data/json/system/widget_types/device_admin_table.json +++ b/application/src/main/data/json/system/widget_types/device_admin_table.json @@ -11,7 +11,7 @@ "resources": [], "templateHtml": "\n", "templateCss": "", - "controllerScript": "self.onInit = function() {\n}\n\nself.onDataUpdated = function() {\n self.ctx.$scope.entitiesTableWidget.onDataUpdated();\n}\n\nself.typeParameters = function() {\n return {\n maxDatasources: 1,\n hasDataPageLink: true,\n warnOnPageDataOverflow: false,\n dataKeysOptional: true\n };\n}\n\nself.actionSources = function() {\n return {\n 'actionCellButton': {\n name: 'widget-action.action-cell-button',\n multiple: true,\n hasShowCondition: true\n },\n 'rowClick': {\n name: 'widget-action.row-click',\n multiple: false\n },\n 'rowDoubleClick': {\n name: 'widget-action.row-double-click',\n multiple: false\n },\n 'cellClick': {\n name: 'widget-action.cell-click',\n multiple: false\n },\n 'cellDoubleClick': {\n name: 'widget-action.cell-double-click',\n multiple: false\n }\n };\n}\n\nself.onDestroy = function() {\n}\n", + "controllerScript": "self.onInit = function() {\n}\n\nself.onDataUpdated = function() {\n self.ctx.$scope.entitiesTableWidget.onDataUpdated();\n}\n\nself.typeParameters = function() {\n return {\n maxDatasources: 1,\n hasDataPageLink: true,\n warnOnPageDataOverflow: false,\n dataKeysOptional: true\n };\n}\n\nself.actionSources = function() {\n return {\n 'actionCellButton': {\n name: 'widget-action.action-cell-button',\n multiple: true,\n hasShowCondition: true\n },\n 'rowClick': {\n name: 'widget-action.row-click',\n multiple: false\n },\n 'rowDoubleClick': {\n name: 'widget-action.row-double-click',\n multiple: false\n },\n 'cellClick': {\n name: 'widget-action.cell-click',\n multiple: true\n }\n };\n}\n\nself.onDestroy = function() {\n}\n", "settingsSchema": "", "dataKeySettingsSchema": "", "settingsDirective": "tb-entities-table-widget-settings", diff --git a/application/src/main/data/json/system/widget_types/entities_table.json b/application/src/main/data/json/system/widget_types/entities_table.json index 5b8ccc1d50..dd78933e0b 100644 --- a/application/src/main/data/json/system/widget_types/entities_table.json +++ b/application/src/main/data/json/system/widget_types/entities_table.json @@ -11,7 +11,7 @@ "resources": [], "templateHtml": "\n", "templateCss": "", - "controllerScript": "self.onInit = function() {\n}\n\nself.onDataUpdated = function() {\n self.ctx.$scope.entitiesTableWidget.onDataUpdated();\n}\n\nself.typeParameters = function() {\n return {\n maxDatasources: 1,\n hasDataPageLink: true,\n warnOnPageDataOverflow: false,\n dataKeysOptional: true,\n defaultDataKeysFunction: function() {\n return [{ name: 'name', type: 'entityField' }];\n }\n };\n}\n\nself.actionSources = function() {\n return {\n 'actionCellButton': {\n name: 'widget-action.action-cell-button',\n multiple: true,\n hasShowCondition: true\n },\n 'rowClick': {\n name: 'widget-action.row-click',\n multiple: false\n },\n 'rowDoubleClick': {\n name: 'widget-action.row-double-click',\n multiple: false\n },\n 'cellClick': {\n name: 'widget-action.cell-click',\n multiple: false\n },\n 'cellDoubleClick': {\n name: 'widget-action.cell-double-click',\n multiple: false\n }\n };\n}\n\nself.onDestroy = function() {\n}\n", + "controllerScript": "self.onInit = function() {\n}\n\nself.onDataUpdated = function() {\n self.ctx.$scope.entitiesTableWidget.onDataUpdated();\n}\n\nself.typeParameters = function() {\n return {\n maxDatasources: 1,\n hasDataPageLink: true,\n warnOnPageDataOverflow: false,\n dataKeysOptional: true,\n defaultDataKeysFunction: function() {\n return [{ name: 'name', type: 'entityField' }];\n }\n };\n}\n\nself.actionSources = function() {\n return {\n 'actionCellButton': {\n name: 'widget-action.action-cell-button',\n multiple: true,\n hasShowCondition: true\n },\n 'rowClick': {\n name: 'widget-action.row-click',\n multiple: false\n },\n 'rowDoubleClick': {\n name: 'widget-action.row-double-click',\n multiple: false\n },\n 'cellClick': {\n name: 'widget-action.cell-click',\n multiple: true\n }\n };\n}\n\nself.onDestroy = function() {\n}\n", "settingsSchema": "", "dataKeySettingsSchema": "", "settingsDirective": "tb-entities-table-widget-settings", diff --git a/ui-ngx/src/app/modules/home/components/widget/action/manage-widget-actions.component.models.ts b/ui-ngx/src/app/modules/home/components/widget/action/manage-widget-actions.component.models.ts index 428fb6fa1b..df63694df0 100644 --- a/ui-ngx/src/app/modules/home/components/widget/action/manage-widget-actions.component.models.ts +++ b/ui-ngx/src/app/modules/home/components/widget/action/manage-widget-actions.component.models.ts @@ -15,6 +15,7 @@ /// import { + CellClickColumnInfo, WidgetActionDescriptor, WidgetActionSource, widgetActionTypeTranslationMap @@ -30,6 +31,7 @@ import { deepClone } from '@core/utils'; export interface WidgetActionCallbacks { fetchDashboardStates: (query: string) => Array; + fetchCellClickColumns: () => Array; } export interface WidgetActionsData { diff --git a/ui-ngx/src/app/modules/home/components/widget/action/widget-action-dialog.component.html b/ui-ngx/src/app/modules/home/components/widget/action/widget-action-dialog.component.html index f75b2e44e7..0330ad5621 100644 --- a/ui-ngx/src/app/modules/home/components/widget/action/widget-action-dialog.component.html +++ b/ui-ngx/src/app/modules/home/components/widget/action/widget-action-dialog.component.html @@ -50,6 +50,27 @@ +
+
{{'widget-config.column-index' | translate}}*
+ + + + {{ getCellClickColumnInfo($index, column) }} + + + + warning + + +
{{'widget-config.action-name' | translate}}*
diff --git a/ui-ngx/src/app/modules/home/components/widget/action/widget-action-dialog.component.ts b/ui-ngx/src/app/modules/home/components/widget/action/widget-action-dialog.component.ts index 2c7f94b8d5..230811fbd1 100644 --- a/ui-ngx/src/app/modules/home/components/widget/action/widget-action-dialog.component.ts +++ b/ui-ngx/src/app/modules/home/components/widget/action/widget-action-dialog.component.ts @@ -14,7 +14,7 @@ /// limitations under the License. /// -import { Component, Inject, OnDestroy, OnInit, SkipSelf } from '@angular/core'; +import { Component, Inject, OnDestroy, OnInit, SkipSelf, ViewChild } from '@angular/core'; import { ErrorStateMatcher } from '@angular/material/core'; import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog'; import { Store } from '@ngrx/store'; @@ -40,6 +40,7 @@ import { import { UtilsService } from '@core/services/utils.service'; import { actionDescriptorToAction, + CellClickColumnInfo, defaultWidgetAction, WidgetActionSource, widgetType @@ -47,6 +48,9 @@ import { import { takeUntil } from 'rxjs/operators'; import { CustomActionEditorCompleter } from '@home/components/widget/lib/settings/common/action/custom-action.models'; import { WidgetService } from '@core/http/widget.service'; +import { isDefinedAndNotNull, isNotEmptyStr } from '@core/utils'; +import { MatSelect } from '@angular/material/select'; +import { TranslateService } from '@ngx-translate/core'; export interface WidgetActionDialogData { isAdd: boolean; @@ -78,6 +82,12 @@ export class WidgetActionDialogComponent extends DialogComponent = []; + usedCellClickColumns: Array = []; + + @ViewChild('columnIndexSelect') columnIndexSelect: MatSelect; + columnIndexPlaceholderText = this.translate.instant('widget-config.select-column-index'); + constructor(protected store: Store, protected router: Router, private utils: UtilsService, @@ -85,7 +95,8 @@ export class WidgetActionDialogComponent extends DialogComponent, - public fb: FormBuilder) { + public fb: FormBuilder, + private translate: TranslateService) { super(store, router, dialogRef); this.isAdd = data.isAdd; if (this.isAdd) { @@ -99,11 +110,15 @@ export class WidgetActionDialogComponent extends DialogComponent { + ).subscribe((value) => { this.widgetActionFormGroup.get('name').updateValueAndValidity(); this.updateShowWidgetActionForm(); + if (value === 'cellClick') { + this.widgetActionFormGroup.get('columnIndex').setValidators([Validators.required]); + this.getCellClickColumnsInfo(); + } else { + this.widgetActionFormGroup.get('columnIndex').clearValidators(); + } + this.widgetActionFormGroup.get('columnIndex').updateValueAndValidity(); }); this.widgetActionFormGroup.get('useShowWidgetActionFunction').valueChanges.pipe( takeUntil(this.destroy$) ).subscribe(() => { this.updateShowWidgetActionForm(); }); + setTimeout(() => { + if (this.action?.actionSourceId === 'cellClick' && isDefinedAndNotNull(this.action.columnIndex) && + this.widgetActionFormGroup.get('columnIndex').value === null) { + this.columnIndexPlaceholderText = `${this.action.columnIndex} (${this.translate.instant('widget-config.not-set')})`; + this.columnIndexSelect.focus(); + } + }); } ngOnDestroy() { @@ -155,6 +184,22 @@ export class WidgetActionDialogComponent extends DialogComponent { + const actionColumn = this.configuredColumns[action.columnIndex]; + if (actionColumn && action.columnIndex !== this.action.columnIndex) { + this.usedCellClickColumns.push(action.columnIndex); + } + }); + } + } + private validateActionName(): ValidatorFn { return (c: FormControl) => { const newName = c.value; @@ -193,6 +238,10 @@ export class WidgetActionDialogComponent extends DialogComponent - + {{ column.title }} + [ngStyle]="cellStyle(alarm, column, row)" + (click)="onCellClick($event, alarm, $index)" + [class.tb-pointer]="columnHasCellClick($index)"> diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/alarm/alarms-table-widget.component.ts b/ui-ngx/src/app/modules/home/components/widget/lib/alarm/alarms-table-widget.component.ts index 6cfb5fb406..6d63c23438 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/alarm/alarms-table-widget.component.ts +++ b/ui-ngx/src/app/modules/home/components/widget/lib/alarm/alarms-table-widget.component.ts @@ -204,6 +204,7 @@ export class AlarmsTableWidgetComponent extends PageComponent implements OnInit, private columnWidth: {[key: string]: string} = {}; private columnDefaultVisibility: {[key: string]: boolean} = {}; private columnSelectionAvailability: {[key: string]: boolean} = {}; + private columnsWithCellClick: Array = []; private rowStylesInfo: RowStyleInfo; @@ -351,6 +352,7 @@ export class AlarmsTableWidgetComponent extends PageComponent implements OnInit, this.enableStickyAction = isDefined(this.settings.enableStickyAction) ? this.settings.enableStickyAction : false; this.showCellActionsMenu = isDefined(this.settings.showCellActionsMenu) ? this.settings.showCellActionsMenu : true; this.columnDisplayAction.show = isDefined(this.settings.enableSelectColumnDisplay) ? this.settings.enableSelectColumnDisplay : true; + this.columnsWithCellClick = this.ctx.actionsApi.getActionDescriptors('cellClick').map(action => action.columnIndex); let enableFilter; if (isDefined(this.settings.enableFilter)) { enableFilter = this.settings.enableFilter; @@ -787,6 +789,33 @@ export class AlarmsTableWidgetComponent extends PageComponent implements OnInit, return res; } + public onCellClick($event: Event, alarm: AlarmDataInfo, columnIndex: number) { + this.alarmsDatasource.toggleCurrentAlarm(alarm); + const descriptors = this.ctx.actionsApi.getActionDescriptors('cellClick'); + let descriptor; + if (descriptors.length) { + descriptor = descriptors.find(desc => desc.columnIndex === columnIndex); + } + if ($event && descriptor) { + $event.stopPropagation(); + let entityId; + let entityName; + let entityLabel; + if (alarm && alarm.originator) { + entityId = alarm.originator; + entityName = alarm.entityName; + entityLabel = alarm.entityLabel; + } + this.ctx.actionsApi.handleWidgetAction($event, descriptor, entityId, entityName, {alarm}, entityLabel); + } + } + + public columnHasCellClick(columnIndex: number) { + if (this.columnsWithCellClick.length) { + return this.columnsWithCellClick.includes(columnIndex); + } + } + public onRowClick($event: Event, alarm: AlarmDataInfo) { if ($event) { $event.stopPropagation(); diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/entity/entities-table-widget.component.html b/ui-ngx/src/app/modules/home/components/widget/lib/entity/entities-table-widget.component.html index 46ea65141c..36d58742a6 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/entity/entities-table-widget.component.html +++ b/ui-ngx/src/app/modules/home/components/widget/lib/entity/entities-table-widget.component.html @@ -40,21 +40,14 @@
- + {{ column.title }} - + (click)="onCellClick($event, entity, column, $index)" + [class.tb-pointer]="columnHasCellClick($index)"> - - - - - - - - - - - +
= []; private rowStylesInfo: RowStyleInfo; @@ -284,6 +284,7 @@ export class EntitiesTableWidgetComponent extends PageComponent implements OnIni this.hasRowAction = !!this.ctx.actionsApi.getActionDescriptors('rowClick').length || !!this.ctx.actionsApi.getActionDescriptors('rowDoubleClick').length; + this.columnsWithCellClick = this.ctx.actionsApi.getActionDescriptors('cellClick').map(action => action.columnIndex); if (this.settings.entitiesTitle && this.settings.entitiesTitle.length) { this.ctx.widgetTitle = this.settings.entitiesTitle; @@ -317,9 +318,6 @@ export class EntitiesTableWidgetComponent extends PageComponent implements OnIni cssParser.cssPreviewNamespace = namespace; cssParser.createStyleElement(namespace, cssString); $(this.elementRef.nativeElement).addClass(namespace); - - this.useCellClickAction = this.isActionsConfigured(['cellClick', 'cellDoubleClick']) && - !this.isActionsConfigured(['rowClick', 'rowDoubleClick']); } private updateDatasources() { @@ -697,14 +695,15 @@ export class EntitiesTableWidgetComponent extends PageComponent implements OnIni } } - public onCellClick($event: Event, entity: EntityData, key: EntityColumn, isDouble?: boolean) { - if ($event) { - $event.stopPropagation(); - } + public onCellClick($event: Event, entity: EntityData, key: EntityColumn, columnIndex: number) { this.entityDatasource.toggleCurrentEntity(entity); - const actionSourceId = isDouble ? 'cellDoubleClick' : 'cellClick'; - const descriptors = this.ctx.actionsApi.getActionDescriptors(actionSourceId); + const descriptors = this.ctx.actionsApi.getActionDescriptors('cellClick'); + let descriptor; if (descriptors.length) { + descriptor = descriptors.find(desc => desc.columnIndex === columnIndex); + } + if ($event && descriptor) { + $event.stopPropagation(); let entityId; let entityName; let entityLabel; @@ -713,7 +712,13 @@ export class EntitiesTableWidgetComponent extends PageComponent implements OnIni entityName = entity.entityName; entityLabel = entity.entityLabel; } - this.ctx.actionsApi.handleWidgetAction($event, descriptors[0], entityId, entityName, {entity, key}, entityLabel); + this.ctx.actionsApi.handleWidgetAction($event, descriptor, entityId, entityName, {entity, key}, entityLabel); + } + } + + public columnHasCellClick(index: number) { + if (this.columnsWithCellClick.length) { + return this.columnsWithCellClick.includes(index); } } diff --git a/ui-ngx/src/app/modules/home/components/widget/widget-config.component.ts b/ui-ngx/src/app/modules/home/components/widget/widget-config.component.ts index 5ace8ac616..2914ed4391 100644 --- a/ui-ngx/src/app/modules/home/components/widget/widget-config.component.ts +++ b/ui-ngx/src/app/modules/home/components/widget/widget-config.component.ts @@ -30,6 +30,7 @@ import { PageComponent } from '@shared/components/page.component'; import { Store } from '@ngrx/store'; import { AppState } from '@core/core.state'; import { + CellClickColumnInfo, DataKey, datasourcesHasAggregation, datasourcesHasOnlyComparisonAggregation, @@ -161,7 +162,8 @@ export class WidgetConfigComponent extends PageComponent implements OnInit, OnDe generateDataKey: this.generateDataKey.bind(this), fetchEntityKeysForDevice: this.fetchEntityKeysForDevice.bind(this), fetchEntityKeys: this.fetchEntityKeys.bind(this), - fetchDashboardStates: this.fetchDashboardStates.bind(this) + fetchDashboardStates: this.fetchDashboardStates.bind(this), + fetchCellClickColumns: this.fetchCellClickColumns.bind(this) }; widgetEditMode = this.utils.widgetEditMode; @@ -870,6 +872,30 @@ export class WidgetConfigComponent extends PageComponent implements OnInit, OnDe } } + private fetchCellClickColumns(): Array { + if (this.modelValue) { + const configuredColumns = new Array(); + if (this.modelValue.config?.datasources[0]?.dataKeys?.length) { + configuredColumns.push(...this.keysToCellClickColumns(this.modelValue.config.datasources[0].dataKeys)); + } + if (this.modelValue.config?.alarmSource?.dataKeys?.length) { + configuredColumns.push(...this.keysToCellClickColumns(this.modelValue.config.alarmSource.dataKeys)); + } + return configuredColumns; + } + } + + private keysToCellClickColumns(dataKeys: Array): Array { + const result: Array = []; + for (const dataKey of dataKeys) { + result.push({ + name: dataKey.name, + label: dataKey?.label + }); + } + return result; + } + private createFilterForDashboardState(query: string): (stateId: string) => boolean { const lowercaseQuery = query.toLowerCase(); return stateId => stateId.toLowerCase().indexOf(lowercaseQuery) === 0; diff --git a/ui-ngx/src/app/shared/models/widget.models.ts b/ui-ngx/src/app/shared/models/widget.models.ts index 47605f108b..20f2062c77 100644 --- a/ui-ngx/src/app/shared/models/widget.models.ts +++ b/ui-ngx/src/app/shared/models/widget.models.ts @@ -359,6 +359,8 @@ export interface DataKey extends KeyInfo { _hash?: number; } +export type CellClickColumnInfo = Pick + export enum DataKeyConfigMode { general = 'general', advanced = 'advanced' @@ -686,6 +688,7 @@ export interface WidgetActionDescriptor extends WidgetAction { displayName?: string; useShowWidgetActionFunction?: boolean; showWidgetActionFunction?: string; + columnIndex?: number; } export const actionDescriptorToAction = (descriptor: WidgetActionDescriptor): WidgetAction => { @@ -696,6 +699,7 @@ export const actionDescriptorToAction = (descriptor: WidgetActionDescriptor): Wi delete result.displayName; delete result.useShowWidgetActionFunction; delete result.showWidgetActionFunction; + delete result.columnIndex; return result; }; diff --git a/ui-ngx/src/assets/locale/locale.constant-en_US.json b/ui-ngx/src/assets/locale/locale.constant-en_US.json index 89486eee7e..0e40240688 100644 --- a/ui-ngx/src/assets/locale/locale.constant-en_US.json +++ b/ui-ngx/src/assets/locale/locale.constant-en_US.json @@ -5290,6 +5290,10 @@ "action-source": "Action source", "select-action-source": "Select action source", "action-source-required": "Action source is required.", + "column-index": "Column index", + "select-column-index": "Select column index", + "column-index-required": "Column index is required.", + "not-set": "Not set", "action-name": "Name", "action-name-required": "Action name is required.", "action-name-not-unique": "Another action with the same name already exists.\nAction name should be unique within the same action source.", diff --git a/ui-ngx/src/styles.scss b/ui-ngx/src/styles.scss index 8ca9fe4e37..4d5ae09a15 100644 --- a/ui-ngx/src/styles.scss +++ b/ui-ngx/src/styles.scss @@ -856,6 +856,9 @@ mat-icon { .mat-icon { color: rgba(0, 0, 0, .54); } + &.tb-pointer { + cursor: pointer; + } } .mdc-data-table__row:last-child .mdc-data-table__cell { From 3c9e7b3d027093231ff9b1e92bb1f60a67479bb6 Mon Sep 17 00:00:00 2001 From: rusikv Date: Fri, 3 May 2024 13:33:06 +0300 Subject: [PATCH 3/3] UI: added passing of column into handleWidgetAction additionalParams of onCellClick for alarms table widget --- .../widget/lib/alarm/alarms-table-widget.component.html | 2 +- .../widget/lib/alarm/alarms-table-widget.component.ts | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/alarm/alarms-table-widget.component.html b/ui-ngx/src/app/modules/home/components/widget/lib/alarm/alarms-table-widget.component.html index 71f7debe84..0aca6e05bc 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/alarm/alarms-table-widget.component.html +++ b/ui-ngx/src/app/modules/home/components/widget/lib/alarm/alarms-table-widget.component.html @@ -83,7 +83,7 @@ diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/alarm/alarms-table-widget.component.ts b/ui-ngx/src/app/modules/home/components/widget/lib/alarm/alarms-table-widget.component.ts index 7d6bc454bd..1d1aa533cd 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/alarm/alarms-table-widget.component.ts +++ b/ui-ngx/src/app/modules/home/components/widget/lib/alarm/alarms-table-widget.component.ts @@ -796,7 +796,7 @@ export class AlarmsTableWidgetComponent extends PageComponent implements OnInit, return res; } - public onCellClick($event: Event, alarm: AlarmDataInfo, columnIndex: number) { + public onCellClick($event: Event, alarm: AlarmDataInfo, key: EntityColumn, columnIndex: number) { this.alarmsDatasource.toggleCurrentAlarm(alarm); const descriptors = this.ctx.actionsApi.getActionDescriptors('cellClick'); let descriptor; @@ -813,7 +813,7 @@ export class AlarmsTableWidgetComponent extends PageComponent implements OnInit, entityName = alarm.entityName; entityLabel = alarm.entityLabel; } - this.ctx.actionsApi.handleWidgetAction($event, descriptor, entityId, entityName, {alarm}, entityLabel); + this.ctx.actionsApi.handleWidgetAction($event, descriptor, entityId, entityName, {alarm, key}, entityLabel); } }