{{ 'widgets.maps.common.common-map-settings' | translate }}
diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/map/map-settings.component.ts b/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/map/map-settings.component.ts
index 710af3478b..c79d6b914c 100644
--- a/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/map/map-settings.component.ts
+++ b/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/map/map-settings.component.ts
@@ -139,7 +139,8 @@ export class MapSettingsComponent implements OnInit, ControlValueAccessor, Valid
useDefaultCenterPosition: [null, []],
defaultCenterPosition: [null, []],
defaultZoomLevel: [null, [Validators.min(0), Validators.max(20)]],
- mapPageSize: [null, [Validators.min(1), Validators.required]]
+ mapPageSize: [null, [Validators.min(1), Validators.required]],
+ mapActionButtons: [null]
});
this.mapSettingsFormGroup.valueChanges.pipe(
takeUntilDestroyed(this.destroyRef)
diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/widget-settings-common.module.ts b/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/widget-settings-common.module.ts
index 933536e86e..536623e86b 100644
--- a/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/widget-settings-common.module.ts
+++ b/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/widget-settings-common.module.ts
@@ -236,6 +236,12 @@ import {
import {
MapTooltipTagActionsComponent
} from '@home/components/widget/lib/settings/common/map/map-tooltip-tag-actions.component';
+import {
+ MapActionButtonsSettingsComponent
+} from '@home/components/widget/lib/settings/common/map/map-action-buttons-settings.component';
+import {
+ MapActionButtonRowComponent
+} from '@home/components/widget/lib/settings/common/map/map-action-button-row.component';
@NgModule({
declarations: [
@@ -313,6 +319,8 @@ import {
DataLayerColorSettingsComponent,
DataLayerColorSettingsPanelComponent,
MapTooltipTagActionsComponent,
+ MapActionButtonsSettingsComponent,
+ MapActionButtonRowComponent,
DataLayerPatternSettingsComponent,
MarkerShapeSettingsComponent,
MarkerShapesComponent,
diff --git a/ui-ngx/src/app/modules/home/components/widget/widget-component.service.ts b/ui-ngx/src/app/modules/home/components/widget/widget-component.service.ts
index fd23239eca..1a397d3a1f 100644
--- a/ui-ngx/src/app/modules/home/components/widget/widget-component.service.ts
+++ b/ui-ngx/src/app/modules/home/components/widget/widget-component.service.ts
@@ -40,11 +40,12 @@ import {
migrateWidgetTypeToDynamicForms,
Widget,
widgetActionSources,
+ WidgetActionType,
WidgetControllerDescriptor,
WidgetType
} from '@shared/models/widget.models';
import { catchError, map, mergeMap, switchMap, tap } from 'rxjs/operators';
-import { isFunction, isUndefined } from '@core/utils';
+import { isDefinedAndNotNull, isFunction, isUndefined } from '@core/utils';
import { TranslateService } from '@ngx-translate/core';
import { DynamicWidgetComponent } from '@home/components/widget/dynamic-widget.component';
import { WidgetComponentsModule } from '@home/components/widget/widget-components.module';
@@ -654,6 +655,13 @@ export class WidgetComponentService {
if (isUndefined(result.typeParameters.targetDeviceOptional)) {
result.typeParameters.targetDeviceOptional = false;
}
+ if (isDefinedAndNotNull(result.typeParameters.additionalWidgetActionTypes)) {
+ if (Array.isArray(result.typeParameters.additionalWidgetActionTypes)) {
+ result.typeParameters.additionalWidgetActionTypes = result.typeParameters.additionalWidgetActionTypes.filter(type => WidgetActionType[type]);
+ } else {
+ result.typeParameters.additionalWidgetActionTypes = null;
+ }
+ }
if (isFunction(widgetTypeInstance.actionSources)) {
result.actionSources = widgetTypeInstance.actionSources();
} else {
diff --git a/ui-ngx/src/app/modules/home/components/widget/widget-config.component.html b/ui-ngx/src/app/modules/home/components/widget/widget-config.component.html
index a3d924fe08..ae4e35aa9c 100644
--- a/ui-ngx/src/app/modules/home/components/widget/widget-config.component.html
+++ b/ui-ngx/src/app/modules/home/components/widget/widget-config.component.html
@@ -164,6 +164,7 @@
[callbacks]="widgetConfigCallbacks"
[widgetType] = "modelValue.widgetType"
[actionSources]="modelValue.actionSources"
+ [additionalWidgetActionTypes]="modelValue.typeParameters.additionalWidgetActionTypes"
formControlName="actions">
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 ad52d57436..8a9b6e194c 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
@@ -1149,6 +1149,7 @@ export class WidgetComponent extends PageComponent implements OnInit, OnChanges,
)
}
break;
+ case WidgetActionType.placeMapItem:
case WidgetActionType.customPretty:
const customPrettyFunction = descriptor.customFunction;
const customHtml = descriptor.customHtml;
diff --git a/ui-ngx/src/app/shared/models/widget.models.ts b/ui-ngx/src/app/shared/models/widget.models.ts
index 1510fe6a8d..415d400523 100644
--- a/ui-ngx/src/app/shared/models/widget.models.ts
+++ b/ui-ngx/src/app/shared/models/widget.models.ts
@@ -192,6 +192,7 @@ export interface WidgetTypeParameters {
dataKeySettingsFunction?: DataKeySettingsFunction;
displayRpcMessageToast?: boolean;
targetDeviceOptional?: boolean;
+ additionalWidgetActionTypes?: WidgetActionType[];
}
export interface WidgetControllerDescriptor {
@@ -576,7 +577,8 @@ export enum WidgetActionType {
custom = 'custom',
customPretty = 'customPretty',
mobileAction = 'mobileAction',
- openURL = 'openURL'
+ openURL = 'openURL',
+ placeMapItem = 'placeMapItem'
}
export enum WidgetMobileActionType {
@@ -590,7 +592,15 @@ export enum WidgetMobileActionType {
takeScreenshot = 'takeScreenshot'
}
-export const widgetActionTypes = Object.keys(WidgetActionType) as WidgetActionType[];
+export enum MapItemType {
+ marker = 'marker',
+ polygon = 'polygon',
+ rectangle = 'rectangle',
+ circle = 'circle'
+}
+
+export const widgetActionTypes = Object.keys(WidgetActionType)
+ .filter(value => value !== WidgetActionType.placeMapItem) as WidgetActionType[];
export const widgetActionTypeTranslationMap = new Map
(
[
@@ -601,7 +611,8 @@ export const widgetActionTypeTranslationMap = new Map(
[ WidgetActionType.custom, 'widget-action.custom' ],
[ WidgetActionType.customPretty, 'widget-action.custom-pretty' ],
[ WidgetActionType.mobileAction, 'widget-action.mobile-action' ],
- [ WidgetActionType.openURL, 'widget-action.open-URL' ]
+ [ WidgetActionType.openURL, 'widget-action.open-URL' ],
+ [ WidgetActionType.placeMapItem, 'widget-action.place-map-item' ],
]
);
@@ -618,6 +629,15 @@ export const widgetMobileActionTypeTranslationMap = new Map(
+ [
+ [ MapItemType.marker, 'widget-action.map-item.marker' ],
+ [ MapItemType.polygon, 'widget-action.map-item.polygon' ],
+ [ MapItemType.rectangle, 'widget-action.map-item.rectangle' ],
+ [ MapItemType.circle, 'widget-action.map-item.circle' ],
+ ]
+)
+
export interface MobileLaunchResult {
launched: boolean;
}
@@ -715,6 +735,7 @@ export interface WidgetAction extends CustomActionDescriptor {
stateEntityParamName?: string;
mobileAction?: WidgetMobileActionDescriptor;
url?: string;
+ mapItemType?: MapItemType;
}
export interface WidgetActionDescriptor extends WidgetAction {
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 dfe60066e0..cc6acce2b2 100644
--- a/ui-ngx/src/assets/locale/locale.constant-en_US.json
+++ b/ui-ngx/src/assets/locale/locale.constant-en_US.json
@@ -6426,7 +6426,15 @@
"take-screenshot": "Take screenshot"
},
"custom-action-function": "Custom action function",
- "custom-pretty-function": "Custom action (with HTML template) function"
+ "custom-pretty-function": "Custom action (with HTML template) function",
+ "map-item-type": "Map item type",
+ "map-item": {
+ "marker": "Marker",
+ "polygon": "Polygon",
+ "rectangle": "Rectangle",
+ "circle": "Circle"
+ },
+ "place-map-item": "Place map item"
},
"widgets-bundle": {
"current": "Current bundle",
@@ -7698,6 +7706,18 @@
"zoom-double-click": "Double click",
"zoom-control-buttons": "Control buttons"
},
+ "map-action": {
+ "map-action-buttons": "Map action buttons",
+ "label": "Label",
+ "icon": "Icon",
+ "color": "Color",
+ "action": "Action",
+ "add-button": "Add button",
+ "no-action-buttons-configured": "No action buttons configured",
+ "remove-action-button": "Remove action button",
+ "map-action-button": "Map action button",
+ "button-requires": "Button requires label or icon"
+ },
"common": {
"common-map-settings": "Common map settings",
"fit-map-bounds": "Fit map bounds to cover all markers",
@@ -7856,7 +7876,8 @@
"edit": "Edit marker",
"remove-marker-for": "Remove marker for '{{entityName}}'",
"place-marker": "Place marker",
- "place-marker-hint": "Click to place '{{entityName}}' entity"
+ "place-marker-hint": "Click to place marker",
+ "place-marker-hint-with-entity": "Click to place '{{entityName}}' entity"
},
"path": {
"decorator-symbol-arrow-head": "Arrow",
@@ -7878,11 +7899,16 @@
"polygon-place-first-point-cut-hint": "Click to place first point",
"continue-polygon-cut-hint": "Click to continue drawing",
"finish-polygon-cut-hint": "Click first marker to finish and save",
- "polygon-place-first-point-hint": "Polygon for '{{entityName}}': click to place first point",
- "continue-polygon-hint": "Polygon for '{{entityName}}': click to continue drawing",
- "finish-polygon-hint": "Polygon for '{{entityName}}': click first marker to finish and save",
- "rectangle-place-first-point-hint": "Rectangle for '{{entityName}}': click to place first point",
- "finish-rectangle-hint": "Rectangle for '{{entityName}}': click to finish and save"
+ "polygon-place-first-point-hint": "Polygon: click to place first point",
+ "polygon-place-first-point-hint-with-entity": "Polygon for '{{entityName}}': click to place first point",
+ "continue-polygon-hint": "Polygon: click to continue drawing",
+ "continue-polygon-hint-with-entity": "Polygon for '{{entityName}}': click to continue drawing",
+ "finish-polygon-hint": "Polygon: click first marker to finish drawing",
+ "finish-polygon-hint-with-entity": "Polygon for '{{entityName}}': click first marker to finish and save",
+ "rectangle-place-first-point-hint": "Rectangle: click to place first point",
+ "rectangle-place-first-point-hint-with-entity": "Rectangle for '{{entityName}}': click to place first point",
+ "finish-rectangle-hint": "Rectangle: click to finish drawing",
+ "finish-rectangle-hint-with-entity": "Rectangle for '{{entityName}}': click to finish and save"
},
"circle": {
"circle-key": "Circle key",
@@ -7894,8 +7920,10 @@
"edit": "Edit circle",
"remove-circle-for": "Remove circle for '{{entityName}}'",
"draw-circle": "Draw circle",
- "place-circle-center-hint": "Circle for '{{entityName}}': click to place circle center",
- "finish-circle-hint": "Circle for '{{entityName}}': click to finish and save circle"
+ "place-circle-center-hint-with-entity": "Circle for '{{entityName}}': click to place circle center",
+ "place-circle-center-hint": "Circle: click to place circle center",
+ "finish-circle-hint-with-entity": "Circle for '{{entityName}}': click to finish and save circle",
+ "finish-circle-hint": "Circle: click to finish drawing"
},
"select-entity": "Select entity",
"select-entity-hint": "Hint: after selection click at the map to set position"
diff --git a/ui-ngx/src/typings/leaflet-extend-tb.d.ts b/ui-ngx/src/typings/leaflet-extend-tb.d.ts
index 7eec52a0ce..de63139bd7 100644
--- a/ui-ngx/src/typings/leaflet-extend-tb.d.ts
+++ b/ui-ngx/src/typings/leaflet-extend-tb.d.ts
@@ -17,6 +17,7 @@
import { FormattedData } from '@shared/models/widget.models';
import L, { Control, ControlOptions } from 'leaflet';
import { TbMapDatasource } from '@home/components/widget/lib/maps/models/map.models';
+import { MatIconRegistry } from '@angular/material/icon';
// redeclare module, maintains compatibility with @types/leaflet
declare module 'leaflet' {
@@ -91,22 +92,28 @@ declare module 'leaflet' {
interface TopToolbarButtonOptions {
icon: string;
- iconColor?: string;
+ color?: string;
title: string;
}
class TopToolbarButton {
- constructor(options: TopToolbarButtonOptions);
- onClick(onClick: (e: MouseEvent) => void): void;
+ constructor(options: TopToolbarButtonOptions, iconRegistry: MatIconRegistry);
+ onClick(onClick: (e: MouseEvent, button: TopToolbarButton) => void): void;
+ setActive(active: boolean): void;
+ isActive(): boolean;
+ setDisabled(disabled: boolean): void;
+ isDisabled(): boolean;
}
interface TopToolbarControlOptions {
mapElement: JQuery;
+ iconRegistry: MatIconRegistry;
}
class TopToolbarControl {
constructor(options: TopToolbarControlOptions);
toolbarButton(options: TopToolbarButtonOptions): TopToolbarButton;
+ setDisabled(disabled: boolean): void;
}
interface ToolbarButtonOptions {