Calculated fields adjustments, improvements and fixes
This commit is contained in:
parent
145789882e
commit
eb3f6b137f
@ -54,7 +54,8 @@ export class CalculatedFieldsTableConfig extends EntityTableConfig<CalculatedFie
|
||||
private durationLeft: DurationLeftPipe,
|
||||
private popoverService: TbPopoverService,
|
||||
private destroyRef: DestroyRef,
|
||||
private renderer: Renderer2
|
||||
private renderer: Renderer2,
|
||||
public entityName: string
|
||||
) {
|
||||
super();
|
||||
this.tableTitle = this.translate.instant('entity.type-calculated-fields');
|
||||
@ -159,6 +160,7 @@ export class CalculatedFieldsTableConfig extends EntityTableConfig<CalculatedFie
|
||||
entityId: this.entityId,
|
||||
debugLimitsConfiguration: this.calculatedFieldsDebugPerTenantLimitsConfiguration,
|
||||
tenantId: this.tenantId,
|
||||
entityName: this.entityName,
|
||||
}
|
||||
})
|
||||
.afterClosed();
|
||||
|
||||
@ -47,6 +47,7 @@ export class CalculatedFieldsTableComponent {
|
||||
|
||||
active = input<boolean>();
|
||||
entityId = input<EntityId>();
|
||||
entityName = input<string>();
|
||||
|
||||
calculatedFieldsTableConfig: CalculatedFieldsTableConfig;
|
||||
|
||||
@ -71,7 +72,8 @@ export class CalculatedFieldsTableComponent {
|
||||
this.durationLeft,
|
||||
this.popoverService,
|
||||
this.destroyRef,
|
||||
this.renderer
|
||||
this.renderer,
|
||||
this.entityName()
|
||||
);
|
||||
this.cd.markForCheck();
|
||||
}
|
||||
|
||||
@ -80,21 +80,26 @@
|
||||
</mat-chip>
|
||||
</mat-chip-listbox>
|
||||
</ng-container>
|
||||
<div class="flex opacity-55">
|
||||
<div class="flex">
|
||||
<button type="button"
|
||||
mat-icon-button
|
||||
#button
|
||||
(click)="manageArgument($event, button, $index)"
|
||||
[matTooltip]="'action.edit' | translate"
|
||||
matTooltipPosition="above">
|
||||
<mat-icon>edit</mat-icon>
|
||||
<mat-icon class="opacity-55">edit</mat-icon>
|
||||
@if (argumentsFormArray.dirty
|
||||
&& group.get('refEntityKey').get('type').value === ArgumentType.Rolling
|
||||
&& calculatedFieldType() === CalculatedFieldType.SIMPLE) {
|
||||
<tb-error class="edit-hint absolute right-0 top-0" [error]="'*'"/>
|
||||
}
|
||||
</button>
|
||||
<button type="button"
|
||||
mat-icon-button
|
||||
(click)="onDelete($index)"
|
||||
[matTooltip]="'action.delete' | translate"
|
||||
matTooltipPosition="above">
|
||||
<mat-icon>delete</mat-icon>
|
||||
<mat-icon class="opacity-55">delete</mat-icon>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -19,4 +19,9 @@
|
||||
font-size: 14px;
|
||||
}
|
||||
}
|
||||
.edit-hint {
|
||||
.mat-mdc-form-field-error {
|
||||
font-size: 16px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -21,7 +21,9 @@ import {
|
||||
forwardRef,
|
||||
input,
|
||||
Input,
|
||||
OnChanges,
|
||||
Renderer2,
|
||||
SimpleChanges,
|
||||
ViewContainerRef,
|
||||
} from '@angular/core';
|
||||
import {
|
||||
@ -70,10 +72,11 @@ import { TbPopoverComponent } from '@shared/components/popover.component';
|
||||
}
|
||||
],
|
||||
})
|
||||
export class CalculatedFieldArgumentsTableComponent implements ControlValueAccessor, Validator {
|
||||
export class CalculatedFieldArgumentsTableComponent implements ControlValueAccessor, Validator, OnChanges {
|
||||
|
||||
@Input() entityId: EntityId;
|
||||
@Input() tenantId: string;
|
||||
@Input() entityName: string;
|
||||
|
||||
calculatedFieldType = input<CalculatedFieldType>()
|
||||
|
||||
@ -84,6 +87,8 @@ export class CalculatedFieldArgumentsTableComponent implements ControlValueAcces
|
||||
readonly ArgumentTypeTranslations = ArgumentTypeTranslations;
|
||||
readonly EntityType = EntityType;
|
||||
readonly ArgumentEntityType = ArgumentEntityType;
|
||||
readonly ArgumentType = ArgumentType;
|
||||
readonly CalculatedFieldType = CalculatedFieldType;
|
||||
|
||||
private popoverComponent: TbPopoverComponent<CalculatedFieldArgumentPanelComponent>;
|
||||
private propagateChange: (argumentsObj: Record<string, CalculatedFieldArgument>) => void = () => {};
|
||||
@ -105,6 +110,13 @@ export class CalculatedFieldArgumentsTableComponent implements ControlValueAcces
|
||||
});
|
||||
}
|
||||
|
||||
ngOnChanges(changes: SimpleChanges): void {
|
||||
if (changes.calculatedFieldType?.previousValue
|
||||
&& changes.calculatedFieldType.currentValue !== changes.calculatedFieldType.previousValue) {
|
||||
this.argumentsFormArray.markAsDirty();
|
||||
}
|
||||
}
|
||||
|
||||
registerOnChange(fn: (argumentsObj: Record<string, CalculatedFieldArgument>) => void): void {
|
||||
this.propagateChange = fn;
|
||||
}
|
||||
@ -137,6 +149,7 @@ export class CalculatedFieldArgumentsTableComponent implements ControlValueAcces
|
||||
calculatedFieldType: this.calculatedFieldType(),
|
||||
buttonTitle: this.argumentsFormArray.at(index)?.value ? 'action.apply' : 'action.add',
|
||||
tenantId: this.tenantId,
|
||||
entityName: this.entityName,
|
||||
};
|
||||
this.popoverComponent = this.popoverService.displayPopover(trigger, this.renderer,
|
||||
this.viewContainerRef, CalculatedFieldArgumentPanelComponent, 'left', false, null,
|
||||
@ -202,6 +215,7 @@ export class CalculatedFieldArgumentsTableComponent implements ControlValueAcces
|
||||
}),
|
||||
} : {}),
|
||||
refEntityKey: this.fb.group({
|
||||
...value.refEntityKey,
|
||||
type: [{ value: value.refEntityKey.type, disabled: true }],
|
||||
key: [{ value: value.refEntityKey.key, disabled: true }],
|
||||
}),
|
||||
|
||||
@ -69,6 +69,7 @@
|
||||
formControlName="arguments"
|
||||
[entityId]="data.entityId"
|
||||
[tenantId]="data.tenantId"
|
||||
[entityName]="data.entityName"
|
||||
[calculatedFieldType]="fieldFormGroup.get('type').value"
|
||||
/>
|
||||
</div>
|
||||
@ -114,7 +115,7 @@
|
||||
</mat-form-field>
|
||||
@if (outputFormGroup.get('type').value === OutputType.Attribute) {
|
||||
<mat-form-field class="flex-1" appearance="outline" subscriptSizing="dynamic">
|
||||
<mat-label>{{ 'calculated-fields.output-type' | translate }}</mat-label>
|
||||
<mat-label>{{ 'calculated-fields.attribute-scope' | translate }}</mat-label>
|
||||
<mat-select formControlName="scope" class="w-full">
|
||||
<mat-option [value]="AttributeScope.SERVER_SCOPE">
|
||||
{{ 'calculated-fields.server-attributes' | translate }}
|
||||
|
||||
@ -36,6 +36,7 @@ import { EntityType } from '@shared/models/entity-type.models';
|
||||
import { map, startWith } from 'rxjs/operators';
|
||||
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
|
||||
import { ScriptLanguage } from '@shared/models/rule-node.models';
|
||||
import { merge } from 'rxjs';
|
||||
|
||||
@Component({
|
||||
selector: 'tb-calculated-field-dialog',
|
||||
@ -59,10 +60,10 @@ export class CalculatedFieldDialogComponent extends DialogComponent<CalculatedFi
|
||||
}),
|
||||
});
|
||||
|
||||
functionArgs$ = this.configFormGroup.valueChanges
|
||||
functionArgs$ = merge(this.configFormGroup.get('arguments').valueChanges, this.fieldFormGroup.get('type').valueChanges)
|
||||
.pipe(
|
||||
startWith(this.data.value?.configuration ?? {}),
|
||||
map(configuration => Object.keys(configuration.arguments))
|
||||
startWith(null),
|
||||
map(() => Object.keys(this.configFormGroup.get('arguments').value ?? this.data.value.configuration.arguments))
|
||||
);
|
||||
|
||||
readonly OutputTypeTranslations = OutputTypeTranslations;
|
||||
|
||||
@ -96,7 +96,7 @@
|
||||
}
|
||||
</mat-form-field>
|
||||
</div>
|
||||
@if (entityFilter.singleEntity.id || entityType === ArgumentEntityType.Current || entityType === ArgumentEntityType.Tenant) {
|
||||
@if (entityFilter.singleEntity?.id || entityType === ArgumentEntityType.Current || entityType === ArgumentEntityType.Tenant) {
|
||||
@if (refEntityKeyFormGroup.get('type').value !== ArgumentType.Attribute) {
|
||||
<div class="tb-form-row">
|
||||
<div class="fixed-title-width tb-required">{{ 'calculated-fields.timeseries-key' | translate }}</div>
|
||||
|
||||
@ -49,6 +49,7 @@ export class CalculatedFieldArgumentPanelComponent implements OnInit {
|
||||
@Input() argument: CalculatedFieldArgumentValue;
|
||||
@Input() entityId: EntityId;
|
||||
@Input() tenantId: string;
|
||||
@Input() entityName: string;
|
||||
@Input() calculatedFieldType: CalculatedFieldType;
|
||||
|
||||
argumentsDataApplied = output<{ value: CalculatedFieldArgumentValue, index: number }>();
|
||||
@ -83,6 +84,8 @@ export class CalculatedFieldArgumentPanelComponent implements OnInit {
|
||||
readonly ArgumentEntityType = ArgumentEntityType;
|
||||
readonly ArgumentEntityTypeParamsMap = ArgumentEntityTypeParamsMap;
|
||||
|
||||
private currentEntityFilter: EntityFilter;
|
||||
|
||||
constructor(
|
||||
private fb: FormBuilder,
|
||||
private cd: ChangeDetectorRef,
|
||||
@ -107,6 +110,7 @@ export class CalculatedFieldArgumentPanelComponent implements OnInit {
|
||||
|
||||
ngOnInit(): void {
|
||||
this.argumentFormGroup.patchValue(this.argument, {emitEvent: false});
|
||||
this.currentEntityFilter = this.getCurrentEntityFilter();
|
||||
this.updateEntityFilter(this.argument.refEntityId?.entityType, true);
|
||||
this.toggleByEntityKeyType(this.argument.refEntityKey?.type);
|
||||
this.setInitialEntityKeyType();
|
||||
@ -138,30 +142,53 @@ export class CalculatedFieldArgumentPanelComponent implements OnInit {
|
||||
}
|
||||
|
||||
private updateEntityFilter(entityType: ArgumentEntityType = ArgumentEntityType.Current, onInit = false): void {
|
||||
let entityId: EntityId;
|
||||
let entityFilter: EntityFilter;
|
||||
switch (entityType) {
|
||||
case ArgumentEntityType.Current:
|
||||
entityId = this.entityId
|
||||
entityFilter = this.currentEntityFilter;
|
||||
break;
|
||||
case ArgumentEntityType.Tenant:
|
||||
entityId = {
|
||||
entityFilter = {
|
||||
type: AliasFilterType.singleEntity,
|
||||
singleEntity: {
|
||||
id: this.tenantId,
|
||||
entityType: EntityType.TENANT
|
||||
},
|
||||
};
|
||||
break;
|
||||
default:
|
||||
entityId = this.argumentFormGroup.get('refEntityId').value as unknown as EntityId;
|
||||
entityFilter = {
|
||||
type: AliasFilterType.singleEntity,
|
||||
singleEntity: this.argumentFormGroup.get('refEntityId').value as unknown as EntityId,
|
||||
};
|
||||
}
|
||||
if (!onInit) {
|
||||
this.argumentFormGroup.get('refEntityKey').get('key').setValue('');
|
||||
}
|
||||
this.entityFilter = {
|
||||
type: AliasFilterType.singleEntity,
|
||||
singleEntity: entityId,
|
||||
};
|
||||
this.entityFilter = entityFilter;
|
||||
this.cd.markForCheck();
|
||||
}
|
||||
|
||||
private getCurrentEntityFilter(): EntityFilter {
|
||||
switch (this.entityId.entityType) {
|
||||
case EntityType.ASSET_PROFILE:
|
||||
return {
|
||||
deviceTypes: [this.entityName],
|
||||
type: AliasFilterType.assetType
|
||||
};
|
||||
case EntityType.DEVICE_PROFILE:
|
||||
return {
|
||||
deviceTypes: [this.entityName],
|
||||
type: AliasFilterType.deviceType
|
||||
};
|
||||
default:
|
||||
return {
|
||||
type: AliasFilterType.singleEntity,
|
||||
singleEntity: this.entityId,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
private observeEntityFilterChanges(): void {
|
||||
merge(
|
||||
this.refEntityIdFormGroup.get('entityType').valueChanges,
|
||||
|
||||
@ -15,6 +15,10 @@
|
||||
limitations under the License.
|
||||
|
||||
-->
|
||||
<mat-tab *ngIf="entity && authUser.authority === authorities.TENANT_ADMIN && !isEdit"
|
||||
label="{{ 'entity.type-calculated-fields' | translate }}" #calculatedFieldsTab="matTab">
|
||||
<tb-calculated-fields-table [active]="calculatedFieldsTab.isActive" [entityId]="entity.id" [entityName]="entity.name"/>
|
||||
</mat-tab>
|
||||
<mat-tab *ngIf="entity && !isEdit" #auditLogsTab="matTab"
|
||||
label="{{ 'audit-log.audit-logs' | translate }}">
|
||||
<tb-audit-log-table detailsMode="true" [active]="auditLogsTab.isActive" [auditLogMode]="auditLogModes.ENTITY" [entityId]="entity.id"></tb-audit-log-table>
|
||||
|
||||
@ -32,6 +32,10 @@
|
||||
[entityName]="entity.name">
|
||||
</tb-attribute-table>
|
||||
</mat-tab>
|
||||
<mat-tab *ngIf="entity && authUser.authority === authorities.TENANT_ADMIN"
|
||||
label="{{ 'entity.type-calculated-fields' | translate }}" #calculatedFieldsTab="matTab">
|
||||
<tb-calculated-fields-table [active]="calculatedFieldsTab.isActive" [entityId]="entity.id"/>
|
||||
</mat-tab>
|
||||
<mat-tab *ngIf="entity"
|
||||
label="{{ 'alarm.alarms' | translate }}" #alarmsTab="matTab">
|
||||
<tb-alarm-table [active]="alarmsTab.isActive" [entityId]="entity.id"></tb-alarm-table>
|
||||
|
||||
@ -69,6 +69,10 @@
|
||||
</div>
|
||||
</div>
|
||||
</mat-tab>
|
||||
<mat-tab *ngIf="entity && authUser.authority === authorities.TENANT_ADMIN && !isEdit"
|
||||
label="{{ 'entity.type-calculated-fields' | translate }}" #calculatedFieldsTab="matTab">
|
||||
<tb-calculated-fields-table [active]="calculatedFieldsTab.isActive" [entityId]="entity.id" [entityName]="entity.name"/>
|
||||
</mat-tab>
|
||||
<mat-tab *ngIf="entity && !isEdit" #auditLogsTab="matTab"
|
||||
label="{{ 'audit-log.audit-logs' | translate }}">
|
||||
<tb-audit-log-table detailsMode="true" [active]="auditLogsTab.isActive" [auditLogMode]="auditLogModes.ENTITY" [entityId]="entity.id"></tb-audit-log-table>
|
||||
|
||||
@ -120,6 +120,7 @@ export interface CalculatedFieldDialogData {
|
||||
entityId: EntityId;
|
||||
debugLimitsConfiguration: string;
|
||||
tenantId: string;
|
||||
entityName?: string;
|
||||
}
|
||||
|
||||
export interface ArgumentEntityTypeParams {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user