diff --git a/ui-ngx/src/app/core/services/dashboard-utils.service.ts b/ui-ngx/src/app/core/services/dashboard-utils.service.ts index dca6dd45eb..1511840c57 100644 --- a/ui-ngx/src/app/core/services/dashboard-utils.service.ts +++ b/ui-ngx/src/app/core/services/dashboard-utils.service.ts @@ -31,7 +31,8 @@ import { DashboardLayoutsInfo, DashboardState, DashboardStateLayouts, - GridSettings, LayoutType, + GridSettings, + LayoutType, WidgetLayout } from '@shared/models/dashboard.models'; import { deepClone, isDefined, isDefinedAndNotNull, isNotEmptyStr, isString, isUndefined } from '@core/utils'; @@ -61,6 +62,7 @@ import { MediaBreakpoints } from '@shared/models/constants'; import { TranslateService } from '@ngx-translate/core'; import { DashboardPageLayout } from '@home/components/dashboard-page/dashboard-page.models'; import { maxGridsterCol, maxGridsterRow } from '@home/models/dashboard-component.models'; +import { findWidgetModelDefinition } from '@shared/models/widget/widget-model.definition'; @Injectable({ providedIn: 'root' @@ -398,6 +400,14 @@ export class DashboardUtilsService { return datasources; } + public getWidgetDatasources(widget: Widget): Datasource[] { + const widgetDefinition = findWidgetModelDefinition(widget); + if (widgetDefinition) { + return widgetDefinition.datasources(widget); + } + return this.validateAndUpdateDatasources(widget.config.datasources); + } + public createDefaultLayoutData(): DashboardLayout { return { widgets: {}, diff --git a/ui-ngx/src/app/core/services/item-buffer.service.ts b/ui-ngx/src/app/core/services/item-buffer.service.ts index cef9bbe7a3..d525bee677 100644 --- a/ui-ngx/src/app/core/services/item-buffer.service.ts +++ b/ui-ngx/src/app/core/services/item-buffer.service.ts @@ -35,7 +35,7 @@ import { FcRuleNode, ruleNodeTypeDescriptors } from '@shared/models/rule-node.mo import { RuleChainService } from '@core/http/rule-chain.service'; import { RuleChainImport } from '@shared/models/rule-chain.models'; import { Filter, FilterInfo, Filters, FiltersInfo, getFilterId } from '@shared/models/query/query.models'; -import { getWidgetExportDefinition } from '@shared/models/widget/widget-export.models'; +import { findWidgetModelDefinition } from '@shared/models/widget/widget-model.definition'; const WIDGET_ITEM = 'widget_item'; const WIDGET_REFERENCE = 'widget_reference'; @@ -142,7 +142,7 @@ export class ItemBufferService { } } let widgetExportInfo: any; - const exportDefinition = getWidgetExportDefinition(widget); + const exportDefinition = findWidgetModelDefinition(widget); if (exportDefinition) { widgetExportInfo = exportDefinition.prepareExportInfo(dashboard, widget); } @@ -270,7 +270,7 @@ export class ItemBufferService { let callFilterUpdateFunction = false; let newEntityAliases: EntityAliases; let newFilters: Filters; - const exportDefinition = getWidgetExportDefinition(widget); + const exportDefinition = findWidgetModelDefinition(widget); if (exportDefinition && widgetExportInfo || aliasesInfo) { newEntityAliases = deepClone(dashboard.configuration.entityAliases); } diff --git a/ui-ngx/src/app/modules/home/components/alias/entity-aliases-dialog.component.ts b/ui-ngx/src/app/modules/home/components/alias/entity-aliases-dialog.component.ts index 235a41876d..f7bb87455a 100644 --- a/ui-ngx/src/app/modules/home/components/alias/entity-aliases-dialog.component.ts +++ b/ui-ngx/src/app/modules/home/components/alias/entity-aliases-dialog.component.ts @@ -14,7 +14,7 @@ /// limitations under the License. /// -import { Component, DestroyRef, Inject, OnInit, SkipSelf } from '@angular/core'; +import { Component, DestroyRef, Inject, SkipSelf } from '@angular/core'; import { ErrorStateMatcher } from '@angular/material/core'; import { MAT_DIALOG_DATA, MatDialog, MatDialogRef } from '@angular/material/dialog'; import { Store } from '@ngrx/store'; @@ -60,7 +60,7 @@ export interface EntityAliasesDialogData { styleUrls: ['./entity-aliases-dialog.component.scss'] }) export class EntityAliasesDialogComponent extends DialogComponent - implements OnInit, ErrorStateMatcher { + implements ErrorStateMatcher { title: string; disableAdd: boolean; @@ -107,8 +107,7 @@ export class EntityAliasesDialogComponent extends DialogComponent { + this.dashboardUtils.getWidgetDatasources(widget).forEach((datasource) => { if ([DatasourceType.entity, DatasourceType.entityCount, DatasourceType.alarmCount].includes(datasource.type) && datasource.entityAliasId) { this.addWidgetTitleToWidgetsMap(datasource.entityAliasId, widget.config.title); @@ -143,7 +142,9 @@ export class EntityAliasesDialogComponent extends DialogComponent - implements OnInit, ErrorStateMatcher { + implements ErrorStateMatcher { title: string; disableAdd: boolean; @@ -96,15 +96,16 @@ export class FiltersDialogComponent extends DialogComponent { - const datasources = this.dashboardUtils.validateAndUpdateDatasources(widget.config.datasources); - datasources.forEach((datasource) => { - if (datasource.type === DatasourceType.entity && datasource.filterId) { + this.dashboardUtils.getWidgetDatasources(widget).forEach((datasource) => { + if (datasource.type !== DatasourceType.function && datasource.filterId) { widgetsTitleList = this.filterToWidgetsMap[datasource.filterId]; if (!widgetsTitleList) { widgetsTitleList = []; this.filterToWidgetsMap[datasource.filterId] = widgetsTitleList; } - widgetsTitleList.push(widget.config.title); + if (!widgetsTitleList.includes(widget.config.title)) { + widgetsTitleList.push(widget.config.title); + } } }); }); @@ -140,9 +141,6 @@ export class FiltersDialogComponent extends DialogComponent = { +export const MapModelDefinition: WidgetModelDefinition = { testWidget(widget: Widget): boolean { if (widget?.config?.settings) { const settings = widget.config.settings; @@ -103,6 +104,26 @@ export const MapExportDefinition: WidgetExportDefinition = { if (info?.additionalDataSources) { updateMapDatasourceFromExportInfo(entityAliases, filters, settings.additionalDataSources, info.additionalDataSources); } + }, + datasources(widget: Widget): Datasource[] { + const settings: BaseMapSettings = widget.config.settings as BaseMapSettings; + const datasources: Datasource[] = []; + if (settings.trips?.length) { + datasources.push(...getMapDataLayersDatasources(settings.trips)); + } + if (settings.markers?.length) { + datasources.push(...getMapDataLayersDatasources(settings.markers)); + } + if (settings.polygons?.length) { + datasources.push(...getMapDataLayersDatasources(settings.polygons)); + } + if (settings.circles?.length) { + datasources.push(...getMapDataLayersDatasources(settings.circles)); + } + if (settings.additionalDataSources?.length) { + datasources.push(...getMapDataLayersDatasources(settings.additionalDataSources)); + } + return datasources; } }; @@ -189,3 +210,16 @@ const prepareAliasAndFilterPair = (dashboard: Dashboard, settings: MapDataSource return null; } } + +const getMapDataLayersDatasources = (settings: MapDataLayerSettings[] | MapDataSourceSettings[]): Datasource[] => { + const datasources: Datasource[] = []; + settings.forEach((dsSettings) => { + datasources.push(mapDataSourceSettingsToDatasource(dsSettings)); + if ((dsSettings as MapDataLayerSettings).additionalDataSources?.length) { + (dsSettings as MapDataLayerSettings).additionalDataSources.forEach((ds) => { + datasources.push(mapDataSourceSettingsToDatasource(ds)); + }); + } + }); + return datasources; +}; diff --git a/ui-ngx/src/app/shared/models/widget/widget-export.models.ts b/ui-ngx/src/app/shared/models/widget/widget-model.definition.ts similarity index 68% rename from ui-ngx/src/app/shared/models/widget/widget-export.models.ts rename to ui-ngx/src/app/shared/models/widget/widget-model.definition.ts index 5b47010285..1b54240c09 100644 --- a/ui-ngx/src/app/shared/models/widget/widget-export.models.ts +++ b/ui-ngx/src/app/shared/models/widget/widget-model.definition.ts @@ -14,22 +14,23 @@ /// limitations under the License. /// -import { Widget } from '@shared/models/widget.models'; +import { Datasource, Widget } from '@shared/models/widget.models'; import { Dashboard } from '@shared/models/dashboard.models'; import { EntityAliases } from '@shared/models/alias.models'; import { Filters } from '@shared/models/query/query.models'; -import { MapExportDefinition } from '@shared/models/widget/maps/map-export.models'; +import { MapModelDefinition } from '@shared/models/widget/maps/map-model.definition'; -export interface WidgetExportDefinition { +export interface WidgetModelDefinition { testWidget(widget: Widget): boolean; prepareExportInfo(dashboard: Dashboard, widget: Widget): T; updateFromExportInfo(widget: Widget, entityAliases: EntityAliases, filters: Filters, info: T): void; + datasources(widget: Widget): Datasource[]; } -const widgetExportDefinitions: WidgetExportDefinition[] = [ - MapExportDefinition +const widgetModelRegistry: WidgetModelDefinition[] = [ + MapModelDefinition ]; -export const getWidgetExportDefinition = (widget: Widget): WidgetExportDefinition => { - return widgetExportDefinitions.find(def => def.testWidget(widget)); +export const findWidgetModelDefinition = (widget: Widget): WidgetModelDefinition => { + return widgetModelRegistry.find(def => def.testWidget(widget)); }