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 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);
|
||||
|
||||
@ -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 {
|
||||
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;
|
||||
}
|
||||
|
||||
@ -15,9 +15,9 @@
|
||||
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-select [required]="required" matInput formControlName="entityType">
|
||||
<mat-select [required]="required" formControlName="entityType">
|
||||
<mat-option *ngFor="let type of entityTypes" [value]="type">
|
||||
{{ displayEntityTypeFn(type) }}
|
||||
</mat-option>
|
||||
|
||||
@ -32,6 +32,7 @@ import { AliasEntityType, EntityType, entityTypeTranslations } from '@app/shared
|
||||
import { EntityService } from '@core/http/entity.service';
|
||||
import { coerceBoolean } from '@shared/decorators/coercion';
|
||||
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
|
||||
import { MatFormFieldAppearance } from '@angular/material/form-field';
|
||||
|
||||
@Component({
|
||||
selector: 'tb-entity-type-select',
|
||||
@ -69,6 +70,9 @@ export class EntityTypeSelectComponent implements ControlValueAccessor, OnInit,
|
||||
@Input()
|
||||
disabled: boolean;
|
||||
|
||||
@Input()
|
||||
appearance: MatFormFieldAppearance = 'fill';
|
||||
|
||||
@Input()
|
||||
additionEntityTypes: {[key in string]: string} = {};
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user