diff --git a/application/src/main/java/org/thingsboard/server/controller/DashboardController.java b/application/src/main/java/org/thingsboard/server/controller/DashboardController.java index 6da5ce337c..8b3647efe2 100644 --- a/application/src/main/java/org/thingsboard/server/controller/DashboardController.java +++ b/application/src/main/java/org/thingsboard/server/controller/DashboardController.java @@ -96,7 +96,7 @@ public class DashboardController extends BaseController { public static final String DASHBOARD_DEFINITION = "The Dashboard object is a heavyweight object that contains information about the dashboard (e.g. title, image, assigned customers) and also configuration JSON (e.g. layouts, widgets, entity aliases)."; public static final String HIDDEN_FOR_MOBILE = "Exclude dashboards that are hidden for mobile"; - @Value("${dashboard.max_datapoints_limit}") + @Value("${ui.dashboard.max_datapoints_limit}") private long maxDatapointsLimit; @ApiOperation(value = "Get server time (getServerTime)", diff --git a/application/src/main/java/org/thingsboard/server/controller/UiSettingsController.java b/application/src/main/java/org/thingsboard/server/controller/UiSettingsController.java new file mode 100644 index 0000000000..e28e378119 --- /dev/null +++ b/application/src/main/java/org/thingsboard/server/controller/UiSettingsController.java @@ -0,0 +1,46 @@ +/** + * Copyright © 2016-2021 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. + */ +package org.thingsboard.server.controller; + +import io.swagger.annotations.ApiOperation; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.ResponseBody; +import org.springframework.web.bind.annotation.RestController; +import org.thingsboard.server.common.data.exception.ThingsboardException; +import org.thingsboard.server.queue.util.TbCoreComponent; + +@RestController +@TbCoreComponent +@RequestMapping("/api") +public class UiSettingsController extends BaseController { + + @Value("${ui.help.base-url}") + private String helpBaseUrl; + + @ApiOperation(value = "Get UI help base url (getHelpBaseUrl)", + notes = "Get UI help base url used to fetch help assets. " + + "The actual value of the base url is configurable in the system configuration file.") + @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')") + @RequestMapping(value = "/uiSettings/helpBaseUrl", method = RequestMethod.GET) + @ResponseBody + public String getHelpBaseUrl() throws ThingsboardException { + return helpBaseUrl; + } + +} diff --git a/application/src/main/resources/thingsboard.yml b/application/src/main/resources/thingsboard.yml index 2b108c2eb9..34742e5444 100644 --- a/application/src/main/resources/thingsboard.yml +++ b/application/src/main/resources/thingsboard.yml @@ -129,10 +129,16 @@ usage: check: cycle: "${USAGE_STATS_CHECK_CYCLE:60000}" -# Dashboard parameters -dashboard: - # Maximum allowed datapoints fetched by widgets - max_datapoints_limit: "${DASHBOARD_MAX_DATAPOINTS_LIMIT:50000}" +# UI parameters +ui: + # Dashboard parameters + dashboard: + # Maximum allowed datapoints fetched by widgets + max_datapoints_limit: "${DASHBOARD_MAX_DATAPOINTS_LIMIT:50000}" + # Help parameters + help: + # Base url for UI help assets + base-url: "${UI_HELP_BASE_URL:https://raw.githubusercontent.com/thingsboard/thingsboard/master/ui-ngx/src/assets}" database: ts_max_intervals: "${DATABASE_TS_MAX_INTERVALS:700}" # Max number of DB queries generated by single API call to fetch telemetry records diff --git a/docker/haproxy/config/haproxy.cfg b/docker/haproxy/config/haproxy.cfg index 16b8af0595..50dcf36434 100644 --- a/docker/haproxy/config/haproxy.cfg +++ b/docker/haproxy/config/haproxy.cfg @@ -70,13 +70,12 @@ frontend http-in acl transport_http_acl path_beg /api/v1/ acl letsencrypt_http_acl path_beg /.well-known/acme-challenge/ acl tb_api_acl path_beg /api/ /swagger /webjars /v2/ /static/rulenode/ /oauth2/ /login/oauth2/ /static/widgets/ - acl tb_rulenode_assets path_reg ^/assets/help/.*/rulenode/.*$ redirect scheme https if !letsencrypt_http_acl !transport_http_acl { env(FORCE_HTTPS_REDIRECT) -m str true } use_backend letsencrypt_http if letsencrypt_http_acl use_backend tb-http-backend if transport_http_acl - use_backend tb-api-backend if tb_api_acl or tb_rulenode_assets + use_backend tb-api-backend if tb_api_acl default_backend tb-web-backend @@ -89,10 +88,9 @@ frontend https_in acl transport_http_acl path_beg /api/v1/ acl tb_api_acl path_beg /api/ /swagger /webjars /v2/ /static/rulenode/ /oauth2/ /login/oauth2/ /static/widgets/ - acl tb_rulenode_assets path_reg ^/assets/help/.*/rulenode/.*$ use_backend tb-http-backend if transport_http_acl - use_backend tb-api-backend if tb_api_acl or tb_rulenode_assets + use_backend tb-api-backend if tb_api_acl default_backend tb-web-backend diff --git a/ui-ngx/proxy.conf.js b/ui-ngx/proxy.conf.js index 1211280966..2e3817445b 100644 --- a/ui-ngx/proxy.conf.js +++ b/ui-ngx/proxy.conf.js @@ -26,10 +26,6 @@ const PROXY_CONFIG = { "target": ruleNodeUiforwardUrl, "secure": false, }, - "/assets/help/*/rulenode/**": { - "target": ruleNodeUiforwardUrl, - "secure": false, - }, "/static/widgets": { "target": forwardUrl, "secure": false, diff --git a/ui-ngx/src/app/core/http/ui-settings.service.ts b/ui-ngx/src/app/core/http/ui-settings.service.ts new file mode 100644 index 0000000000..e86ecb53e7 --- /dev/null +++ b/ui-ngx/src/app/core/http/ui-settings.service.ts @@ -0,0 +1,43 @@ +/// +/// Copyright © 2016-2021 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. +/// + +import { Injectable } from '@angular/core'; +import { HttpClient } from '@angular/common/http'; +import { defaultHttpOptions, defaultHttpOptionsFromConfig, RequestConfig } from '@core/http/http-utils'; +import { Observable } from 'rxjs'; +import { publishReplay, refCount } from 'rxjs/operators'; + +@Injectable({ + providedIn: 'root' +}) +export class UiSettingsService { + + private helpBaseUrlObservable: Observable; + + constructor( + private http: HttpClient + ) { } + + public getHelpBaseUrl(): Observable { + if (!this.helpBaseUrlObservable) { + this.helpBaseUrlObservable = this.http.get('/api/uiSettings/helpBaseUrl', {responseType: 'text', ...defaultHttpOptions(true)}).pipe( + publishReplay(1), + refCount() + ); + } + return this.helpBaseUrlObservable; + } +} diff --git a/ui-ngx/src/app/core/services/help.service.ts b/ui-ngx/src/app/core/services/help.service.ts index 2ed8863b4d..df8b14d71c 100644 --- a/ui-ngx/src/app/core/services/help.service.ts +++ b/ui-ngx/src/app/core/services/help.service.ts @@ -18,23 +18,29 @@ import { Injectable } from '@angular/core'; import { HttpClient } from '@angular/common/http'; import { TranslateService } from '@ngx-translate/core'; import { Observable, of } from 'rxjs'; -import { catchError, mergeMap, tap } from 'rxjs/operators'; -import { helpBaseUrl } from '@shared/models/constants'; +import { catchError, map, mergeMap, tap } from 'rxjs/operators'; +import { helpBaseUrl as siteBaseUrl } from '@shared/models/constants'; +import { UiSettingsService } from '@core/http/ui-settings.service'; -const NOT_FOUND_CONTENT = '## Not found'; +const localHelpBaseUrl = '/assets'; + +const NOT_FOUND_CONTENT: HelpData = { + content: '## Not found', + helpBaseUrl: localHelpBaseUrl +}; @Injectable({ providedIn: 'root' }) export class HelpService { - private helpBaseUrl = helpBaseUrl; - + private siteBaseUrl = siteBaseUrl; private helpCache: {[lang: string]: {[key: string]: string}} = {}; constructor( private translate: TranslateService, - private http: HttpClient + private http: HttpClient, + private uiSettingsService: UiSettingsService ) {} getHelpContent(key: string): Observable { @@ -70,13 +76,38 @@ export class HelpService { } } - private loadHelpContent(lang: string, key: string): Observable { - return this.http.get(`/assets/help/${lang}/${key}.md`, {responseType: 'text'} ); + private loadHelpContent(lang: string, key: string): Observable { + return this.uiSettingsService.getHelpBaseUrl().pipe( + mergeMap((helpBaseUrl) => { + return this.loadHelpContentFromBaseUrl(helpBaseUrl, lang, key).pipe( + catchError((e) => { + if (localHelpBaseUrl !== helpBaseUrl) { + return this.loadHelpContentFromBaseUrl(localHelpBaseUrl, lang, key); + } else { + throw e; + } + }) + ); + }) + ); } - private processVariables(content: string): string { - const baseUrlReg = /\${baseUrl}/g; - return content.replace(baseUrlReg, this.helpBaseUrl); + private loadHelpContentFromBaseUrl(helpBaseUrl: string, lang: string, key: string): Observable { + return this.http.get(`${helpBaseUrl}/help/${lang}/${key}.md`, {responseType: 'text'} ).pipe( + map((content) => { + return { + content, + helpBaseUrl + }; + }) + ); + } + + private processVariables(helpData: HelpData): string { + const baseUrlReg = /\${siteBaseUrl}/g; + helpData.content = helpData.content.replace(baseUrlReg, this.siteBaseUrl); + const helpBaseUrlReg = /\${helpBaseUrl}/g; + return helpData.content.replace(helpBaseUrlReg, helpData.helpBaseUrl); } private processIncludes(content: string): Observable { @@ -96,3 +127,8 @@ export class HelpService { } } + +interface HelpData { + content: string; + helpBaseUrl: string; +} diff --git a/rule-engine/rule-engine-components/src/main/resources/public/assets/help/en_US/rulenode/clear_alarm_node_script_fn.md b/ui-ngx/src/assets/help/en_US/rulenode/clear_alarm_node_script_fn.md similarity index 90% rename from rule-engine/rule-engine-components/src/main/resources/public/assets/help/en_US/rulenode/clear_alarm_node_script_fn.md rename to ui-ngx/src/assets/help/en_US/rulenode/clear_alarm_node_script_fn.md index 2191887ebd..74e4c83828 100644 --- a/rule-engine/rule-engine-components/src/main/resources/public/assets/help/en_US/rulenode/clear_alarm_node_script_fn.md +++ b/ui-ngx/src/assets/help/en_US/rulenode/clear_alarm_node_script_fn.md @@ -58,11 +58,11 @@ return details;
-More details about Alarms can be found in [this tutorial{:target="_blank"}](${baseUrl}/docs/user-guide/alarms/). +More details about Alarms can be found in [this tutorial{:target="_blank"}](${siteBaseUrl}/docs/user-guide/alarms/). You can see the real life example, where this node is used, in the next tutorial: -- [Create and Clear Alarms{:target="_blank"}](${baseUrl}/docs/user-guide/rule-engine-2-0/tutorials/create-clear-alarms/) +- [Create and Clear Alarms{:target="_blank"}](${siteBaseUrl}/docs/user-guide/rule-engine-2-0/tutorials/create-clear-alarms/)

diff --git a/rule-engine/rule-engine-components/src/main/resources/public/assets/help/en_US/rulenode/common_node_script_args.md b/ui-ngx/src/assets/help/en_US/rulenode/common_node_script_args.md similarity index 100% rename from rule-engine/rule-engine-components/src/main/resources/public/assets/help/en_US/rulenode/common_node_script_args.md rename to ui-ngx/src/assets/help/en_US/rulenode/common_node_script_args.md diff --git a/rule-engine/rule-engine-components/src/main/resources/public/assets/help/en_US/rulenode/create_alarm_node_script_fn.md b/ui-ngx/src/assets/help/en_US/rulenode/create_alarm_node_script_fn.md similarity index 90% rename from rule-engine/rule-engine-components/src/main/resources/public/assets/help/en_US/rulenode/create_alarm_node_script_fn.md rename to ui-ngx/src/assets/help/en_US/rulenode/create_alarm_node_script_fn.md index 66355d5dfc..c6c2fe2481 100644 --- a/rule-engine/rule-engine-components/src/main/resources/public/assets/help/en_US/rulenode/create_alarm_node_script_fn.md +++ b/ui-ngx/src/assets/help/en_US/rulenode/create_alarm_node_script_fn.md @@ -59,11 +59,11 @@ return details;
-More details about Alarms can be found in [this tutorial{:target="_blank"}](${baseUrl}/docs/user-guide/alarms/). +More details about Alarms can be found in [this tutorial{:target="_blank"}](${siteBaseUrl}/docs/user-guide/alarms/). You can see the real life example, where this node is used, in the next tutorial: -- [Create and Clear Alarms{:target="_blank"}](${baseUrl}/docs/user-guide/rule-engine-2-0/tutorials/create-clear-alarms/) +- [Create and Clear Alarms{:target="_blank"}](${siteBaseUrl}/docs/user-guide/rule-engine-2-0/tutorials/create-clear-alarms/)

diff --git a/rule-engine/rule-engine-components/src/main/resources/public/assets/help/en_US/rulenode/filter_node_script_fn.md b/ui-ngx/src/assets/help/en_US/rulenode/filter_node_script_fn.md similarity index 85% rename from rule-engine/rule-engine-components/src/main/resources/public/assets/help/en_US/rulenode/filter_node_script_fn.md rename to ui-ngx/src/assets/help/en_US/rulenode/filter_node_script_fn.md index 16de83ca32..3740d88c64 100644 --- a/rule-engine/rule-engine-components/src/main/resources/public/assets/help/en_US/rulenode/filter_node_script_fn.md +++ b/ui-ngx/src/assets/help/en_US/rulenode/filter_node_script_fn.md @@ -61,8 +61,8 @@ return false; You can see real life example, how to use this node in those tutorials: -- [Create and Clear Alarms{:target="_blank"}](${baseUrl}/docs/user-guide/rule-engine-2-0/tutorials/create-clear-alarms/#node-a-filter-script) -- [Reply to RPC Calls{:target="_blank"}](${baseUrl}/docs/user-guide/rule-engine-2-0/tutorials/rpc-reply-tutorial#add-filter-script-node) +- [Create and Clear Alarms{:target="_blank"}](${siteBaseUrl}/docs/user-guide/rule-engine-2-0/tutorials/create-clear-alarms/#node-a-filter-script) +- [Reply to RPC Calls{:target="_blank"}](${siteBaseUrl}/docs/user-guide/rule-engine-2-0/tutorials/rpc-reply-tutorial#add-filter-script-node)

diff --git a/rule-engine/rule-engine-components/src/main/resources/public/assets/help/en_US/rulenode/generator_node_script_fn.md b/ui-ngx/src/assets/help/en_US/rulenode/generator_node_script_fn.md similarity index 100% rename from rule-engine/rule-engine-components/src/main/resources/public/assets/help/en_US/rulenode/generator_node_script_fn.md rename to ui-ngx/src/assets/help/en_US/rulenode/generator_node_script_fn.md diff --git a/rule-engine/rule-engine-components/src/main/resources/public/assets/help/en_US/rulenode/log_node_script_fn.md b/ui-ngx/src/assets/help/en_US/rulenode/log_node_script_fn.md similarity index 84% rename from rule-engine/rule-engine-components/src/main/resources/public/assets/help/en_US/rulenode/log_node_script_fn.md rename to ui-ngx/src/assets/help/en_US/rulenode/log_node_script_fn.md index c5cf6bcd34..ababc52ffe 100644 --- a/rule-engine/rule-engine-components/src/main/resources/public/assets/help/en_US/rulenode/log_node_script_fn.md +++ b/ui-ngx/src/assets/help/en_US/rulenode/log_node_script_fn.md @@ -31,7 +31,7 @@ return 'Incoming message:\n' + JSON.stringify(msg) + You can see real life example, how to use this node in this tutorial: -- [Reply to RPC Calls{:target="_blank"}](${baseUrl}/docs/user-guide/rule-engine-2-0/tutorials/rpc-reply-tutorial#log-unknown-request) +- [Reply to RPC Calls{:target="_blank"}](${siteBaseUrl}/docs/user-guide/rule-engine-2-0/tutorials/rpc-reply-tutorial#log-unknown-request)

diff --git a/rule-engine/rule-engine-components/src/main/resources/public/assets/help/en_US/rulenode/switch_node_script_fn.md b/ui-ngx/src/assets/help/en_US/rulenode/switch_node_script_fn.md similarity index 95% rename from rule-engine/rule-engine-components/src/main/resources/public/assets/help/en_US/rulenode/switch_node_script_fn.md rename to ui-ngx/src/assets/help/en_US/rulenode/switch_node_script_fn.md index 1f6a1067b8..de08fb9020 100644 --- a/rule-engine/rule-engine-components/src/main/resources/public/assets/help/en_US/rulenode/switch_node_script_fn.md +++ b/ui-ngx/src/assets/help/en_US/rulenode/switch_node_script_fn.md @@ -90,7 +90,7 @@ return []; You can see real life example, how to use this node in this tutorial: -- [Data function based on telemetry from 2 devices{:target="_blank"}](${baseUrl}/docs/user-guide/rule-engine-2-0/tutorials/function-based-on-telemetry-from-two-devices#delta-temperature-rule-chain) +- [Data function based on telemetry from 2 devices{:target="_blank"}](${siteBaseUrl}/docs/user-guide/rule-engine-2-0/tutorials/function-based-on-telemetry-from-two-devices#delta-temperature-rule-chain)

diff --git a/rule-engine/rule-engine-components/src/main/resources/public/assets/help/en_US/rulenode/transformation_node_script_fn.md b/ui-ngx/src/assets/help/en_US/rulenode/transformation_node_script_fn.md similarity index 82% rename from rule-engine/rule-engine-components/src/main/resources/public/assets/help/en_US/rulenode/transformation_node_script_fn.md rename to ui-ngx/src/assets/help/en_US/rulenode/transformation_node_script_fn.md index ae2f1a0ffa..acc49c623c 100644 --- a/rule-engine/rule-engine-components/src/main/resources/public/assets/help/en_US/rulenode/transformation_node_script_fn.md +++ b/ui-ngx/src/assets/help/en_US/rulenode/transformation_node_script_fn.md @@ -52,8 +52,8 @@ return {msg: msg, metadata: metadata, msgType: newType}; You can see real life example, how to use this node in those tutorials: -- [Transform incoming telemetry{:target="_blank"}](${baseUrl}/docs/user-guide/rule-engine-2-0/tutorials/transform-incoming-telemetry/) -- [Reply to RPC Calls{:target="_blank"}](${baseUrl}/docs/user-guide/rule-engine-2-0/tutorials/rpc-reply-tutorial#add-transform-script-node) +- [Transform incoming telemetry{:target="_blank"}](${siteBaseUrl}/docs/user-guide/rule-engine-2-0/tutorials/transform-incoming-telemetry/) +- [Reply to RPC Calls{:target="_blank"}](${siteBaseUrl}/docs/user-guide/rule-engine-2-0/tutorials/rpc-reply-tutorial#add-transform-script-node)

diff --git a/ui-ngx/src/assets/help/en_US/widget/action/custom_action_fn.md b/ui-ngx/src/assets/help/en_US/widget/action/custom_action_fn.md index de5eec3943..7ea3417f39 100644 --- a/ui-ngx/src/assets/help/en_US/widget/action/custom_action_fn.md +++ b/ui-ngx/src/assets/help/en_US/widget/action/custom_action_fn.md @@ -20,6 +20,7 @@ A JavaScript function performing custom action. * Display alert dialog with entity information: ```javascript +{:code-style="max-height: 300px;"} var title; var content; if (entityName) { @@ -52,6 +53,7 @@ function showAlertDialog(title, content) { * Delete device after confirmation: ```javascript +{:code-style="max-height: 300px;"} var $injector = widgetContext.$scope.$injector; var dialogs = $injector.get(widgetContext.servicesMap.get('dialogs')); var deviceService = $injector.get(widgetContext.servicesMap.get('deviceService')); diff --git a/ui-ngx/src/assets/help/en_US/widget/action/examples/custom_pretty_create_dialog_html.md b/ui-ngx/src/assets/help/en_US/widget/action/examples/custom_pretty_create_dialog_html.md index a604bc3e18..567e093c76 100644 --- a/ui-ngx/src/assets/help/en_US/widget/action/examples/custom_pretty_create_dialog_html.md +++ b/ui-ngx/src/assets/help/en_US/widget/action/examples/custom_pretty_create_dialog_html.md @@ -1,6 +1,7 @@ #### HTML template of dialog to create a device or an asset ```html +{:code-style="max-height: 400px;"}
@@ -158,3 +159,6 @@ {:copy-code} ``` + +
+
diff --git a/ui-ngx/src/assets/help/en_US/widget/action/examples/custom_pretty_create_dialog_js.md b/ui-ngx/src/assets/help/en_US/widget/action/examples/custom_pretty_create_dialog_js.md index 9a904bb944..5dda1b524c 100644 --- a/ui-ngx/src/assets/help/en_US/widget/action/examples/custom_pretty_create_dialog_js.md +++ b/ui-ngx/src/assets/help/en_US/widget/action/examples/custom_pretty_create_dialog_js.md @@ -1,6 +1,7 @@ #### Function displaying dialog to create a device or an asset ```javascript +{:code-style="max-height: 400px;"} let $injector = widgetContext.$scope.$injector; let customDialog = $injector.get(widgetContext.servicesMap.get('customDialog')); let assetService = $injector.get(widgetContext.servicesMap.get('assetService')); @@ -130,3 +131,6 @@ function AddEntityDialogController(instance) { } {:copy-code} ``` + +
+
diff --git a/ui-ngx/src/assets/help/en_US/widget/action/examples/custom_pretty_edit_dialog_html.md b/ui-ngx/src/assets/help/en_US/widget/action/examples/custom_pretty_edit_dialog_html.md index 2737070a26..4e3cd0c608 100644 --- a/ui-ngx/src/assets/help/en_US/widget/action/examples/custom_pretty_edit_dialog_html.md +++ b/ui-ngx/src/assets/help/en_US/widget/action/examples/custom_pretty_edit_dialog_html.md @@ -1,6 +1,7 @@ #### HTML template of dialog to edit a device or an asset ```html +{:code-style="max-height: 400px;"}
@@ -190,3 +191,6 @@ {:copy-code} ``` + +
+
diff --git a/ui-ngx/src/assets/help/en_US/widget/action/examples/custom_pretty_edit_dialog_js.md b/ui-ngx/src/assets/help/en_US/widget/action/examples/custom_pretty_edit_dialog_js.md index 5a222e9aee..b2a6a635df 100644 --- a/ui-ngx/src/assets/help/en_US/widget/action/examples/custom_pretty_edit_dialog_js.md +++ b/ui-ngx/src/assets/help/en_US/widget/action/examples/custom_pretty_edit_dialog_js.md @@ -1,6 +1,7 @@ #### Function displaying dialog to edit a device or an asset ```javascript +{:code-style="max-height: 400px;"} let $injector = widgetContext.$scope.$injector; let customDialog = $injector.get(widgetContext.servicesMap.get('customDialog')); let entityService = $injector.get(widgetContext.servicesMap.get('entityService')); @@ -218,3 +219,6 @@ function EditEntityDialogController(instance) { } {:copy-code} ``` + +
+
diff --git a/ui-ngx/src/assets/help/en_US/widget/action/mobile_process_qr_code_fn.md b/ui-ngx/src/assets/help/en_US/widget/action/mobile_process_qr_code_fn.md index 6a011ead79..bb663f9e7d 100644 --- a/ui-ngx/src/assets/help/en_US/widget/action/mobile_process_qr_code_fn.md +++ b/ui-ngx/src/assets/help/en_US/widget/action/mobile_process_qr_code_fn.md @@ -34,7 +34,7 @@ function showQrCodeDialog(title, code, format) { {:copy-code} ``` -* Parse code as a device claiming info (in this case ```{deviceName: string, secretKey: string}```)
and then claim device (see [Claiming devices{:target="_blank"}](${baseUrl}/docs/user-guide/claiming-devices/) for details): +* Parse code as a device claiming info (in this case ```{deviceName: string, secretKey: string}```)
and then claim device (see [Claiming devices{:target="_blank"}](${siteBaseUrl}/docs/user-guide/claiming-devices/) for details): ```javascript var $scope = widgetContext.$scope; diff --git a/ui-ngx/src/assets/help/en_US/widget/editor/examples/alarm_widget.md b/ui-ngx/src/assets/help/en_US/widget/editor/examples/alarm_widget.md index 5d43c50db2..f3ba4c0590 100644 --- a/ui-ngx/src/assets/help/en_US/widget/editor/examples/alarm_widget.md +++ b/ui-ngx/src/assets/help/en_US/widget/editor/examples/alarm_widget.md @@ -127,7 +127,7 @@ self.onDataUpdated = function() { - Click the **Run** button on the **Widget Editor Toolbar** in order to see the result in **Widget preview** section. -![image](${baseUrl}/images/user-guide/contribution/widgets/alarm-widget-sample.png) +![image](${helpBaseUrl}/help/images/widget/editor/examples/alarm-widget-sample.png) In this example, the **alarmSource** and **alarms** properties of are assigned to **$scope** and become accessible within HTML template. diff --git a/ui-ngx/src/assets/help/en_US/widget/editor/examples/ext_latest_values_example.md b/ui-ngx/src/assets/help/en_US/widget/editor/examples/ext_latest_values_example.md index 277bdac835..dcb9293f84 100644 --- a/ui-ngx/src/assets/help/en_US/widget/editor/examples/ext_latest_values_example.md +++ b/ui-ngx/src/assets/help/en_US/widget/editor/examples/ext_latest_values_example.md @@ -57,7 +57,7 @@ self.onDataUpdated = function() { - Click the **Run** button on the **Widget Editor Toolbar** in order to see the result in **Widget preview** section. -![image](${baseUrl}/images/user-guide/contribution/widgets/external-js-widget-sample.png) +![image](${helpBaseUrl}/help/images/widget/editor/examples/external-js-widget-sample.png) In this example, the external JS library API was used that becomes available after injecting the corresponding URL in **Resources** section. diff --git a/ui-ngx/src/assets/help/en_US/widget/editor/examples/ext_timeseries_example.md b/ui-ngx/src/assets/help/en_US/widget/editor/examples/ext_timeseries_example.md index 9c0e14fd42..6d66e15d4f 100644 --- a/ui-ngx/src/assets/help/en_US/widget/editor/examples/ext_timeseries_example.md +++ b/ui-ngx/src/assets/help/en_US/widget/editor/examples/ext_timeseries_example.md @@ -98,7 +98,7 @@ self.onDataUpdated = function() { - Click the **Run** button on the **Widget Editor Toolbar** in order to see the result in **Widget preview** section. -![image](${baseUrl}/images/user-guide/contribution/widgets/external-js-timeseries-widget-sample.png) +![image](${helpBaseUrl}/help/images/widget/editor/examples/external-js-timeseries-widget-sample.png) In this example, the external JS library API was used that becomes available after injecting the corresponding URL in **Resources** section. diff --git a/ui-ngx/src/assets/help/en_US/widget/editor/examples/latest_values_widget.md b/ui-ngx/src/assets/help/en_US/widget/editor/examples/latest_values_widget.md index 2cda617889..afe4f6a0e1 100644 --- a/ui-ngx/src/assets/help/en_US/widget/editor/examples/latest_values_widget.md +++ b/ui-ngx/src/assets/help/en_US/widget/editor/examples/latest_values_widget.md @@ -37,7 +37,7 @@ The **Widget Editor** will open, pre-populated with the content of the default * - Click the **Run** button on the **Widget Editor Toolbar** in order to see the result in **Widget preview** section. -![image](${baseUrl}/images/user-guide/contribution/widgets/latest-values-widget-sample.png) +![image](${helpBaseUrl}/help/images/widget/editor/examples/latest-values-widget-sample.png) In this example, the **data** property of is assigned to the **$scope** and becomes accessible within the HTML template. diff --git a/ui-ngx/src/assets/help/en_US/widget/editor/examples/rpc_widget.md b/ui-ngx/src/assets/help/en_US/widget/editor/examples/rpc_widget.md index d6f24b2055..74bcca2cd5 100644 --- a/ui-ngx/src/assets/help/en_US/widget/editor/examples/rpc_widget.md +++ b/ui-ngx/src/assets/help/en_US/widget/editor/examples/rpc_widget.md @@ -114,7 +114,7 @@ self.onInit = function() { - Click the **Run** button on the **Widget Editor Toolbar** in order to see the result in **Widget preview** section. - Click dashboard edit button on the preview section to change the size of the resulting widget. Then click dashboard apply button. The final widget should look like the image below. -![image](${baseUrl}/images/user-guide/contribution/widgets/control-widget-sample.png) +![image](${helpBaseUrl}/help/images/widget/editor/examples/control-widget-sample.png) - Click the **Save** button on the **Widget Editor Toolbar** to save widget type. @@ -123,13 +123,13 @@ To test how this widget performs RPC commands, we will need to place it in a das - Login as Tenant administrator. - Navigate to **Devices** and create new device with some name, for ex. "My RPC Device". - Open device details and click "Copy Access Token" button to copy device access token to clipboard. -- Download [mqtt-js-rpc-from-server.sh{:target="_blank"}](${baseUrl}/docs/reference/resources/mqtt-js-rpc-from-server.sh) and [mqtt-js-rpc-from-server.js{:target="_blank"}](${baseUrl}/docs/reference/resources/mqtt-js-rpc-from-server.js). Place these files in a folder. +- Download [mqtt-js-rpc-from-server.sh{:target="_blank"}](${siteBaseUrl}/docs/reference/resources/mqtt-js-rpc-from-server.sh) and [mqtt-js-rpc-from-server.js{:target="_blank"}](${siteBaseUrl}/docs/reference/resources/mqtt-js-rpc-from-server.js). Place these files in a folder. Edit **mqtt-js-rpc-from-server.sh** - replace **$ACCESS_TOKEN** with your device access token from the clipboard. And install mqtt client library. - Run **mqtt-js-rpc-from-server.sh** script. You should see a "connected" message in the console. - Navigate to **Dashboards** and create a new dashboard with some name, for ex. "My first control dashboard". Open this dashboard. - Click dashboard "edit" button. In the dashboard edit mode, click the "Entity aliases" button located on the dashboard toolbar. -![image](${baseUrl}/images/user-guide/contribution/widgets/dashboard-toolbar-entity-aliases.png) +![image](${helpBaseUrl}/help/images/widget/editor/examples/dashboard-toolbar-entity-aliases.png) - Inside **Entity aliases** popup click "Add alias". - Fill "Alias name" field, for ex. "My RPC Device Alias". @@ -137,12 +137,12 @@ To test how this widget performs RPC commands, we will need to place it in a das - Choose "Device" in "Type" field. - Select your device in "Entity list" field. In this example "My RPC Device". -![image](${baseUrl}/images/user-guide/contribution/widgets/add-rpc-device-alias.png) +![image](${helpBaseUrl}/help/images/widget/editor/examples/add-rpc-device-alias.png) - Click "Add" and then "Save" in **Entity aliases**. - Click dashboard "+" button then click "Create new widget" button. -![image](${baseUrl}/images/user-guide/contribution/widgets/dashboard-create-new-widget-button.png) +![image](${helpBaseUrl}/help/images/widget/editor/examples/dashboard-create-new-widget-button.png) - Then select **Widget Bundle** where your RPC widget was saved. Select "Control widget" tab. - Click your widget. In this example, "My first control widget". @@ -152,7 +152,7 @@ To test how this widget performs RPC commands, we will need to place it in a das - Fill **RPC params** field with RPC params. For ex. "{ param1: "value1" }". - Click **Send RPC command** button. You should see the following response in the widget. -![image](${baseUrl}/images/user-guide/contribution/widgets/control-widget-sample-response-one-way.png) +![image](${helpBaseUrl}/help/images/widget/editor/examples/control-widget-sample-response-one-way.png) The following output should be printed in the device console: @@ -166,18 +166,18 @@ In order to test "Two way" RPC command mode, we need to change the corresponding - Click dashboard "edit" button. In dashboard edit mode, click **Edit widget** button located in the header of Control widget. - In the widget details, view select "Advanced" tab and uncheck "Is One Way Command" checkbox. -![image](${baseUrl}/images/user-guide/contribution/widgets/control-widget-sample-settings.png) +![image](${helpBaseUrl}/help/images/widget/editor/examples/control-widget-sample-settings.png) - Click **Apply changes** button on the widget details header. Close details and click dashboard **Apply changes** button. - Fill widget fields with RPC method name and params like in previous steps. Click **Send RPC command** button. You should see the following response in the widget. -![image](${baseUrl}/images/user-guide/contribution/widgets/control-widget-sample-response-two-way.png) +![image](${helpBaseUrl}/help/images/widget/editor/examples/control-widget-sample-response-two-way.png) - stop **mqtt-js-rpc-from-server.sh** script. Click **Send RPC command** button. You should see the following response in the widget. -![image](${baseUrl}/images/user-guide/contribution/widgets/control-widget-sample-response-timeout.png) +![image](${helpBaseUrl}/help/images/widget/editor/examples/control-widget-sample-response-timeout.png) In this example, **controlApi** is used to send RPC commands. Additionally, custom widget settings were introduced in order to configure RPC command mode and RPC request timeout. diff --git a/ui-ngx/src/assets/help/en_US/widget/editor/examples/static_widget.md b/ui-ngx/src/assets/help/en_US/widget/editor/examples/static_widget.md index 793da7c7c2..7e73b63307 100644 --- a/ui-ngx/src/assets/help/en_US/widget/editor/examples/static_widget.md +++ b/ui-ngx/src/assets/help/en_US/widget/editor/examples/static_widget.md @@ -58,7 +58,7 @@ self.onInit = function() { - Click the **Run** button on the **Widget Editor Toolbar** to see the resulting **Widget preview** section. -![image](${baseUrl}/images/user-guide/contribution/widgets/static-widget-sample.png) +![image](${helpBaseUrl}/help/images/widget/editor/examples/static-widget-sample.png) This is just a static HTML widget. There is no subscription data and no special widget API was used. diff --git a/ui-ngx/src/assets/help/en_US/widget/editor/examples/timeseries_widget.md b/ui-ngx/src/assets/help/en_US/widget/editor/examples/timeseries_widget.md index 6dcffbe9e5..66cb83b7fe 100644 --- a/ui-ngx/src/assets/help/en_US/widget/editor/examples/timeseries_widget.md +++ b/ui-ngx/src/assets/help/en_US/widget/editor/examples/timeseries_widget.md @@ -75,7 +75,7 @@ self.onDataUpdated = function() { - Click the **Run** button on the **Widget Editor Toolbar** in order to see the result in **Widget preview** section. -![image](${baseUrl}/images/user-guide/contribution/widgets/timeseries-widget-sample.png) +![image](${helpBaseUrl}/help/images/widget/editor/examples/timeseries-widget-sample.png) In this example, the **datasources** and **data** properties are assigned to **$scope** and become accessible within the HTML template. diff --git a/ui-ngx/src/assets/help/en_US/widget/editor/widget_js_fn.md b/ui-ngx/src/assets/help/en_US/widget/editor/widget_js_fn.md index 2c9cd63475..f301e40b77 100644 --- a/ui-ngx/src/assets/help/en_US/widget/editor/widget_js_fn.md +++ b/ui-ngx/src/assets/help/en_US/widget/editor/widget_js_fn.md @@ -3,7 +3,7 @@

-All widget related JavaScript code according to the [Widget API{:target="_blank"}](${baseUrl}/docs/user-guide/contribution/widgets-development/#basic-widget-api). +All widget related JavaScript code according to the [Widget API{:target="_blank"}](${siteBaseUrl}/docs/user-guide/contribution/widgets-development/#basic-widget-api). The built-in variable **self** is a reference to the widget instance.
Each widget function should be defined as a property of the **self** variable. **self** variable has property **ctx** of type [WidgetContext{:target="_blank"}](https://github.com/thingsboard/thingsboard/blob/5bb6403407aa4898084832d6698aa9ea6d484889/ui-ngx/src/app/modules/home/models/widget-component.models.ts#L107) - a reference to widget context that has all necessary API and data used by widget instance. @@ -129,7 +129,7 @@ Browser debugger (if enabled) will automatically pause code execution at the deb ##### Further reading -For more information read [Widgets Development Guide{:target="_blank"}](${baseUrl}/docs/user-guide/contribution/widgets-development). +For more information read [Widgets Development Guide{:target="_blank"}](${siteBaseUrl}/docs/user-guide/contribution/widgets-development).

diff --git a/ui-ngx/src/assets/help/en_US/widget/editor/widget_js_subscription_object.md b/ui-ngx/src/assets/help/en_US/widget/editor/widget_js_subscription_object.md index 4a92fd270e..87988e8682 100644 --- a/ui-ngx/src/assets/help/en_US/widget/editor/widget_js_subscription_object.md +++ b/ui-ngx/src/assets/help/en_US/widget/editor/widget_js_subscription_object.md @@ -3,10 +3,10 @@

-The widget subscription object is instance of [IWidgetSubscription{:target="_blank"}](https://github.com/thingsboard/thingsboard/blob/2627fe51d491055d4140f16617ed543f7f5bd8f6/ui-ngx/src/app/core/api/widget-api.models.ts#L264") and contains all subscription information, including current data, according to the [widget type{:target="_blank"}](${baseUrl}/docs/user-guide/ui/widget-library/#widget-types). +The widget subscription object is instance of [IWidgetSubscription{:target="_blank"}](https://github.com/thingsboard/thingsboard/blob/2627fe51d491055d4140f16617ed543f7f5bd8f6/ui-ngx/src/app/core/api/widget-api.models.ts#L264") and contains all subscription information, including current data, according to the [widget type{:target="_blank"}](${siteBaseUrl}/docs/user-guide/ui/widget-library/#widget-types). Depending on widget type, subscription object provides different data structures. -For [Latest values{:target="_blank"}](${baseUrl}/docs/user-guide/ui/widget-library/#latest-values) and [Time-series{:target="_blank"}](${baseUrl}/docs/user-guide/ui/widget-library/#time-series) widget types, it provides the following properties: +For [Latest values{:target="_blank"}](${siteBaseUrl}/docs/user-guide/ui/widget-library/#latest-values) and [Time-series{:target="_blank"}](${siteBaseUrl}/docs/user-guide/ui/widget-library/#time-series) widget types, it provides the following properties: - **datasources** - array of datasources (Array<[Datasource{:target="_blank"}](https://github.com/thingsboard/thingsboard/blob/2627fe51d491055d4140f16617ed543f7f5bd8f6/ui-ngx/src/app/shared/models/widget.models.ts#L279)>) used by this subscription, using the following structure: @@ -54,7 +54,7 @@ For [Latest values{:target="_blank"}](${baseUrl}/docs/user-guide/ui/widget-libra ] ``` -For [Alarm widget{:target="_blank"}](${baseUrl}/docs/user-guide/ui/widget-library/#alarm-widget) type it provides the following properties: +For [Alarm widget{:target="_blank"}](${siteBaseUrl}/docs/user-guide/ui/widget-library/#alarm-widget) type it provides the following properties: - **alarmSource** - ([Datasource{:target="_blank"}](https://github.com/thingsboard/thingsboard/blob/2627fe51d491055d4140f16617ed543f7f5bd8f6/ui-ngx/src/app/shared/models/widget.models.ts#L279)) information about entity for which alarms are fetched, using the following structure: @@ -110,4 +110,4 @@ For [Alarm widget{:target="_blank"}](${baseUrl}/docs/user-guide/ui/widget-librar ] ``` -For [RPC{:target="_blank"}](${baseUrl}/docs/user-guide/ui/widget-library/#rpc-control-widget) or [Static{:target="_blank"}](${baseUrl}/docs/user-guide/ui/widget-library/#static) widget types, subscription object is optional and does not contain necessary information. +For [RPC{:target="_blank"}](${siteBaseUrl}/docs/user-guide/ui/widget-library/#rpc-control-widget) or [Static{:target="_blank"}](${siteBaseUrl}/docs/user-guide/ui/widget-library/#static) widget types, subscription object is optional and does not contain necessary information. diff --git a/ui-ngx/src/assets/help/en_US/widget/lib/markdown/markdown_text_fn.md b/ui-ngx/src/assets/help/en_US/widget/lib/markdown/markdown_text_fn.md index b3ea25d683..9bbcb7fd7c 100644 --- a/ui-ngx/src/assets/help/en_US/widget/lib/markdown/markdown_text_fn.md +++ b/ui-ngx/src/assets/help/en_US/widget/lib/markdown/markdown_text_fn.md @@ -33,7 +33,7 @@ return '# Some title\n - Entity name: ' + data[0]['entityName'];
  • Display greetings for currently logged-in user.
    -Let's assume widget has first datasource configured using Current User Single entity alias
    +Let's assume widget has first datasource configured using Current User Single entity alias
    and has data keys for firstName, lastName and name entity fields:
diff --git a/ui-ngx/src/assets/help/en_US/widget/lib/qrcode/qrcode_text_fn.md b/ui-ngx/src/assets/help/en_US/widget/lib/qrcode/qrcode_text_fn.md index d119592030..2d7f40bf00 100644 --- a/ui-ngx/src/assets/help/en_US/widget/lib/qrcode/qrcode_text_fn.md +++ b/ui-ngx/src/assets/help/en_US/widget/lib/qrcode/qrcode_text_fn.md @@ -34,7 +34,7 @@ return data[0] ? data[0]['entityName'] : '';
  • Prepare QR code text to use as device claiming info (in this case {deviceName: string, secretKey: string}).
    Let's assume device has claimingData attribute with string JSON value containing secretKey field
    -(see Claiming devices): +(see Claiming devices):
  • diff --git a/ui-ngx/src/assets/help/images/widget/editor/examples/add-rpc-device-alias.png b/ui-ngx/src/assets/help/images/widget/editor/examples/add-rpc-device-alias.png new file mode 100644 index 0000000000..6d7e3c22ac Binary files /dev/null and b/ui-ngx/src/assets/help/images/widget/editor/examples/add-rpc-device-alias.png differ diff --git a/ui-ngx/src/assets/help/images/widget/editor/examples/alarm-widget-sample.png b/ui-ngx/src/assets/help/images/widget/editor/examples/alarm-widget-sample.png new file mode 100644 index 0000000000..8d9b4f3dfb Binary files /dev/null and b/ui-ngx/src/assets/help/images/widget/editor/examples/alarm-widget-sample.png differ diff --git a/ui-ngx/src/assets/help/images/widget/editor/examples/control-widget-sample-response-one-way.png b/ui-ngx/src/assets/help/images/widget/editor/examples/control-widget-sample-response-one-way.png new file mode 100644 index 0000000000..579e4edbc5 Binary files /dev/null and b/ui-ngx/src/assets/help/images/widget/editor/examples/control-widget-sample-response-one-way.png differ diff --git a/ui-ngx/src/assets/help/images/widget/editor/examples/control-widget-sample-response-timeout.png b/ui-ngx/src/assets/help/images/widget/editor/examples/control-widget-sample-response-timeout.png new file mode 100644 index 0000000000..2a71e15795 Binary files /dev/null and b/ui-ngx/src/assets/help/images/widget/editor/examples/control-widget-sample-response-timeout.png differ diff --git a/ui-ngx/src/assets/help/images/widget/editor/examples/control-widget-sample-response-two-way.png b/ui-ngx/src/assets/help/images/widget/editor/examples/control-widget-sample-response-two-way.png new file mode 100644 index 0000000000..c7761074d0 Binary files /dev/null and b/ui-ngx/src/assets/help/images/widget/editor/examples/control-widget-sample-response-two-way.png differ diff --git a/ui-ngx/src/assets/help/images/widget/editor/examples/control-widget-sample-settings.png b/ui-ngx/src/assets/help/images/widget/editor/examples/control-widget-sample-settings.png new file mode 100644 index 0000000000..32870de750 Binary files /dev/null and b/ui-ngx/src/assets/help/images/widget/editor/examples/control-widget-sample-settings.png differ diff --git a/ui-ngx/src/assets/help/images/widget/editor/examples/control-widget-sample.png b/ui-ngx/src/assets/help/images/widget/editor/examples/control-widget-sample.png new file mode 100644 index 0000000000..8aa35f755c Binary files /dev/null and b/ui-ngx/src/assets/help/images/widget/editor/examples/control-widget-sample.png differ diff --git a/ui-ngx/src/assets/help/images/widget/editor/examples/dashboard-create-new-widget-button.png b/ui-ngx/src/assets/help/images/widget/editor/examples/dashboard-create-new-widget-button.png new file mode 100644 index 0000000000..c9bc57dbf7 Binary files /dev/null and b/ui-ngx/src/assets/help/images/widget/editor/examples/dashboard-create-new-widget-button.png differ diff --git a/ui-ngx/src/assets/help/images/widget/editor/examples/dashboard-toolbar-entity-aliases.png b/ui-ngx/src/assets/help/images/widget/editor/examples/dashboard-toolbar-entity-aliases.png new file mode 100644 index 0000000000..32deda06cf Binary files /dev/null and b/ui-ngx/src/assets/help/images/widget/editor/examples/dashboard-toolbar-entity-aliases.png differ diff --git a/ui-ngx/src/assets/help/images/widget/editor/examples/external-js-timeseries-widget-sample.png b/ui-ngx/src/assets/help/images/widget/editor/examples/external-js-timeseries-widget-sample.png new file mode 100644 index 0000000000..b69cd945af Binary files /dev/null and b/ui-ngx/src/assets/help/images/widget/editor/examples/external-js-timeseries-widget-sample.png differ diff --git a/ui-ngx/src/assets/help/images/widget/editor/examples/external-js-widget-sample.png b/ui-ngx/src/assets/help/images/widget/editor/examples/external-js-widget-sample.png new file mode 100644 index 0000000000..1c82113ac3 Binary files /dev/null and b/ui-ngx/src/assets/help/images/widget/editor/examples/external-js-widget-sample.png differ diff --git a/ui-ngx/src/assets/help/images/widget/editor/examples/latest-values-widget-sample.png b/ui-ngx/src/assets/help/images/widget/editor/examples/latest-values-widget-sample.png new file mode 100644 index 0000000000..70ed92dee6 Binary files /dev/null and b/ui-ngx/src/assets/help/images/widget/editor/examples/latest-values-widget-sample.png differ diff --git a/ui-ngx/src/assets/help/images/widget/editor/examples/static-widget-sample.png b/ui-ngx/src/assets/help/images/widget/editor/examples/static-widget-sample.png new file mode 100644 index 0000000000..f804da9e93 Binary files /dev/null and b/ui-ngx/src/assets/help/images/widget/editor/examples/static-widget-sample.png differ diff --git a/ui-ngx/src/assets/help/images/widget/editor/examples/timeseries-widget-sample.png b/ui-ngx/src/assets/help/images/widget/editor/examples/timeseries-widget-sample.png new file mode 100644 index 0000000000..f9cb92baf7 Binary files /dev/null and b/ui-ngx/src/assets/help/images/widget/editor/examples/timeseries-widget-sample.png differ