Browse Source

UI: Extract same method in cf for service

pull/14691/head
Vladyslav_Prykhodko 9 months ago
parent
commit
c50b24d014
  1. 94
      ui-ngx/src/app/modules/home/components/calculated-fields/calculated-field-form.service.ts
  2. 74
      ui-ngx/src/app/modules/home/components/calculated-fields/calculated-field.component.ts
  3. 30
      ui-ngx/src/app/modules/home/components/calculated-fields/components/dialog/calculated-field-dialog.component.html
  4. 78
      ui-ngx/src/app/modules/home/components/calculated-fields/components/dialog/calculated-field-dialog.component.ts
  5. 9
      ui-ngx/src/app/modules/home/models/entity/entity-table-component.models.ts
  6. 10
      ui-ngx/src/app/modules/home/pages/calculated-fields/calculated-fields-tabs.component.ts
  7. 30
      ui-ngx/src/app/shared/components/entity/entity-select.component.ts

94
ui-ngx/src/app/modules/home/components/calculated-fields/calculated-field-form.service.ts

@ -0,0 +1,94 @@
///
/// Copyright © 2016-2025 The Thingsboard Authors
///
/// Licensed under the Apache License, Version 2.0 (the "License");
/// you may not use this file except in compliance with the License.
/// You may obtain a copy of the License at
///
/// http://www.apache.org/licenses/LICENSE-2.0
///
/// Unless required by applicable law or agreed to in writing, software
/// distributed under the License is distributed on an "AS IS" BASIS,
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
/// See the License for the specific language governing permissions and
/// limitations under the License.
///
import { DestroyRef, inject, Injectable } from '@angular/core';
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
import { pairwise, switchMap } from 'rxjs/operators';
import { Observable } from 'rxjs';
import {
CalculatedField,
CalculatedFieldConfiguration,
CalculatedFieldEventArguments,
CalculatedFieldType,
OutputStrategyType
} from '@shared/models/calculated-field.models';
import { oneSpaceInsideRegex } from '@shared/models/regex.constants';
import { isDefined } from '@core/utils';
import { CalculatedFieldsService } from '@core/http/calculated-fields.service';
import { CalculatedFieldsTableEntity } from '@home/components/calculated-fields/calculated-fields-table-config';
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
import { EntityType } from '@shared/models/entity-type.models';
@Injectable({ providedIn: 'root' })
export class CalculatedFieldFormService {
private fb = inject(FormBuilder);
private calculatedFieldsService = inject(CalculatedFieldsService);
buildForm(): FormGroup {
return this.fb.group({
name: ['', [Validators.required, Validators.pattern(oneSpaceInsideRegex), Validators.maxLength(255)]],
entityId: [{type: EntityType.DEVICE_PROFILE, id: null}, Validators.required],
type: [CalculatedFieldType.SIMPLE],
debugSettings: [],
configuration: this.fb.control<CalculatedFieldConfiguration>({} as CalculatedFieldConfiguration),
});
}
setupTypeChange(form: FormGroup, destroyRef: DestroyRef, isEditActive?: () => boolean): void {
form.get('type').valueChanges.pipe(
pairwise(),
takeUntilDestroyed(destroyRef)
).subscribe(([prevType, nextType]) => {
const shouldCheck = isEditActive ? isEditActive() : true;
if (shouldCheck) {
if (![CalculatedFieldType.SIMPLE, CalculatedFieldType.SCRIPT].includes(prevType) ||
![CalculatedFieldType.SIMPLE, CalculatedFieldType.SCRIPT].includes(nextType)) {
form.get('configuration').setValue({} as CalculatedFieldConfiguration, { emitEvent: false });
}
}
});
}
prepareConfig(configuration: CalculatedFieldConfiguration): CalculatedFieldConfiguration {
const config = configuration || ({} as CalculatedFieldConfiguration);
if (config.type !== CalculatedFieldType.ALARM) {
if (isDefined(config?.output) && !config?.output?.strategy) {
config.output.strategy = { type: OutputStrategyType.RULE_CHAIN };
}
}
return config;
}
testScript(
calculatedFieldId: string,
formValue: CalculatedField,
testDialogFn: (calculatedField: CalculatedFieldsTableEntity, argumentsObj?: CalculatedFieldEventArguments, openCalculatedFieldEdit?: boolean, expression?: string) => Observable<string>,
destroyRef: DestroyRef,
expression?: string,
): Observable<string> {
if (calculatedFieldId) {
return this.calculatedFieldsService.getLatestCalculatedFieldDebugEvent(calculatedFieldId, {ignoreLoading: true})
.pipe(
switchMap(event => {
const args = event?.arguments ? JSON.parse(event.arguments) : null;
return testDialogFn(formValue, args, false, expression);
}),
takeUntilDestroyed(destroyRef)
);
}
return testDialogFn(formValue, null, false, expression);
}
}

74
ui-ngx/src/app/modules/home/components/calculated-fields/calculated-field.component.ts

@ -14,11 +14,11 @@
/// limitations under the License. /// limitations under the License.
/// ///
import { ChangeDetectorRef, Component, DestroyRef, Inject, Input } from '@angular/core'; import { ChangeDetectorRef, Component, DestroyRef, inject, Inject, Input } from '@angular/core';
import { Store } from '@ngrx/store'; import { Store } from '@ngrx/store';
import { AppState } from '@core/core.state'; import { AppState } from '@core/core.state';
import { EntityComponent } from '../../components/entity/entity.component'; import { EntityComponent } from '../../components/entity/entity.component';
import { FormBuilder, FormGroup, Validators } from '@angular/forms'; import { FormBuilder, FormGroup } from '@angular/forms';
import { EntityType } from '@shared/models/entity-type.models'; import { EntityType } from '@shared/models/entity-type.models';
import { TranslateService } from '@ngx-translate/core'; import { TranslateService } from '@ngx-translate/core';
import { import {
@ -27,23 +27,18 @@ import {
calculatedFieldsEntityTypeList, calculatedFieldsEntityTypeList,
CalculatedFieldType, CalculatedFieldType,
calculatedFieldTypes, calculatedFieldTypes,
CalculatedFieldTypeTranslations, CalculatedFieldTypeTranslations
OutputStrategyType
} from '@shared/models/calculated-field.models'; } from '@shared/models/calculated-field.models';
import { oneSpaceInsideRegex } from '@shared/models/regex.constants';
import { isDefined } from '@core/utils';
import { EntityId } from '@shared/models/id/entity-id'; import { EntityId } from '@shared/models/id/entity-id';
import { pairwise, switchMap } from 'rxjs/operators';
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
import { BaseData } from '@shared/models/base-data'; import { BaseData } from '@shared/models/base-data';
import { Observable } from 'rxjs'; import { Observable } from 'rxjs';
import { CalculatedFieldsService } from '@core/http/calculated-fields.service';
import { getCurrentAuthUser } from '@core/auth/auth.selectors'; import { getCurrentAuthUser } from '@core/auth/auth.selectors';
import { import {
CalculatedFieldsTableConfig, CalculatedFieldsTableConfig,
CalculatedFieldsTableEntity CalculatedFieldsTableEntity
} from '@home/components/calculated-fields/calculated-fields-table-config'; } from '@home/components/calculated-fields/calculated-fields-table-config';
import { TenantId } from '@shared/models/id/tenant-id'; import { TenantId } from '@shared/models/id/tenant-id';
import { CalculatedFieldFormService } from '@home/components/calculated-fields/calculated-field-form.service';
@Component({ @Component({
selector: 'tb-calculated-field', selector: 'tb-calculated-field',
@ -68,14 +63,15 @@ export class CalculatedFieldComponent extends EntityComponent<CalculatedFieldsTa
readonly fieldTypes = calculatedFieldTypes; readonly fieldTypes = calculatedFieldTypes;
readonly CalculatedFieldTypeTranslations = CalculatedFieldTypeTranslations; readonly CalculatedFieldTypeTranslations = CalculatedFieldTypeTranslations;
private cfFormService = inject(CalculatedFieldFormService);
private destroyRef = inject(DestroyRef);
constructor(protected store: Store<AppState>, constructor(protected store: Store<AppState>,
protected translate: TranslateService, protected translate: TranslateService,
@Inject('entity') protected entityValue: CalculatedFieldInfo, @Inject('entity') protected entityValue: CalculatedFieldInfo,
@Inject('entitiesTableConfig') protected entitiesTableConfigValue: CalculatedFieldsTableConfig, @Inject('entitiesTableConfig') protected entitiesTableConfigValue: CalculatedFieldsTableConfig,
protected fb: FormBuilder, protected fb: FormBuilder,
protected cd: ChangeDetectorRef, protected cd: ChangeDetectorRef) {
private destroyRef: DestroyRef,
private calculatedFieldsService: CalculatedFieldsService) {
super(store, fb, entityValue, entitiesTableConfigValue, cd); super(store, fb, entityValue, entitiesTableConfigValue, cd);
} }
@ -111,60 +107,30 @@ export class CalculatedFieldComponent extends EntityComponent<CalculatedFieldsTa
this.entityName = entity?.name; this.entityName = entity?.name;
} }
buildForm(entity?: CalculatedFieldInfo): FormGroup { buildForm(_entity?: CalculatedFieldInfo): FormGroup {
const form = this.fb.group({ const form = inject(CalculatedFieldFormService).buildForm();
name: ['', [Validators.required, Validators.pattern(oneSpaceInsideRegex), Validators.maxLength(255)]], inject(CalculatedFieldFormService).setupTypeChange(form, inject(DestroyRef), () => this.isEditValue);
entityId: [null],
type: [CalculatedFieldType.SIMPLE],
debugSettings: [],
configuration: this.fb.control<CalculatedFieldConfiguration>({} as CalculatedFieldConfiguration),
});
form.get('type').valueChanges.pipe(
pairwise(),
takeUntilDestroyed(this.destroyRef)
).subscribe(([prevType, nextType]) => {
if (this.isEditValue) {
if (![CalculatedFieldType.SIMPLE, CalculatedFieldType.SCRIPT].includes(prevType) ||
![CalculatedFieldType.SIMPLE, CalculatedFieldType.SCRIPT].includes(nextType)) {
form.get('configuration').setValue(({} as CalculatedFieldConfiguration), {emitEvent: false});
}
}
});
return form; return form;
} }
updateForm(entity: CalculatedFieldInfo) { updateForm(entity: CalculatedFieldInfo) {
const { configuration = {} as CalculatedFieldConfiguration, type = CalculatedFieldType.SIMPLE, debugSettings = { failuresEnabled: true, allEnabled: true }, entityId = this.entityId, ...value } = entity ?? {}; const { configuration = {} as CalculatedFieldConfiguration, type = CalculatedFieldType.SIMPLE, debugSettings = { failuresEnabled: true, allEnabled: true }, entityId = this.entityId, ...value } = entity ?? {};
if (configuration.type !== CalculatedFieldType.ALARM) { const preparedConfig = this.cfFormService.prepareConfig(configuration);
if (isDefined(configuration?.output) && !configuration?.output?.strategy) {
configuration.output.strategy = {type: OutputStrategyType.RULE_CHAIN};
}
}
this.entityForm.patchValue({ type }, {emitEvent: false}); this.entityForm.patchValue({ type }, {emitEvent: false});
setTimeout(() => { setTimeout(() => {
this.entityForm.patchValue({ configuration, debugSettings, entityId, ...value }, {emitEvent: false}); this.entityForm.patchValue({ configuration: preparedConfig, debugSettings, entityId, ...value }, {emitEvent: false});
this.entityForm.get('type').updateValueAndValidity({onlySelf: true}); this.entityForm.get('type').updateValueAndValidity({onlySelf: true});
}); });
if (!entityId) {
this.entityForm.get('configuration').disable({emitEvent: false});
this.disabledConfiguration = true;
}
} }
onTestScript(expression?: string): Observable<string> { onTestScript(expression?: string): Observable<string> {
const calculatedFieldId = this.entity?.id?.id; return this.cfFormService.testScript(
if (calculatedFieldId) { this.entity?.id?.id,
return this.calculatedFieldsService.getLatestCalculatedFieldDebugEvent(calculatedFieldId, {ignoreLoading: true}) this.entityFormValue(),
.pipe( this.entitiesTableConfig.getTestScriptDialog.bind(this.entitiesTableConfig),
switchMap(event => { this.destroyRef,
const args = event?.arguments ? JSON.parse(event.arguments) : null; expression
return this.entitiesTableConfig.getTestScriptDialog(this.entityFormValue(), args, false, expression); );
}),
takeUntilDestroyed(this.destroyRef)
)
}
return this.entitiesTableConfig.getTestScriptDialog(this.entityFormValue(), null, false, expression);
} }
updateFormState() { updateFormState() {

30
ui-ngx/src/app/modules/home/components/calculated-fields/components/dialog/calculated-field-dialog.component.html

@ -56,29 +56,13 @@
/> />
</div> </div>
@if (!data.entityId) { @if (!data.entityId) {
<div class="flex flex-row gap-4 xs:flex-col" formGroupName="entityId"> <tb-entity-select formControlName="entityId"
<tb-entity-type-select #entityTypeSelect appearance="outline"
appearance="outline" [filterAllowedEntityTypes]="false"
class="flex-1" [allowedEntityTypes]="calculatedFieldsEntityTypeList"
showLabel [defaultEntityType]="EntityType.DEVICE_PROFILE"
required (entityChanged)="changeEntity($event)">
label="{{ 'entity.entity-type' | translate }}" </tb-entity-select>
[filterAllowedEntityTypes]="false"
[allowedEntityTypes]="calculatedFieldsEntityTypeList"
formControlName="entityType">
</tb-entity-type-select>
@if (fieldFormGroup.get('entityId.entityType').value) {
<tb-entity-autocomplete #entityAutocompleteComponent
formControlName="id"
appearance="outline"
class="flex-1"
[placeholder]="'action.set' | translate"
[required]="true"
[entityType]="fieldFormGroup.get('entityId.entityType').value"
(entityChanged)="changeEntity($event)"
/>
}
</div>
} }
<mat-form-field appearance="outline" subscriptSizing="dynamic"> <mat-form-field appearance="outline" subscriptSizing="dynamic">
<mat-label>{{ 'common.type' | translate }}</mat-label> <mat-label>{{ 'common.type' | translate }}</mat-label>

78
ui-ngx/src/app/modules/home/components/calculated-fields/components/dialog/calculated-field-dialog.component.ts

@ -14,11 +14,10 @@
/// limitations under the License. /// limitations under the License.
/// ///
import { Component, DestroyRef, Inject, ViewChild, ViewEncapsulation } from '@angular/core'; import { Component, DestroyRef, Inject, ViewEncapsulation } from '@angular/core';
import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog'; import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog';
import { Store } from '@ngrx/store'; import { Store } from '@ngrx/store';
import { AppState } from '@core/core.state'; import { AppState } from '@core/core.state';
import { FormBuilder, Validators } from '@angular/forms';
import { Router } from '@angular/router'; import { Router } from '@angular/router';
import { DialogComponent } from '@shared/components/dialog.component'; import { DialogComponent } from '@shared/components/dialog.component';
import { import {
@ -28,21 +27,18 @@ import {
CalculatedFieldTestScriptFn, CalculatedFieldTestScriptFn,
CalculatedFieldType, CalculatedFieldType,
calculatedFieldTypes, calculatedFieldTypes,
CalculatedFieldTypeTranslations, CalculatedFieldTypeTranslations
OutputStrategyType
} from '@shared/models/calculated-field.models'; } from '@shared/models/calculated-field.models';
import { oneSpaceInsideRegex } from '@shared/models/regex.constants'; import { EntityType } from '@shared/models/entity-type.models';
import { AliasEntityType, EntityType } from '@shared/models/entity-type.models';
import { pairwise, switchMap } from 'rxjs/operators';
import { takeUntilDestroyed } from '@angular/core/rxjs-interop'; import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
import { CalculatedFieldsService } from '@core/http/calculated-fields.service'; import { CalculatedFieldsService } from '@core/http/calculated-fields.service';
import { Observable } from 'rxjs'; import { Observable } from 'rxjs';
import { EntityId } from '@shared/models/id/entity-id'; import { EntityId } from '@shared/models/id/entity-id';
import { AdditionalDebugActionConfig } from '@home/components/entity/debug/entity-debug-settings.model'; import { AdditionalDebugActionConfig } from '@home/components/entity/debug/entity-debug-settings.model';
import { deepTrim, isDefined } from '@core/utils'; import { deepTrim } from '@core/utils';
import { EntityTypeSelectComponent } from '@shared/components/entity/entity-type-select.component';
import { EntityAutocompleteComponent } from '@shared/components/entity/entity-autocomplete.component';
import { BaseData } from '@shared/models/base-data'; import { BaseData } from '@shared/models/base-data';
import { CalculatedFieldFormService } from '@home/components/calculated-fields/calculated-field-form.service';
import { FormGroup } from '@angular/forms';
export interface CalculatedFieldDialogData { export interface CalculatedFieldDialogData {
value?: CalculatedField; value?: CalculatedField;
@ -64,16 +60,7 @@ export interface CalculatedFieldDialogData {
}) })
export class CalculatedFieldDialogComponent extends DialogComponent<CalculatedFieldDialogComponent, CalculatedField> { export class CalculatedFieldDialogComponent extends DialogComponent<CalculatedFieldDialogComponent, CalculatedField> {
fieldFormGroup = this.fb.group({ fieldFormGroup: FormGroup;
name: ['', [Validators.required, Validators.pattern(oneSpaceInsideRegex), Validators.maxLength(255)]],
entityId: this.fb.group({
entityType: this.fb.control<EntityType | AliasEntityType | null>(EntityType.DEVICE_PROFILE, Validators.required),
id: [null as null | string, Validators.required],
}),
type: [CalculatedFieldType.SIMPLE],
debugSettings: [],
configuration: this.fb.control<CalculatedFieldConfiguration>({} as CalculatedFieldConfiguration),
});
additionalDebugActionConfig = this.data.value?.id ? { additionalDebugActionConfig = this.data.value?.id ? {
...this.data.additionalDebugActionConfig, ...this.data.additionalDebugActionConfig,
@ -91,18 +78,16 @@ export class CalculatedFieldDialogComponent extends DialogComponent<CalculatedFi
readonly fieldTypes = calculatedFieldTypes; readonly fieldTypes = calculatedFieldTypes;
readonly CalculatedFieldTypeTranslations = CalculatedFieldTypeTranslations; readonly CalculatedFieldTypeTranslations = CalculatedFieldTypeTranslations;
@ViewChild('entityTypeSelect') entityTypeSelect: EntityTypeSelectComponent;
@ViewChild('entityAutocompleteComponent') entityAutocompleteComponent: EntityAutocompleteComponent;
constructor(protected store: Store<AppState>, constructor(protected store: Store<AppState>,
protected router: Router, protected router: Router,
@Inject(MAT_DIALOG_DATA) public data: CalculatedFieldDialogData, @Inject(MAT_DIALOG_DATA) public data: CalculatedFieldDialogData,
protected dialogRef: MatDialogRef<CalculatedFieldDialogComponent, CalculatedField>, protected dialogRef: MatDialogRef<CalculatedFieldDialogComponent, CalculatedField>,
private calculatedFieldsService: CalculatedFieldsService, private calculatedFieldsService: CalculatedFieldsService,
private destroyRef: DestroyRef, private destroyRef: DestroyRef,
private fb: FormBuilder) { private cfFormService: CalculatedFieldFormService) {
super(store, router, dialogRef); super(store, router, dialogRef);
this.observeType(); this.fieldFormGroup = this.cfFormService.buildForm();
this.cfFormService.setupTypeChange(this.fieldFormGroup, this.destroyRef);
this.applyDialogData(); this.applyDialogData();
if (this.data.isDirty) { if (this.data.isDirty) {
@ -110,7 +95,7 @@ export class CalculatedFieldDialogComponent extends DialogComponent<CalculatedFi
} }
if (!this.data.entityId) { if (!this.data.entityId) {
this.fieldFormGroup.get('entityId.id').valueChanges.pipe( this.fieldFormGroup.get('entityId').valueChanges.pipe(
takeUntilDestroyed(this.destroyRef) takeUntilDestroyed(this.destroyRef)
).subscribe((entityId) => { ).subscribe((entityId) => {
this.disabledConfiguration = !entityId; this.disabledConfiguration = !entityId;
@ -142,24 +127,17 @@ export class CalculatedFieldDialogComponent extends DialogComponent<CalculatedFi
}); });
} else { } else {
this.fieldFormGroup.get('name').markAsTouched(); this.fieldFormGroup.get('name').markAsTouched();
this.entityTypeSelect?.markAsTouched();
this.entityAutocompleteComponent?.markAsTouched();
} }
} }
onTestScript(expression?: string): Observable<string> { onTestScript(expression?: string): Observable<string> {
const calculatedFieldId = this.data.value?.id?.id; return this.cfFormService.testScript(
if (calculatedFieldId) { this.data.value?.id?.id,
return this.calculatedFieldsService.getLatestCalculatedFieldDebugEvent(calculatedFieldId, {ignoreLoading: true}) this.fromGroupValue,
.pipe( this.data.getTestScriptDialogFn,
switchMap(event => { this.destroyRef,
const args = event?.arguments ? JSON.parse(event.arguments) : null; expression
return this.data.getTestScriptDialogFn(this.fromGroupValue, args, false, expression); );
}),
takeUntilDestroyed(this.destroyRef)
)
}
return this.data.getTestScriptDialogFn(this.fromGroupValue, null, false, expression);
} }
changeEntity(entity: BaseData<EntityId>): void { changeEntity(entity: BaseData<EntityId>): void {
@ -172,28 +150,12 @@ export class CalculatedFieldDialogComponent extends DialogComponent<CalculatedFi
private applyDialogData(): void { private applyDialogData(): void {
const { configuration = {} as CalculatedFieldConfiguration, type = CalculatedFieldType.SIMPLE, debugSettings = { failuresEnabled: true, allEnabled: true }, entityId = this.data.entityId, ...value } = this.data.value ?? {}; const { configuration = {} as CalculatedFieldConfiguration, type = CalculatedFieldType.SIMPLE, debugSettings = { failuresEnabled: true, allEnabled: true }, entityId = this.data.entityId, ...value } = this.data.value ?? {};
if (configuration.type !== CalculatedFieldType.ALARM) { const preparedConfig = this.cfFormService.prepareConfig(configuration);
if (isDefined(configuration?.output) && !configuration?.output?.strategy) { this.fieldFormGroup.patchValue({ configuration: preparedConfig, type, debugSettings, entityId, ...value }, {emitEvent: false});
configuration.output.strategy = {type: OutputStrategyType.RULE_CHAIN};
}
}
this.fieldFormGroup.patchValue({ configuration, type, debugSettings, entityId, ...value }, {emitEvent: false});
setTimeout(() => this.fieldFormGroup.get('type').updateValueAndValidity({onlySelf: true})); setTimeout(() => this.fieldFormGroup.get('type').updateValueAndValidity({onlySelf: true}));
if (!this.data.entityId) { if (!this.data.entityId) {
this.fieldFormGroup.get('configuration').disable({emitEvent: false}); this.fieldFormGroup.get('configuration').disable({emitEvent: false});
this.disabledConfiguration = true; this.disabledConfiguration = true;
} }
} }
private observeType(): void {
this.fieldFormGroup.get('type').valueChanges.pipe(
pairwise(),
takeUntilDestroyed(this.destroyRef)
).subscribe(([prevType, nextType]) => {
if (![CalculatedFieldType.SIMPLE, CalculatedFieldType.SCRIPT].includes(prevType) ||
![CalculatedFieldType.SIMPLE, CalculatedFieldType.SCRIPT].includes(nextType)) {
this.fieldFormGroup.get('configuration').setValue(({} as CalculatedFieldConfiguration), {emitEvent: false});
}
});
}
} }

9
ui-ngx/src/app/modules/home/models/entity/entity-table-component.models.ts

@ -20,18 +20,22 @@ import { SafeHtml } from '@angular/platform-browser';
import { PageLink } from '@shared/models/page/page-link'; import { PageLink } from '@shared/models/page/page-link';
import { Timewindow } from '@shared/models/time/time.models'; import { Timewindow } from '@shared/models/time/time.models';
import { EntitiesDataSource } from '@home/models/datasource/entity-datasource'; import { EntitiesDataSource } from '@home/models/datasource/entity-datasource';
import { ElementRef, EventEmitter, Renderer2, ViewContainerRef } from '@angular/core'; import { ElementRef, EventEmitter, ViewContainerRef } from '@angular/core';
import { TbAnchorComponent } from '@shared/components/tb-anchor.component'; import { TbAnchorComponent } from '@shared/components/tb-anchor.component';
import { MatPaginator } from '@angular/material/paginator'; import { MatPaginator } from '@angular/material/paginator';
import { MatSort } from '@angular/material/sort'; import { MatSort } from '@angular/material/sort';
import { EntityAction } from '@home/models/entity/entity-component.models'; import { EntityAction } from '@home/models/entity/entity-component.models';
import { import {
CellActionDescriptor, EntityActionTableColumn, EntityColumn, EntityTableColumn, CellActionDescriptor,
EntityActionTableColumn,
EntityColumn,
EntityTableColumn,
EntityTableConfig, EntityTableConfig,
GroupActionDescriptor, GroupActionDescriptor,
HeaderActionDescriptor HeaderActionDescriptor
} from '@home/models/entity/entities-table-config.models'; } from '@home/models/entity/entities-table-config.models';
import { ActivatedRoute } from '@angular/router'; import { ActivatedRoute } from '@angular/router';
import type { EntityDetailsPanelComponent } from '@home/components/entity/entity-details-panel.component';
export type EntitiesTableAction = 'add'; export type EntitiesTableAction = 'add';
@ -64,6 +68,7 @@ export interface IEntitiesTableComponent {
paginator: MatPaginator; paginator: MatPaginator;
sort: MatSort; sort: MatSort;
route: ActivatedRoute; route: ActivatedRoute;
entityDetailsPanel: EntityDetailsPanelComponent;
viewContainerRef: ViewContainerRef; viewContainerRef: ViewContainerRef;
addEnabled(): boolean; addEnabled(): boolean;

10
ui-ngx/src/app/modules/home/pages/calculated-fields/calculated-fields-tabs.component.ts

@ -42,8 +42,16 @@ export class CalculatedFieldsTabsComponent extends EntityTabsComponent<Calculate
}; };
onDebugEventSelected(event: CalculatedFieldEventBody) { onDebugEventSelected(event: CalculatedFieldEventBody) {
(this.entitiesTableConfig as CalculatedFieldsTableConfig).getTestScriptDialog(this.entity, JSON.parse(event.arguments)) (this.entitiesTableConfig as CalculatedFieldsTableConfig).getTestScriptDialog(this.entity, JSON.parse(event.arguments), false)
.subscribe((expression) => { .subscribe((expression) => {
(this.entitiesTableConfig as CalculatedFieldsTableConfig).getTable();
const entityDetailsPanel = this.entitiesTableConfig.getTable().entityDetailsPanel;
entityDetailsPanel.onToggleEditMode(true);
entityDetailsPanel.selectedTab = 0;
setTimeout(() => {
entityDetailsPanel.detailsForm.get('configuration').setValue({...this.entity.configuration, expression});
entityDetailsPanel.detailsForm.get('configuration').markAsDirty();
});
}); });
}; };
} }

30
ui-ngx/src/app/shared/components/entity/entity-select.component.ts

@ -14,7 +14,7 @@
/// limitations under the License. /// limitations under the License.
/// ///
import { AfterViewInit, Component, DestroyRef, EventEmitter, forwardRef, Input, OnInit, Output } from '@angular/core'; import { Component, DestroyRef, EventEmitter, forwardRef, Input, OnInit, Output } from '@angular/core';
import { ControlValueAccessor, NG_VALUE_ACCESSOR, UntypedFormBuilder, UntypedFormGroup } from '@angular/forms'; import { ControlValueAccessor, NG_VALUE_ACCESSOR, UntypedFormBuilder, UntypedFormGroup } from '@angular/forms';
import { Store } from '@ngrx/store'; import { Store } from '@ngrx/store';
import { AppState } from '@core/core.state'; import { AppState } from '@core/core.state';
@ -38,7 +38,7 @@ import { BaseData } from '@shared/models/base-data';
multi: true multi: true
}] }]
}) })
export class EntitySelectComponent implements ControlValueAccessor, OnInit, AfterViewInit { export class EntitySelectComponent implements ControlValueAccessor, OnInit {
entitySelectFormGroup: UntypedFormGroup; entitySelectFormGroup: UntypedFormGroup;
@ -70,6 +70,9 @@ export class EntitySelectComponent implements ControlValueAccessor, OnInit, Afte
@Input() @Input()
filterAllowedEntityTypes: boolean; filterAllowedEntityTypes: boolean;
@Input()
defaultEntityType: AliasEntityType | EntityType;
@Output() @Output()
entityChanged = new EventEmitter<BaseData<EntityId>>(); entityChanged = new EventEmitter<BaseData<EntityId>>();
@ -81,8 +84,6 @@ export class EntitySelectComponent implements ControlValueAccessor, OnInit, Afte
AliasEntityType.CURRENT_TENANT, AliasEntityType.CURRENT_USER, AliasEntityType.CURRENT_USER_OWNER AliasEntityType.CURRENT_TENANT, AliasEntityType.CURRENT_USER, AliasEntityType.CURRENT_USER_OWNER
]); ]);
private readonly defaultEntityType: EntityType | AliasEntityType = null;
private propagateChange = (v: any) => { }; private propagateChange = (v: any) => { };
constructor(private store: Store<AppState>, constructor(private store: Store<AppState>,
@ -93,15 +94,18 @@ export class EntitySelectComponent implements ControlValueAccessor, OnInit, Afte
const entityTypes = this.entityService.prepareAllowedEntityTypesList(this.allowedEntityTypes, const entityTypes = this.entityService.prepareAllowedEntityTypesList(this.allowedEntityTypes,
this.useAliasEntityTypes); this.useAliasEntityTypes);
let defaultEntityType: EntityType | AliasEntityType = null
if (entityTypes.length === 1) { if (entityTypes.length === 1) {
this.displayEntityTypeSelect = false; this.displayEntityTypeSelect = false;
this.defaultEntityType = entityTypes[0]; defaultEntityType = entityTypes[0];
} else { } else {
this.displayEntityTypeSelect = true; this.displayEntityTypeSelect = true;
} }
this.entitySelectFormGroup = this.fb.group({ this.entitySelectFormGroup = this.fb.group({
entityType: [this.defaultEntityType], entityType: [defaultEntityType],
entityId: [null] entityId: [null]
}); });
} }
@ -133,9 +137,19 @@ export class EntitySelectComponent implements ControlValueAccessor, OnInit, Afte
if (additionNullUIIDEntityTypes.length > 0) { if (additionNullUIIDEntityTypes.length > 0) {
additionNullUIIDEntityTypes.forEach((entityType) => this.entityTypeNullUUID.add(entityType)); additionNullUIIDEntityTypes.forEach((entityType) => this.entityTypeNullUUID.add(entityType));
} }
}
ngAfterViewInit(): void { if (this.filterAllowedEntityTypes === false) {
if (this.allowedEntityTypes?.length === 1) {
this.displayEntityTypeSelect = false;
this.entitySelectFormGroup.get('entityType').setValue(this.allowedEntityTypes[0])
} else {
this.displayEntityTypeSelect = true;
}
}
if (this.defaultEntityType) {
this.entitySelectFormGroup.get('entityType').setValue(this.defaultEntityType);
}
} }
setDisabledState(isDisabled: boolean): void { setDisabledState(isDisabled: boolean): void {

Loading…
Cancel
Save