diff --git a/application/src/main/data/json/tenant/dashboards/gateways.json b/application/src/main/data/json/tenant/dashboards/gateways.json index 13902a9158..0ddfc98705 100644 --- a/application/src/main/data/json/tenant/dashboards/gateways.json +++ b/application/src/main/data/json/tenant/dashboards/gateways.json @@ -185,16 +185,12 @@ "icon": "terminal", "useShowWidgetActionFunction": null, "showWidgetActionFunction": "return true;", - "type": "openDashboardState", - "targetDashboardStateId": "launch_command", - "setEntityId": true, - "stateEntityParamName": null, - "openRightLayout": false, - "dialogTitle": "Docker commands", - "dialogHideDashboardToolbar": true, - "dialogWidth": null, - "dialogHeight": 55, - "openInSeparateDialog": true, + "type": "customPretty", + "customHtml": "
\n \n

Docker commands

\n \n
\n \n
\n \n
\n \n
\n
\n", + "customCss": ".container {\n display: grid;\n grid-template-rows: min-content minmax(auto, 1fr) min-content;\n height: 100%;\n max-height: 100vh;\n width: 600px;\n max-width: 100%;\n}", + "customFunction": "let $injector = widgetContext.$scope.$injector;\nlet customDialog = $injector.get(widgetContext.servicesMap.get('customDialog'));\n\nopenCommands();\n\nfunction openCommands() {\n customDialog.customDialog(htmlTemplate, CommandsDialogController, {panelClass: \"test\"}).subscribe();\n}\n\nfunction CommandsDialogController(instance) {\n let vm = instance;\n \n vm.entityId = entityId.id;\n\n vm.cancel = function() {\n vm.dialogRef.close(null);\n };\n}\n", + "customResources": [], + "openInSeparateDialog": false, "openInPopover": false, "id": "ae2e5995-505f-a241-5fb2-6cbaf08b1b55" }, @@ -1889,16 +1885,12 @@ "icon": "more_horiz", "useShowWidgetActionFunction": null, "showWidgetActionFunction": "return true;", - "type": "openDashboardState", - "targetDashboardStateId": "launch_command", - "setEntityId": true, - "stateEntityParamName": "", - "openRightLayout": false, - "dialogTitle": "Launch command", - "dialogHideDashboardToolbar": true, - "dialogWidth": null, - "dialogHeight": 55, - "openInSeparateDialog": true, + "type": "customPretty", + "customHtml": "
\n \n

Launch command

\n \n
\n \n
\n \n
\n \n
\n
\n", + "customCss": ".container {\n display: grid;\n grid-template-rows: min-content minmax(auto, 1fr) min-content;\n height: 100%;\n max-height: 100vh;\n width: 600px;\n max-width: 100%;\n}", + "customFunction": "let $injector = widgetContext.$scope.$injector;\nlet customDialog = $injector.get(widgetContext.servicesMap.get('customDialog'));\n\nopenCommands();\n\nfunction openCommands() {\n customDialog.customDialog(htmlTemplate, CommandsDialogController, {panelClass: \"test\"}).subscribe();\n}\n\nfunction CommandsDialogController(instance) {\n let vm = instance;\n \n vm.entityId = entityId.id;\n\n vm.cancel = function() {\n vm.dialogRef.close(null);\n };\n}\n", + "customResources": [], + "openInSeparateDialog": false, "openInPopover": false, "id": "337c767b-3217-d3d3-b955-7b0bd0858a1d" } @@ -5160,96 +5152,6 @@ "col": 0, "id": "75b6372d-4def-42b4-8774-4edf413a8b83", "typeFullFqn": "system.cards.entities_table" - }, - "dfda1a57-6c04-3482-2054-84954bbef626": { - "type": "latest", - "sizeX": 5, - "sizeY": 3.5, - "config": { - "datasources": [ - { - "type": "entity", - "name": null, - "entityAliasId": "a2f01c66-96cf-49c5-303f-e6f21c559ee8", - "filterId": null, - "dataKeys": [] - } - ], - "timewindow": { - "displayValue": "", - "selectedTab": 0, - "realtime": { - "realtimeType": 1, - "interval": 1000, - "timewindowMs": 60000, - "quickInterval": "CURRENT_DAY" - }, - "history": { - "historyType": 0, - "interval": 1000, - "timewindowMs": 60000, - "fixedTimewindow": { - "startTimeMs": 1685437116892, - "endTimeMs": 1685523516892 - }, - "quickInterval": "CURRENT_DAY" - }, - "aggregation": { - "type": "AVG", - "limit": 25000 - } - }, - "showTitle": false, - "backgroundColor": "#fff", - "color": "rgba(0, 0, 0, 0.87)", - "padding": "0px", - "settings": { - "useMarkdownTextFunction": true, - "markdownTextFunction": "return `
\n\n
`;", - "applyDefaultMarkdownStyle": false, - "markdownCss": ".action-container {\r\n display: flex;\r\n flex-wrap: wrap;\r\n flex-direction: row;\r\n height: 100%;\r\n width: 100%;\r\n}\r\n\r\nbutton {\r\n flex-grow: 1;\r\n margin: 10px;\r\n min-width: 150px;\r\n height: auto;\r\n}" - }, - "title": "Gateway commands", - "showTitleIcon": false, - "iconColor": "rgba(0, 0, 0, 0.87)", - "iconSize": "24px", - "titleTooltip": "", - "dropShadow": false, - "enableFullscreen": false, - "widgetStyle": {}, - "titleStyle": { - "fontSize": "16px", - "fontWeight": 400 - }, - "showLegend": false, - "useDashboardTimewindow": true, - "actions": { - "elementClick": [ - { - "name": "Launch command", - "icon": "more_horiz", - "useShowWidgetActionFunction": null, - "showWidgetActionFunction": "return true;", - "type": "customPretty", - "customHtml": "
\r\n \r\n

gateway.command

\r\n \r\n \r\n
\r\n \r\n \r\n
\r\n \r\n
\r\n \r\n
\r\n
", - "customCss": "/*=======================================================================*/\r\n/*========== There are two examples: for edit and add entity ==========*/\r\n/*=======================================================================*/\r\n/*======================== Edit entity example ========================*/\r\n/*=======================================================================*/\r\n/*\r\n.edit-entity-form .boolean-value-input {\r\n padding-left: 5px;\r\n}\r\n\r\n.edit-entity-form .boolean-value-input .checkbox-label {\r\n margin-bottom: 8px;\r\n color: rgba(0,0,0,0.54);\r\n font-size: 12px;\r\n}\r\n\r\n.relations-list .header {\r\n padding-right: 5px;\r\n padding-bottom: 5px;\r\n padding-left: 5px;\r\n}\r\n\r\n.relations-list .header .cell {\r\n padding-right: 5px;\r\n padding-left: 5px;\r\n font-size: 12px;\r\n font-weight: 700;\r\n color: rgba(0, 0, 0, .54);\r\n white-space: nowrap;\r\n}\r\n\r\n.relations-list .mat-form-field-infix {\r\n width: auto !important;\r\n}\r\n\r\n.relations-list .body {\r\n padding-right: 5px;\r\n padding-bottom: 15px;\r\n padding-left: 5px;\r\n}\r\n\r\n.relations-list .body .row {\r\n padding-top: 5px;\r\n}\r\n\r\n.relations-list .body .cell {\r\n padding-right: 5px;\r\n padding-left: 5px;\r\n}\r\n\r\n.relations-list .body .md-button {\r\n margin: 0;\r\n}\r\n*/\r\n/*========================================================================*/\r\n/*========================= Add entity example =========================*/\r\n/*========================================================================*/\r\n/*\r\n.add-entity-form .boolean-value-input {\r\n padding-left: 5px;\r\n}\r\n\r\n.add-entity-form .boolean-value-input .checkbox-label {\r\n margin-bottom: 8px;\r\n color: rgba(0,0,0,0.54);\r\n font-size: 12px;\r\n}\r\n\r\n.relations-list .header {\r\n padding-right: 5px;\r\n padding-bottom: 5px;\r\n padding-left: 5px;\r\n}\r\n\r\n.relations-list .header .cell {\r\n padding-right: 5px;\r\n padding-left: 5px;\r\n font-size: 12px;\r\n font-weight: 700;\r\n color: rgba(0, 0, 0, .54);\r\n white-space: nowrap;\r\n}\r\n\r\n.relations-list .mat-form-field-infix {\r\n width: auto !important;\r\n}\r\n\r\n.relations-list .body {\r\n padding-right: 5px;\r\n padding-bottom: 15px;\r\n padding-left: 5px;\r\n}\r\n\r\n.relations-list .body .row {\r\n padding-top: 5px;\r\n}\r\n\r\n.relations-list .body .cell {\r\n padding-right: 5px;\r\n padding-left: 5px;\r\n}\r\n\r\n.relations-list .body .md-button {\r\n margin: 0;\r\n}\r\n*/\r\n", - "customFunction": "let $injector = widgetContext.$scope.$injector;\r\nlet customDialog = $injector.get(widgetContext.servicesMap.get('customDialog'));\r\nlet deviceService = $injector.get(widgetContext.servicesMap.get('deviceService'));\r\nlet data = {};\r\n\r\nopenEditEntityDialog();\r\n\r\nfunction openEditEntityDialog() {\r\n deviceService.getDeviceCredentials(entityId.id).subscribe(credentials => {\r\n data.credentials = credentials;\r\n customDialog.customDialog(htmlTemplate, EditEntityDialogController).subscribe();\r\n });\r\n}\r\n\r\nfunction EditEntityDialogController(instance) {\r\n let vm = instance;\r\n vm.data = data;\r\n\r\n vm.close = function() {\r\n vm.dialogRef.close(null);\r\n };\r\n\r\n\r\n}", - "customResources": [], - "openInSeparateDialog": false, - "openInPopover": false, - "id": "337c767b-3217-d3d3-b955-7b0bd0858a1d" - } - ] - }, - "widgetCss": "", - "pageSize": 1024, - "noDataDisplayMessage": "", - "enableDataExport": false - }, - "row": 0, - "col": 0, - "id": "dfda1a57-6c04-3482-2054-84954bbef626", - "typeFullFqn": "system.cards.markdown_card" } }, "states": { @@ -6079,33 +5981,6 @@ } } } - }, - "launch_command": { - "name": "launch command", - "root": false, - "layouts": { - "main": { - "widgets": { - "dfda1a57-6c04-3482-2054-84954bbef626": { - "sizeX": 24, - "sizeY": 3, - "row": 0, - "col": 0 - } - }, - "gridSettings": { - "backgroundColor": "#eeeeee", - "columns": 24, - "margin": 0, - "outerMargin": true, - "backgroundSizeMode": "100%", - "autoFillHeight": true, - "backgroundImageUrl": null, - "mobileAutoFillHeight": false, - "mobileRowHeight": 70 - } - } - } } }, "entityAliases": { @@ -6866,4 +6741,4 @@ }, "externalId": null, "name": "Gateway" -} \ No newline at end of file +} diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/gateway/device-gateway-command.component.html b/ui-ngx/src/app/modules/home/components/widget/lib/gateway/device-gateway-command.component.html index 084eb49245..905d33730f 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/gateway/device-gateway-command.component.html +++ b/ui-ngx/src/app/modules/home/components/widget/lib/gateway/device-gateway-command.component.html @@ -15,59 +15,39 @@ limitations under the License. --> -
-
- {{ 'gateway.docker-label' | translate }} -
+
+
{{ 'gateway.docker-label' | translate }}
+
+
device.connectivity.install-necessary-client-tools
+
-
+ +
+
gateway.download-configuration-file
+
+
gateway.download-docker-compose
+ + download + {{ 'action.download' | translate }} + +
- - - - - Windows - - - - - - - - - - Linux - - - - - - - - - - MacOS - - - - - - - -
- -
-
device.connectivity.execute-following-command
+
+
gateway.launch-gateway
+
gateway.launch-docker-compose
- +
diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/gateway/device-gateway-command.component.scss b/ui-ngx/src/app/modules/home/components/widget/lib/gateway/device-gateway-command.component.scss index befa034375..6922398c00 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/gateway/device-gateway-command.component.scss +++ b/ui-ngx/src/app/modules/home/components/widget/lib/gateway/device-gateway-command.component.scss @@ -14,28 +14,35 @@ * limitations under the License. */ :host { - width: 100%; - height: 100%; - display: block; + .tb-commands-hint { + color: inherit; + font-weight: normal; + flex: 1; + } } :host ::ng-deep { .tb-markdown-view { .start-code { - code[class*="language-"] { - white-space: break-spaces; - word-break: break-all; - } - pre[class*="language-"] { - overflow: hidden; - background: #F3F6FA; - border-color: #305680; - } .code-wrapper { padding: 0; + + pre[class*=language-] { + margin: 0; + background: #F3F6FA; + border-color: #305680; + padding-right: 38px; + overflow: scroll; + padding-bottom: 4px; + + &::-webkit-scrollbar { + width: 4px; + height: 4px; + } + } } button.clipboard-btn { - right: 0; + right: -2px; p { color: #305680; } @@ -60,9 +67,5 @@ } } } - - .tb-form-panel.tb-tab-body { - margin-top: 16px; - } } diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/gateway/device-gateway-command.component.ts b/ui-ngx/src/app/modules/home/components/widget/lib/gateway/device-gateway-command.component.ts index d5516dd59b..95de2c4285 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/gateway/device-gateway-command.component.ts +++ b/ui-ngx/src/app/modules/home/components/widget/lib/gateway/device-gateway-command.component.ts @@ -14,11 +14,8 @@ /// limitations under the License. /// -import { ChangeDetectorRef, Component, Input, OnInit } from '@angular/core'; -import { DeviceService } from '@core/http/device.service'; -import { helpBaseUrl } from '@shared/models/constants'; -import { getOS } from '@core/utils'; -import { PublishLaunchCommand } from '@shared/models/device.models'; +import { Component, Inject, Input, OnInit } from '@angular/core'; +import { WINDOW } from '@core/services/window.service'; @Component({ selector: 'tb-gateway-command', @@ -28,45 +25,18 @@ import { PublishLaunchCommand } from '@shared/models/device.models'; export class DeviceGatewayCommandComponent implements OnInit { - @Input() - token: string; - @Input() deviceId: string; - commands: PublishLaunchCommand; - - helpLink: string = helpBaseUrl + '/docs/iot-gateway/install/docker-installation/'; + downloadUrl: string; - tabIndex = 0; - - constructor(private cd: ChangeDetectorRef, - private deviceService: DeviceService) { + constructor(@Inject(WINDOW) private window: Window) { } ngOnInit(): void { if (this.deviceId) { - this.deviceService.getDevicePublishLaunchCommands(this.deviceId).subscribe(commands => { - this.commands = commands; - this.cd.detectChanges(); - }); - } - const currentOS = getOS(); - switch (currentOS) { - case 'linux': - case 'android': - this.tabIndex = 1; - break; - case 'macos': - case 'ios': - this.tabIndex = 2; - break; - case 'windows': - this.tabIndex = 0; - break; - default: - this.tabIndex = 1; + this.downloadUrl = `${this.window.location.origin}/api/device-connectivity/gateway-launch/${this.deviceId}/docker-compose/download`; } } } diff --git a/ui-ngx/src/app/shared/models/constants.ts b/ui-ngx/src/app/shared/models/constants.ts index c119ae327f..b566c15280 100644 --- a/ui-ngx/src/app/shared/models/constants.ts +++ b/ui-ngx/src/app/shared/models/constants.ts @@ -176,6 +176,7 @@ export const HelpLinks = { recipientNotifications: helpBaseUrl + '/docs/user-guide/notifications/#recipients', ruleNotifications: helpBaseUrl + '/docs/user-guide/notifications/#rules', jwtSecuritySettings: helpBaseUrl + '/docs/user-guide/ui/jwt-security-settings/', + gatewayInstall: helpBaseUrl + '/docs/iot-gateway/install/docker-installation/', } }; 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 603794c6cf..1904cb796f 100644 --- a/ui-ngx/src/assets/locale/locale.constant-en_US.json +++ b/ui-ngx/src/assets/locale/locale.constant-en_US.json @@ -2697,7 +2697,12 @@ "rpc-command-result": "Response", "rpc-command-edit-params": "Edit parameters", "gateway-configuration": "General Configuration", - "docker-label": "In order to run ThingsBoard IoT gateway in docker with credentials for this device you can use the following commands.", + "docker-label": "Use the following instruction to run IoT Gateway in in Docker compose with credentials for selected device", + "install-docker-compose": "Use the instructions to download, install and setup docker compose", + "download-configuration-file": "Download configuration file", + "download-docker-compose": "Download docker-compose.yml for your gateway", + "launch-gateway": "Launch gateway", + "launch-docker-compose": "Start the gateway using the following command in the terminal from folder with docker-compose.yml file", "create-new-gateway": "Create a new gateway", "create-new-gateway-text": "Are you sure you want create a new gateway with name: '{{gatewayName}}'?", "created-time": "Created time", diff --git a/ui-ngx/src/assets/locale/locale.constant-es_ES.json b/ui-ngx/src/assets/locale/locale.constant-es_ES.json index 7a63c626c8..f1d51de0c2 100644 --- a/ui-ngx/src/assets/locale/locale.constant-es_ES.json +++ b/ui-ngx/src/assets/locale/locale.constant-es_ES.json @@ -2655,7 +2655,6 @@ "rpc-command-result": "Resultado", "rpc-command-edit-params": "Editar parametros", "gateway-configuration": "Configuración General", - "docker-label": "Usa los siguientes comandos para ejecutar el gateway en Docker.", "create-new-gateway": "Crear un gateway nuevo", "create-new-gateway-text": "Crear un nuevo gateway con el nombre: '{{gatewayName}}'?", "created-time": "Hora de creación", diff --git a/ui-ngx/src/assets/locale/locale.constant-zh_CN.json b/ui-ngx/src/assets/locale/locale.constant-zh_CN.json index adda072f8f..aaf90d3db0 100644 --- a/ui-ngx/src/assets/locale/locale.constant-zh_CN.json +++ b/ui-ngx/src/assets/locale/locale.constant-zh_CN.json @@ -2685,7 +2685,6 @@ "rpc-command-result": "结果", "rpc-command-edit-params": "编辑参数", "gateway-configuration": "通用配置", - "docker-label": "要在 Docker 中使用此设备的凭据运行 ThingsBoard IoT 网关,您可以使用以下命令。", "create-new-gateway": "创建网关", "create-new-gateway-text": "确定要创建名为 '{{gatewayName}}' 的新网关?", "created-time": "创建时间",