Added highlight rules

This commit is contained in:
mpetrov 2025-02-18 18:21:59 +02:00
parent 036cff6a75
commit 7216719d3e
8 changed files with 139 additions and 16 deletions

View File

@ -43,6 +43,7 @@ import {
CalculatedFieldDialogData, CalculatedFieldDialogData,
CalculatedFieldTestScriptDialogData, CalculatedFieldTestScriptDialogData,
getCalculatedFieldArgumentsEditorCompleter, getCalculatedFieldArgumentsEditorCompleter,
getCalculatedFieldArgumentsHighlights,
} from '@shared/models/calculated-field.models'; } from '@shared/models/calculated-field.models';
import { import {
CalculatedFieldDebugDialogComponent, CalculatedFieldDebugDialogComponent,
@ -275,6 +276,7 @@ export class CalculatedFieldsTableConfig extends EntityTableConfig<CalculatedFie
arguments: resultArguments, arguments: resultArguments,
expression: calculatedField.configuration.expression, expression: calculatedField.configuration.expression,
argumentsEditorCompleter: getCalculatedFieldArgumentsEditorCompleter(calculatedField.configuration.arguments), argumentsEditorCompleter: getCalculatedFieldArgumentsEditorCompleter(calculatedField.configuration.arguments),
argumentsHighlightRules: getCalculatedFieldArgumentsHighlights(calculatedField.configuration.arguments),
openCalculatedFieldEdit openCalculatedFieldEdit
} }
}).afterClosed() }).afterClosed()

View File

@ -96,9 +96,11 @@
required required
formControlName="expressionSCRIPT" formControlName="expressionSCRIPT"
functionName="calculate" functionName="calculate"
class="expression-edit"
[functionArgs]="functionArgs$ | async" [functionArgs]="functionArgs$ | async"
[disableUndefinedCheck]="true" [disableUndefinedCheck]="true"
[scriptLanguage]="ScriptLanguage.TBEL" [scriptLanguage]="ScriptLanguage.TBEL"
[highlightRules]="argumentsHighlightRules$ | async"
[editorCompleter]="argumentsEditorCompleter$ | async" [editorCompleter]="argumentsEditorCompleter$ | async"
helpId="calculated-field/expression_fn" helpId="calculated-field/expression_fn"
> >

View File

@ -20,3 +20,21 @@
max-width: 100%; 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;
}
}
}
}
}

View File

@ -28,6 +28,7 @@ import {
CalculatedFieldType, CalculatedFieldType,
CalculatedFieldTypeTranslations, CalculatedFieldTypeTranslations,
getCalculatedFieldArgumentsEditorCompleter, getCalculatedFieldArgumentsEditorCompleter,
getCalculatedFieldArgumentsHighlights,
OutputType, OutputType,
OutputTypeTranslations OutputTypeTranslations
} from '@shared/models/calculated-field.models'; } from '@shared/models/calculated-field.models';
@ -74,6 +75,12 @@ export class CalculatedFieldDialogComponent extends DialogComponent<CalculatedFi
map(argumentsObj => getCalculatedFieldArgumentsEditorCompleter(argumentsObj)) map(argumentsObj => getCalculatedFieldArgumentsEditorCompleter(argumentsObj))
); );
argumentsHighlightRules$ = this.configFormGroup.get('arguments').valueChanges
.pipe(
startWith(this.data.value?.configuration?.arguments ?? {}),
map(argumentsObj => getCalculatedFieldArgumentsHighlights(argumentsObj))
);
additionalDebugActionConfig = this.data.value?.id ? { additionalDebugActionConfig = this.data.value?.id ? {
...this.data.additionalDebugActionConfig, ...this.data.additionalDebugActionConfig,
action: () => this.data.additionalDebugActionConfig.action({ id: this.data.value.id, ...this.fromGroupValue }), action: () => this.data.additionalDebugActionConfig.action({ id: this.data.value.id, ...this.fromGroupValue }),

View File

@ -36,9 +36,11 @@
#expressionContent #expressionContent
formControlName="expression" formControlName="expression"
functionName="calculate" functionName="calculate"
class="expression-edit"
[functionArgs]="functionArgs" [functionArgs]="functionArgs"
[disableUndefinedCheck]="true" [disableUndefinedCheck]="true"
[fillHeight]="true" [fillHeight]="true"
[highlightRules]="data.argumentsHighlightRules"
[scriptLanguage]="ScriptLanguage.TBEL" [scriptLanguage]="ScriptLanguage.TBEL"
[editorCompleter]="data.argumentsEditorCompleter" [editorCompleter]="data.argumentsEditorCompleter"
resultType="object" resultType="object"

View File

@ -71,4 +71,20 @@
background-image: url("../../../../../../../assets/split.js/grips/vertical.png"); 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;
}
}
}
}
} }

View File

@ -187,6 +187,9 @@ export class JsFuncComponent implements OnInit, OnChanges, OnDestroy, ControlVal
if (changes.editorCompleter?.previousValue) { if (changes.editorCompleter?.previousValue) {
this.updateCompleters(); this.updateCompleters();
} }
if (changes.highlightRules?.previousValue) {
this.updateHighlightRules();
}
} }
ngOnInit(): void { ngOnInit(): void {
@ -247,21 +250,7 @@ export class JsFuncComponent implements OnInit, OnChanges, OnDestroy, ControlVal
} }
}); });
} }
// @ts-ignore this.updateHighlightRules();
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.updateJsWorkerGlobals(); this.updateJsWorkerGlobals();
this.initialCompleters = this.jsEditor.completers || []; this.initialCompleters = this.jsEditor.completers || [];
this.updateCompleters(); 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() { private onAceEditorResize() {
if (this.editorsResizeCaf) { if (this.editorsResizeCaf) {
this.editorsResizeCaf(); this.editorsResizeCaf();

View File

@ -28,6 +28,7 @@ import { EntityType } from '@shared/models/entity-type.models';
import { AliasFilterType } from '@shared/models/alias.models'; import { AliasFilterType } from '@shared/models/alias.models';
import { Observable } from 'rxjs'; import { Observable } from 'rxjs';
import { TbEditorCompleter } from '@shared/models/ace/completion.models'; import { TbEditorCompleter } from '@shared/models/ace/completion.models';
import { AceHighlightRules } from '@shared/models/ace/ace.models';
export interface CalculatedField extends Omit<BaseData<CalculatedFieldId>, 'label'>, HasVersion, HasTenantId, ExportableEntity<CalculatedFieldId> { export interface CalculatedField extends Omit<BaseData<CalculatedFieldId>, 'label'>, HasVersion, HasTenantId, ExportableEntity<CalculatedFieldId> {
debugSettings?: EntityDebugSettings; debugSettings?: EntityDebugSettings;
@ -168,6 +169,7 @@ export interface CalculatedFieldTestScriptInputParams {
export interface CalculatedFieldTestScriptDialogData extends CalculatedFieldTestScriptInputParams { export interface CalculatedFieldTestScriptDialogData extends CalculatedFieldTestScriptInputParams {
argumentsEditorCompleter: TbEditorCompleter; argumentsEditorCompleter: TbEditorCompleter;
argumentsHighlightRules: AceHighlightRules;
openCalculatedFieldEdit?: boolean; openCalculatedFieldEdit?: boolean;
} }
@ -313,5 +315,72 @@ export const getCalculatedFieldArgumentsEditorCompleter = (argumentsObj: Record<
break; break;
} }
return acc; return acc;
}, {})) }, {}));
}
export const getCalculatedFieldArgumentsHighlights = (
argumentsObj: Record<string, CalculatedFieldArgument>
): 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'
}
]
} }