diff --git a/application/src/main/data/json/system/widget_bundles/gateway_widgets.json b/application/src/main/data/json/system/widget_bundles/gateway_widgets.json
index dc86c0f003..c81b564960 100644
--- a/application/src/main/data/json/system/widget_bundles/gateway_widgets.json
+++ b/application/src/main/data/json/system/widget_bundles/gateway_widgets.json
@@ -62,6 +62,24 @@
"settingsDirective": "tb-gateway-config-single-device-widget-settings",
"defaultConfig": "{\"datasources\":[{\"type\":\"function\",\"name\":\"function\",\"dataKeys\":[{\"name\":\"f(x)\",\"type\":\"function\",\"label\":\"Random\",\"color\":\"#2196f3\",\"settings\":{},\"_hash\":0.15479322438769105,\"funcBody\":\"var value = prevValue + Math.random() * 100 - 50;\\nvar multiplier = Math.pow(10, 2 || 0);\\nvar value = Math.round(value * multiplier) / multiplier;\\nif (value < -1000) {\\n\\tvalue = -1000;\\n} else if (value > 1000) {\\n\\tvalue = 1000;\\n}\\nreturn value;\"}]}],\"timewindow\":{\"realtime\":{\"timewindowMs\":60000}},\"showTitle\":true,\"backgroundColor\":\"#fff\",\"color\":\"rgba(0, 0, 0, 0.87)\",\"padding\":\"8px\",\"settings\":{\"gatewayTitle\":\"Gateway configuration (Single device)\"},\"title\":\"Gateway configuration (Single device)\"}"
}
- }
+ },
+ {
+ "alias": "gateway_list",
+ "name": "Gateway list",
+ "image": null,
+ "description": null,
+ "descriptor": {
+ "type": "static",
+ "sizeX": 7.5,
+ "sizeY": 3,
+ "resources": [],
+ "templateHtml": "",
+ "templateCss": " .tb-entity-table {\r\n padding: 0 !important;\r\n }",
+ "controllerScript": "self.onInit = function() {\n}\n",
+ "settingsSchema": "{}",
+ "dataKeySettingsSchema": "{}",
+ "settingsDirective": "tb-gateway-list-widget-settings",
+ "defaultConfig": "{\"datasources\":[{\"type\":\"static\",\"name\":\"function\",\"dataKeys\":[{\"name\":\"f(x)\",\"type\":\"function\",\"label\":\"Random\",\"color\":\"#2196f3\",\"settings\":{},\"_hash\":0.15479322438769105,\"funcBody\":\"var value = prevValue + Math.random() * 100 - 50;\\nvar multiplier = Math.pow(10, 2 || 0);\\nvar value = Math.round(value * multiplier) / multiplier;\\nif (value < -1000) {\\n\\tvalue = -1000;\\n} else if (value > 1000) {\\n\\tvalue = 1000;\\n}\\nreturn value;\"}]}],\"timewindow\":{\"realtime\":{\"timewindowMs\":60000}},\"showTitle\":false,\"backgroundColor\":\"rgb(255, 255, 255)\",\"color\":\"rgba(0, 0, 0, 0.87)\",\"padding\":\"8px\",\"settings\":{\"cardHtml\":\"
HTML code here
\",\"cardCss\":\".card {\\n font-weight: bold;\\n font-size: 32px;\\n color: #999;\\n width: 100%;\\n height: 100%;\\n display: flex;\\n align-items: center;\\n justify-content: center;\\n}\"},\"title\":\"Gateway list\",\"dropShadow\":true,\"enableFullscreen\":false,\"enableDataExport\":true,\"widgetStyle\":{},\"widgetCss\":\"\",\"pageSize\":1024,\"noDataDisplayMessage\":\"\",\"showLegend\":false}"
+ },
]
}
\ No newline at end of file
diff --git a/ui-ngx/src/app/modules/home/components/gateway/gateway-command-dialog.component.html b/ui-ngx/src/app/modules/home/components/gateway/gateway-command-dialog.component.html
new file mode 100644
index 0000000000..d5040b8714
--- /dev/null
+++ b/ui-ngx/src/app/modules/home/components/gateway/gateway-command-dialog.component.html
@@ -0,0 +1,85 @@
+
+
diff --git a/ui-ngx/src/app/modules/home/components/gateway/gateway-command-dialog.component.ts b/ui-ngx/src/app/modules/home/components/gateway/gateway-command-dialog.component.ts
new file mode 100644
index 0000000000..7c742e4e01
--- /dev/null
+++ b/ui-ngx/src/app/modules/home/components/gateway/gateway-command-dialog.component.ts
@@ -0,0 +1,93 @@
+///
+/// ThingsBoard, Inc. ("COMPANY") CONFIDENTIAL
+///
+/// Copyright © 2016-2022 ThingsBoard, Inc. All Rights Reserved.
+///
+/// NOTICE: All information contained herein is, and remains
+/// the property of ThingsBoard, Inc. and its suppliers,
+/// if any. The intellectual and technical concepts contained
+/// herein are proprietary to ThingsBoard, Inc.
+/// and its suppliers and may be covered by U.S. and Foreign Patents,
+/// patents in process, and are protected by trade secret or copyright law.
+///
+/// Dissemination of this information or reproduction of this material is strictly forbidden
+/// unless prior written permission is obtained from COMPANY.
+///
+/// Access to the source code contained herein is hereby forbidden to anyone except current COMPANY employees,
+/// managers or contractors who have executed Confidentiality and Non-disclosure agreements
+/// explicitly covering such access.
+///
+/// The copyright notice above does not evidence any actual or intended publication
+/// or disclosure of this source code, which includes
+/// information that is confidential and/or proprietary, and is a trade secret, of COMPANY.
+/// ANY REPRODUCTION, MODIFICATION, DISTRIBUTION, PUBLIC PERFORMANCE,
+/// OR PUBLIC DISPLAY OF OR THROUGH USE OF THIS SOURCE CODE WITHOUT
+/// THE EXPRESS WRITTEN CONSENT OF COMPANY IS STRICTLY PROHIBITED,
+/// AND IN VIOLATION OF APPLICABLE LAWS AND INTERNATIONAL TREATIES.
+/// THE RECEIPT OR POSSESSION OF THIS SOURCE CODE AND/OR RELATED INFORMATION
+/// DOES NOT CONVEY OR IMPLY ANY RIGHTS TO REPRODUCE, DISCLOSE OR DISTRIBUTE ITS CONTENTS,
+/// OR TO MANUFACTURE, USE, OR SELL ANYTHING THAT IT MAY DESCRIBE, IN WHOLE OR IN PART.
+///
+
+import { Component, Inject, OnInit } from '@angular/core';
+import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog';
+import { Store } from '@ngrx/store';
+import { AppState } from '@core/core.state';
+import { Router } from '@angular/router';
+import { DialogComponent } from '@app/shared/components/dialog.component';
+import { TranslateService } from '@ngx-translate/core';
+import {Device, DeviceCredentials} from "@shared/models/device.models";
+import {ActionNotificationShow} from "@core/notification/notification.actions";
+
+export interface GatewayCommandDialogData {
+ device: Device,
+ credentials: DeviceCredentials
+}
+
+@Component({
+ selector: 'tb-gateway-command-dialog',
+ templateUrl: './gateway-command-dialog.component.html',
+ styleUrls: []
+})
+export class GatewayCommandDialogComponent extends DialogComponent implements OnInit {
+ linuxCode: string;
+ windowsCode: string;
+
+ constructor(protected router: Router,
+ protected store: Store,
+ private translate: TranslateService,
+ @Inject(MAT_DIALOG_DATA) public data: GatewayCommandDialogData,
+ public dialogRef: MatDialogRef,) {
+ super(store, router, dialogRef);
+ const ACCESS_TOKEN = data.credentials.credentialsId;
+ this.linuxCode = "docker run -it -v ~/.tb-gateway/logs:/thingsboard_gateway/logs -v " +
+ "~/.tb-gateway/extensions:/thingsboard_gateway/extensions -v ~/.tb-gateway/config:/thingsboard_gateway/config --name tb-gateway -e accessToken=" +
+ ACCESS_TOKEN +
+ " --restart always thingsboard/tb-gateway";
+ this.windowsCode = "docker run -it -v %HOMEPATH%/tb-gateway/config:/thingsboard_gateway/config -v " +
+ "%HOMEPATH%/tb-gateway/extensions:/thingsboard_gateway/extensions -v %HOMEPATH%/tb-gateway/logs:/thingsboard_gateway/logs " +
+ "--name tb-gateway -e host=thingsboard.cloud -p 1883 -e accessToken=" +
+ ACCESS_TOKEN +
+ " --restart always thingsboard/tb-gateway";
+
+ }
+
+ ngOnInit(): void {
+ }
+
+ close(): void {
+ this.dialogRef.close();
+ }
+
+ onDockerCodeCopied() {
+ this.store.dispatch(new ActionNotificationShow(
+ {
+ message: this.translate.instant('gateway.command-copied-message'),
+ type: 'success',
+ target: 'dockerCommandDialogContent',
+ duration: 1200,
+ verticalPosition: 'bottom',
+ horizontalPosition: 'left'
+ }));
+ }
+}
diff --git a/ui-ngx/src/app/modules/home/components/gateway/gateway-list-table-config.ts b/ui-ngx/src/app/modules/home/components/gateway/gateway-list-table-config.ts
new file mode 100644
index 0000000000..da45dce83d
--- /dev/null
+++ b/ui-ngx/src/app/modules/home/components/gateway/gateway-list-table-config.ts
@@ -0,0 +1,142 @@
+///
+/// ThingsBoard, Inc. ("COMPANY") CONFIDENTIAL
+///
+/// Copyright © 2016-2022 ThingsBoard, Inc. All Rights Reserved.
+///
+/// NOTICE: All information contained herein is, and remains
+/// the property of ThingsBoard, Inc. and its suppliers,
+/// if any. The intellectual and technical concepts contained
+/// herein are proprietary to ThingsBoard, Inc.
+/// and its suppliers and may be covered by U.S. and Foreign Patents,
+/// patents in process, and are protected by trade secret or copyright law.
+///
+/// Dissemination of this information or reproduction of this material is strictly forbidden
+/// unless prior written permission is obtained from COMPANY.
+///
+/// Access to the source code contained herein is hereby forbidden to anyone except current COMPANY employees,
+/// managers or contractors who have executed Confidentiality and Non-disclosure agreements
+/// explicitly covering such access.
+///
+/// The copyright notice above does not evidence any actual or intended publication
+/// or disclosure of this source code, which includes
+/// information that is confidential and/or proprietary, and is a trade secret, of COMPANY.
+/// ANY REPRODUCTION, MODIFICATION, DISTRIBUTION, PUBLIC PERFORMANCE,
+/// OR PUBLIC DISPLAY OF OR THROUGH USE OF THIS SOURCE CODE WITHOUT
+/// THE EXPRESS WRITTEN CONSENT OF COMPANY IS STRICTLY PROHIBITED,
+/// AND IN VIOLATION OF APPLICABLE LAWS AND INTERNATIONAL TREATIES.
+/// THE RECEIPT OR POSSESSION OF THIS SOURCE CODE AND/OR RELATED INFORMATION
+/// DOES NOT CONVEY OR IMPLY ANY RIGHTS TO REPRODUCE, DISCLOSE OR DISTRIBUTE ITS CONTENTS,
+/// OR TO MANUFACTURE, USE, OR SELL ANYTHING THAT IT MAY DESCRIBE, IN WHOLE OR IN PART.
+///
+
+import {
+ DateEntityTableColumn,
+ EntityTableColumn,
+ EntityTableConfig
+} from '@home/models/entity/entities-table-config.models';
+import {EntityTypeResource} from '@shared/models/entity-type.models';
+import {TranslateService} from '@ngx-translate/core';
+import {DatePipe} from '@angular/common';
+import {Direction} from '@shared/models/page/sort-order';
+import {MatDialog} from '@angular/material/dialog';
+import {TimePageLink} from '@shared/models/page/page-link';
+import {Observable} from 'rxjs';
+import {PageData} from '@shared/models/page/page-data';
+import {UtilsService} from '@core/services/utils.service';
+import {DeviceService} from "@core/http/device.service";
+import {AttributeService} from "@core/http/attribute.service";
+import {Device} from "@shared/models/device.models";
+import {
+ GatewayCommandDialogComponent,
+ GatewayCommandDialogData
+} from "@home/components/gateway/gateway-command-dialog.component";
+import {ActionNotificationShow} from "@core/notification/notification.actions";
+import {Store} from "@ngrx/store";
+import {AppState} from "@core/core.state";
+import {map} from "rxjs/operators";
+
+export class GatewayListTableConfig extends EntityTableConfig {
+
+ constructor(protected store: Store,
+ private deviceService: DeviceService,
+ private attributeService: AttributeService,
+ private datePipe: DatePipe,
+ private translate: TranslateService,
+ private utils: UtilsService,
+ private dialog: MatDialog,
+ updateOnInit = true,
+ pageMode = false) {
+ super();
+ this.loadDataOnInit = updateOnInit;
+ this.tableTitle = '';
+ this.useTimePageLink = false;
+ this.pageMode = pageMode;
+ this.detailsPanelEnabled = false;
+ this.selectionEnabled = false;
+ this.searchEnabled = true;
+ this.addEnabled = false;
+ this.entitiesDeleteEnabled = false;
+ this.actionsColumnTitle = '';
+ this.entityTranslations = {
+ noEntities: 'gateway.no-gateway-found',
+ search: 'gateway.gateway-search'
+ };
+ this.entityResources = {} as EntityTypeResource;
+
+ this.entitiesFetchFunction = pageLink => this.fetchGateways(pageLink);
+
+ this.defaultSortOrder = {property: 'createdTime', direction: Direction.DESC};
+
+ this.columns.push(
+ new DateEntityTableColumn('createdTime', 'gateway.created-time', this.datePipe, '150px'));
+
+ this.columns.push(
+ new EntityTableColumn('entityName', 'gateway.gateway-name', '20%',
+ (entity => this.utils.customTranslation(entity.name, entity.name))
+ )
+ );
+
+ this.cellActionDescriptors.push(
+ {
+ name: this.translate.instant('gateway.command'),
+ icon: 'vpn_key',
+ isEnabled: () => true,
+ onAction: ($event, entity) => this.showGatewayDockerCommand(entity)
+ }
+ );
+ }
+
+ showGatewayDockerCommand(entity: Device) {
+ this.deviceService.getDeviceCredentials(entity.id.id).subscribe(credentials => {
+ this.dialog.open
+ (GatewayCommandDialogComponent,
+ {
+ disableClose: true,
+ panelClass: ['tb-dialog', 'tb-fullscreen-dialog'],
+ data: {
+ credentials: credentials,
+ device: entity
+ }
+ }).afterClosed().subscribe(
+ (res) => {
+ if (res) {
+ this.updateData();
+ }
+ }
+ );
+ }, error => {
+ const messageToShow = `${error}
`;
+ this.store.dispatch(new ActionNotificationShow({message: messageToShow, type: 'error'}));
+ })
+ }
+
+ fetchGateways(pageLink: TimePageLink): Observable> {
+ return this.deviceService.getUserDevices(pageLink).pipe(
+ map(pageData => {
+ pageData.data = pageData.data.filter(device => device.additionalInfo.gateway);
+ pageData.totalElements = pageData.data.length;
+ return pageData;
+ })
+ );
+ }
+}
diff --git a/ui-ngx/src/app/modules/home/components/gateway/gateway-list.component.html b/ui-ngx/src/app/modules/home/components/gateway/gateway-list.component.html
new file mode 100644
index 0000000000..35cde6d91b
--- /dev/null
+++ b/ui-ngx/src/app/modules/home/components/gateway/gateway-list.component.html
@@ -0,0 +1,33 @@
+
+
diff --git a/ui-ngx/src/app/modules/home/components/gateway/gateway-list.component.scss b/ui-ngx/src/app/modules/home/components/gateway/gateway-list.component.scss
new file mode 100644
index 0000000000..0ad3466e17
--- /dev/null
+++ b/ui-ngx/src/app/modules/home/components/gateway/gateway-list.component.scss
@@ -0,0 +1,55 @@
+/**
+ * ThingsBoard, Inc. ("COMPANY") CONFIDENTIAL
+ *
+ * Copyright © 2016-2022 ThingsBoard, Inc. All Rights Reserved.
+ *
+ * NOTICE: All information contained herein is, and remains
+ * the property of ThingsBoard, Inc. and its suppliers,
+ * if any. The intellectual and technical concepts contained
+ * herein are proprietary to ThingsBoard, Inc.
+ * and its suppliers and may be covered by U.S. and Foreign Patents,
+ * patents in process, and are protected by trade secret or copyright law.
+ *
+ * Dissemination of this information or reproduction of this material is strictly forbidden
+ * unless prior written permission is obtained from COMPANY.
+ *
+ * Access to the source code contained herein is hereby forbidden to anyone except current COMPANY employees,
+ * managers or contractors who have executed Confidentiality and Non-disclosure agreements
+ * explicitly covering such access.
+ *
+ * The copyright notice above does not evidence any actual or intended publication
+ * or disclosure of this source code, which includes
+ * information that is confidential and/or proprietary, and is a trade secret, of COMPANY.
+ * ANY REPRODUCTION, MODIFICATION, DISTRIBUTION, PUBLIC PERFORMANCE,
+ * OR PUBLIC DISPLAY OF OR THROUGH USE OF THIS SOURCE CODE WITHOUT
+ * THE EXPRESS WRITTEN CONSENT OF COMPANY IS STRICTLY PROHIBITED,
+ * AND IN VIOLATION OF APPLICABLE LAWS AND INTERNATIONAL TREATIES.
+ * THE RECEIPT OR POSSESSION OF THIS SOURCE CODE AND/OR RELATED INFORMATION
+ * DOES NOT CONVEY OR IMPLY ANY RIGHTS TO REPRODUCE, DISCLOSE OR DISTRIBUTE ITS CONTENTS,
+ * OR TO MANUFACTURE, USE, OR SELL ANYTHING THAT IT MAY DESCRIBE, IN WHOLE OR IN PART.
+ */
+:host {
+ width: 100%;
+ height: 100%;
+ display: block;
+ .tb-table-widget {
+ .table-container {
+ position: relative;
+ }
+ .mat-table {
+ .mat-row {
+ &.invisible {
+ visibility: hidden;
+ }
+ }
+ }
+ span.no-data-found {
+ position: absolute;
+ top: 60px;
+ bottom: 0;
+ left: 0;
+ right: 0;
+ }
+ }
+}
+
diff --git a/ui-ngx/src/app/modules/home/components/gateway/gateway-list.component.ts b/ui-ngx/src/app/modules/home/components/gateway/gateway-list.component.ts
new file mode 100644
index 0000000000..73214a56ec
--- /dev/null
+++ b/ui-ngx/src/app/modules/home/components/gateway/gateway-list.component.ts
@@ -0,0 +1,75 @@
+///
+/// ThingsBoard, Inc. ("COMPANY") CONFIDENTIAL
+///
+/// Copyright © 2016-2022 ThingsBoard, Inc. All Rights Reserved.
+///
+/// NOTICE: All information contained herein is, and remains
+/// the property of ThingsBoard, Inc. and its suppliers,
+/// if any. The intellectual and technical concepts contained
+/// herein are proprietary to ThingsBoard, Inc.
+/// and its suppliers and may be covered by U.S. and Foreign Patents,
+/// patents in process, and are protected by trade secret or copyright law.
+///
+/// Dissemination of this information or reproduction of this material is strictly forbidden
+/// unless prior written permission is obtained from COMPANY.
+///
+/// Access to the source code contained herein is hereby forbidden to anyone except current COMPANY employees,
+/// managers or contractors who have executed Confidentiality and Non-disclosure agreements
+/// explicitly covering such access.
+///
+/// The copyright notice above does not evidence any actual or intended publication
+/// or disclosure of this source code, which includes
+/// information that is confidential and/or proprietary, and is a trade secret, of COMPANY.
+/// ANY REPRODUCTION, MODIFICATION, DISTRIBUTION, PUBLIC PERFORMANCE,
+/// OR PUBLIC DISPLAY OF OR THROUGH USE OF THIS SOURCE CODE WITHOUT
+/// THE EXPRESS WRITTEN CONSENT OF COMPANY IS STRICTLY PROHIBITED,
+/// AND IN VIOLATION OF APPLICABLE LAWS AND INTERNATIONAL TREATIES.
+/// THE RECEIPT OR POSSESSION OF THIS SOURCE CODE AND/OR RELATED INFORMATION
+/// DOES NOT CONVEY OR IMPLY ANY RIGHTS TO REPRODUCE, DISCLOSE OR DISTRIBUTE ITS CONTENTS,
+/// OR TO MANUFACTURE, USE, OR SELL ANYTHING THAT IT MAY DESCRIBE, IN WHOLE OR IN PART.
+///
+
+import {Component, OnInit} from '@angular/core';
+import {UtilsService} from '@core/services/utils.service';
+import {TranslateService} from '@ngx-translate/core';
+import {DeviceService} from '@core/http/device.service';
+import {AttributeService} from '@core/http/attribute.service';
+import {GatewayListTableConfig} from "@home/components/gateway/gateway-list-table-config";
+import {DatePipe} from "@angular/common";
+import {MatDialog} from "@angular/material/dialog";
+import {Store} from "@ngrx/store";
+import {AppState} from "@core/core.state";
+
+@Component({
+ selector: 'tb-gateway-list',
+ templateUrl: './gateway-list.component.html',
+ styleUrls: ['./gateway-list.component.scss']
+})
+
+
+export class GatewayListComponent implements OnInit {
+ gatewayListTableConfig: GatewayListTableConfig;
+
+ constructor(
+ protected store: Store,
+ private utils: UtilsService,
+ private translate: TranslateService,
+ private datePipe: DatePipe,
+ private deviceService: DeviceService,
+ private attributeService: AttributeService,
+ private dialog: MatDialog,
+ ) {
+ }
+
+ ngOnInit(): void {
+ this.gatewayListTableConfig = new GatewayListTableConfig(
+ this.store,
+ this.deviceService,
+ this.attributeService,
+ this.datePipe,
+ this.translate,
+ this.utils,
+ this.dialog
+ );
+ }
+}
diff --git a/ui-ngx/src/app/modules/home/components/home-components.module.ts b/ui-ngx/src/app/modules/home/components/home-components.module.ts
index 7cfcf269de..466967da74 100644
--- a/ui-ngx/src/app/modules/home/components/home-components.module.ts
+++ b/ui-ngx/src/app/modules/home/components/home-components.module.ts
@@ -173,6 +173,7 @@ import { RateLimitsDetailsDialogComponent } from '@home/components/profile/tenan
import { AssetProfileComponent } from '@home/components/profile/asset-profile.component';
import { AssetProfileDialogComponent } from '@home/components/profile/asset-profile-dialog.component';
import { AssetProfileAutocompleteComponent } from '@home/components/profile/asset-profile-autocomplete.component';
+import { GatewayListComponent } from "@home/components/gateway/gateway-list.component";
@NgModule({
declarations:
@@ -195,6 +196,7 @@ import { AssetProfileAutocompleteComponent } from '@home/components/profile/asse
RelationFiltersComponent,
AlarmTableHeaderComponent,
AlarmTableComponent,
+ GatewayListComponent,
AttributeTableComponent,
AddAttributeDialogComponent,
EditAttributeValuePanelComponent,
@@ -342,6 +344,7 @@ import { AssetProfileAutocompleteComponent } from '@home/components/profile/asse
RelationTableComponent,
RelationFiltersComponent,
AlarmTableComponent,
+ GatewayListComponent,
AttributeTableComponent,
AliasesEntitySelectComponent,
AliasesEntityAutocompleteComponent,
diff --git a/ui-ngx/src/app/modules/home/components/shared-home-components.module.ts b/ui-ngx/src/app/modules/home/components/shared-home-components.module.ts
index 4052958e86..5ba9dc8dc5 100644
--- a/ui-ngx/src/app/modules/home/components/shared-home-components.module.ts
+++ b/ui-ngx/src/app/modules/home/components/shared-home-components.module.ts
@@ -18,6 +18,7 @@ import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { SharedModule } from '@app/shared/shared.module';
import { AlarmDetailsDialogComponent } from '@home/components/alarm/alarm-details-dialog.component';
+import { GatewayCommandDialogComponent } from "@home/components/gateway/gateway-command-dialog.component";
import { SHARED_HOME_COMPONENTS_MODULE_TOKEN } from '@home/components/tokens';
@NgModule({
@@ -26,14 +27,16 @@ import { SHARED_HOME_COMPONENTS_MODULE_TOKEN } from '@home/components/tokens';
],
declarations:
[
- AlarmDetailsDialogComponent
+ AlarmDetailsDialogComponent,
+ GatewayCommandDialogComponent
],
imports: [
CommonModule,
SharedModule
],
exports: [
- AlarmDetailsDialogComponent
+ AlarmDetailsDialogComponent,
+ GatewayCommandDialogComponent
]
})
export class SharedHomeComponentsModule { }
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 434535a785..1af245c05e 100644
--- a/ui-ngx/src/assets/locale/locale.constant-en_US.json
+++ b/ui-ngx/src/assets/locale/locale.constant-en_US.json
@@ -2364,6 +2364,8 @@
},
"gateway": {
"add-entry": "Add configuration",
+ "command": "Docker commands",
+ "command-copied-message": "Docker command has been copied to clipboard",
"connector-add": "Add new connector",
"connector-enabled": "Enable connector",
"connector-name": "Connector name",
@@ -2371,8 +2373,10 @@
"connector-type": "Connector type",
"connector-type-required": "Connector type is required.",
"connectors": "Connectors configuration",
+ "copy-command": "Copy docker command",
"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",
"delete": "Delete configuration",
"download-tip": "Download configuration file",
"gateway": "Gateway",
@@ -2380,8 +2384,10 @@
"gateway-name": "Gateway name",
"gateway-name-required": "Gateway name is required.",
"gateway-saved": "Gateway configuration successfully saved.",
+ "gateway-search": "Gateway search",
"json-parse": "Not valid JSON.",
"json-required": "Field cannot be empty.",
+ "linux-macos": "Linux/MacOS",
"no-connectors": "No connectors",
"no-data": "No configurations",
"no-gateway-found": "No gateway found.",
@@ -2434,7 +2440,8 @@
"tls-path-private-key": "Path to private key on gateway",
"toggle-fullscreen": "Toggle fullscreen",
"transformer-json-config": "Configuration JSON*",
- "update-config": "Add/update configuration JSON"
+ "update-config": "Add/update configuration JSON",
+ "windows": "Windows"
},
"grid": {
"delete-item-title": "Are you sure you want to delete this item?",