From 0b44abe121850d2b8eb3cdb9b28bc5bf730c3f69 Mon Sep 17 00:00:00 2001 From: mpetrov Date: Wed, 26 Feb 2025 18:33:26 +0200 Subject: [PATCH] JS func update --- .../api/tbel/TbelCfTsRollingArgTest.java | 2 +- .../shared/components/js-func.component.ts | 101 ++++++++++++------ 2 files changed, 67 insertions(+), 36 deletions(-) diff --git a/common/script/script-api/src/test/java/org/thingsboard/script/api/tbel/TbelCfTsRollingArgTest.java b/common/script/script-api/src/test/java/org/thingsboard/script/api/tbel/TbelCfTsRollingArgTest.java index e4ebf8a8c1..327b477b6f 100644 --- a/common/script/script-api/src/test/java/org/thingsboard/script/api/tbel/TbelCfTsRollingArgTest.java +++ b/common/script/script-api/src/test/java/org/thingsboard/script/api/tbel/TbelCfTsRollingArgTest.java @@ -1,5 +1,5 @@ /** - * Copyright © 2016-2024 The Thingsboard Authors + * Copyright © 2016-2025 The Thingsboard Authors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. 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 4ea4abea3c..dfb76b4620 100644 --- a/ui-ngx/src/app/shared/components/js-func.component.ts +++ b/ui-ngx/src/app/shared/components/js-func.component.ts @@ -37,7 +37,7 @@ import { ActionNotificationHide, ActionNotificationShow } from '@core/notificati import { Store } from '@ngrx/store'; import { AppState } from '@core/core.state'; import { UtilsService } from '@core/services/utils.service'; -import { deepClone, guid, isUndefined, isUndefinedOrNull } from '@app/core/utils'; +import { deepClone, guid, isEqual, isObject, isUndefined, isUndefinedOrNull } from '@app/core/utils'; import { TranslateService } from '@ngx-translate/core'; import { CancelAnimationFrame, RafService } from '@core/services/raf.service'; import { TbEditorCompleter } from '@shared/models/ace/completion.models'; @@ -179,26 +179,12 @@ export class JsFuncComponent implements OnInit, OnChanges, OnDestroy, ControlVal private http: HttpClient) { } - ngOnChanges(changes: SimpleChanges): void { - if (changes.functionArgs) { - this.updateFunctionArgsString(); - this.updateFunctionLabel(); - } - if (changes.editorCompleter?.previousValue) { - this.updateCompleters(); - } - if (changes.highlightRules?.previousValue) { - this.updateHighlightRules(); - } - } - ngOnInit(): void { - if (this.functionTitle || this.label) { - this.hideBrackets = true; - } if (!this.resultType || this.resultType.length === 0) { this.resultType = 'nocheck'; } + this.updateFunctionArgsString() + this.updateFunctionLabel(); const editorElement = this.javascriptEditorElmRef.nativeElement; let editorOptions: Partial = { mode: 'ace/mode/javascript', @@ -262,6 +248,16 @@ export class JsFuncComponent implements OnInit, OnChanges, OnDestroy, ControlVal ); } + ngOnChanges(changes: SimpleChanges): void { + for (const propName of Object.keys(changes)) { + const { firstChange, currentValue, previousValue } = changes[propName]; + const isChanged = isObject(currentValue) ? isEqual(currentValue, previousValue) : currentValue !== previousValue; + if (!firstChange && isChanged) { + this.updateByChangesPropName(propName); + } + } + } + ngOnDestroy(): void { if (this.editorResize$) { this.editorResize$.disconnect(); @@ -271,24 +267,6 @@ 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(); @@ -340,6 +318,9 @@ export class JsFuncComponent implements OnInit, OnChanges, OnDestroy, ControlVal } private updateFunctionLabel(): void { + if (this.functionTitle || this.label) { + this.hideBrackets = true; + } if (this.functionTitle) { this.functionLabel = `${this.functionTitle}: f(${this.functionArgsString})`; } else if (this.label) { @@ -351,6 +332,10 @@ export class JsFuncComponent implements OnInit, OnChanges, OnDestroy, ControlVal this.cd.markForCheck(); } + private updatedScriptLanguage() { + this.jsEditor.session.setMode(`ace/mode/${ScriptLanguage.TBEL === this.scriptLanguage ? 'tbel' : 'javascript'}`); + } + validateOnSubmit(): Observable { if (!this.disabled) { this.cleanupJsErrors(); @@ -561,6 +546,52 @@ export class JsFuncComponent implements OnInit, OnChanges, OnDestroy, ControlVal } } + private updateByChangesPropName(propName: string): void { + switch (propName) { + case 'functionArgs': + this.updateFunctionArgsString() + this.updateFunctionLabel(); + this.updateJsWorkerGlobals(); + break; + case 'label': + case 'functionTitle': + case 'functionName': + this.updateFunctionLabel(); + break; + case 'scriptLanguage': + this.updatedScriptLanguage(); + break; + case 'disableUndefinedCheck': + case 'globalVariables': + this.updateJsWorkerGlobals(); + break; + case 'editorCompleter': + this.updateCompleters(); + break; + case 'highlightRules': + this.updateHighlightRules(); + break; + } + } + + 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 updateJsWorkerGlobals() { // @ts-ignore if (!!this.jsEditor.session.$worker) {