Merge pull request #10600 from rusikv/feature/cell-click-action

Cell click action type
This commit is contained in:
Igor Kulikov 2024-05-08 15:32:10 +03:00 committed by GitHub
commit 9e3f3429e8
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
15 changed files with 197 additions and 15 deletions

View File

@ -11,7 +11,7 @@
"resources": [],
"templateHtml": "<tb-alarms-table-widget \n [ctx]=\"ctx\">\n</tb-alarms-table-widget>",
"templateCss": "",
"controllerScript": "self.onInit = function() {\n}\n\nself.onDataUpdated = function() {\n self.ctx.$scope.alarmsTableWidget.onDataUpdated();\n}\n\nself.onEditModeChanged = function() {\n self.ctx.$scope.alarmsTableWidget.onEditModeChanged();\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.onEditModeChanged = function() {\n self.ctx.$scope.alarmsTableWidget.onEditModeChanged();\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: false\n }\n };\n}\n\nself.onDestroy = function() {\n}\n",
"settingsSchema": "",
"dataKeySettingsSchema": "",
"settingsDirective": "tb-alarms-table-widget-settings",

View File

@ -11,7 +11,7 @@
"resources": [],
"templateHtml": "<tb-entities-table-widget \n [ctx]=\"ctx\">\n</tb-entities-table-widget>",
"templateCss": "",
"controllerScript": "self.onInit = function() {\n}\n\nself.onDataUpdated = function() {\n self.ctx.$scope.entitiesTableWidget.onDataUpdated();\n}\n\nself.onEditModeChanged = function() {\n self.ctx.$scope.entitiesTableWidget.onEditModeChanged();\n}\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.onEditModeChanged = function() {\n self.ctx.$scope.entitiesTableWidget.onEditModeChanged();\n}\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 };\n}\n\nself.onDestroy = function() {\n}\n",
"settingsSchema": "",
"dataKeySettingsSchema": "",
"settingsDirective": "tb-entities-table-widget-settings",

View File

@ -11,7 +11,7 @@
"resources": [],
"templateHtml": "<tb-entities-table-widget \n [ctx]=\"ctx\">\n</tb-entities-table-widget>",
"templateCss": "",
"controllerScript": "self.onInit = function() {\n}\n\nself.onDataUpdated = function() {\n self.ctx.$scope.entitiesTableWidget.onDataUpdated();\n}\n\nself.onEditModeChanged = function() {\n self.ctx.$scope.entitiesTableWidget.onEditModeChanged();\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.onEditModeChanged = function() {\n self.ctx.$scope.entitiesTableWidget.onEditModeChanged();\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 };\n}\n\nself.onDestroy = function() {\n}\n",
"settingsSchema": "",
"dataKeySettingsSchema": "",
"settingsDirective": "tb-entities-table-widget-settings",

View File

@ -11,7 +11,7 @@
"resources": [],
"templateHtml": "<tb-entities-table-widget \n [ctx]=\"ctx\">\n</tb-entities-table-widget>",
"templateCss": "",
"controllerScript": "self.onInit = function() {\n}\n\nself.onDataUpdated = function() {\n self.ctx.$scope.entitiesTableWidget.onDataUpdated();\n}\n\nself.onEditModeChanged = function() {\n self.ctx.$scope.entitiesTableWidget.onEditModeChanged();\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.onEditModeChanged = function() {\n self.ctx.$scope.entitiesTableWidget.onEditModeChanged();\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 };\n}\n\nself.onDestroy = function() {\n}\n",
"settingsSchema": "",
"dataKeySettingsSchema": "",
"settingsDirective": "tb-entities-table-widget-settings",

View File

@ -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<string>;
fetchCellClickColumns: () => Array<CellClickColumnInfo>;
}
export interface WidgetActionsData {

View File

@ -50,6 +50,27 @@
</mat-icon>
</mat-form-field>
</div>
<div class="tb-form-row" *ngIf="widgetActionFormGroup.get('actionSourceId').value === 'cellClick'">
<div class="fixed-title-width">{{'widget-config.column-index' | translate}}*</div>
<mat-form-field fxFlex appearance="outline" subscriptSizing="dynamic">
<mat-select #columnIndexSelect formControlName="columnIndex" placeholder="{{ columnIndexPlaceholderText }}">
<mat-option *ngFor="let column of configuredColumns; let $index = index"
[value]="$index"
[disabled]="usedCellClickColumns.includes($index)">
{{ getCellClickColumnInfo($index, column) }}
</mat-option>
</mat-select>
<mat-icon matSuffix
matTooltipPosition="above"
matTooltipClass="tb-error-tooltip"
[matTooltip]="'widget-config.column-index-required' | translate"
*ngIf="widgetActionFormGroup.get('columnIndex').hasError('required') &&
widgetActionFormGroup.get('columnIndex').touched"
class="tb-error">
warning
</mat-icon>
</mat-form-field>
</div>
<div class="tb-form-row">
<div class="fixed-title-width">{{'widget-config.action-name' | translate}}*</div>
<mat-form-field fxFlex appearance="outline" subscriptSizing="dynamic">

View File

@ -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<WidgetActionDia
functionScopeVariables: string[];
configuredColumns: Array<CellClickColumnInfo> = [];
usedCellClickColumns: Array<number> = [];
@ViewChild('columnIndexSelect') columnIndexSelect: MatSelect;
columnIndexPlaceholderText = this.translate.instant('widget-config.select-column-index');
constructor(protected store: Store<AppState>,
protected router: Router,
private utils: UtilsService,
@ -85,7 +95,8 @@ export class WidgetActionDialogComponent extends DialogComponent<WidgetActionDia
@Inject(MAT_DIALOG_DATA) public data: WidgetActionDialogData,
@SkipSelf() private errorStateMatcher: ErrorStateMatcher,
public dialogRef: MatDialogRef<WidgetActionDialogComponent, WidgetActionDescriptorInfo>,
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<WidgetActionDia
this.action = this.data.action;
}
this.functionScopeVariables = this.widgetService.getWidgetScopeVariables();
if (this.action.actionSourceId === 'cellClick') {
this.getCellClickColumnsInfo();
}
}
ngOnInit(): void {
this.widgetActionFormGroup = this.fb.group({
actionSourceId: [this.action.actionSourceId, Validators.required],
columnIndex: [this.checkColumnIndex(this.action.columnIndex), Validators.required],
name: [this.action.name, [this.validateActionName(), Validators.required]],
icon: [this.action.icon, Validators.required],
useShowWidgetActionFunction: [this.action.useShowWidgetActionFunction],
@ -113,15 +128,29 @@ export class WidgetActionDialogComponent extends DialogComponent<WidgetActionDia
this.updateShowWidgetActionForm();
this.widgetActionFormGroup.get('actionSourceId').valueChanges.pipe(
takeUntil(this.destroy$)
).subscribe(() => {
).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<WidgetActionDia
this.widgetActionFormGroup.get('showWidgetActionFunction').updateValueAndValidity();
}
private checkColumnIndex(columnIndex: number): number | null {
return isDefinedAndNotNull(columnIndex) && this.configuredColumns.length - 1 < columnIndex ? null : columnIndex;
}
private getCellClickColumnsInfo(): void {
if (!this.configuredColumns.length) {
this.configuredColumns = this.data.callbacks.fetchCellClickColumns();
this.data.actionsData.actionsMap['cellClick']?.forEach(action => {
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<WidgetActionDia
}
}
public getCellClickColumnInfo(index: number, columnInfo: CellClickColumnInfo): string {
return `${index} (${isNotEmptyStr(columnInfo.label) ? columnInfo.label : columnInfo.name})`;
}
cancel(): void {
this.dialogRef.close(null);
}
@ -204,6 +253,9 @@ export class WidgetActionDialogComponent extends DialogComponent<WidgetActionDia
{...this.widgetActionFormGroup.value, ...this.widgetActionFormGroup.get('widgetAction').value};
delete (result as any).widgetAction;
result.id = this.action.id;
if (!isDefinedAndNotNull(result.columnIndex)) {
delete result.columnIndex;
}
this.dialogRef.close(result);
}
}

View File

@ -77,12 +77,14 @@
</mat-checkbox>
</mat-cell>
</ng-container>
<ng-container [matColumnDef]="column.def" *ngFor="let column of columns; trackBy: trackByColumnDef;">
<ng-container [matColumnDef]="column.def" *ngFor="let column of columns; let $index = index; trackBy: trackByColumnDef;">
<mat-header-cell [ngStyle]="headerStyle(column)" *matHeaderCellDef mat-sort-header [disabled]="isSorting(column)">
{{ column.title }}
</mat-header-cell>
<mat-cell *matCellDef="let alarm; let row = index"
[ngStyle]="cellStyle(alarm, column, row)">
[ngStyle]="cellStyle(alarm, column, row)"
(click)="onCellClick($event, alarm, column, $index)"
[class.tb-pointer]="columnHasCellClick($index)">
<span [innerHTML]="cellContent(alarm, column, row)"></span>
<ng-container *ngIf="column.entityKey.key === 'assignee'">
<span class="assignee-cell" fxLayout="row" fxLayoutAlign="start center">

View File

@ -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<number> = [];
private rowStylesInfo: RowStyleInfo;
@ -358,6 +359,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;
@ -794,6 +796,33 @@ export class AlarmsTableWidgetComponent extends PageComponent implements OnInit,
return res;
}
public onCellClick($event: Event, alarm: AlarmDataInfo, key: EntityColumn, 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, key}, entityLabel);
}
}
public columnHasCellClick(columnIndex: number) {
if (this.columnsWithCellClick.length) {
return this.columnsWithCellClick.includes(columnIndex);
}
}
public onRowClick($event: Event, alarm: AlarmDataInfo) {
if ($event) {
$event.stopPropagation();

View File

@ -40,12 +40,14 @@
<div fxFlex class="table-container">
<table mat-table [dataSource]="entityDatasource" [trackBy]="trackByEntityId"
matSort [matSortActive]="sortOrderProperty" [matSortDirection]="pageLinkSortDirection()" matSortDisableClear>
<ng-container [matColumnDef]="column.def" *ngFor="let column of columns; trackBy: trackByColumnDef;">
<ng-container [matColumnDef]="column.def" *ngFor="let column of columns; let $index = index; trackBy: trackByColumnDef;">
<mat-header-cell [ngStyle]="headerStyle(column)" *matHeaderCellDef mat-sort-header [disabled]="!column.sortable"> {{ column.title }} </mat-header-cell>
<mat-cell *matCellDef="let entity; let row = index"
[innerHTML]="cellContent(entity, column, row)"
[ngStyle]="cellStyle(entity, column, row)">
</mat-cell>
<mat-cell *matCellDef="let entity; let row = index"
[innerHTML]="cellContent(entity, column, row)"
[ngStyle]="cellStyle(entity, column, row)"
(click)="onCellClick($event, entity, column, $index)"
[class.tb-pointer]="columnHasCellClick($index)">
</mat-cell>
</ng-container>
<ng-container matColumnDef="actions" [stickyEnd]="enableStickyAction">
<mat-header-cell *matHeaderCellDef [ngStyle.gt-md]="{ minWidth: (entityDatasource.countCellButtonAction * 48) + 'px',

View File

@ -169,6 +169,7 @@ export class EntitiesTableWidgetComponent extends PageComponent implements OnIni
private columnWidth: {[key: string]: string} = {};
private columnDefaultVisibility: {[key: string]: boolean} = {};
private columnSelectionAvailability: {[key: string]: boolean} = {};
private columnsWithCellClick: Array<number> = [];
private rowStylesInfo: RowStyleInfo;
@ -230,6 +231,12 @@ export class EntitiesTableWidgetComponent extends PageComponent implements OnIni
}
}
private isActionsConfigured(actionSourceIds: Array<string>): 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();
@ -284,6 +291,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;
@ -694,6 +702,33 @@ export class EntitiesTableWidgetComponent extends PageComponent implements OnIni
}
}
public onCellClick($event: Event, entity: EntityData, key: EntityColumn, columnIndex: number) {
this.entityDatasource.toggleCurrentEntity(entity);
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 (entity) {
entityId = entity.id;
entityName = entity.entityName;
entityLabel = entity.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);
}
}
public onRowClick($event: Event, entity: EntityData, isDouble?: boolean) {
if ($event) {
$event.stopPropagation();

View File

@ -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<CellClickColumnInfo> {
if (this.modelValue) {
const configuredColumns = new Array<CellClickColumnInfo>();
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<DataKey>): Array<CellClickColumnInfo> {
const result: Array<CellClickColumnInfo> = [];
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;

View File

@ -359,6 +359,8 @@ export interface DataKey extends KeyInfo {
_hash?: number;
}
export type CellClickColumnInfo = Pick<DataKey, 'name' | 'label'>
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;
};

View File

@ -5461,6 +5461,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.",
@ -7465,6 +7469,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",
@ -7473,6 +7478,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"
}

View File

@ -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 {