Skip to content

Commit

Permalink
Merge pull request #9848 from vvlladd28/improvement/gateway/launch-ga…
Browse files Browse the repository at this point in the history
…teway/dialog

Redesign gateway launch commands dialog
  • Loading branch information
ashvayka authored Dec 18, 2023
2 parents a0fd420 + 9c07f2a commit 1419782
Show file tree
Hide file tree
Showing 8 changed files with 72 additions and 240 deletions.
151 changes: 13 additions & 138 deletions application/src/main/data/json/tenant/dashboards/gateways.json
Original file line number Diff line number Diff line change
Expand Up @@ -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": "<div class=\"container\">\n <mat-toolbar fxLayout=\"row\" color=\"primary\">\n <h2>Docker commands</h2>\n <span fxFlex></span>\n <div [tb-help]=\"'gatewayInstall'\"></div>\n <button mat-icon-button (click)=\"cancel()\" type=\"button\">\n <mat-icon class=\"material-icons\">close</mat-icon>\n </button>\n </mat-toolbar>\n <tb-gateway-command [deviceId]=\"entityId\"></tb-gateway-command>\n <div mat-dialog-actions fxLayout=\"row\" fxLayoutAlign=\"end center\">\n <button mat-button color=\"primary\"\n type=\"button\"\n (click)=\"cancel()\" cdkFocusInitial>\n {{ 'action.close' | translate }}\n </button>\n </div>\n</div>\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"
},
Expand Down Expand Up @@ -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": "<div class=\"container\">\n <mat-toolbar fxLayout=\"row\" color=\"primary\">\n <h2>Launch command</h2>\n <span fxFlex></span>\n <div [tb-help]=\"'gatewayInstall'\"></div>\n <button mat-icon-button (click)=\"cancel()\" type=\"button\">\n <mat-icon class=\"material-icons\">close</mat-icon>\n </button>\n </mat-toolbar>\n <tb-gateway-command [deviceId]=\"entityId\"></tb-gateway-command>\n <div mat-dialog-actions fxLayout=\"row\" fxLayoutAlign=\"end center\">\n <button mat-button color=\"primary\"\n type=\"button\"\n (click)=\"cancel()\" cdkFocusInitial>\n {{ 'action.close' | translate }}\n </button>\n </div>\n</div>\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"
}
Expand Down Expand Up @@ -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 `<div class=\"action-container\">\n<tb-gateway-command deviceId=\"${data[0].entityId}\"></tb-gateway-command>\n </div>`;",
"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": "<form style=\"min-width: 400px; max-width: 1000px; position: relative;\">\r\n <mat-toolbar color=\"primary\">\r\n <h2 translate>gateway.command</h2>\r\n <span fxFlex></span>\r\n <button mat-icon-button\r\n (click)=\"close()\"\r\n type=\"button\">\r\n <mat-icon class=\"material-icons\">close</mat-icon>\r\n </button>\r\n </mat-toolbar>\r\n <mat-progress-bar color=\"warn\" mode=\"indeterminate\" *ngIf=\"isLoading$ | async\">\r\n </mat-progress-bar>\r\n <div style=\"height: 4px;\" *ngIf=\"!(isLoading$ | async)\"></div>\r\n <tb-gateway-command [token]=\"data.credentials.credentialsId\"></tb-gateway-command>\r\n <div mat-dialog-actions fxLayoutAlign=\"end center\">\r\n <button mat-button color=\"primary\"\r\n type=\"button\"\r\n cdkFocusInitial\r\n [disabled]=\"(isLoading$ | async)\"\r\n (click)=\"close()\">\r\n {{ 'action.ok' | translate }}\r\n </button>\r\n </div>\r\n</form>",
"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": {
Expand Down Expand Up @@ -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": {
Expand Down Expand Up @@ -6866,4 +6741,4 @@
},
"externalId": null,
"name": "Gateway"
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,59 +15,39 @@
limitations under the License.
-->
<div mat-dialog-content fxLayout="column" style="padding: 0 8px 8px">
<div fxLayout="row" fxLayoutAlign="space-between center">
<span class="tb-no-data-text">{{ 'gateway.docker-label' | translate }}</span>
<div fxFlexAlign="end" class="tb-help" [tb-help]="helpLink"></div>
<div mat-dialog-content style="padding: 16px 16px 8px" class="tb-form-panel no-border">
<div class="tb-no-data-text">{{ 'gateway.docker-label' | translate }}</div>
<div class="tb-form-panel stroked">
<div class="tb-form-panel-title" translate>device.connectivity.install-necessary-client-tools</div>
<div class="tb-form-row no-border no-padding space-between">
<div class="tb-no-data-text tb-commands-hint" translate>gateway.install-docker-compose</div>
<a mat-stroked-button color="primary" href="https://docs.docker.com/compose/install/" target="_blank">
<mat-icon>description</mat-icon>
{{ 'common.documentation' | translate }}
</a>
</div>
</div>
<div fxFlex fxLayout="row" style="justify-content: space-between; flex-grow: 0; align-items: center">

<div class="tb-form-panel stroked">
<div class="tb-form-panel-title" translate>gateway.download-configuration-file</div>
<div class="tb-form-row no-border no-padding space-between">
<div class="tb-no-data-text tb-commands-hint" translate>gateway.download-docker-compose</div>
<a mat-stroked-button color="primary" href="{{downloadUrl}}" target="_blank">
<mat-icon>download</mat-icon>
{{ 'action.download' | translate }}
</a>
</div>
</div>
<mat-tab-group [(selectedIndex)]="tabIndex">
<mat-tab>
<ng-template mat-tab-label>
<mat-icon class="tabs-icon" svgIcon="windows"></mat-icon>
Windows
</ng-template>
<ng-template matTabContent>
<ng-container
*ngTemplateOutlet="commandsExample; context: {command: commands?.mqtt?.windows }">
</ng-container>
</ng-template>
</mat-tab>
<mat-tab>
<ng-template mat-tab-label>
<mat-icon class="tabs-icon" svgIcon="linux"></mat-icon>
Linux
</ng-template>
<ng-template matTabContent>
<ng-container
*ngTemplateOutlet="commandsExample; context: {command: commands?.mqtt?.linux }">
</ng-container>
</ng-template>
</mat-tab>
<mat-tab>
<ng-template mat-tab-label>
<mat-icon class="tabs-icon" svgIcon="macos"></mat-icon>
MacOS
</ng-template>
<ng-template matTabContent>
<ng-container
*ngTemplateOutlet="commandsExample; context: {command: commands?.mqtt?.macos }">
</ng-container>
</ng-template>
</mat-tab>
</mat-tab-group>
</div>

<ng-template #commandsExample let-command="command">
<div class="tb-form-panel stroked tb-tab-body">
<div class="tb-form-panel-title" translate>device.connectivity.execute-following-command</div>
<div class="tb-form-panel stroked">
<div class="tb-form-panel-title" translate>gateway.launch-gateway</div>
<div class="tb-no-data-text tb-commands-hint" translate>gateway.launch-docker-compose</div>
<tb-markdown usePlainMarkdown containerClass="start-code"
data="
data="
```bash
{{ command }}
docker compose up
{:copy-code}
```
"></tb-markdown>
</div>
</ng-template>
</div>
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand All @@ -60,9 +67,5 @@
}
}
}

.tb-form-panel.tb-tab-body {
margin-top: 16px;
}
}

Original file line number Diff line number Diff line change
Expand Up @@ -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',
Expand All @@ -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`;
}
}
}
Loading

0 comments on commit 1419782

Please sign in to comment.