Browse Source

UI: Improved view gateway dashboard and updated gateway widget types

pull/9242/head
Vladyslav_Prykhodko 3 years ago
parent
commit
65145284ca
  1. 656
      application/src/main/data/json/demo/dashboards/gateway_list.json
  2. 6
      application/src/main/data/json/system/widget_types/gateway_configuration2.json
  3. 10
      application/src/main/data/json/system/widget_types/gateway_connector.json
  4. 8
      application/src/main/data/json/system/widget_types/gateway_general_statistics.json
  5. 10
      application/src/main/data/json/system/widget_types/gateway_logs.json
  6. 10
      application/src/main/data/json/system/widget_types/gateway_statistics.json
  7. 6
      application/src/main/data/json/system/widget_types/service_rpc.json
  8. 14
      ui-ngx/src/app/modules/home/components/widget/dialog/custom-dialog.service.ts
  9. 5
      ui-ngx/src/app/modules/home/components/widget/lib/gateway/device-gateway-command.component.html
  10. 32
      ui-ngx/src/app/modules/home/components/widget/lib/gateway/device-gateway-command.component.scss
  11. 13
      ui-ngx/src/app/modules/home/components/widget/lib/gateway/gateway-configuration.component.html
  12. 21
      ui-ngx/src/app/modules/home/components/widget/lib/gateway/gateway-configuration.component.scss
  13. 250
      ui-ngx/src/app/modules/home/components/widget/lib/gateway/gateway-connectors.component.html
  14. 16
      ui-ngx/src/app/modules/home/components/widget/lib/gateway/gateway-connectors.component.scss

656
application/src/main/data/json/demo/dashboards/gateway_list.json

File diff suppressed because it is too large

6
application/src/main/data/json/system/widget_types/gateway_configuration2.json

File diff suppressed because one or more lines are too long

10
application/src/main/data/json/system/widget_types/gateway_connector.json

File diff suppressed because one or more lines are too long

8
application/src/main/data/json/system/widget_types/gateway_general_statistics.json

File diff suppressed because one or more lines are too long

10
application/src/main/data/json/system/widget_types/gateway_logs.json

File diff suppressed because one or more lines are too long

10
application/src/main/data/json/system/widget_types/gateway_statistics.json

File diff suppressed because one or more lines are too long

6
application/src/main/data/json/system/widget_types/service_rpc.json

File diff suppressed because one or more lines are too long

14
ui-ngx/src/app/modules/home/components/widget/dialog/custom-dialog.service.ts

@ -17,8 +17,6 @@
import { Inject, Injectable, Type } from '@angular/core';
import { Observable } from 'rxjs';
import { MatDialog, MatDialogConfig } from '@angular/material/dialog';
import { TranslateService } from '@ngx-translate/core';
import { AuthService } from '@core/auth/auth.service';
import { DynamicComponentFactoryService } from '@core/services/dynamic-component-factory.service';
import { CommonModule } from '@angular/common';
import { mergeMap, tap } from 'rxjs/operators';
@ -28,7 +26,11 @@ import {
CustomDialogContainerData
} from '@home/components/widget/dialog/custom-dialog-container.component';
import { SHARED_MODULE_TOKEN } from '@shared/components/tokens';
import { HOME_COMPONENTS_MODULE_TOKEN, SHARED_HOME_COMPONENTS_MODULE_TOKEN } from '@home/components/tokens';
import {
HOME_COMPONENTS_MODULE_TOKEN,
SHARED_HOME_COMPONENTS_MODULE_TOKEN,
WIDGET_COMPONENTS_MODULE_TOKEN
} from '@home/components/tokens';
@Injectable()
export class CustomDialogService {
@ -36,12 +38,11 @@ export class CustomDialogService {
private customModules: Array<Type<any>>;
constructor(
private translate: TranslateService,
private authService: AuthService,
private dynamicComponentFactoryService: DynamicComponentFactoryService,
@Inject(SHARED_MODULE_TOKEN) private sharedModule: Type<any>,
@Inject(SHARED_HOME_COMPONENTS_MODULE_TOKEN) private sharedHomeComponentsModule: Type<any>,
@Inject(HOME_COMPONENTS_MODULE_TOKEN) private homeComponentsModule: Type<any>,
@Inject(WIDGET_COMPONENTS_MODULE_TOKEN) private widgetComponentsModule: Type<any>,
public dialog: MatDialog
) {
}
@ -52,7 +53,8 @@ export class CustomDialogService {
customDialog(template: string, controller: (instance: CustomDialogComponent) => void, data?: any,
config?: MatDialogConfig): Observable<any> {
const modules = [this.sharedModule, CommonModule, this.sharedHomeComponentsModule, this.homeComponentsModule];
const modules = [this.sharedModule, CommonModule, this.sharedHomeComponentsModule, this.homeComponentsModule,
this.widgetComponentsModule];
if (Array.isArray(this.customModules)) {
modules.push(...this.customModules);
}

5
ui-ngx/src/app/modules/home/components/widget/lib/gateway/device-gateway-command.component.html

@ -15,7 +15,7 @@
limitations under the License.
-->
<div mat-dialog-content fxLayout="column" style="padding: 0">
<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>
@ -60,7 +60,8 @@
</div>
<ng-template #commandsExample let-command="command">
<div class="tb-form-panel no-padding no-border tb-tab-body">
<div class="tb-form-panel stroked tb-tab-body">
<div class="tb-form-panel-title" translate>device.connectivity.execute-following-command</div>
<tb-markdown usePlainMarkdown containerClass="start-code"
data="
```bash

32
ui-ngx/src/app/modules/home/components/widget/lib/gateway/device-gateway-command.component.scss

@ -26,12 +26,44 @@
overflow: hidden;
white-space: break-spaces;
word-break: break-all;
background: #F3F6FA;
border-color: #305680;
}
.code-wrapper {
padding: 0;
}
button.clipboard-btn {
right: 0;
p {
color: #305680;
}
p, div {
background-color: #F3F6FA;
}
div {
img {
display: none;
}
&:after {
content: "";
position: initial;
display: block;
width: 18px;
height: 18px;
background: #305680;
mask-image: url(/assets/copy-code-icon.svg);
mask-repeat: no-repeat;
}
}
}
}
}
.tb-form-panel.tb-tab-body {
margin-top: 16px;
}
}

13
ui-ngx/src/app/modules/home/components/widget/lib/gateway/gateway-configuration.component.html

@ -15,17 +15,10 @@
limitations under the License.
-->
<mat-toolbar color="primary">
<mat-toolbar color="primary" *ngIf="!dialogRef">
<h2 translate>gateway.gateway-configuration</h2>
<span fxFlex></span>
<button mat-icon-button
type="button"
(click)="cancel()"
*ngIf="dialogRef">
<mat-icon class="material-icons" style="color:#000;">close</mat-icon>
</button>
</mat-toolbar>
<mat-tab-group style="max-height: calc(100% - 117px); height: 100%;" [formGroup]="gatewayConfigGroup">
<mat-tab-group class="tab-group-block" [formGroup]="gatewayConfigGroup">
<mat-tab label="{{ 'gateway.thingsboard-general' | translate }}">
<div formGroupName="thingsboard" class="mat-content mat-padding configuration-block">
<div class="tb-form-panel no-padding-bottom">
@ -713,7 +706,7 @@
</div>
</mat-tab>
</mat-tab-group>
<div mat-dialog-actions fxLayoutAlign="start center">
<div class="actions">
<button mat-button color="primary"
type="button"
*ngIf="dialogRef"

21
ui-ngx/src/app/modules/home/components/widget/lib/gateway/gateway-configuration.component.scss

@ -16,8 +16,8 @@
:host {
width: 100%;
height: 100%;
display: flex;
flex-direction: column;
display: grid;
grid-template-rows: min-content minmax(auto, 1fr) min-content;
.configuration-block {
display: flex;
@ -26,10 +26,18 @@
}
.mat-toolbar {
grid-row: 1;
background: transparent;
color: rgba(0, 0, 0, .87) !important;
}
.tab-group-block {
min-width: 0;
height: 100%;
min-height: 0;
grid-row: 2;
}
.toggle-group {
margin-right: auto;
}
@ -45,6 +53,15 @@
.saving-period {
flex: 1;
}
.actions {
grid-row: 3;
padding: 8px;
display: flex;
gap: 8px;
justify-content: flex-end;
flex: 1;
}
}
:host ::ng-deep {

250
ui-ngx/src/app/modules/home/components/widget/lib/gateway/gateway-connectors.component.html

@ -16,7 +16,7 @@
-->
<div class="connector-container tb-form-panel no-border">
<section class="table-container tb-form-panel stroked no-padding flex">
<section class="table-section tb-form-panel no-padding flex section-container">
<mat-toolbar class="mat-mdc-table-toolbar">
<h2>{{ 'gateway.connectors' | translate }}</h2>
<span fxFlex></span>
@ -28,89 +28,64 @@
<mat-icon>add</mat-icon>
</button>
</mat-toolbar>
<table mat-table [dataSource]="dataSource"
matSort [matSortActive]="pageLink.sortOrder.property" [matSortDirection]="pageLink.sortDirection()"
matSortDisableClear>
<ng-container matColumnDef="enabled" sticky>
<mat-header-cell *matHeaderCellDef style="width: 60px;min-width: 60px;">
{{ 'gateway.connectors-table-enabled' | translate }}
</mat-header-cell>
<mat-cell *matCellDef="let attribute">
<mat-slide-toggle [checked]="activeConnectors.includes(attribute.key)"
(click)="$event.stopPropagation(); enableConnector(attribute)"></mat-slide-toggle>
</mat-cell>
</ng-container>
<ng-container matColumnDef="key">
<mat-header-cell *matHeaderCellDef mat-sort-header style="width: 40%">
{{ 'gateway.connectors-table-name' | translate }}</mat-header-cell>
<mat-cell *matCellDef="let attribute">
{{ attribute.key }}
</mat-cell>
</ng-container>
<ng-container matColumnDef="type">
<mat-header-cell *matHeaderCellDef mat-sort-header style="width: 30%">
{{ 'gateway.connectors-table-type' | translate }}
</mat-header-cell>
<mat-cell *matCellDef="let attribute" style="text-transform: uppercase">
{{ returnType(attribute) }}
</mat-cell>
</ng-container>
<ng-container matColumnDef="syncStatus">
<mat-header-cell *matHeaderCellDef mat-sort-header style="width: 30%">
{{ 'gateway.configuration' | translate }}
</mat-header-cell>
<mat-cell *matCellDef="let attribute" style="text-transform: uppercase">
<div class="status" [class]="isConnectorSynced(attribute) ? 'status-sync' : 'status-unsync'">
{{ isConnectorSynced(attribute) ? 'sync' : 'out of sync' }}
</div>
</mat-cell>
</ng-container>
<ng-container matColumnDef="errors">
<mat-header-cell *matHeaderCellDef mat-sort-header style="width: 30%">
{{ 'gateway.connectors-table-status' | translate }}
</mat-header-cell>
<mat-cell *matCellDef="let attribute" style="text-transform: uppercase">
<span class="dot"
matTooltip="{{ 'Errors: '+ getErrorsCount(attribute)}}"
matTooltipPosition="above"
[class]="{'hasErrors': +getErrorsCount(attribute) > 0,
'noErrors': +getErrorsCount(attribute) === 0 || getErrorsCount(attribute) === ''}"></span>
</mat-cell>
</ng-container>
<ng-container matColumnDef="actions" stickyEnd>
<mat-header-cell *matHeaderCellDef
[ngStyle.gt-md]="{ minWidth: '144px', maxWidth: '144px', width: '144px'}">
{{ 'gateway.connectors-table-actions' | translate }}
</mat-header-cell>
<mat-cell *matCellDef="let attribute"
[ngStyle.gt-md]="{ minWidth: '144px', maxWidth: '144px', width: '144px'}">
<div fxHide fxShow.gt-md fxFlex fxLayout="row" fxLayoutAlign="end">
<button mat-icon-button
matTooltip="RPC"
matTooltipPosition="above"
(click)="connectorRpc(attribute, $event)">
<mat-icon>private_connectivity</mat-icon>
</button>
<button mat-icon-button
matTooltip="Logs"
matTooltipPosition="above"
(click)="connectorLogs(attribute, $event)">
<mat-icon>list</mat-icon>
</button>
<button mat-icon-button
matTooltip="Delete connector"
matTooltipPosition="above"
(click)="deleteConnector(attribute, $event)">
<mat-icon>delete</mat-icon>
</button>
</div>
<div fxHide fxShow.lt-lg>
<button mat-icon-button
(click)="$event.stopPropagation()"
[matMenuTriggerFor]="cellActionsMenu">
<mat-icon class="material-icons">more_vert</mat-icon>
</button>
<mat-menu #cellActionsMenu="matMenu" xPosition="before">
<div class="table-container">
<table mat-table [dataSource]="dataSource"
matSort [matSortActive]="pageLink.sortOrder.property" [matSortDirection]="pageLink.sortDirection()"
matSortDisableClear>
<ng-container matColumnDef="enabled" sticky>
<mat-header-cell *matHeaderCellDef style="width: 60px;min-width: 60px;">
{{ 'gateway.connectors-table-enabled' | translate }}
</mat-header-cell>
<mat-cell *matCellDef="let attribute">
<mat-slide-toggle [checked]="activeConnectors.includes(attribute.key)"
(click)="$event.stopPropagation(); enableConnector(attribute)"></mat-slide-toggle>
</mat-cell>
</ng-container>
<ng-container matColumnDef="key">
<mat-header-cell *matHeaderCellDef mat-sort-header style="width: 40%">
{{ 'gateway.connectors-table-name' | translate }}</mat-header-cell>
<mat-cell *matCellDef="let attribute">
{{ attribute.key }}
</mat-cell>
</ng-container>
<ng-container matColumnDef="type">
<mat-header-cell *matHeaderCellDef mat-sort-header style="width: 30%">
{{ 'gateway.connectors-table-type' | translate }}
</mat-header-cell>
<mat-cell *matCellDef="let attribute" style="text-transform: uppercase">
{{ returnType(attribute) }}
</mat-cell>
</ng-container>
<ng-container matColumnDef="syncStatus">
<mat-header-cell *matHeaderCellDef mat-sort-header style="width: 30%">
{{ 'gateway.configuration' | translate }}
</mat-header-cell>
<mat-cell *matCellDef="let attribute" style="text-transform: uppercase">
<div class="status" [class]="isConnectorSynced(attribute) ? 'status-sync' : 'status-unsync'">
{{ isConnectorSynced(attribute) ? 'sync' : 'out of sync' }}
</div>
</mat-cell>
</ng-container>
<ng-container matColumnDef="errors">
<mat-header-cell *matHeaderCellDef mat-sort-header style="width: 30%">
{{ 'gateway.connectors-table-status' | translate }}
</mat-header-cell>
<mat-cell *matCellDef="let attribute" style="text-transform: uppercase">
<span class="dot"
matTooltip="{{ 'Errors: '+ getErrorsCount(attribute)}}"
matTooltipPosition="above"
[class]="{'hasErrors': +getErrorsCount(attribute) > 0,
'noErrors': +getErrorsCount(attribute) === 0 || getErrorsCount(attribute) === ''}"></span>
</mat-cell>
</ng-container>
<ng-container matColumnDef="actions" stickyEnd>
<mat-header-cell *matHeaderCellDef
[ngStyle.gt-md]="{ minWidth: '144px', maxWidth: '144px', width: '144px'}">
{{ 'gateway.connectors-table-actions' | translate }}
</mat-header-cell>
<mat-cell *matCellDef="let attribute"
[ngStyle.gt-md]="{ minWidth: '144px', maxWidth: '144px', width: '144px'}">
<div fxHide fxShow.gt-md fxFlex fxLayout="row" fxLayoutAlign="end">
<button mat-icon-button
matTooltip="RPC"
matTooltipPosition="above"
@ -118,7 +93,7 @@
<mat-icon>private_connectivity</mat-icon>
</button>
<button mat-icon-button
matTooltip="Delete connector"
matTooltip="Logs"
matTooltipPosition="above"
(click)="connectorLogs(attribute, $event)">
<mat-icon>list</mat-icon>
@ -129,55 +104,84 @@
(click)="deleteConnector(attribute, $event)">
<mat-icon>delete</mat-icon>
</button>
</mat-menu>
</div>
</mat-cell>
</ng-container>
<mat-header-row class="mat-row-select"
*matHeaderRowDef="displayedColumns; sticky: true"></mat-header-row>
<mat-row class="mat-row-select" [class]="{'tb-current-entity': isSameConnector(attribute)}"
*matRowDef="let attribute; columns: displayedColumns;" (click)="selectConnector(attribute)"></mat-row>
</table>
</div>
<div fxHide fxShow.lt-lg>
<button mat-icon-button
(click)="$event.stopPropagation()"
[matMenuTriggerFor]="cellActionsMenu">
<mat-icon class="material-icons">more_vert</mat-icon>
</button>
<mat-menu #cellActionsMenu="matMenu" xPosition="before">
<button mat-icon-button
matTooltip="RPC"
matTooltipPosition="above"
(click)="connectorRpc(attribute, $event)">
<mat-icon>private_connectivity</mat-icon>
</button>
<button mat-icon-button
matTooltip="Delete connector"
matTooltipPosition="above"
(click)="connectorLogs(attribute, $event)">
<mat-icon>list</mat-icon>
</button>
<button mat-icon-button
matTooltip="Delete connector"
matTooltipPosition="above"
(click)="deleteConnector(attribute, $event)">
<mat-icon>delete</mat-icon>
</button>
</mat-menu>
</div>
</mat-cell>
</ng-container>
<mat-header-row class="mat-row-select"
*matHeaderRowDef="displayedColumns; sticky: true"></mat-header-row>
<mat-row class="mat-row-select" [class]="{'tb-current-entity': isSameConnector(attribute)}"
*matRowDef="let attribute; columns: displayedColumns;" (click)="selectConnector(attribute)"></mat-row>
</table>
</div>
</section>
<section [formGroup]="connectorForm" class="tb-form-panel no-border no-padding flex">
<section class="tb-form-row tb-not-inline-field same-padding input-container">
<mat-form-field class="flex" subscriptSizing="dynamic">
<mat-label>{{ 'gateway.connectors-table-name' | translate }}</mat-label>
<input matInput formControlName="name" #nameInput/>
</mat-form-field>
<mat-form-field class="flex" subscriptSizing="dynamic" hideRequiredMarker>
<mat-label>{{ 'gateway.connectors-table-type' | translate }}</mat-label>
<mat-select formControlName="type">
<mat-option style="text-transform: uppercase"
*ngFor="let type of gatewayConnectorDefaultTypes | keyvalue" [value]="type.key">{{ type.value }}</mat-option>
</mat-select>
</mat-form-field>
<mat-form-field class="flex" *ngIf="connectorForm.get('type').value === 'grpc'" subscriptSizing="dynamic">
<mat-label>{{ 'gateway.connectors-table-key' | translate }}</mat-label>
<input matInput formControlName="key"/>
</mat-form-field>
<mat-form-field class="flex" *ngIf="connectorForm.get('type').value === 'custom'" subscriptSizing="dynamic">
<mat-label>{{ 'gateway.connectors-table-class' | translate }}</mat-label>
<input matInput formControlName="class"/>
</mat-form-field>
<mat-form-field class="flex" subscriptSizing="dynamic" hideRequiredMarker>
<mat-label translate>gateway.remote-logging-level</mat-label>
<mat-select formControlName="logLevel">
<mat-option *ngFor="let logLevel of gatewayLogLevel" [value]="logLevel">{{ logLevel }}</mat-option>
</mat-select>
</mat-form-field>
<section class="tb-form-panel input-container section-container">
<section class="tb-form-row tb-not-inline-field no-padding no-border column-lt-md input-container">
<mat-form-field class="flex" subscriptSizing="dynamic">
<mat-label>{{ 'gateway.connectors-table-name' | translate }}</mat-label>
<input matInput formControlName="name" #nameInput/>
</mat-form-field>
<mat-form-field class="flex" subscriptSizing="dynamic" hideRequiredMarker>
<mat-label>{{ 'gateway.connectors-table-type' | translate }}</mat-label>
<mat-select formControlName="type">
<mat-option style="text-transform: uppercase"
*ngFor="let type of gatewayConnectorDefaultTypes | keyvalue" [value]="type.key">{{ type.value }}</mat-option>
</mat-select>
</mat-form-field>
<mat-form-field class="flex" *ngIf="connectorForm.get('type').value === 'grpc'" subscriptSizing="dynamic">
<mat-label>{{ 'gateway.connectors-table-key' | translate }}</mat-label>
<input matInput formControlName="key"/>
</mat-form-field>
<mat-form-field class="flex" *ngIf="connectorForm.get('type').value === 'custom'" subscriptSizing="dynamic">
<mat-label>{{ 'gateway.connectors-table-class' | translate }}</mat-label>
<input matInput formControlName="class"/>
</mat-form-field>
<mat-form-field class="flex" subscriptSizing="dynamic" hideRequiredMarker>
<mat-label translate>gateway.remote-logging-level</mat-label>
<mat-select formControlName="logLevel">
<mat-option *ngFor="let logLevel of gatewayLogLevel" [value]="logLevel">{{ logLevel }}</mat-option>
</mat-select>
</mat-form-field>
</section>
</section>
<section class="tb-form-panel stroked flex">
<section class="tb-form-panel flex section-container">
<tb-json-object-edit
fillHeight="true"
class="flex"
fxLayout="column"
required
label="{{ 'gateway.configuration' | translate }}"
formControlName="configurationJson">
</tb-json-object-edit>
<div fxLayoutAlign="start center">
<div fxLayoutAlign="end center">
<button mat-raised-button color="primary"
class="action-button"
type="button"
[disabled]="!connectorForm.dirty || connectorForm.invalid"
(click)="saveConnector()">

16
ui-ngx/src/app/modules/home/components/widget/lib/gateway/gateway-connectors.component.scss

@ -30,9 +30,13 @@
flex-direction: column;
}
.table-container {
overflow: auto;
.table-section {
min-height: 35vh;
overflow: hidden;
.table-container {
overflow: auto;
}
}
.flex {
@ -42,6 +46,10 @@
.input-container {
height: auto;
}
.section-container {
background-color: #fff;
}
}
.mat-toolbar {
@ -69,10 +77,6 @@
}
}
.action-button {
margin: 0 15px;
}
mat-row {
cursor: pointer;
}

Loading…
Cancel
Save