From 8ebf5125af9d17ea5bf7373a5b6a1fa600d9e1a6 Mon Sep 17 00:00:00 2001 From: Vladyslav Prykhodko Date: Sun, 2 Mar 2025 22:27:42 +0200 Subject: [PATCH 1/2] UI: Fix process header widget action - place map item --- .../widget/lib/maps/map-widget.component.ts | 2 +- .../home/components/widget/lib/maps/map.ts | 74 ++++++++-------- .../widget/lib/maps/models/map.models.ts | 5 +- .../components/widget/widget.component.ts | 87 +++++++++++-------- 4 files changed, 93 insertions(+), 75 deletions(-) diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/maps/map-widget.component.ts b/ui-ngx/src/app/modules/home/components/widget/lib/maps/map-widget.component.ts index a462a01356..a020bb1527 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/maps/map-widget.component.ts +++ b/ui-ngx/src/app/modules/home/components/widget/lib/maps/map-widget.component.ts @@ -64,7 +64,7 @@ export class MapWidgetComponent implements OnInit, OnDestroy { overlayStyle: ComponentStyle = {}; padding: string; - private map: TbMap; + map: TbMap; constructor(public widgetComponent: WidgetComponent, private imagePipe: ImagePipe, diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/maps/map.ts b/ui-ngx/src/app/modules/home/components/widget/lib/maps/map.ts index 11af4338e9..121277e7da 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/maps/map.ts +++ b/ui-ngx/src/app/modules/home/components/widget/lib/maps/map.ts @@ -33,7 +33,8 @@ import { formattedDataArrayFromDatasourceData, formattedDataFormDatasourceData, isDefined, - isDefinedAndNotNull, isUndefined, + isDefinedAndNotNull, + isUndefined, mergeDeepIgnoreArray } from '@core/utils'; import { DeepPartial } from '@shared/models/common'; @@ -48,7 +49,7 @@ import { UnplacedMapDataItem, } from '@home/components/widget/lib/maps/data-layer/map-data-layer'; import { IWidgetSubscription, WidgetSubscriptionOptions } from '@core/api/widget-api.models'; -import { FormattedData, MapItemType, WidgetAction, WidgetActionType, widgetType } from '@shared/models/widget.models'; +import { FormattedData, MapItemType, WidgetAction, widgetType } from '@shared/models/widget.models'; import { EntityDataPageLink } from '@shared/models/query/query.models'; import { CustomTranslatePipe } from '@shared/pipe/custom-translate.pipe'; import { TbMarkersDataLayer } from '@home/components/widget/lib/maps/data-layer/markers-data-layer'; @@ -545,66 +546,67 @@ export abstract class TbMap { title: customTranslate.transform(actionButton.label) }; const toolbarButton = this.customActionsToolbar.toolbarButton(actionButtonConfig); - if (actionButton.action.type !== WidgetActionType.placeMapItem) { - toolbarButton.onClick((e) => this.ctx.actionsApi.handleWidgetAction(e, actionButton.action)); - } else { - switch (actionButton.action.mapItemType) { - case MapItemType.marker: - toolbarButton.onClick((e, button) => this.createMarker(e, {button, action: actionButton.action})); - break; - case MapItemType.polygon: - toolbarButton.onClick((e, button) => this.createPolygon(e, {button, action: actionButton.action})); - break; - case MapItemType.rectangle: - toolbarButton.onClick((e, button) => this.createRectangle(e, {button, action: actionButton.action})); - break; - case MapItemType.circle: - toolbarButton.onClick((e, button) => this.createCircle(e, {button, action: actionButton.action})); - break; - } - } + toolbarButton.onClick((e, button) => this.ctx.actionsApi.handleWidgetAction(e, actionButton.action, null, null, {button})); }); } } - private createMarker(e: MouseEvent, actionData: CustomActionData) { - this.createItem(e, actionData, () => this.prepareDrawMode('Marker', { + public placeMapItem(actionData: CustomActionData): void { + switch (actionData.action.mapItemType) { + case MapItemType.marker: + this.createMarker(actionData); + break; + case MapItemType.polygon: + this.createPolygon(actionData); + break; + case MapItemType.rectangle: + this.createRectangle(actionData); + break; + case MapItemType.circle: + this.createCircle(actionData); + break; + } + } + + private createMarker(actionData: CustomActionData) { + this.createItem(actionData, () => this.prepareDrawMode('Marker', { placeMarker: this.ctx.translate.instant('widgets.maps.data-layer.marker.place-marker-hint') })); } - private createRectangle(e: MouseEvent, actionData: CustomActionData): void { - this.createItem(e, actionData, () => this.prepareDrawMode('Rectangle', { + private createRectangle(actionData: CustomActionData): void { + this.createItem(actionData, () => this.prepareDrawMode('Rectangle', { firstVertex: this.ctx.translate.instant('widgets.maps.data-layer.polygon.rectangle-place-first-point-hint'), finishRect: this.ctx.translate.instant('widgets.maps.data-layer.polygon.finish-rectangle-hint') })); } - private createPolygon(e: MouseEvent, actionData: CustomActionData): void { - this.createItem(e, actionData, () => this.prepareDrawMode('Polygon', { + private createPolygon(actionData: CustomActionData): void { + this.createItem(actionData, () => this.prepareDrawMode('Polygon', { firstVertex: this.ctx.translate.instant('widgets.maps.data-layer.polygon.polygon-place-first-point-hint'), continueLine: this.ctx.translate.instant('widgets.maps.data-layer.polygon.continue-polygon-hint'), finishPoly: this.ctx.translate.instant('widgets.maps.data-layer.polygon.finish-polygon-hint') })); } - private createCircle(e: MouseEvent, actionData: CustomActionData): void { - this.createItem(e, actionData, () => this.prepareDrawMode('Circle', { + private createCircle(actionData: CustomActionData): void { + this.createItem(actionData, () => this.prepareDrawMode('Circle', { startCircle: this.ctx.translate.instant('widgets.maps.data-layer.circle.place-circle-center-hint'), finishCircle: this.ctx.translate.instant('widgets.maps.data-layer.circle.finish-circle-hint') })); } - private createItem(e: MouseEvent, actionData: CustomActionData, prepareDrawMode: () => void) { + private createItem(actionData: CustomActionData, prepareDrawMode: () => void) { if (this.isPlacingItem) { return; } - this.updatePlaceItemState(actionData.button); + this.updatePlaceItemState(actionData.button, true); this.map.once('pm:create', (e) => { - this.ctx.actionsApi.handleWidgetAction(e as any, actionData.action, null, null, { + actionData.afterPlaceItemCallback(e as any, actionData.action, null, null, { coordinates: convertLayerToCoordinates(actionData.action.mapItemType, e.layer), - layer: e.layer + layer: e.layer, + button: actionData.button }); // @ts-ignore @@ -673,7 +675,7 @@ export abstract class TbMap { L.DomUtil.addClass(this.map.pm.Draw[shape]._hintMarker.getTooltip()._container, 'tb-place-item-label'); } - private updatePlaceItemState(addButton?: L.TB.ToolbarButton): void { + private updatePlaceItemState(addButton?: L.TB.ToolbarButton, disabled = false): void { if (addButton) { this.deselectItem(false, true); addButton.setActive(true); @@ -681,7 +683,7 @@ export abstract class TbMap { this.currentAddButton.setActive(false); } this.currentAddButton = addButton; - this.updateAddButtonsStates(); + this.updateAddButtonsStates(disabled); } private createdControlButtonTooltip(root: HTMLElement, side: TooltipPositioningSide) { @@ -856,8 +858,8 @@ export abstract class TbMap { } } - private updateAddButtonsStates() { - if (this.currentAddButton) { + private updateAddButtonsStates(disabled = false) { + if (this.currentAddButton || disabled) { if (this.addMarkerButton && this.addMarkerButton !== this.currentAddButton) { this.addMarkerButton.setDisabled(true); } diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/maps/models/map.models.ts b/ui-ngx/src/app/modules/home/components/widget/lib/maps/models/map.models.ts index 79fb8a7c04..9863253ff8 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/maps/models/map.models.ts +++ b/ui-ngx/src/app/modules/home/components/widget/lib/maps/models/map.models.ts @@ -34,6 +34,7 @@ import { ImagePipe } from '@shared/pipe/image.pipe'; import { MarkerShape } from '@home/components/widget/lib/maps/models/marker-shape.models'; import { UnplacedMapDataItem } from '@home/components/widget/lib/maps/data-layer/map-data-layer'; import { DateFormatSettings, simpleDateFormat } from '@shared/models/widget-settings.models'; +import { EntityId } from '@shared/models/id/entity-id'; export enum MapType { geoMap = 'geoMap', @@ -1033,8 +1034,10 @@ export interface MarkerIconInfo { } export interface CustomActionData { - button: L.TB.TopToolbarButton; + button?: L.TB.TopToolbarButton; action: WidgetAction; + afterPlaceItemCallback: ($event: Event, descriptor: WidgetAction, entityId?: EntityId, entityName?: string, + additionalParams?: any, entityLabel?: string) => void } export type MapStringFunction = (data: FormattedData, diff --git a/ui-ngx/src/app/modules/home/components/widget/widget.component.ts b/ui-ngx/src/app/modules/home/components/widget/widget.component.ts index 8a9b6e194c..2ac0a6a0e7 100644 --- a/ui-ngx/src/app/modules/home/components/widget/widget.component.ts +++ b/ui-ngx/src/app/modules/home/components/widget/widget.component.ts @@ -125,6 +125,7 @@ import { IModulesMap } from '@modules/common/modules-map.models'; import { DashboardUtilsService } from '@core/services/dashboard-utils.service'; import { CompiledTbFunction, compileTbFunction, isNotEmptyTbFunction } from '@shared/models/js-function.models'; import { HttpClient } from '@angular/common/http'; +import type { MapWidgetComponent } from '@home/components/widget/lib/maps/map-widget.component'; @Component({ selector: 'tb-widget', @@ -1150,44 +1151,17 @@ export class WidgetComponent extends PageComponent implements OnInit, OnChanges, } break; case WidgetActionType.placeMapItem: - case WidgetActionType.customPretty: - const customPrettyFunction = descriptor.customFunction; - const customHtml = descriptor.customHtml; - const customCss = descriptor.customCss; - const customResources = descriptor.customResources; - const actionNamespace = `custom-action-pretty-${guid()}`; - let htmlTemplate = ''; - if (isDefined(customHtml) && customHtml.length > 0) { - htmlTemplate = customHtml; + const mapWidget: MapWidgetComponent = this.widgetContext.$scope.mapWidget + if (mapWidget) { + mapWidget.map.placeMapItem({ + action: descriptor, + afterPlaceItemCallback: this.executeCustomPrettyAction.bind(this), + button: additionalParams?.button + }); } - this.loadCustomActionResources(actionNamespace, customCss, customResources, descriptor).subscribe({ - next: () => { - if (isNotEmptyTbFunction(customPrettyFunction)) { - compileTbFunction(this.http, customPrettyFunction, '$event', 'widgetContext', 'entityId', - 'entityName', 'htmlTemplate', 'additionalParams', 'entityLabel').subscribe( - { - next: (compiled) => { - try { - if (!additionalParams) { - additionalParams = {}; - } - this.widgetContext.customDialog.setAdditionalImports(descriptor.customImports); - compiled.execute($event, this.widgetContext, entityId, entityName, htmlTemplate, additionalParams, entityLabel); - } catch (e) { - console.error(e); - } - }, - error: (err) => { - console.error(err); - } - } - ) - } - }, - error: (errorMessages: string[]) => { - this.processResourcesLoadErrors(errorMessages); - } - }); + break; + case WidgetActionType.customPretty: + this.executeCustomPrettyAction($event, descriptor, entityId, entityName, additionalParams, entityLabel); break; case WidgetActionType.mobileAction: const mobileAction = descriptor.mobileAction; @@ -1559,6 +1533,45 @@ export class WidgetComponent extends PageComponent implements OnInit, OnChanges, this.handleWidgetAction($event, action, entityId, entityName, null, entityLabel); } + private executeCustomPrettyAction($event: Event, descriptor: WidgetAction, entityId?: EntityId, + entityName?: string, additionalParams?: any, entityLabel?: string) { + const customPrettyFunction = descriptor.customFunction; + const customHtml = descriptor.customHtml; + const customCss = descriptor.customCss; + const customResources = descriptor.customResources; + const actionNamespace = `custom-action-pretty-${guid()}`; + let htmlTemplate = ''; + if (isDefined(customHtml) && customHtml.length > 0) { + htmlTemplate = customHtml; + } + this.loadCustomActionResources(actionNamespace, customCss, customResources, descriptor).subscribe({ + next: () => { + if (isNotEmptyTbFunction(customPrettyFunction)) { + compileTbFunction(this.http, customPrettyFunction, '$event', 'widgetContext', 'entityId', + 'entityName', 'htmlTemplate', 'additionalParams', 'entityLabel').subscribe({ + next: (compiled) => { + try { + if (!additionalParams) { + additionalParams = {}; + } + this.widgetContext.customDialog.setAdditionalImports(descriptor.customImports); + compiled.execute($event, this.widgetContext, entityId, entityName, htmlTemplate, additionalParams, entityLabel); + } catch (e) { + console.error(e); + } + }, + error: (err) => { + console.error(err); + } + }); + } + }, + error: (errorMessages: string[]) => { + this.processResourcesLoadErrors(errorMessages); + } + }); + } + private loadCustomActionResources(actionNamespace: string, customCss: string, customResources: Array, actionDescriptor: WidgetAction): Observable { const resourceTasks: Observable[] = []; From c40d8e87975056aca95c6df374b94609964b8c08 Mon Sep 17 00:00:00 2001 From: Vladyslav_Prykhodko Date: Tue, 4 Mar 2025 17:23:53 +0200 Subject: [PATCH 2/2] UI: Refactoring setupCustomActions in map widget --- ui-ngx/src/app/core/api/widget-api.models.ts | 8 +++ .../widget/lib/maps/map-widget.component.ts | 2 +- .../home/components/widget/lib/maps/map.ts | 69 ++++++++++--------- .../widget/lib/maps/models/map.models.ts | 8 --- .../lib/maps/models/marker-shape.models.ts | 15 +++- .../components/widget/widget.component.ts | 17 ++--- 6 files changed, 65 insertions(+), 54 deletions(-) diff --git a/ui-ngx/src/app/core/api/widget-api.models.ts b/ui-ngx/src/app/core/api/widget-api.models.ts index 548f6cd013..7d0f091739 100644 --- a/ui-ngx/src/app/core/api/widget-api.models.ts +++ b/ui-ngx/src/app/core/api/widget-api.models.ts @@ -90,6 +90,13 @@ export interface IWidgetUtils { getEntityDetailsPageURL: (id: string, entityType: EntityType) => string; } +export interface PlaceMapItemActionData { + action: WidgetAction; + additionalParams?: any; + afterPlaceItemCallback: ($event: Event, descriptor: WidgetAction, entityId?: EntityId, entityName?: string, + additionalParams?: any, entityLabel?: string) => void; +} + export interface WidgetActionsApi { actionDescriptorsBySourceId: {[sourceId: string]: Array}; getActionDescriptors: (actionSourceId: string) => Array; @@ -106,6 +113,7 @@ export interface WidgetActionsApi { hideDashboardToolbar?: boolean, preferredPlacement?: PopoverPlacement, hideOnClickOutside?: boolean, popoverWidth?: string, popoverHeight?: string, popoverStyle?: { [klass: string]: any }) => void; + placeMapItem: (action: PlaceMapItemActionData) => void; } export interface AliasInfo { diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/maps/map-widget.component.ts b/ui-ngx/src/app/modules/home/components/widget/lib/maps/map-widget.component.ts index a020bb1527..a462a01356 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/maps/map-widget.component.ts +++ b/ui-ngx/src/app/modules/home/components/widget/lib/maps/map-widget.component.ts @@ -64,7 +64,7 @@ export class MapWidgetComponent implements OnInit, OnDestroy { overlayStyle: ComponentStyle = {}; padding: string; - map: TbMap; + private map: TbMap; constructor(public widgetComponent: WidgetComponent, private imagePipe: ImagePipe, diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/maps/map.ts b/ui-ngx/src/app/modules/home/components/widget/lib/maps/map.ts index 51e0d38089..f279a9fb68 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/maps/map.ts +++ b/ui-ngx/src/app/modules/home/components/widget/lib/maps/map.ts @@ -17,7 +17,6 @@ import { additionalMapDataSourcesToDatasources, BaseMapSettings, - CustomActionData, DataKeyValuePair, MapBooleanFunction, mapDataLayerTypes, @@ -49,8 +48,8 @@ import { TbLatestMapDataLayer, UnplacedMapDataItem, } from '@home/components/widget/lib/maps/data-layer/latest-map-data-layer'; -import { IWidgetSubscription, WidgetSubscriptionOptions } from '@core/api/widget-api.models'; -import { FormattedData, MapItemType, WidgetAction, widgetType } from '@shared/models/widget.models'; +import { IWidgetSubscription, PlaceMapItemActionData, WidgetSubscriptionOptions } from '@core/api/widget-api.models'; +import { FormattedData, MapItemType, WidgetAction, WidgetActionType, widgetType } from '@shared/models/widget.models'; import { EntityDataPageLink } from '@shared/models/query/query.models'; import { CustomTranslatePipe } from '@shared/pipe/custom-translate.pipe'; import { TbMarkersDataLayer } from '@home/components/widget/lib/maps/data-layer/markers-data-layer'; @@ -64,10 +63,9 @@ import { SelectMapEntityPanelComponent } from '@home/components/widget/lib/maps/panels/select-map-entity-panel.component'; import { TbPopoverComponent } from '@shared/components/popover.component'; -import { createColorMarkerShapeURI, MarkerShape } from '@home/components/widget/lib/maps/models/marker-shape.models'; +import { createPlaceItemIcon } from '@home/components/widget/lib/maps/models/marker-shape.models'; import { MatIconRegistry } from '@angular/material/icon'; import { DomSanitizer } from '@angular/platform-browser'; -import tinycolor from 'tinycolor2'; import { MapTimelinePanelComponent } from '@home/components/widget/lib/maps/panels/map-timeline-panel.component'; import { ComponentRef } from '@angular/core'; import { TbTripsDataLayer } from '@home/components/widget/lib/maps/data-layer/trips-data-layer'; @@ -138,6 +136,7 @@ export abstract class TbMap { protected constructor(protected ctx: WidgetContext, protected inputSettings: DeepPartial, protected containerElement: HTMLElement) { + this.ctx.actionsApi.placeMapItem = this.placeMapItem.bind(this); this.settings = mergeDeepIgnoreArray({} as S, this.defaultSettings(), this.inputSettings as S); $(containerElement).empty(); @@ -550,36 +549,40 @@ export abstract class TbMap { } private setupCustomActions() { - if (!this.settings.mapActionButtons) { + const widgetHeaderActions = this.ctx.actionsApi.getActionDescriptors('headerButton'); + const mapActionButtons = this.settings.mapActionButtons; + + const hasMarkerAction = + mapActionButtons?.some(actionButton => actionButton.action.mapItemType === MapItemType.marker) || + widgetHeaderActions.some(action => action.type === WidgetActionType.placeMapItem && action.mapItemType === MapItemType.marker); + + if (hasMarkerAction) { + this.setPlaceMarkerStyle(); + } + + if (!mapActionButtons?.length) { return; } + this.customActionsToolbar = L.TB.topToolbar({ mapElement: $(this.mapElement), iconRegistry: this.ctx.$injector.get(MatIconRegistry) }); - const mapActionButtons = this.settings.mapActionButtons; + const customTranslate = this.ctx.$injector.get(CustomTranslatePipe); - if (mapActionButtons.length) { - const customTranslate = this.ctx.$injector.get(CustomTranslatePipe); - - if (mapActionButtons.some(actionButton => actionButton.action.mapItemType === MapItemType.marker)) { - this.setPlaceMarkerStyle(); - } - - mapActionButtons.forEach(actionButton => { - const actionButtonConfig = { - icon: actionButton.icon, - color: actionButton.color, - title: customTranslate.transform(actionButton.label) - }; - const toolbarButton = this.customActionsToolbar.toolbarButton(actionButtonConfig); - toolbarButton.onClick((e, button) => this.ctx.actionsApi.handleWidgetAction(e, actionButton.action, null, null, {button})); - }); - } + mapActionButtons.forEach(actionButton => { + const actionButtonConfig = { + icon: actionButton.icon, + color: actionButton.color, + title: customTranslate.transform(actionButton.label) + }; + const toolbarButton = this.customActionsToolbar.toolbarButton(actionButtonConfig); + toolbarButton.onClick((e, button) => this.ctx.actionsApi.handleWidgetAction(e, actionButton.action, null, null, {button})); + }); } - public placeMapItem(actionData: CustomActionData): void { + public placeMapItem(actionData: PlaceMapItemActionData): void { switch (actionData.action.mapItemType) { case MapItemType.marker: this.createMarker(actionData); @@ -596,20 +599,20 @@ export abstract class TbMap { } } - private createMarker(actionData: CustomActionData) { + private createMarker(actionData: PlaceMapItemActionData) { this.createItem(actionData, () => this.prepareDrawMode('Marker', { placeMarker: this.ctx.translate.instant('widgets.maps.data-layer.marker.place-marker-hint') })); } - private createRectangle(actionData: CustomActionData): void { + private createRectangle(actionData: PlaceMapItemActionData): void { this.createItem(actionData, () => this.prepareDrawMode('Rectangle', { firstVertex: this.ctx.translate.instant('widgets.maps.data-layer.polygon.rectangle-place-first-point-hint'), finishRect: this.ctx.translate.instant('widgets.maps.data-layer.polygon.finish-rectangle-hint') })); } - private createPolygon(actionData: CustomActionData): void { + private createPolygon(actionData: PlaceMapItemActionData): void { this.createItem(actionData, () => this.prepareDrawMode('Polygon', { firstVertex: this.ctx.translate.instant('widgets.maps.data-layer.polygon.polygon-place-first-point-hint'), continueLine: this.ctx.translate.instant('widgets.maps.data-layer.polygon.continue-polygon-hint'), @@ -617,24 +620,24 @@ export abstract class TbMap { })); } - private createCircle(actionData: CustomActionData): void { + private createCircle(actionData: PlaceMapItemActionData): void { this.createItem(actionData, () => this.prepareDrawMode('Circle', { startCircle: this.ctx.translate.instant('widgets.maps.data-layer.circle.place-circle-center-hint'), finishCircle: this.ctx.translate.instant('widgets.maps.data-layer.circle.finish-circle-hint') })); } - private createItem(actionData: CustomActionData, prepareDrawMode: () => void) { + private createItem(actionData: PlaceMapItemActionData, prepareDrawMode: () => void) { if (this.isPlacingItem) { return; } - this.updatePlaceItemState(actionData.button, true); + this.updatePlaceItemState(actionData.additionalParams?.button, true); this.map.once('pm:create', (e) => { actionData.afterPlaceItemCallback(e as any, actionData.action, null, null, { coordinates: convertLayerToCoordinates(actionData.action.mapItemType, e.layer), layer: e.layer, - button: actionData.button + button: actionData.additionalParams?.button }); // @ts-ignore @@ -916,7 +919,7 @@ export abstract class TbMap { } private setPlaceMarkerStyle() { - createColorMarkerShapeURI(this.getCtx().$injector.get(MatIconRegistry), this.getCtx().$injector.get(DomSanitizer), MarkerShape.markerShape1, tinycolor('rgba(255,255,255,0.75)')).subscribe( + createPlaceItemIcon(this.getCtx().$injector.get(MatIconRegistry), this.getCtx().$injector.get(DomSanitizer)).subscribe( ((iconUrl) => { const icon = L.icon({ iconUrl, diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/maps/models/map.models.ts b/ui-ngx/src/app/modules/home/components/widget/lib/maps/models/map.models.ts index 77a25ddb5f..d28e04b4fc 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/maps/models/map.models.ts +++ b/ui-ngx/src/app/modules/home/components/widget/lib/maps/models/map.models.ts @@ -41,7 +41,6 @@ import { map } from 'rxjs/operators'; import { ImagePipe } from '@shared/pipe/image.pipe'; import { MarkerShape } from '@home/components/widget/lib/maps/models/marker-shape.models'; import { DateFormatSettings, simpleDateFormat } from '@shared/models/widget-settings.models'; -import { EntityId } from '@shared/models/id/entity-id'; export enum MapType { geoMap = 'geoMap', @@ -1035,13 +1034,6 @@ export interface MarkerIconInfo { size: [number, number]; } -export interface CustomActionData { - button?: L.TB.TopToolbarButton; - action: WidgetAction; - afterPlaceItemCallback: ($event: Event, descriptor: WidgetAction, entityId?: EntityId, entityName?: string, - additionalParams?: any, entityLabel?: string) => void -} - export type MapStringFunction = (data: FormattedData, dsData: FormattedData[]) => string; diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/maps/models/marker-shape.models.ts b/ui-ngx/src/app/modules/home/components/widget/lib/maps/models/marker-shape.models.ts index 1948ff6fe7..fa7007b886 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/maps/models/marker-shape.models.ts +++ b/ui-ngx/src/app/modules/home/components/widget/lib/maps/models/marker-shape.models.ts @@ -17,10 +17,10 @@ import tinycolor from 'tinycolor2'; import { MatIconRegistry } from '@angular/material/icon'; import { DomSanitizer } from '@angular/platform-browser'; -import { Observable, of, switchMap } from 'rxjs'; +import { Observable, of, shareReplay, switchMap } from 'rxjs'; import { catchError, map, take } from 'rxjs/operators'; import { isSvgIcon, splitIconName } from '@shared/models/icon.models'; -import { Element, Text, G } from '@svgdotjs/svg.js'; +import { Element, G, Text } from '@svgdotjs/svg.js'; export enum MarkerShape { markerShape1 = 'markerShape1', @@ -203,3 +203,14 @@ export const createColorMarkerIconElement = (iconRegistry: MatIconRegistry, domS ); } +let placeItemIconURI$: Observable; + +export const createPlaceItemIcon= (iconRegistry: MatIconRegistry, domSanitizer: DomSanitizer): Observable => { + if (placeItemIconURI$) { + return placeItemIconURI$; + } + placeItemIconURI$ = createColorMarkerShapeURI(iconRegistry, domSanitizer, MarkerShape.markerShape1, tinycolor('rgba(255,255,255,0.75)')).pipe( + shareReplay({refCount: true, bufferSize: 1}) + ); + return placeItemIconURI$; +} diff --git a/ui-ngx/src/app/modules/home/components/widget/widget.component.ts b/ui-ngx/src/app/modules/home/components/widget/widget.component.ts index 2ac0a6a0e7..da56004ae2 100644 --- a/ui-ngx/src/app/modules/home/components/widget/widget.component.ts +++ b/ui-ngx/src/app/modules/home/components/widget/widget.component.ts @@ -125,7 +125,6 @@ import { IModulesMap } from '@modules/common/modules-map.models'; import { DashboardUtilsService } from '@core/services/dashboard-utils.service'; import { CompiledTbFunction, compileTbFunction, isNotEmptyTbFunction } from '@shared/models/js-function.models'; import { HttpClient } from '@angular/common/http'; -import type { MapWidgetComponent } from '@home/components/widget/lib/maps/map-widget.component'; @Component({ selector: 'tb-widget', @@ -274,7 +273,8 @@ export class WidgetComponent extends PageComponent implements OnInit, OnChanges, click: this.click.bind(this), getActiveEntityInfo: this.getActiveEntityInfo.bind(this), openDashboardStateInSeparateDialog: this.openDashboardStateInSeparateDialog.bind(this), - openDashboardStateInPopover: this.openDashboardStateInPopover.bind(this) + openDashboardStateInPopover: this.openDashboardStateInPopover.bind(this), + placeMapItem: () => {} }; this.widgetContext.customHeaderActions = []; @@ -1151,14 +1151,11 @@ export class WidgetComponent extends PageComponent implements OnInit, OnChanges, } break; case WidgetActionType.placeMapItem: - const mapWidget: MapWidgetComponent = this.widgetContext.$scope.mapWidget - if (mapWidget) { - mapWidget.map.placeMapItem({ - action: descriptor, - afterPlaceItemCallback: this.executeCustomPrettyAction.bind(this), - button: additionalParams?.button - }); - } + this.widgetContext.actionsApi.placeMapItem({ + action: descriptor, + afterPlaceItemCallback: this.executeCustomPrettyAction.bind(this), + additionalParams: additionalParams + }); break; case WidgetActionType.customPretty: this.executeCustomPrettyAction($event, descriptor, entityId, entityName, additionalParams, entityLabel);