UI: Add new predefined example when created action place map item
This commit is contained in:
parent
c9ef125911
commit
c25b57eb39
@ -22,6 +22,8 @@ import { deepClone, isDefined, isUndefined } from '@core/utils';
|
|||||||
import customSampleJs from './custom-sample-js.raw';
|
import customSampleJs from './custom-sample-js.raw';
|
||||||
import customSampleCss from './custom-sample-css.raw';
|
import customSampleCss from './custom-sample-css.raw';
|
||||||
import customSampleHtml from './custom-sample-html.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 = {
|
const customActionCompletions: TbEditorCompletions = {
|
||||||
...{
|
...{
|
||||||
@ -96,5 +98,15 @@ export const toCustomAction = (action: WidgetAction): CustomActionDescriptor =>
|
|||||||
return result;
|
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 CustomActionEditorCompleter = new TbEditorCompleter(customActionCompletions);
|
||||||
export const CustomPrettyActionEditorCompleter = new TbEditorCompleter(customPrettyActionCompletions);
|
export const CustomPrettyActionEditorCompleter = new TbEditorCompleter(customPrettyActionCompletions);
|
||||||
|
|||||||
@ -0,0 +1,82 @@
|
|||||||
|
<!--========================================================================-->
|
||||||
|
<!--========================= Add entity example =========================-->
|
||||||
|
<!--========================================================================-->
|
||||||
|
|
||||||
|
<form #addEntityForm="ngForm" [formGroup]="addEntityFormGroup"
|
||||||
|
(ngSubmit)="save()" style="width: 552px">
|
||||||
|
<mat-toolbar class="flex flex-row" color="primary">
|
||||||
|
<h2>Add entity</h2>
|
||||||
|
<span class="flex-1"></span>
|
||||||
|
<button mat-icon-button (click)="cancel()" type="button">
|
||||||
|
<mat-icon class="material-icons">close</mat-icon>
|
||||||
|
</button>
|
||||||
|
</mat-toolbar>
|
||||||
|
<mat-progress-bar color="warn" mode="indeterminate" *ngIf="isLoading$ | async">
|
||||||
|
</mat-progress-bar>
|
||||||
|
<div style="height: 4px;" *ngIf="!(isLoading$ | async)"></div>
|
||||||
|
<div mat-dialog-content class="flex flex-col" style="padding-bottom: 0">
|
||||||
|
<div class="flex flex-row gap-2 xs:flex-col xs:gap-0">
|
||||||
|
<mat-form-field class="mat-block flex-1" appearance="outline">
|
||||||
|
<mat-label>Entity Name</mat-label>
|
||||||
|
<input matInput formControlName="entityName" required>
|
||||||
|
<mat-error *ngIf="addEntityFormGroup.get('entityName').hasError('required')">
|
||||||
|
Entity name is required.
|
||||||
|
</mat-error>
|
||||||
|
</mat-form-field>
|
||||||
|
<mat-form-field class="mat-block flex-1" appearance="outline">
|
||||||
|
<mat-label>Entity Label</mat-label>
|
||||||
|
<input matInput formControlName="entityLabel" >
|
||||||
|
</mat-form-field>
|
||||||
|
</div>
|
||||||
|
<div class="flex flex-row gap-2 xs:flex-col xs:gap-0">
|
||||||
|
<tb-entity-type-select
|
||||||
|
class="mat-block flex-1"
|
||||||
|
formControlName="entityType"
|
||||||
|
[showLabel]="true"
|
||||||
|
[appearance]="'outline'"
|
||||||
|
[allowedEntityTypes]="allowedEntityTypes"
|
||||||
|
></tb-entity-type-select>
|
||||||
|
<tb-entity-subtype-autocomplete
|
||||||
|
*ngIf="addEntityFormGroup.get('entityType').value == 'ASSET'"
|
||||||
|
class="mat-block flex-1"
|
||||||
|
formControlName="type"
|
||||||
|
[required]="true"
|
||||||
|
[entityType]="'ASSET'"
|
||||||
|
[appearance]="'outline'"
|
||||||
|
></tb-entity-subtype-autocomplete>
|
||||||
|
<tb-entity-subtype-autocomplete
|
||||||
|
*ngIf="addEntityFormGroup.get('entityType').value != 'ASSET'"
|
||||||
|
class="mat-block flex-1"
|
||||||
|
formControlName="type"
|
||||||
|
[required]="true"
|
||||||
|
[entityType]="'DEVICE'"
|
||||||
|
[appearance]="'outline'"
|
||||||
|
></tb-entity-subtype-autocomplete>
|
||||||
|
</div>
|
||||||
|
<div formGroupName="attributes" class="flex flex-col">
|
||||||
|
<div class="flex flex-row gap-2 xs:flex-col xs:gap-0">
|
||||||
|
<mat-form-field class="mat-block flex-1" appearance="outline">
|
||||||
|
<mat-label>Address</mat-label>
|
||||||
|
<input matInput formControlName="address">
|
||||||
|
</mat-form-field>
|
||||||
|
<mat-form-field class="mat-block flex-1" appearance="outline">
|
||||||
|
<mat-label>Owner</mat-label>
|
||||||
|
<input matInput formControlName="owner">
|
||||||
|
</mat-form-field>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div mat-dialog-actions class="flex flex-row items-center justify-end">
|
||||||
|
<button mat-button color="primary"
|
||||||
|
type="button"
|
||||||
|
[disabled]="(isLoading$ | async)"
|
||||||
|
(click)="cancel()" cdkFocusInitial>
|
||||||
|
Cancel
|
||||||
|
</button>
|
||||||
|
<button mat-button mat-raised-button color="primary"
|
||||||
|
type="submit"
|
||||||
|
[disabled]="(isLoading$ | async) || addEntityForm.invalid || !addEntityForm.dirty">
|
||||||
|
Create
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -48,7 +48,8 @@ import { TranslateService } from '@ngx-translate/core';
|
|||||||
import { PopoverPlacement, PopoverPlacements } from '@shared/components/popover.models';
|
import { PopoverPlacement, PopoverPlacements } from '@shared/components/popover.models';
|
||||||
import {
|
import {
|
||||||
CustomActionEditorCompleter,
|
CustomActionEditorCompleter,
|
||||||
toCustomAction
|
toCustomAction,
|
||||||
|
toPlaceMapItemAction
|
||||||
} from '@home/components/widget/lib/settings/common/action/custom-action.models';
|
} from '@home/components/widget/lib/settings/common/action/custom-action.models';
|
||||||
import { coerceBoolean } from '@shared/decorators/coercion';
|
import { coerceBoolean } from '@shared/decorators/coercion';
|
||||||
|
|
||||||
@ -336,7 +337,7 @@ export class WidgetActionComponent implements ControlValueAccessor, OnInit, Vali
|
|||||||
);
|
);
|
||||||
this.actionTypeFormGroup.addControl(
|
this.actionTypeFormGroup.addControl(
|
||||||
'customAction',
|
'customAction',
|
||||||
this.fb.control(toCustomAction(action), [Validators.required])
|
this.fb.control(toPlaceMapItemAction(action), [Validators.required])
|
||||||
);
|
);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -15,9 +15,9 @@
|
|||||||
limitations under the License.
|
limitations under the License.
|
||||||
|
|
||||||
-->
|
-->
|
||||||
<mat-form-field [formGroup]="entityTypeFormGroup">
|
<mat-form-field [formGroup]="entityTypeFormGroup" [appearance]="appearance">
|
||||||
<mat-label *ngIf="showLabel">{{ 'entity.type' | translate }}</mat-label>
|
<mat-label *ngIf="showLabel">{{ 'entity.type' | translate }}</mat-label>
|
||||||
<mat-select [required]="required" matInput formControlName="entityType">
|
<mat-select [required]="required" formControlName="entityType">
|
||||||
<mat-option *ngFor="let type of entityTypes" [value]="type">
|
<mat-option *ngFor="let type of entityTypes" [value]="type">
|
||||||
{{ displayEntityTypeFn(type) }}
|
{{ displayEntityTypeFn(type) }}
|
||||||
</mat-option>
|
</mat-option>
|
||||||
|
|||||||
@ -32,6 +32,7 @@ import { AliasEntityType, EntityType, entityTypeTranslations } from '@app/shared
|
|||||||
import { EntityService } from '@core/http/entity.service';
|
import { EntityService } from '@core/http/entity.service';
|
||||||
import { coerceBoolean } from '@shared/decorators/coercion';
|
import { coerceBoolean } from '@shared/decorators/coercion';
|
||||||
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
|
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
|
||||||
|
import { MatFormFieldAppearance } from '@angular/material/form-field';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'tb-entity-type-select',
|
selector: 'tb-entity-type-select',
|
||||||
@ -69,6 +70,9 @@ export class EntityTypeSelectComponent implements ControlValueAccessor, OnInit,
|
|||||||
@Input()
|
@Input()
|
||||||
disabled: boolean;
|
disabled: boolean;
|
||||||
|
|
||||||
|
@Input()
|
||||||
|
appearance: MatFormFieldAppearance = 'fill';
|
||||||
|
|
||||||
@Input()
|
@Input()
|
||||||
additionEntityTypes: {[key in string]: string} = {};
|
additionEntityTypes: {[key in string]: string} = {};
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user