diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/action/custom-action-pretty-editor.component.html b/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/action/custom-action-pretty-editor.component.html
index 0d53bc6c44..abcc4ad7af 100644
--- a/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/action/custom-action-pretty-editor.component.html
+++ b/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/action/custom-action-pretty-editor.component.html
@@ -37,6 +37,7 @@
@@ -44,6 +45,7 @@
@@ -58,7 +60,7 @@
[validationArgs]="[]"
[editorCompleter]="customPrettyActionEditorCompleter"
functionTitle="{{ 'widget-action.custom-pretty-function' | translate }}"
- helpId="widget/action/custom_pretty_action_fn">
+ [helpId]="helpId">
diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/action/custom-action-pretty-editor.component.ts b/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/action/custom-action-pretty-editor.component.ts
index 2e177eb918..77f835a668 100644
--- a/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/action/custom-action-pretty-editor.component.ts
+++ b/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/action/custom-action-pretty-editor.component.ts
@@ -14,28 +14,22 @@
/// limitations under the License.
///
-// eslint-disable-next-line @typescript-eslint/triple-slash-reference
-///
-
import {
AfterViewInit,
Component,
ElementRef,
forwardRef,
Input,
- OnDestroy,
- OnInit,
QueryList,
ViewChildren,
ViewEncapsulation
} from '@angular/core';
import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';
-import { PageComponent } from '@shared/components/page.component';
-import { Store } from '@ngrx/store';
-import { AppState } from '@core/core.state';
import { combineLatest } from 'rxjs';
-import { CustomActionDescriptor } from '@shared/models/widget.models';
-import { CustomPrettyActionEditorCompleter } from '@home/components/widget/lib/settings/common/action/custom-action.models';
+import { CustomActionDescriptor, WidgetActionType } from '@shared/models/widget.models';
+import {
+ CustomPrettyActionEditorCompleter
+} from '@home/components/widget/lib/settings/common/action/custom-action.models';
@Component({
selector: 'tb-custom-action-pretty-editor',
@@ -50,7 +44,7 @@ import { CustomPrettyActionEditorCompleter } from '@home/components/widget/lib/s
],
encapsulation: ViewEncapsulation.None
})
-export class CustomActionPrettyEditorComponent extends PageComponent implements OnInit, AfterViewInit, OnDestroy, ControlValueAccessor {
+export class CustomActionPrettyEditorComponent implements AfterViewInit, ControlValueAccessor {
@Input() disabled: boolean;
@@ -58,6 +52,17 @@ export class CustomActionPrettyEditorComponent extends PageComponent implements
fullscreen = false;
+ helpId= 'widget/action/custom_pretty_action_fn';
+
+ @Input()
+ set widgetActionType(type: WidgetActionType) {
+ if (type === WidgetActionType.placeMapItem) {
+ this.helpId = 'widget/action/place_map_item/place_map_item_action';
+ } else {
+ this.helpId = 'widget/action/custom_pretty_action_fn';
+ }
+ }
+
@ViewChildren('leftPanel')
leftPanelElmRef: QueryList>;
@@ -68,15 +73,11 @@ export class CustomActionPrettyEditorComponent extends PageComponent implements
private propagateChange = (_: any) => {};
- constructor(protected store: Store) {
- super(store);
- }
-
- ngOnInit(): void {
+ constructor() {
}
ngAfterViewInit(): void {
- combineLatest(this.leftPanelElmRef.changes, this.rightPanelElmRef.changes).subscribe(() => {
+ combineLatest([this.leftPanelElmRef.changes, this.rightPanelElmRef.changes]).subscribe(() => {
if (this.leftPanelElmRef.length && this.rightPanelElmRef.length) {
this.initSplitLayout(this.leftPanelElmRef.first.nativeElement,
this.rightPanelElmRef.first.nativeElement);
@@ -92,14 +93,11 @@ export class CustomActionPrettyEditorComponent extends PageComponent implements
});
}
- ngOnDestroy(): void {
- }
-
registerOnChange(fn: any): void {
this.propagateChange = fn;
}
- registerOnTouched(fn: any): void {
+ registerOnTouched(_fn: any): void {
}
setDisabledState(isDisabled: boolean): void {
diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/action/custom-action-pretty-resources-tabs.component.html b/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/action/custom-action-pretty-resources-tabs.component.html
index 9f351345c1..0852e7cc0d 100644
--- a/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/action/custom-action-pretty-resources-tabs.component.html
+++ b/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/action/custom-action-pretty-resources-tabs.component.html
@@ -101,7 +101,7 @@
[validationArgs]="[]"
[editorCompleter]="customPrettyActionEditorCompleter"
functionTitle="{{ 'widget-action.custom-pretty-function' | translate }}"
- helpId="widget/action/custom_pretty_action_fn">
+ [helpId]="helpId">
diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/action/custom-action-pretty-resources-tabs.component.ts b/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/action/custom-action-pretty-resources-tabs.component.ts
index 5c65e23b58..367f90d160 100644
--- a/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/action/custom-action-pretty-resources-tabs.component.ts
+++ b/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/action/custom-action-pretty-resources-tabs.component.ts
@@ -27,16 +27,15 @@ import {
ViewChild,
ViewEncapsulation
} from '@angular/core';
-import { TranslateService } from '@ngx-translate/core';
import { PageComponent } from '@shared/components/page.component';
-import { Store } from '@ngrx/store';
-import { AppState } from '@core/core.state';
import { CustomActionDescriptor } from '@shared/models/widget.models';
import { Ace } from 'ace-builds';
import { CancelAnimationFrame, RafService } from '@core/services/raf.service';
-import { CustomPrettyActionEditorCompleter } from '@home/components/widget/lib/settings/common/action/custom-action.models';
+import {
+ CustomPrettyActionEditorCompleter
+} from '@home/components/widget/lib/settings/common/action/custom-action.models';
import { Observable } from 'rxjs/internal/Observable';
-import { forkJoin, from } from 'rxjs';
+import { forkJoin } from 'rxjs';
import { map, tap } from 'rxjs/operators';
import { getAce } from '@shared/models/ace/ace.models';
import { beautifyCss, beautifyHtml } from '@shared/models/beautify.models';
@@ -55,6 +54,9 @@ export class CustomActionPrettyResourcesTabsComponent extends PageComponent impl
@Input()
hasCustomFunction: boolean;
+ @Input()
+ helpId: string;
+
@Output()
actionUpdated: EventEmitter = new EventEmitter();
@@ -76,10 +78,8 @@ export class CustomActionPrettyResourcesTabsComponent extends PageComponent impl
customPrettyActionEditorCompleter = CustomPrettyActionEditorCompleter;
- constructor(protected store: Store,
- private translate: TranslateService,
- private raf: RafService) {
- super(store);
+ constructor(private raf: RafService) {
+ super();
}
ngOnInit(): void {
diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/action/custom-action.models.ts b/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/action/custom-action.models.ts
index 1b63e97ad6..40f1a6c819 100644
--- a/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/action/custom-action.models.ts
+++ b/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/action/custom-action.models.ts
@@ -22,6 +22,8 @@ import { deepClone, isDefined, isUndefined } from '@core/utils';
import customSampleJs from './custom-sample-js.raw';
import customSampleCss from './custom-sample-css.raw';
import customSampleHtml from './custom-sample-html.raw';
+import placeMapItemSampleHtml from './place-map-item-sample-html.raw';
+import placeMapItemSampleJs from './place-map-item-sample-js.raw';
const customActionCompletions: TbEditorCompletions = {
...{
@@ -96,5 +98,15 @@ export const toCustomAction = (action: WidgetAction): CustomActionDescriptor =>
return result;
};
+export const toPlaceMapItemAction = (action: WidgetAction): CustomActionDescriptor => {
+ const result: CustomActionDescriptor = {
+ customHtml: action?.customHtml ?? placeMapItemSampleHtml,
+ customCss: action?.customCss ?? '',
+ customFunction: action?.customFunction ?? placeMapItemSampleJs
+ };
+ result.customResources = isDefined(action?.customResources) ? deepClone(action.customResources) : [];
+ return result;
+};
+
export const CustomActionEditorCompleter = new TbEditorCompleter(customActionCompletions);
export const CustomPrettyActionEditorCompleter = new TbEditorCompleter(customPrettyActionCompletions);
diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/action/place-map-item-sample-html.raw b/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/action/place-map-item-sample-html.raw
new file mode 100644
index 0000000000..bb36a39986
--- /dev/null
+++ b/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/action/place-map-item-sample-html.raw
@@ -0,0 +1,82 @@
+
+
+
+
+
diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/action/place-map-item-sample-js.raw b/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/action/place-map-item-sample-js.raw
new file mode 100644
index 0000000000..cb8c23faee
--- /dev/null
+++ b/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/action/place-map-item-sample-js.raw
@@ -0,0 +1,89 @@
+/*========================================================================*/
+/*========================= Add entity example =========================*/
+/*========================================================================*/
+
+let $injector = widgetContext.$scope.$injector;
+let customDialog = $injector.get(widgetContext.servicesMap.get('customDialog'));
+let assetService = $injector.get(widgetContext.servicesMap.get('assetService'));
+let deviceService = $injector.get(widgetContext.servicesMap.get('deviceService'));
+let attributeService = $injector.get(widgetContext.servicesMap.get('attributeService'));
+
+openAddEntityDialog();
+
+function openAddEntityDialog() {
+ customDialog.customDialog(htmlTemplate, AddEntityDialogController).subscribe();
+}
+
+function AddEntityDialogController(instance) {
+ let vm = instance;
+
+ vm.allowedEntityTypes = ['ASSET', 'DEVICE'];
+
+ vm.addEntityFormGroup = vm.fb.group({
+ entityName: ['', [vm.validators.required]],
+ entityType: ['DEVICE'],
+ entityLabel: [null],
+ type: ['', [vm.validators.required]],
+ attributes: vm.fb.group({
+ address: [null],
+ owner: [null]
+ })
+ });
+
+ vm.cancel = function() {
+ vm.dialogRef.close(null);
+ };
+
+ vm.save = function() {
+ vm.addEntityFormGroup.markAsPristine();
+ saveEntityObservable().pipe(
+ widgetContext.rxjs.switchMap((entity) => saveAttributes(entity.id))
+ ).subscribe(() => {
+ widgetContext.updateAliases();
+ vm.dialogRef.close(null);
+ });
+ };
+
+ function saveEntityObservable() {
+ const formValues = vm.addEntityFormGroup.value;
+ let entity = {
+ name: formValues.entityName,
+ type: formValues.type,
+ label: formValues.entityLabel
+ };
+ if (formValues.entityType == 'ASSET') {
+ return assetService.saveAsset(entity);
+ } else if (formValues.entityType == 'DEVICE') {
+ return deviceService.saveDevice(entity);
+ }
+ }
+
+ function saveAttributes(entityId) {
+ let attributes = vm.addEntityFormGroup.get('attributes').value;
+ let attributesArray = getMapItemLocationAttributes();
+ for (let key in attributes) {
+ if(attributes[key] !== null) {
+ attributesArray.push({key: key, value: attributes[key]});
+ }
+ }
+ if (attributesArray.length > 0) {
+ return attributeService.saveEntityAttributes(entityId, "SERVER_SCOPE", attributesArray);
+ }
+ return widgetContext.rxjs.of([]);
+ }
+
+ function getMapItemLocationAttributes() {
+ const attributes = [];
+ const mapItemType = $event.shape;
+ if (mapItemType === 'Marker') {
+ const mapType = widgetContext.mapInstance.type();
+ attributes.push({key: mapType === 'image' ? 'xPos' : 'latitude', value: additionalParams.coordinates.x});
+ attributes.push({key: mapType === 'image' ? 'yPos' : 'longitude', value: additionalParams.coordinates.y});
+ } else if (mapItemType === 'Rectangle' || mapItemType === 'Polygon') {
+ attributes.push({key: 'perimeter', value: additionalParams.coordinates});
+ } else if (mapItemType === 'Circle') {
+ attributes.push({key: 'circle', value: additionalParams.coordinates});
+ }
+ return attributes;
+ }
+}
diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/action/widget-action.component.html b/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/action/widget-action.component.html
index ca2405b8b4..c4c90067dd 100644
--- a/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/action/widget-action.component.html
+++ b/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/action/widget-action.component.html
@@ -274,7 +274,8 @@
|| widgetActionFormGroup.get('type').value === widgetActionType.placeMapItem
? widgetActionFormGroup.get('type').value : ''">
+ [widgetActionType]="widgetActionFormGroup.get('type').value"
+ formControlName="customAction">
diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/action/widget-action.component.ts b/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/action/widget-action.component.ts
index 932c0e52c3..bd0fe36910 100644
--- a/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/action/widget-action.component.ts
+++ b/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/action/widget-action.component.ts
@@ -48,7 +48,8 @@ import { TranslateService } from '@ngx-translate/core';
import { PopoverPlacement, PopoverPlacements } from '@shared/components/popover.models';
import {
CustomActionEditorCompleter,
- toCustomAction
+ toCustomAction,
+ toPlaceMapItemAction
} from '@home/components/widget/lib/settings/common/action/custom-action.models';
import { coerceBoolean } from '@shared/decorators/coercion';
@@ -336,7 +337,7 @@ export class WidgetActionComponent implements ControlValueAccessor, OnInit, Vali
);
this.actionTypeFormGroup.addControl(
'customAction',
- this.fb.control(toCustomAction(action), [Validators.required])
+ this.fb.control(toPlaceMapItemAction(action), [Validators.required])
);
break;
}
diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/map/map-data-layer-dialog.component.html b/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/map/map-data-layer-dialog.component.html
index 803cdd01f1..cc2d3ab031 100644
--- a/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/map/map-data-layer-dialog.component.html
+++ b/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/map/map-data-layer-dialog.component.html
@@ -430,7 +430,7 @@
}
diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/map/map-settings.component.html b/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/map/map-settings.component.html
index 38a5d13922..b8d9515564 100644
--- a/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/map/map-settings.component.html
+++ b/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/map/map-settings.component.html
@@ -36,7 +36,7 @@