diff --git a/ui-ngx/src/app/modules/home/components/calculated-fields/components/dialog/calculated-field-dialog.component.html b/ui-ngx/src/app/modules/home/components/calculated-fields/components/dialog/calculated-field-dialog.component.html index 0695b9d2b9..7e0f87a12e 100644 --- a/ui-ngx/src/app/modules/home/components/calculated-fields/components/dialog/calculated-field-dialog.component.html +++ b/ui-ngx/src/app/modules/home/components/calculated-fields/components/dialog/calculated-field-dialog.component.html @@ -78,7 +78,7 @@
{{ 'calculated-fields.expression' | translate }}
@if (fieldFormGroup.get('type').value === CalculatedFieldType.SIMPLE) { - + @if (configFormGroup.get('expressionSIMPLE').errors && configFormGroup.get('expressionSIMPLE').touched) { @if (configFormGroup.get('expressionSIMPLE').hasError('required')) { @@ -89,6 +89,8 @@ {{ 'calculated-fields.hint.expression-max-length' | translate }} } + } @else { + {{ 'calculated-fields.hint.expression' | translate }} } } @else { 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 900758761c..0e994ed825 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 @@ -40,7 +40,7 @@ &-key { color: #C52F00; } - &-ts, &-time-window, &-values, &-value { + &-ts, &-time-window, &-values, &-value, &-func { color: #7214D0; } &-start-ts, &-end-ts, &-limit { 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 57234aa692..cda99f6c09 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 @@ -45,7 +45,7 @@ [scriptLanguage]="ScriptLanguage.TBEL" [editorCompleter]="data.argumentsEditorCompleter" resultType="object" - helpId="calculated-field/test-expression_fn" + helpId="calculated-field/expression_fn" /> 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 298ab64e26..2187b47e0d 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 @@ -78,7 +78,7 @@ &-key { color: #C52F00; } - &-ts, &-time-window, &-values, &-value { + &-ts, &-time-window, &-values, &-value, &-func { color: #7214D0; } &-start-ts, &-end-ts, &-limit { 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 5d9c4f14c6..f6d7aaaa1e 100644 --- a/ui-ngx/src/app/shared/models/calculated-field.models.ts +++ b/ui-ngx/src/app/shared/models/calculated-field.models.ts @@ -29,6 +29,7 @@ import { AliasFilterType } from '@shared/models/alias.models'; import { Observable } from 'rxjs'; import { TbEditorCompleter } from '@shared/models/ace/completion.models'; import { + AceHighlightRule, AceHighlightRules, dotOperatorHighlightRule, endGroupHighlightRule @@ -268,12 +269,159 @@ export const CalculatedFieldAttributeValueArgumentAutocomplete = { } }, }; +export const CalculatedFieldRollingValueArgumentFunctionsAutocomplete = { + max: { + meta: 'function', + description: 'Computes the maximum value in the list of rolling argument values. Returns NaN if any value is NaN and ignoreNaN is false.', + args: [ + { + name: 'ignoreNaN', + description: 'Whether to ignore NaN values. Equals true by default.', + type: 'boolean', + optional: true, + } + ], + return: { + description: 'The maximum value, or NaN if applicable', + type: 'number' + } + }, + min: { + meta: 'function', + description: 'Computes the minimum value in the list of rolling argument values. Returns NaN if any value is NaN and ignoreNaN is false.', + args: [ + { + name: 'ignoreNaN', + description: 'Whether to ignore NaN values. Equals true by default.', + type: 'boolean', + optional: true, + } + ], + return: { + description: 'The minimum value, or NaN if applicable', + type: 'number' + } + }, + mean: { + meta: 'function', + description: 'Computes the mean value of the rolling argument values list. Returns NaN if any value is NaN and ignoreNaN is false.', + args: [ + { + name: 'ignoreNaN', + description: 'Whether to ignore NaN values. Equals true by default.', + type: 'boolean', + optional: true, + } + ], + return: { + description: 'The mean value, or NaN if applicable', + type: 'number' + } + }, + std: { + meta: 'function', + description: 'Computes the standard deviation in the list of rolling argument values. Returns NaN if any value is NaN and ignoreNaN is false.', + args: [ + { + name: 'ignoreNaN', + description: 'Whether to ignore NaN values. Equals true by default.', + type: 'boolean', + optional: true, + } + ], + return: { + description: 'The standard deviation, or NaN if applicable', + type: 'number' + } + }, + median: { + meta: 'function', + description: 'Computes the median value of the rolling argument values list. Returns NaN if any value is NaN and ignoreNaN is false.', + args: [ + { + name: 'ignoreNaN', + description: 'Whether to ignore NaN values. Equals true by default.', + type: 'boolean', + optional: true, + } + ], + return: { + description: 'The median value, or NaN if applicable', + type: 'number' + } + }, + count: { + meta: 'function', + description: 'Counts values in the list of rolling argument values. Counts non-NaN values if ignoreNaN is true, otherwise - total size.', + args: [ + { + name: 'ignoreNaN', + description: 'Whether to ignore NaN values. Equals true by default.', + type: 'boolean', + optional: true, + } + ], + return: { + description: 'The count of values', + type: 'number' + } + }, + last: { + meta: 'function', + description: 'Returns the last non-NaN value in the list of rolling argument values if ignoreNaN is true, otherwise - the last value.', + args: [ + { + name: 'ignoreNaN', + description: 'Whether to ignore NaN values. Equals true by default.', + type: 'boolean', + optional: true, + } + ], + return: { + description: 'The last value, or NaN if applicable', + type: 'number' + } + }, + first: { + meta: 'function', + description: 'Returns the first non-NaN value in the list of rolling argument values if ignoreNaN is true, otherwise - the first value.', + args: [ + { + name: 'ignoreNaN', + description: 'Whether to ignore NaN values. Equals true by default.', + type: 'boolean', + optional: true, + } + ], + return: { + description: 'The first value, or NaN if applicable', + type: 'number' + } + }, + sum: { + meta: 'function', + description: 'Computes the sum of values in the list of rolling argument values. Returns NaN if any value is NaN and ignoreNaN is false.', + args: [ + { + name: 'ignoreNaN', + description: 'Whether to ignore NaN values. Equals true by default.', + type: 'boolean', + optional: true, + } + ], + return: { + description: 'The sum of values, or NaN if applicable', + type: 'number' + } + } +}; export const CalculatedFieldRollingValueArgumentAutocomplete = { meta: 'object', type: '{ values: { ts: number; value: any; }[]; timeWindow: { startTs: number; endTs: number; limit: number } }; }', description: 'Calculated field rolling value argument.', children: { + ...CalculatedFieldRollingValueArgumentFunctionsAutocomplete, values: { meta: 'array', type: '{ ts: number; value: any; }[]', @@ -355,6 +503,13 @@ const calculatedFieldSingleArgumentValueHighlightRules: AceHighlightRules = { ], } +const calculatedFieldRollingArgumentValueFunctionsHighlightRules: Array = + ['max', 'min', 'mean', 'std', 'median', 'count', 'last', 'first', 'sum'].map(funcName => ({ + token: 'tb.calculated-field-func', + regex: `\\b${funcName}\\b`, + next: 'no_regex' + })); + const calculatedFieldRollingArgumentValueHighlightRules: AceHighlightRules = { calculatedFieldRollingArgumentValue: [ dotOperatorHighlightRule, @@ -368,6 +523,7 @@ const calculatedFieldRollingArgumentValueHighlightRules: AceHighlightRules = { regex: /timeWindow/, next: 'calculatedFieldRollingArgumentTimeWindow' }, + ...calculatedFieldRollingArgumentValueFunctionsHighlightRules, endGroupHighlightRule ], } diff --git a/ui-ngx/src/assets/help/en_US/calculated-field/test-expression_fn.md b/ui-ngx/src/assets/help/en_US/calculated-field/test-expression_fn.md deleted file mode 100644 index f8173dc528..0000000000 --- a/ui-ngx/src/assets/help/en_US/calculated-field/test-expression_fn.md +++ /dev/null @@ -1 +0,0 @@ - diff --git a/ui-ngx/src/assets/locale/locale.constant-en_US.json b/ui-ngx/src/assets/locale/locale.constant-en_US.json index 9de260bed2..1163024e90 100644 --- a/ui-ngx/src/assets/locale/locale.constant-en_US.json +++ b/ui-ngx/src/assets/locale/locale.constant-en_US.json @@ -1069,7 +1069,8 @@ "argument-name-duplicate": "Argument with such name already exists.", "argument-name-max-length": "Argument name should be less than 256 characters.", "argument-type-required": "Argument type is required.", - "max-args": "Maximum number of arguments reached." + "max-args": "Maximum number of arguments reached.", + "expression": "Default expression demonstrates how to transform a temperature from Fahrenheit to Celsius." } }, "confirm-on-exit": {