diff --git a/ui-ngx/src/app/modules/home/components/calculated-fields/calculated-fields-table-config.ts b/ui-ngx/src/app/modules/home/components/calculated-fields/calculated-fields-table-config.ts index 93fd6d1fd6..783ae6be5c 100644 --- a/ui-ngx/src/app/modules/home/components/calculated-fields/calculated-fields-table-config.ts +++ b/ui-ngx/src/app/modules/home/components/calculated-fields/calculated-fields-table-config.ts @@ -43,6 +43,7 @@ import { CalculatedFieldDialogData, CalculatedFieldTestScriptDialogData, getCalculatedFieldArgumentsEditorCompleter, + getCalculatedFieldArgumentsHighlights, } from '@shared/models/calculated-field.models'; import { CalculatedFieldDebugDialogComponent, @@ -275,6 +276,7 @@ export class CalculatedFieldsTableConfig extends EntityTableConfig diff --git a/ui-ngx/src/app/modules/home/components/calculated-fields/components/dialog/calculated-field-dialog.component.scss b/ui-ngx/src/app/modules/home/components/calculated-fields/components/dialog/calculated-field-dialog.component.scss index bc49e05e8d..c17dbf8bb5 100644 --- a/ui-ngx/src/app/modules/home/components/calculated-fields/components/dialog/calculated-field-dialog.component.scss +++ b/ui-ngx/src/app/modules/home/components/calculated-fields/components/dialog/calculated-field-dialog.component.scss @@ -20,3 +20,21 @@ max-width: 100%; } } + +:host ::ng-deep { + .expression-edit { + .ace_tb { + &.ace_calculated-field { + &-key { + color: #C52F00; + } + &-ts, &-time-window, &-values, &-value { + color: #7214D0; + } + &-start-ts, &-end-ts, &-limit { + color: #185F2A; + } + } + } + } +} diff --git a/ui-ngx/src/app/modules/home/components/calculated-fields/components/dialog/calculated-field-dialog.component.ts b/ui-ngx/src/app/modules/home/components/calculated-fields/components/dialog/calculated-field-dialog.component.ts index 5785c62cc9..bffb405534 100644 --- a/ui-ngx/src/app/modules/home/components/calculated-fields/components/dialog/calculated-field-dialog.component.ts +++ b/ui-ngx/src/app/modules/home/components/calculated-fields/components/dialog/calculated-field-dialog.component.ts @@ -28,6 +28,7 @@ import { CalculatedFieldType, CalculatedFieldTypeTranslations, getCalculatedFieldArgumentsEditorCompleter, + getCalculatedFieldArgumentsHighlights, OutputType, OutputTypeTranslations } from '@shared/models/calculated-field.models'; @@ -74,6 +75,12 @@ export class CalculatedFieldDialogComponent extends DialogComponent getCalculatedFieldArgumentsEditorCompleter(argumentsObj)) ); + argumentsHighlightRules$ = this.configFormGroup.get('arguments').valueChanges + .pipe( + startWith(this.data.value?.configuration?.arguments ?? {}), + map(argumentsObj => getCalculatedFieldArgumentsHighlights(argumentsObj)) + ); + additionalDebugActionConfig = this.data.value?.id ? { ...this.data.additionalDebugActionConfig, action: () => this.data.additionalDebugActionConfig.action({ id: this.data.value.id, ...this.fromGroupValue }), diff --git a/ui-ngx/src/app/modules/home/components/calculated-fields/components/test-dialog/calculated-field-script-test-dialog.component.html b/ui-ngx/src/app/modules/home/components/calculated-fields/components/test-dialog/calculated-field-script-test-dialog.component.html index 6b0a273a51..789d290a6d 100644 --- a/ui-ngx/src/app/modules/home/components/calculated-fields/components/test-dialog/calculated-field-script-test-dialog.component.html +++ b/ui-ngx/src/app/modules/home/components/calculated-fields/components/test-dialog/calculated-field-script-test-dialog.component.html @@ -36,9 +36,11 @@ #expressionContent formControlName="expression" functionName="calculate" + class="expression-edit" [functionArgs]="functionArgs" [disableUndefinedCheck]="true" [fillHeight]="true" + [highlightRules]="data.argumentsHighlightRules" [scriptLanguage]="ScriptLanguage.TBEL" [editorCompleter]="data.argumentsEditorCompleter" resultType="object" diff --git a/ui-ngx/src/app/modules/home/components/calculated-fields/components/test-dialog/calculated-field-script-test-dialog.component.scss b/ui-ngx/src/app/modules/home/components/calculated-fields/components/test-dialog/calculated-field-script-test-dialog.component.scss index eaee8e443d..03ef1c3540 100644 --- a/ui-ngx/src/app/modules/home/components/calculated-fields/components/test-dialog/calculated-field-script-test-dialog.component.scss +++ b/ui-ngx/src/app/modules/home/components/calculated-fields/components/test-dialog/calculated-field-script-test-dialog.component.scss @@ -71,4 +71,20 @@ background-image: url("../../../../../../../assets/split.js/grips/vertical.png"); } } + + .expression-edit { + .ace_tb { + &.ace_calculated-field { + &-key { + color: #C52F00; + } + &-ts, &-time-window, &-values, &-value { + color: #7214D0; + } + &-start-ts, &-end-ts, &-limit { + color: #185F2A; + } + } + } + } } diff --git a/ui-ngx/src/app/shared/components/js-func.component.ts b/ui-ngx/src/app/shared/components/js-func.component.ts index b1744038c3..b4898b2377 100644 --- a/ui-ngx/src/app/shared/components/js-func.component.ts +++ b/ui-ngx/src/app/shared/components/js-func.component.ts @@ -187,6 +187,9 @@ export class JsFuncComponent implements OnInit, OnChanges, OnDestroy, ControlVal if (changes.editorCompleter?.previousValue) { this.updateCompleters(); } + if (changes.highlightRules?.previousValue) { + this.updateHighlightRules(); + } } ngOnInit(): void { @@ -247,21 +250,7 @@ export class JsFuncComponent implements OnInit, OnChanges, OnDestroy, ControlVal } }); } - // @ts-ignore - if (!!this.highlightRules && !!this.jsEditor.session.$mode) { - // @ts-ignore - const newMode = new this.jsEditor.session.$mode.constructor(); - newMode.$highlightRules = new newMode.HighlightRules(); - for(const group in this.highlightRules) { - if(!!newMode.$highlightRules.$rules[group]) { - newMode.$highlightRules.$rules[group].unshift(...this.highlightRules[group]); - } else { - newMode.$highlightRules.$rules[group] = this.highlightRules[group]; - } - } - // @ts-ignore - this.jsEditor.session.$onChangeMode(newMode); - } + this.updateHighlightRules(); this.updateJsWorkerGlobals(); this.initialCompleters = this.jsEditor.completers || []; this.updateCompleters(); @@ -282,6 +271,24 @@ export class JsFuncComponent implements OnInit, OnChanges, OnDestroy, ControlVal } } + private updateHighlightRules(): void { + // @ts-ignore + if (!!this.highlightRules && !!this.jsEditor.session.$mode) { + // @ts-ignore + const newMode = new this.jsEditor.session.$mode.constructor(); + newMode.$highlightRules = new newMode.HighlightRules(); + for(const group in this.highlightRules) { + if(!!newMode.$highlightRules.$rules[group]) { + newMode.$highlightRules.$rules[group].unshift(...this.highlightRules[group]); + } else { + newMode.$highlightRules.$rules[group] = this.highlightRules[group]; + } + } + // @ts-ignore + this.jsEditor.session.$onChangeMode(newMode); + } + } + private onAceEditorResize() { if (this.editorsResizeCaf) { this.editorsResizeCaf(); diff --git a/ui-ngx/src/app/shared/models/calculated-field.models.ts b/ui-ngx/src/app/shared/models/calculated-field.models.ts index ba4131147f..5ce1a50d04 100644 --- a/ui-ngx/src/app/shared/models/calculated-field.models.ts +++ b/ui-ngx/src/app/shared/models/calculated-field.models.ts @@ -28,6 +28,7 @@ import { EntityType } from '@shared/models/entity-type.models'; import { AliasFilterType } from '@shared/models/alias.models'; import { Observable } from 'rxjs'; import { TbEditorCompleter } from '@shared/models/ace/completion.models'; +import { AceHighlightRules } from '@shared/models/ace/ace.models'; export interface CalculatedField extends Omit, 'label'>, HasVersion, HasTenantId, ExportableEntity { debugSettings?: EntityDebugSettings; @@ -168,6 +169,7 @@ export interface CalculatedFieldTestScriptInputParams { export interface CalculatedFieldTestScriptDialogData extends CalculatedFieldTestScriptInputParams { argumentsEditorCompleter: TbEditorCompleter; + argumentsHighlightRules: AceHighlightRules; openCalculatedFieldEdit?: boolean; } @@ -313,5 +315,72 @@ export const getCalculatedFieldArgumentsEditorCompleter = (argumentsObj: Record< break; } return acc; - }, {})) + }, {})); +} + +export const getCalculatedFieldArgumentsHighlights = ( + argumentsObj: Record +): AceHighlightRules => { + return { + start: Object.keys(argumentsObj).map(key => ({ + token: 'tb.calculated-field-key', + regex: `\\b${key}\\b`, + next: argumentsObj[key].refEntityKey.type === ArgumentType.Rolling + ? 'calculatedFieldRollingArgumentValue' + : 'calculatedFieldSingleArgumentValue' + })), + ...calculatedFieldSingleArgumentValueHighlightRules, + ...calculatedFieldRollingArgumentValueHighlightRules, + ...calculatedFieldTimeWindowArgumentValueHighlightRules + }; +}; + +const calculatedFieldSingleArgumentValueHighlightRules: AceHighlightRules = { + calculatedFieldSingleArgumentValue: [ + { + token: 'tb.calculated-field-value', + regex: /value/, + next: 'no_regex' + }, + { + token: 'tb.calculated-field-ts', + regex: /ts/, + next: 'no_regex' + } + ], +} + +const calculatedFieldRollingArgumentValueHighlightRules: AceHighlightRules = { + calculatedFieldRollingArgumentValue: [ + { + token: 'tb.calculated-field-values', + regex: /values/, + next: 'no_regex' + }, + { + token: 'tb.calculated-field-time-window', + regex: /timeWindow/, + next: 'calculatedFieldRollingArgumentTimeWindow' + } + ], +} + +const calculatedFieldTimeWindowArgumentValueHighlightRules: AceHighlightRules = { + calculatedFieldRollingArgumentTimeWindow: [ + { + token: 'tb.calculated-field-start-ts', + regex: /startTs/, + next: 'no_regex' + }, + { + token: 'tb.calculated-field-end-ts', + regex: /endTs/, + next: 'no_regex' + }, + { + token: 'tb.calculated-field-limit', + regex: /limit/, + next: 'no_regex' + } + ] }