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 3bb2759274..8bc422eed1 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 @@ -36,14 +36,20 @@ .tb-js-func { .ace_tb { &.ace_calculated-field { - &-key { + &-ctx { color: #C52F00; } - &-ts, &-time-window, &-values, &-value, &-func { + &-args { + color: #185F2A; + } + &-key { + color: #c24c1a; + } + &-time-window, &-values, &-func, &-value, &-ts { color: #7214D0; } - &-start-ts, &-end-ts, &-limit { - color: #185F2A; + &-start-ts, &-end-ts { + color: #2CAA00; } } } 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 0c3e7464cd..052b660c3c 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 @@ -70,7 +70,7 @@ export class CalculatedFieldDialogComponent extends DialogComponent Object.keys(argumentsObj)) + map(argumentsObj => ['ctx', ...Object.keys(argumentsObj)]) ); argumentsEditorCompleter$ = this.configFormGroup.get('arguments').valueChanges diff --git a/ui-ngx/src/app/modules/home/components/calculated-fields/components/panel/calculated-field-argument-panel.component.ts b/ui-ngx/src/app/modules/home/components/calculated-fields/components/panel/calculated-field-argument-panel.component.ts index 7e41f60968..1058f70b49 100644 --- a/ui-ngx/src/app/modules/home/components/calculated-fields/components/panel/calculated-field-argument-panel.component.ts +++ b/ui-ngx/src/app/modules/home/components/calculated-fields/components/panel/calculated-field-argument-panel.component.ts @@ -64,7 +64,7 @@ export class CalculatedFieldArgumentPanelComponent implements OnInit { readonly defaultLimit = Math.floor(this.maxDataPointsPerRollingArg / 10); argumentFormGroup = this.fb.group({ - argumentName: ['', [Validators.required, this.uniqNameRequired(), Validators.pattern(charsWithNumRegex), Validators.maxLength(255)]], + argumentName: ['', [Validators.required, this.uniqNameRequired(), Validators.pattern(/^(?!ctx$).+$/), Validators.pattern(charsWithNumRegex), Validators.maxLength(255)]], refEntityId: this.fb.group({ entityType: [ArgumentEntityType.Current], id: [''] 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 7083ce7ae0..d20a9d8924 100644 --- a/ui-ngx/src/app/shared/models/calculated-field.models.ts +++ b/ui-ngx/src/app/shared/models/calculated-field.models.ts @@ -235,10 +235,10 @@ export type CalculatedFieldArgumentEventValue = CalculatedF export type CalculatedFieldEventArguments = Record>; -export const CalculatedFieldLatestTelemetryArgumentAutocomplete = { +export const CalculatedFieldCtxLatestTelemetryArgumentAutocomplete = { meta: 'object', type: '{ ts: number; value: any; }', - description: 'Calculated field latest telemetry value argument.', + description: 'Calculated field context latest telemetry value argument.', children: { ts: { meta: 'number', @@ -253,10 +253,10 @@ export const CalculatedFieldLatestTelemetryArgumentAutocomplete = { }, }; -export const CalculatedFieldAttributeValueArgumentAutocomplete = { +export const CalculatedFieldCtxAttributeValueArgumentAutocomplete = { meta: 'object', type: '{ ts: number; value: any; }', - description: 'Calculated field attribute value argument.', + description: 'Calculated field context attribute value argument.', children: { ts: { meta: 'number', @@ -270,6 +270,19 @@ export const CalculatedFieldAttributeValueArgumentAutocomplete = { } }, }; + +export const CalculatedFieldLatestTelemetryArgumentAutocomplete = { + meta: 'any', + type: 'any', + description: 'Calculated field latest telemetry argument value.', +}; + +export const CalculatedFieldAttributeValueArgumentAutocomplete = { + meta: 'any', + type: 'any', + description: 'Calculated field attribute argument value.', +}; + export const CalculatedFieldRollingValueArgumentFunctionsAutocomplete = { max: { meta: 'function', @@ -513,35 +526,84 @@ export const getCalculatedFieldArgumentsEditorCompleter = (argumentsObj: Record< switch (argumentsObj[key].refEntityKey.type) { case ArgumentType.Attribute: acc[key] = CalculatedFieldAttributeValueArgumentAutocomplete; + acc.ctx.children.args.children[key] = CalculatedFieldCtxAttributeValueArgumentAutocomplete; break; case ArgumentType.LatestTelemetry: - acc[key] = CalculatedFieldLatestTelemetryArgumentAutocomplete; + acc[key] = { ...CalculatedFieldLatestTelemetryArgumentAutocomplete, children: {} }; + acc.ctx.children.args.children[key] = CalculatedFieldCtxLatestTelemetryArgumentAutocomplete; break; case ArgumentType.Rolling: acc[key] = CalculatedFieldRollingValueArgumentAutocomplete; + acc.ctx.children.args.children[key] = CalculatedFieldRollingValueArgumentAutocomplete; break; } return acc; - }, {})); + }, { + ctx: { + meta: 'object', + type: '{ args: { [key: string]: object } }', + description: 'Calculated field context.', + children: { + args: { + meta: 'object', + type: '{ [key: string]: object }', + description: 'Calculated field context arguments.', + children: {} + } + } + } + })); } export const getCalculatedFieldArgumentsHighlights = ( argumentsObj: Record ): AceHighlightRules => { + const calculatedFieldArgumentsKeys = Object.keys(argumentsObj).map(key => ({ + token: 'tb.calculated-field-key', + regex: `\\b${key}\\b`, + next: argumentsObj[key].refEntityKey.type === ArgumentType.Rolling + ? 'calculatedFieldRollingArgumentValue' + : 'start' + })); + const calculatedFieldCtxArgumentsHighlightRules = { + calculatedFieldCtxArgs: [ + dotOperatorHighlightRule, + ...calculatedFieldArgumentsKeys.map(argumentRule => argumentRule.next === 'start' ? {...argumentRule, next: 'calculatedFieldSingleArgumentValue' } : argumentRule), + endGroupHighlightRule + ] + }; + 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' - })), + start: [ + calculatedFieldArgumentsContextHighlightRules, + ...calculatedFieldArgumentsKeys, + ], + ...calculatedFieldArgumentsContextValueHighlightRules, + ...calculatedFieldCtxArgumentsHighlightRules, ...calculatedFieldSingleArgumentValueHighlightRules, ...calculatedFieldRollingArgumentValueHighlightRules, ...calculatedFieldTimeWindowArgumentValueHighlightRules }; }; +const calculatedFieldArgumentsContextHighlightRules: AceHighlightRule = { + token: 'tb.calculated-field-ctx', + regex: /ctx/, + next: 'calculatedFieldCtxValue' +} + +const calculatedFieldArgumentsContextValueHighlightRules: AceHighlightRules = { + calculatedFieldCtxValue: [ + dotOperatorHighlightRule, + { + token: 'tb.calculated-field-args', + regex: /args/, + next: 'calculatedFieldCtxArgs' + }, + endGroupHighlightRule + ] +} + const calculatedFieldSingleArgumentValueHighlightRules: AceHighlightRules = { calculatedFieldSingleArgumentValue: [ dotOperatorHighlightRule, @@ -597,16 +659,11 @@ const calculatedFieldTimeWindowArgumentValueHighlightRules: AceHighlightRules = regex: /endTs/, next: 'no_regex' }, - { - token: 'tb.calculated-field-limit', - regex: /limit/, - next: 'no_regex' - }, endGroupHighlightRule ] } export const calculatedFieldDefaultScript = 'return {\n' + ' // Convert Fahrenheit to Celsius\n' + - ' "temperatureCelsius": (temperature.value - 32) / 1.8\n' + + ' "temperatureCelsius": (temperature - 32) / 1.8\n' + '};'