This commit is contained in:
mpetrov 2025-01-31 19:18:57 +02:00
parent 8dca91c909
commit dd8ce35b86
7 changed files with 14 additions and 12 deletions

View File

@ -50,7 +50,7 @@ import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
import { EntityId } from '@shared/models/id/entity-id'; import { EntityId } from '@shared/models/id/entity-id';
import { EntityType, entityTypeTranslations } from '@shared/models/entity-type.models'; import { EntityType, entityTypeTranslations } from '@shared/models/entity-type.models';
import { isDefinedAndNotNull } from '@core/utils'; import { isDefinedAndNotNull } from '@core/utils';
import { charNumRegex } from '@shared/models/regex.constants'; import { charsWithNumRegex } from '@shared/models/regex.constants';
@Component({ @Component({
selector: 'tb-calculated-field-arguments-table', selector: 'tb-calculated-field-arguments-table',
@ -187,7 +187,7 @@ export class CalculatedFieldArgumentsTableComponent implements ControlValueAcces
private populateArgumentsFormArray(argumentsObj: Record<string, CalculatedFieldArgument>): void { private populateArgumentsFormArray(argumentsObj: Record<string, CalculatedFieldArgument>): void {
Object.keys(argumentsObj).forEach(key => { Object.keys(argumentsObj).forEach(key => {
this.argumentsFormArray.push(this.fb.group({ this.argumentsFormArray.push(this.fb.group({
argumentName: [key, [Validators.required, Validators.maxLength(255), Validators.pattern(charNumRegex)]], argumentName: [key, [Validators.required, Validators.maxLength(255), Validators.pattern(charsWithNumRegex)]],
...argumentsObj[key], ...argumentsObj[key],
...(argumentsObj[key].refEntityId ? { ...(argumentsObj[key].refEntityId ? {
refEntityId: this.fb.group({ refEntityId: this.fb.group({
@ -206,7 +206,7 @@ export class CalculatedFieldArgumentsTableComponent implements ControlValueAcces
private getArgumentFormGroup(value: CalculatedFieldArgumentValue): AbstractControl { private getArgumentFormGroup(value: CalculatedFieldArgumentValue): AbstractControl {
return this.fb.group({ return this.fb.group({
...value, ...value,
argumentName: [value.argumentName, [Validators.required, Validators.maxLength(255), Validators.pattern(charNumRegex)]], argumentName: [value.argumentName, [Validators.required, Validators.maxLength(255), Validators.pattern(charsWithNumRegex)]],
...(value.refEntityId ? { ...(value.refEntityId ? {
refEntityId: this.fb.group({ refEntityId: this.fb.group({
entityType: [{ value: value.refEntityId.entityType, disabled: true }], entityType: [{ value: value.refEntityId.entityType, disabled: true }],

View File

@ -61,7 +61,7 @@ export class CalculatedFieldDialogComponent extends DialogComponent<CalculatedFi
}), }),
}); });
functionArgs$ = this.fieldFormGroup.get('configuration').valueChanges functionArgs$ = this.configFormGroup.valueChanges
.pipe( .pipe(
map(configuration => isObject(configuration?.arguments) ? Object.keys(configuration.arguments) : []) map(configuration => isObject(configuration?.arguments) ? Object.keys(configuration.arguments) : [])
); );

View File

@ -23,7 +23,7 @@
<div class="fixed-title-width tb-required">{{ 'calculated-fields.argument-name' | translate }}</div> <div class="fixed-title-width tb-required">{{ 'calculated-fields.argument-name' | translate }}</div>
<div class="tb-flex no-gap"> <div class="tb-flex no-gap">
<mat-form-field class="tb-flex no-gap" appearance="outline" subscriptSizing="dynamic"> <mat-form-field class="tb-flex no-gap" appearance="outline" subscriptSizing="dynamic">
<input matInput name="value" formControlName="argumentName" maxlength="255" placeholder="{{ 'action.set' | translate }}"/> <input matInput autocomplete="off" name="value" formControlName="argumentName" maxlength="255" placeholder="{{ 'action.set' | translate }}"/>
<div class="h-5 pr-2"> <div class="h-5 pr-2">
@if (argumentFormGroup.get('argumentName').touched) { @if (argumentFormGroup.get('argumentName').touched) {
@if (argumentFormGroup.get('argumentName').hasError('required')) { @if (argumentFormGroup.get('argumentName').hasError('required')) {

View File

@ -18,7 +18,7 @@ import { ChangeDetectorRef, Component, ElementRef, Input, OnInit, output, ViewCh
import { TbPopoverComponent } from '@shared/components/popover.component'; import { TbPopoverComponent } from '@shared/components/popover.component';
import { PageComponent } from '@shared/components/page.component'; import { PageComponent } from '@shared/components/page.component';
import { FormBuilder, FormGroup, Validators } from '@angular/forms'; import { FormBuilder, FormGroup, Validators } from '@angular/forms';
import { charNumRegex, noLeadTrailSpacesRegex } from '@shared/models/regex.constants'; import { charsWithNumRegex, noLeadTrailSpacesRegex } from '@shared/models/regex.constants';
import { import {
ArgumentEntityType, ArgumentEntityType,
ArgumentEntityTypeTranslations, ArgumentEntityTypeTranslations,
@ -58,7 +58,7 @@ export class CalculatedFieldArgumentPanelComponent extends PageComponent impleme
argumentsDataApplied = output<{ value: CalculatedFieldArgumentValue, index: number }>(); argumentsDataApplied = output<{ value: CalculatedFieldArgumentValue, index: number }>();
argumentFormGroup = this.fb.group({ argumentFormGroup = this.fb.group({
argumentName: ['', [Validators.required, Validators.pattern(charNumRegex), Validators.maxLength(255)]], argumentName: ['', [Validators.required, Validators.pattern(charsWithNumRegex), Validators.maxLength(255)]],
refEntityId: this.fb.group({ refEntityId: this.fb.group({
entityType: [ArgumentEntityType.Current], entityType: [ArgumentEntityType.Current],
id: [''] id: ['']
@ -66,10 +66,10 @@ export class CalculatedFieldArgumentPanelComponent extends PageComponent impleme
refEntityKey: this.fb.group({ refEntityKey: this.fb.group({
type: [ArgumentType.LatestTelemetry, [Validators.required]], type: [ArgumentType.LatestTelemetry, [Validators.required]],
key: [''], key: [''],
scope: [{ value: AttributeScope.SERVER_SCOPE, disabled: true }], scope: [{ value: AttributeScope.SERVER_SCOPE, disabled: true }, [Validators.required]],
}), }),
defaultValue: ['', [Validators.pattern(noLeadTrailSpacesRegex)]], defaultValue: ['', [Validators.pattern(noLeadTrailSpacesRegex)]],
limit: [10], limit: [1000],
timeWindow: [MINUTE * 15], timeWindow: [MINUTE * 15],
}); });

View File

@ -43,7 +43,9 @@
@for (key of filteredKeys$ | async; track key) { @for (key of filteredKeys$ | async; track key) {
<mat-option [value]="key"><span [innerHTML]="key | highlight: searchText"></span></mat-option> <mat-option [value]="key"><span [innerHTML]="key | highlight: searchText"></span></mat-option>
} @empty { } @empty {
<mat-option [value]="''">{{ 'entity.no-keys-found' | translate }}</mat-option> @if (!this.keyControl.value) {
<mat-option [value]="''">{{ 'entity.no-keys-found' | translate }}</mat-option>
}
} }
</mat-autocomplete> </mat-autocomplete>
</mat-form-field> </mat-form-field>

View File

@ -16,4 +16,4 @@
export const noLeadTrailSpacesRegex = /^\S+(?: \S+)*$/; export const noLeadTrailSpacesRegex = /^\S+(?: \S+)*$/;
export const charNumRegex = /^[a-zA-Z0-9]+$/; export const charsWithNumRegex = /^[a-zA-Z]+[a-zA-Z0-9]*$/;

View File

@ -1048,7 +1048,7 @@
"delete-multiple-title": "Are you sure you want to delete { count, plural, =1 {1 calculated field} other {# calculated fields} }?", "delete-multiple-title": "Are you sure you want to delete { count, plural, =1 {1 calculated field} other {# calculated fields} }?",
"delete-multiple-text": "Be careful, after the confirmation all selected calculated fields will be removed and all related data will become unrecoverable.", "delete-multiple-text": "Be careful, after the confirmation all selected calculated fields will be removed and all related data will become unrecoverable.",
"hint": { "hint": {
"arguments-simple-with-rolling": "Simple type calculated field should not contain keys with rolling type.", "arguments-simple-with-rolling": "Simple type calculated field should not contain keys with time series rolling type.",
"arguments-empty": "Arguments should not be empty.", "arguments-empty": "Arguments should not be empty.",
"expression-required": "Expression is required.", "expression-required": "Expression is required.",
"expression-invalid": "Expression is invalid", "expression-invalid": "Expression is invalid",