Merge branch 'feature/mvel-executor' of github.com:thingsboard/thingsboard into feature/mvel-executor
This commit is contained in:
commit
c76e43ac25
@ -21,6 +21,7 @@ export interface SysParamsState {
|
||||
allowedDashboardIds: string[];
|
||||
edgesSupportEnabled: boolean;
|
||||
hasRepository: boolean;
|
||||
mvelEnabled: boolean;
|
||||
}
|
||||
|
||||
export interface AuthPayload extends SysParamsState {
|
||||
|
||||
@ -24,7 +24,8 @@ const emptyUserAuthState: AuthPayload = {
|
||||
forceFullscreen: false,
|
||||
allowedDashboardIds: [],
|
||||
edgesSupportEnabled: false,
|
||||
hasRepository: false
|
||||
hasRepository: false,
|
||||
mvelEnabled: false
|
||||
};
|
||||
|
||||
export const initialState: AuthState = {
|
||||
|
||||
@ -60,6 +60,11 @@ export const selectHasRepository = createSelector(
|
||||
(state: AuthState) => state.hasRepository
|
||||
);
|
||||
|
||||
export const selectMvelEnabled = createSelector(
|
||||
selectAuthState,
|
||||
(state: AuthState) => state.mvelEnabled
|
||||
);
|
||||
|
||||
export function getCurrentAuthState(store: Store<AppState>): AuthState {
|
||||
let state: AuthState;
|
||||
store.pipe(select(selectAuth), take(1)).subscribe(
|
||||
|
||||
@ -478,11 +478,20 @@ export class AuthService {
|
||||
}
|
||||
}
|
||||
|
||||
private loadMvelEnabled(authUser: AuthUser): Observable<boolean> {
|
||||
if (authUser.authority === Authority.TENANT_ADMIN) {
|
||||
return this.http.get<boolean>('/api/ruleChain/mvelEnabled', defaultHttpOptions());
|
||||
} else {
|
||||
return of(false);
|
||||
}
|
||||
}
|
||||
|
||||
private loadSystemParams(authPayload: AuthPayload): Observable<SysParamsState> {
|
||||
const sources = [this.loadIsUserTokenAccessEnabled(authPayload.authUser),
|
||||
this.fetchAllowedDashboardIds(authPayload),
|
||||
this.loadIsEdgesSupportEnabled(),
|
||||
this.loadHasRepository(authPayload.authUser),
|
||||
this.loadMvelEnabled(authPayload.authUser),
|
||||
this.timeService.loadMaxDatapointsLimit()];
|
||||
return forkJoin(sources)
|
||||
.pipe(map((data) => {
|
||||
@ -490,7 +499,8 @@ export class AuthService {
|
||||
const allowedDashboardIds: string[] = data[1] as string[];
|
||||
const edgesSupportEnabled: boolean = data[2] as boolean;
|
||||
const hasRepository: boolean = data[3] as boolean;
|
||||
return {userTokenAccessEnabled, allowedDashboardIds, edgesSupportEnabled, hasRepository};
|
||||
const mvelEnabled: boolean = data[4] as boolean;
|
||||
return {userTokenAccessEnabled, allowedDashboardIds, edgesSupportEnabled, hasRepository, mvelEnabled};
|
||||
}, catchError((err) => {
|
||||
return of({});
|
||||
})));
|
||||
|
||||
21
ui-ngx/src/app/core/auth/public-api.ts
Normal file
21
ui-ngx/src/app/core/auth/public-api.ts
Normal file
@ -0,0 +1,21 @@
|
||||
///
|
||||
/// Copyright © 2016-2022 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.
|
||||
/// You may obtain a copy of the License at
|
||||
///
|
||||
/// http://www.apache.org/licenses/LICENSE-2.0
|
||||
///
|
||||
/// Unless required by applicable law or agreed to in writing, software
|
||||
/// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
/// See the License for the specific language governing permissions and
|
||||
/// limitations under the License.
|
||||
///
|
||||
|
||||
export * from './auth.actions';
|
||||
export * from './auth.models';
|
||||
export * from './auth.reducer';
|
||||
export * from './auth.selectors';
|
||||
export * from './auth.service';
|
||||
@ -31,7 +31,7 @@ import { ComponentDescriptorService } from './component-descriptor.service';
|
||||
import {
|
||||
IRuleNodeConfigurationComponent,
|
||||
LinkLabel,
|
||||
RuleNodeComponentDescriptor, RuleNodeConfiguration,
|
||||
RuleNodeComponentDescriptor, RuleNodeConfiguration, ScriptLanguage,
|
||||
TestScriptInputParams,
|
||||
TestScriptResult
|
||||
} from '@app/shared/models/rule-node.models';
|
||||
@ -170,8 +170,12 @@ export class RuleChainService {
|
||||
return this.http.get<DebugRuleNodeEventBody>(`/api/ruleNode/${ruleNodeId}/debugIn`, defaultHttpOptionsFromConfig(config));
|
||||
}
|
||||
|
||||
public testScript(inputParams: TestScriptInputParams, config?: RequestConfig): Observable<TestScriptResult> {
|
||||
return this.http.post<TestScriptResult>('/api/ruleChain/testScript', inputParams, defaultHttpOptionsFromConfig(config));
|
||||
public testScript(inputParams: TestScriptInputParams, scriptLang?: ScriptLanguage, config?: RequestConfig): Observable<TestScriptResult> {
|
||||
let url = '/api/ruleChain/testScript';
|
||||
if (scriptLang) {
|
||||
url += `?scriptLang=${scriptLang}`;
|
||||
}
|
||||
return this.http.post<TestScriptResult>(url, inputParams, defaultHttpOptionsFromConfig(config));
|
||||
}
|
||||
|
||||
private loadRuleNodeComponents(ruleChainType: RuleChainType, config?: RequestConfig): Observable<Array<RuleNodeComponentDescriptor>> {
|
||||
|
||||
@ -22,3 +22,4 @@ export * from './ws/telemetry-websocket.service';
|
||||
export * from './core.state';
|
||||
export * from './core.module';
|
||||
export * from './utils';
|
||||
export * from './auth/public-api';
|
||||
|
||||
@ -24,6 +24,7 @@ import {
|
||||
NodeScriptTestDialogData
|
||||
} from '@shared/components/dialog/node-script-test-dialog.component';
|
||||
import { sortObjectKeys } from '@core/utils';
|
||||
import { ScriptLanguage } from '@shared/models/rule-node.models';
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root'
|
||||
@ -35,7 +36,8 @@ export class NodeScriptTestService {
|
||||
}
|
||||
|
||||
testNodeScript(script: string, scriptType: string, functionTitle: string,
|
||||
functionName: string, argNames: string[], ruleNodeId: string, helpId?: string): Observable<string> {
|
||||
functionName: string, argNames: string[], ruleNodeId: string, helpId?: string,
|
||||
scriptLang?: ScriptLanguage): Observable<string> {
|
||||
if (ruleNodeId) {
|
||||
return this.ruleChainService.getLatestRuleNodeDebugInput(ruleNodeId).pipe(
|
||||
switchMap((debugIn) => {
|
||||
@ -57,13 +59,14 @@ export class NodeScriptTestService {
|
||||
);
|
||||
} else {
|
||||
return this.openTestScriptDialog(script, scriptType, functionTitle,
|
||||
functionName, argNames, null, null, null, helpId);
|
||||
functionName, argNames, null, null, null, helpId, scriptLang);
|
||||
}
|
||||
}
|
||||
|
||||
private openTestScriptDialog(script: string, scriptType: string,
|
||||
functionTitle: string, functionName: string, argNames: string[],
|
||||
msg?: any, metadata?: {[key: string]: string}, msgType?: string, helpId?: string): Observable<string> {
|
||||
msg?: any, metadata?: {[key: string]: string}, msgType?: string, helpId?: string,
|
||||
scriptLang?: ScriptLanguage): Observable<string> {
|
||||
if (!msg) {
|
||||
msg = {
|
||||
temperature: 22.4,
|
||||
@ -95,7 +98,8 @@ export class NodeScriptTestService {
|
||||
script,
|
||||
scriptType,
|
||||
argNames,
|
||||
helpId
|
||||
helpId,
|
||||
scriptLang
|
||||
}
|
||||
}).afterClosed();
|
||||
}
|
||||
|
||||
@ -37,7 +37,7 @@ import { Router } from '@angular/router';
|
||||
import { DialogComponent } from '@shared/components/dialog.component';
|
||||
import { ContentType } from '@shared/models/constants';
|
||||
import { JsonContentComponent } from '@shared/components/json-content.component';
|
||||
import { TestScriptInputParams } from '@shared/models/rule-node.models';
|
||||
import { ScriptLanguage, TestScriptInputParams } from '@shared/models/rule-node.models';
|
||||
import { RuleChainService } from '@core/http/rule-chain.service';
|
||||
import { mergeMap } from 'rxjs/operators';
|
||||
import { ActionNotificationShow } from '@core/notification/notification.actions';
|
||||
@ -49,6 +49,7 @@ export interface NodeScriptTestDialogData {
|
||||
functionTitle: string;
|
||||
functionName: string;
|
||||
argNames: string[];
|
||||
scriptLang?: ScriptLanguage;
|
||||
msg?: any;
|
||||
metadata?: {[key: string]: string};
|
||||
msgType?: string;
|
||||
@ -191,7 +192,8 @@ export class NodeScriptTestDialogComponent extends DialogComponent<NodeScriptTes
|
||||
metadata: this.nodeScriptTestFormGroup.get('metadata').value,
|
||||
script: this.nodeScriptTestFormGroup.get('script').value
|
||||
};
|
||||
return this.ruleChainService.testScript(inputParams).pipe(
|
||||
const scriptLang = this.data.scriptLang ? this.data.scriptLang : ScriptLanguage.JS;
|
||||
return this.ruleChainService.testScript(inputParams, scriptLang).pipe(
|
||||
mergeMap((result) => {
|
||||
if (result.error) {
|
||||
this.store.dispatch(new ActionNotificationShow(
|
||||
|
||||
@ -328,6 +328,11 @@ export interface FcRuleEdge extends FcEdge {
|
||||
labels?: string[];
|
||||
}
|
||||
|
||||
export enum ScriptLanguage {
|
||||
JS = 'JS',
|
||||
MVEL = 'MVEL'
|
||||
}
|
||||
|
||||
export interface TestScriptInputParams {
|
||||
script: string;
|
||||
scriptType: string;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user