Browse Source

UI: Updated show device connectivity commands and detect operating system from user

pull/8938/head
Vladyslav_Prykhodko 3 years ago
parent
commit
26044fc035
  1. 5
      ui-ngx/src/app/app.component.ts
  2. 10
      ui-ngx/src/app/core/http/device.service.ts
  3. 26
      ui-ngx/src/app/core/utils.ts
  4. 363
      ui-ngx/src/app/modules/home/pages/device/device-check-connectivity-dialog.component.html
  5. 19
      ui-ngx/src/app/modules/home/pages/device/device-check-connectivity-dialog.component.scss
  6. 89
      ui-ngx/src/app/modules/home/pages/device/device-check-connectivity-dialog.component.ts
  7. 25
      ui-ngx/src/app/shared/models/device.models.ts
  8. 1
      ui-ngx/src/assets/docker.svg
  9. 40
      ui-ngx/src/assets/help/en_US/device/install_coap_client.md
  10. 34
      ui-ngx/src/assets/help/en_US/device/install_curl.md
  11. 38
      ui-ngx/src/assets/help/en_US/device/install_mqtt_client.md
  12. 1
      ui-ngx/src/assets/linux.svg
  13. 15
      ui-ngx/src/assets/locale/locale.constant-en_US.json
  14. 1
      ui-ngx/src/assets/macos.svg
  15. 1
      ui-ngx/src/assets/windows.svg
  16. 7
      ui-ngx/src/form.scss

5
ui-ngx/src/app/app.component.ts

@ -94,6 +94,11 @@ export class AppComponent implements OnInit {
)
);
this.matIconRegistry.addSvgIcon('windows', this.domSanitizer.bypassSecurityTrustResourceUrl('/assets/windows.svg'));
this.matIconRegistry.addSvgIcon('macos', this.domSanitizer.bypassSecurityTrustResourceUrl('/assets/macos.svg'));
this.matIconRegistry.addSvgIcon('linux', this.domSanitizer.bypassSecurityTrustResourceUrl('/assets/linux.svg'));
this.matIconRegistry.addSvgIcon('docker', this.domSanitizer.bypassSecurityTrustResourceUrl('/assets/docker.svg'));
this.storageService.testLocalStorage();
this.setupTranslate();

10
ui-ngx/src/app/core/http/device.service.ts

@ -25,8 +25,10 @@ import {
ClaimResult,
Device,
DeviceCredentials,
DeviceInfo, DeviceInfoQuery,
DeviceSearchQuery
DeviceInfo,
DeviceInfoQuery,
DeviceSearchQuery,
PublishTelemetryCommand
} from '@app/shared/models/device.models';
import { EntitySubtype } from '@app/shared/models/entity-type.models';
import { AuthService } from '@core/auth/auth.service';
@ -208,8 +210,8 @@ export class DeviceService {
return this.http.post<BulkImportResult>('/api/device/bulk_import', entitiesData, defaultHttpOptionsFromConfig(config));
}
public getDevicePublishTelemetryCommands(deviceId: string, config?: RequestConfig): Observable<{[key: string]: string}> {
return this.http.get<{[key: string]: string}>(`/api/device/${deviceId}/commands`, defaultHttpOptionsFromConfig(config));
public getDevicePublishTelemetryCommands(deviceId: string, config?: RequestConfig): Observable<PublishTelemetryCommand> {
return this.http.get<PublishTelemetryCommand>(`/api/device-connectivity/${deviceId}`, defaultHttpOptionsFromConfig(config));
}
}

26
ui-ngx/src/app/core/utils.ts

@ -355,9 +355,7 @@ const SNAKE_CASE_REGEXP = /[A-Z]/g;
export function snakeCase(name: string, separator: string): string {
separator = separator || '_';
return name.replace(SNAKE_CASE_REGEXP, (letter, pos) => {
return (pos ? separator : '') + letter.toLowerCase();
});
return name.replace(SNAKE_CASE_REGEXP, (letter, pos) => (pos ? separator : '') + letter.toLowerCase());
}
export function getDescendantProp(obj: any, path: string): any {
@ -776,3 +774,25 @@ export function genNextLabel(name: string, datasources: Datasource[]): string {
}
return label;
}
export const getOS = (): string => {
const userAgent = window.navigator.userAgent.toLowerCase();
const macosPlatforms = /(macintosh|macintel|macppc|mac68k|macos|mac_powerpc)/i;
const windowsPlatforms = /(win32|win64|windows|wince)/i;
const iosPlatforms = /(iphone|ipad|ipod|darwin|ios)/i;
let os = null;
if (macosPlatforms.test(userAgent)) {
os = 'macos';
} else if (iosPlatforms.test(userAgent)) {
os = 'ios';
} else if (windowsPlatforms.test(userAgent)) {
os = 'windows';
} else if (/android/.test(userAgent)) {
os = 'android';
} else if (/linux/.test(userAgent)) {
os = 'linux';
}
return os;
};

363
ui-ngx/src/app/modules/home/pages/device/device-check-connectivity-dialog.component.html

@ -59,121 +59,235 @@
{{ deviceTransportTypeTranslationMap.get(DeviceTransportType.LWM2M) | translate }}
</tb-toggle-option>
</tb-toggle-header>
<div class="tb-form-panel stroked" [fxHide]="!allowTransportType.size">
<div class="tb-form-panel no-padding no-border" [fxHide]="!allowTransportType.size">
<ng-container [ngSwitch]="transportProtocol.value">
<ng-template [ngSwitchCase]="BasicTransportType.HTTP">
<div class="tb-form-panel-hint tb-font-14" translate>device.connectivity.use-following-instructions</div>
<div class="tb-hint-instruction">
<span class="content tb-form-panel-hint" translate>device.connectivity.install-curl</span>
<span tb-help-popup="device/install_curl"
tb-help-popup-placement="bottom"
trigger-style="letter-spacing:0.25px; font-size: 12px"
[tb-help-popup-style]="{maxWidth: '800px'}"
trigger-text="{{ 'action.see-documentation' | translate }}"></span>
</div>
<div *ngIf="commands.http">
<div class="tb-form-panel-hint tb-font-14" translate>device.connectivity.http-command</div>
<tb-markdown usePlainMarkdown containerClass="tb-command-code"
[data]=createMarkDownCommand(commands.http)></tb-markdown>
</div>
<div *ngIf="commands.https">
<div class="tb-form-panel-hint tb-font-14" translate>device.connectivity.https-command</div>
<tb-markdown usePlainMarkdown containerClass="tb-command-code"
[data]=createMarkDownCommand(commands.https)></tb-markdown>
</div>
<div class="tb-no-data-text" translate>device.connectivity.use-following-instructions</div>
<mat-tab-group [(selectedIndex)]="httpTabIndex">
<mat-tab>
<ng-template mat-tab-label>
<mat-icon class="tabs-icon" svgIcon="windows"></mat-icon>
Windows
</ng-template>
<ng-template matTabContent>
<div class="tb-form-panel no-padding no-border tb-tab-body">
<div class="tb-form-panel stroked">
<div class="tb-form-panel-title" translate>device.connectivity.install-necessary-client-tools</div>
<div class="tb-install-windows" translate>device.connectivity.install-curl-windows</div>
</div>
<ng-container
*ngTemplateOutlet="executeCommand; context: {cmd: {
noSecLabel: 'HTTP', noSec: commands.http.http,
secLabel: 'HTTPs', sec: commands.http.https,
doc: {text: '', href: ''}}}">
</ng-container>
</div>
</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>
<div class="tb-form-panel no-padding no-border tb-tab-body">
<div class="tb-form-panel stroked">
<div class="tb-form-panel-title" translate>device.connectivity.install-necessary-client-tools</div>
<tb-markdown usePlainMarkdown containerClass="tb-command-code"
[data]='createMarkDownCommand("sudo apt-get install curl")'></tb-markdown>
</div>
<ng-container
*ngTemplateOutlet="executeCommand; context: {cmd: {
noSecLabel: 'HTTP', noSec: commands.http.http,
secLabel: 'HTTPs', sec: commands.http.https,
doc: {text: '', href: ''}}}">
</ng-container>
</div>
</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>
<div class="tb-form-panel no-padding no-border tb-tab-body">
<div class="tb-form-panel stroked">
<div class="tb-form-panel-title" translate>device.connectivity.install-necessary-client-tools</div>
<tb-markdown usePlainMarkdown containerClass="tb-command-code"
[data]='createMarkDownCommand("brew install curl")'></tb-markdown>
</div>
<ng-container
*ngTemplateOutlet="executeCommand; context: {cmd: {
noSecLabel: 'HTTP', noSec: commands.http.http,
secLabel: 'HTTPs', sec: commands.http.https,
doc: {text: '', href: ''}}}">
</ng-container>
</div>
</ng-template>
</mat-tab>
</mat-tab-group>
</ng-template>
<ng-template [ngSwitchCase]="DeviceTransportType.MQTT">
<div *ngIf="!(commands.mqtts && commands.mqtts === 'Check documentation')" class="tb-form-panel no-padding no-border">
<div class="tb-form-panel-hint tb-font-14" translate>device.connectivity.use-following-instructions</div>
<div class="tb-hint-instruction">
<span class="content tb-form-panel-hint" translate>device.connectivity.install-mqtt-client</span>
<span tb-help-popup="device/install_mqtt_client"
tb-help-popup-placement="bottom"
trigger-style="letter-spacing:0.25px; font-size: 12px"
[tb-help-popup-style]="{maxWidth: '800px'}"
trigger-text="{{ 'action.see-documentation' | translate }}"></span>
</div>
</div>
<div *ngIf="commands.mqtt">
<div class="tb-form-panel-hint tb-font-14" translate>device.connectivity.mqtt-command</div>
<tb-markdown usePlainMarkdown containerClass="tb-command-code"
[data]=createMarkDownCommand(commands.mqtt)></tb-markdown>
</div>
<div *ngIf="commands.mqtts">
<div *ngIf="commands.mqtts !== 'Check documentation'; else mqttCertificate">
<div class="tb-form-panel-hint tb-font-14" translate>device.connectivity.mqtts-command</div>
<tb-markdown usePlainMarkdown containerClass="tb-command-code"
[data]=createMarkDownCommand(commands.mqtts)></tb-markdown>
</div>
<ng-template #mqttCertificate>
<div class="tb-form-panel-hint tb-font-14" translate>device.connectivity.mqtts-x509-command</div>
<div>
<a mat-button color="primary" href="https://thingsboard.io/docs/user-guide/certificates/?ubuntuThingsboardX509=x509Chain" target="_blank">
<span>
{{ 'action.see-documentation' | translate }}
<mat-icon class="tb-mat-18">open_in_new</mat-icon>
</span>
</a>
</div>
</ng-template>
</div>
<div class="tb-no-data-text" translate>device.connectivity.use-following-instructions</div>
<mat-tab-group [(selectedIndex)]="mqttTabIndex">
<mat-tab>
<ng-template mat-tab-label>
<mat-icon class="tabs-icon" svgIcon="windows"></mat-icon>
Windows
</ng-template>
<ng-template matTabContent>
<div class="tb-form-panel no-padding no-border tb-tab-body">
<div class="tb-form-panel stroked">
<div class="tb-form-panel-title" translate>device.connectivity.install-necessary-client-tools</div>
<div class="tb-install-windows">Coming Soon!!!!</div>
</div>
<ng-container
*ngTemplateOutlet="executeCommand; context: {cmd: {
noSecLabel: 'MQTT', noSec: this.commands.mqtt.mqtt,
secLabel: 'MQTTs', sec: this.commands.mqtt.mqtts,
doc: {text: 'device.connectivity.mqtts-x509-command', href: 'https://thingsboard.io/docs/user-guide/mqtt-over-ssl/'}}}">
</ng-container>
</div>
</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>
<div class="tb-form-panel no-padding no-border tb-tab-body">
<div class="tb-form-panel stroked">
<div class="tb-form-panel-title" translate>device.connectivity.install-necessary-client-tools</div>
<tb-markdown usePlainMarkdown containerClass="tb-command-code"
[data]='createMarkDownCommand("brew install mosquitto-clients")'></tb-markdown>
</div>
<ng-container
*ngTemplateOutlet="executeCommand; context: {cmd: {
noSecLabel: 'MQTT', noSec: this.commands.mqtt.mqtt,
secLabel: 'MQTTs', sec: this.commands.mqtt.mqtts,
doc: {text: 'device.connectivity.mqtts-x509-command', href: 'https://thingsboard.io/docs/user-guide/mqtt-over-ssl/'}}}">
</ng-container>
</div>
</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>
<div class="tb-form-panel no-padding no-border tb-tab-body">
<div class="tb-form-panel stroked">
<div class="tb-form-panel-title" translate>device.connectivity.install-necessary-client-tools</div>
<tb-markdown usePlainMarkdown containerClass="tb-command-code"
[data]='createMarkDownCommand("sudo apt-get install curl mosquitto-clients")'></tb-markdown>
</div>
<ng-container
*ngTemplateOutlet="executeCommand; context: {cmd: {
noSecLabel: 'MQTT', noSec: this.commands.mqtt.mqtt,
secLabel: 'MQTTs', sec: this.commands.mqtt.mqtts,
doc: {text: 'device.connectivity.mqtts-x509-command', href: 'https://thingsboard.io/docs/user-guide/mqtt-over-ssl/'}}}">
</ng-container>
</div>
</ng-template>
</mat-tab>
<mat-tab *ngIf="!!this.commands.mqtt.docker">
<ng-template mat-tab-label>
<mat-icon class="tabs-icon" svgIcon="docker"></mat-icon>
Docker
</ng-template>
<ng-template matTabContent>
<div class="tb-form-panel no-padding no-border tb-tab-body">
<ng-container
*ngTemplateOutlet="executeCommand; context: {cmd: {
noSecLabel: 'MQTT', noSec: this.commands.mqtt.docker.mqtt,
secLabel: 'MQTTs', sec: this.commands.mqtt.docker.mqtts,
doc: {text: 'device.connectivity.mqtts-x509-command', href: 'https://thingsboard.io/docs/user-guide/mqtt-over-ssl/'}}}">
</ng-container>
</div>
</ng-template>
</mat-tab>
</mat-tab-group>
</ng-template>
<ng-template [ngSwitchCase]="DeviceTransportType.COAP">
<div *ngIf="!(commands.coaps && commands.coaps === 'Check documentation')" class="tb-form-panel no-padding no-border">
<div class="tb-form-panel-hint tb-font-14" translate>device.connectivity.use-following-instructions</div>
<div class="tb-hint-instruction">
<span class="content tb-form-panel-hint" translate>device.connectivity.install-coap-cli</span>
<span tb-help-popup="device/install_coap_client"
tb-help-popup-placement="bottom"
trigger-style="letter-spacing:0.25px; font-size: 12px"
[tb-help-popup-style]="{maxWidth: '800px'}"
trigger-text="{{ 'action.see-documentation' | translate }}"></span>
</div>
</div>
<div *ngIf="commands.coap">
<div class="tb-form-panel-hint tb-font-14" translate>device.connectivity.coap-command</div>
<tb-markdown usePlainMarkdown containerClass="tb-command-code"
[data]=createMarkDownCommand(commands.coap)></tb-markdown>
</div>
<div *ngIf="commands.coaps">
<div *ngIf="commands.coaps !== 'Check documentation'; else coapCertificate">
<div class="tb-form-panel-hint tb-font-14" translate>device.connectivity.coaps-command</div>
<tb-markdown usePlainMarkdown containerClass="tb-command-code"
[data]=createMarkDownCommand(commands.coaps)></tb-markdown>
</div>
<ng-template #coapCertificate>
<div class="tb-form-panel-hint tb-font-14" translate>device.connectivity.coaps-x509-command</div>
<div>
<a mat-button color="primary" href="https://thingsboard.io/docs/user-guide/ssl/coap-x509-certificates/" target="_blank">
<span>
{{ 'action.see-documentation' | translate }}
<mat-icon class="tb-mat-18">open_in_new</mat-icon>
</span>
</a>
</div>
</ng-template>
</div>
<div class="tb-no-data-text" translate>device.connectivity.use-following-instructions</div>
<mat-tab-group [(selectedIndex)]="coapTabIndex">
<mat-tab>
<ng-template mat-tab-label>
<mat-icon class="tabs-icon" svgIcon="macos"></mat-icon>
MacOS
</ng-template>
<ng-template matTabContent>
<div class="tb-form-panel no-padding no-border tb-tab-body">
<div class="tb-form-panel stroked">
<div class="tb-form-panel-title" translate>device.connectivity.install-necessary-client-tools</div>
<tb-markdown usePlainMarkdown containerClass="tb-command-code"
[data]='installCoap'></tb-markdown>
</div>
<ng-container
*ngTemplateOutlet="executeCommand; context: {cmd: {
noSecLabel: 'CoAP', noSec: this.commands.coap.coap,
secLabel: 'CoAPs', sec: this.commands.coap.coaps,
doc: {text: 'device.connectivity.coaps-x509-command', href: 'https://thingsboard.io/docs/user-guide/ssl/coap-x509-certificates/'}}}">
</ng-container>
</div>
</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>
<div class="tb-form-panel no-padding no-border tb-tab-body">
<div class="tb-form-panel stroked">
<div class="tb-form-panel-title" translate>device.connectivity.install-necessary-client-tools</div>
<tb-markdown usePlainMarkdown containerClass="tb-command-code"
[data]='installCoap'></tb-markdown>
</div>
<ng-container
*ngTemplateOutlet="executeCommand; context: {cmd: {
noSecLabel: 'CoAP', noSec: this.commands.coap.coap,
secLabel: 'CoAPs', sec: this.commands.coap.coaps,
doc: {text: 'device.connectivity.coaps-x509-command', href: 'https://thingsboard.io/docs/user-guide/ssl/coap-x509-certificates/'}}}">
</ng-container>
</div>
</ng-template>
</mat-tab>
<mat-tab *ngIf="!!this.commands.coap.docker">
<ng-template mat-tab-label>
<mat-icon class="tabs-icon" svgIcon="docker"></mat-icon>
Docker
</ng-template>
<ng-template matTabContent>
<div class="tb-form-panel no-padding no-border tb-tab-body">
<ng-container
*ngTemplateOutlet="executeCommand; context: {cmd: {
noSecLabel: 'CoAP', noSec: this.commands.coap.docker.coap,
secLabel: 'CoAPs', sec: this.commands.coap.docker.coaps,
doc: {text: 'device.connectivity.coaps-x509-command', href: 'https://thingsboard.io/docs/user-guide/ssl/coap-x509-certificates/'}}}">
</ng-container>
</div>
</ng-template>
</mat-tab>
</mat-tab-group>
</ng-template>
<ng-template [ngSwitchCase]="DeviceTransportType.SNMP">
<div class="tb-form-panel-hint tb-font-14" translate>device.connectivity.snmp-command</div>
<div>
<a mat-button color="primary" href="https://thingsboard.io/docs/reference/snmp-api/" target="_blank">
<span>
{{ 'action.see-documentation' | translate }}
<mat-icon class="tb-mat-18">open_in_new</mat-icon>
</span>
</a>
<div class="tb-form-panel stroked">
<ng-container
*ngTemplateOutlet="seeDocumentation; context:
{doc: {text: 'device.connectivity.snmp-command', href: 'https://thingsboard.io/docs/reference/snmp-api/'}}">
</ng-container>
</div>
</ng-template>
<ng-template [ngSwitchCase]="DeviceTransportType.LWM2M">
<div class="tb-form-panel-hint tb-font-14" translate>device.connectivity.lwm2m-command</div>
<div>
<a mat-button color="primary" href="https://thingsboard.io/docs/reference/lwm2m-api/" target="_blank">
<span>
{{ 'action.see-documentation' | translate }}
<mat-icon class="tb-mat-18">open_in_new</mat-icon>
</span>
</a>
<div class="tb-form-panel stroked">
<ng-container
*ngTemplateOutlet="seeDocumentation; context:
{doc: {text: 'device.connectivity.lwm2m-command', href: 'https://thingsboard.io/docs/reference/lwm2m-api/'}}">
</ng-container>
</div>
</ng-template>
</ng-container>
@ -224,3 +338,44 @@
<div class="tb-no-data-text" translate>attribute.no-latest-telemetry</div>
</div>
</ng-template>
<ng-template #executeCommand let-cmd="cmd">
<div class="tb-form-panel stroked">
<div fxLayout="row" fxLayoutAlign="space-between center" [fxHide]="!(cmd.noSec || cmd.sec !== 'Check documentation')">
<div class="tb-form-panel-title" translate>device.connectivity.execute-following-command</div>
<tb-toggle-header #protocolType value="{{ cmd.noSec ? 'noSec' : 'sec'}}" name="protocolType" useSelectOnMdLg="false"
[fxShow]="cmd.noSec && cmd.sec">
<tb-toggle-option value="noSec">{{ cmd.noSecLabel }}</tb-toggle-option>
<tb-toggle-option value="sec">{{ cmd.secLabel }}</tb-toggle-option>
</tb-toggle-header>
</div>
<ng-container [ngSwitch]="protocolType.value">
<ng-template [ngSwitchCase]="'noSec'">
<tb-markdown usePlainMarkdown containerClass="tb-command-code"
[data]=createMarkDownCommand(cmd.noSec)></tb-markdown>
</ng-template>
<ng-template [ngSwitchCase]="'sec'">
<div *ngIf="cmd.sec !== 'Check documentation'; else checkDocumentation">
<tb-markdown usePlainMarkdown containerClass="tb-command-code"
[data]=createMarkDownCommand(cmd.sec)></tb-markdown>
</div>
<ng-template #checkDocumentation>
<ng-container
*ngTemplateOutlet="seeDocumentation; context:
{doc: cmd.doc}">
</ng-container>
</ng-template>
</ng-template>
</ng-container>
</div>
</ng-template>
<ng-template #seeDocumentation let-doc="doc">
<div class="tb-form-row no-border no-padding space-between">
<div class="tb-font-14 tb-flex-1">{{ doc.text | translate }}</div>
<a mat-stroked-button color="primary" href="{{doc.href }}" target="_blank">
<mat-icon>description</mat-icon>
{{ 'common.documentation' | translate }}
</a>
</div>
</ng-template>

19
ui-ngx/src/app/modules/home/pages/device/device-check-connectivity-dialog.component.scss

@ -68,6 +68,10 @@
font-size: 14px;
}
.tb-flex-1 {
flex: 1;
}
.tb-form-table-body {
max-height: 88px;
overflow-y: auto;
@ -84,6 +88,10 @@
}
}
.tb-install-windows {
min-height: 42px;
}
@media #{$mat-sm} {
width: 470px;
}
@ -112,12 +120,13 @@
.code-wrapper {
padding: 0;
pre[class*=language-] {
margin: 0;
background: #F3F6FA;
border-color: #305680;
}
}
button.clipboard-btn {
right: 0;
right: -2px;
p {
color: #305680;
}
@ -148,4 +157,12 @@
box-sizing: initial;
}
}
.tabs-icon {
margin-right: 8px;
}
.tb-form-panel.tb-tab-body {
padding: 16px 0 0;
}
}

89
ui-ngx/src/app/modules/home/pages/device/device-check-connectivity-dialog.component.ts

@ -38,16 +38,19 @@ import {
BasicTransportType,
DeviceTransportType,
deviceTransportTypeTranslationMap,
NetworkTransportType
NetworkTransportType,
PublishTelemetryCommand
} from '@shared/models/device.models';
import { UserSettingsService } from '@core/http/user-settings.service';
import { ActionPreferencesUpdateUserSettings } from '@core/auth/auth.actions';
import { coerceBooleanProperty } from '@angular/cdk/coercion';
import { getOS } from '@core/utils';
export interface DeviceCheckConnectivityDialogData {
deviceId: EntityId;
afterAdd: boolean;
}
@Component({
selector: 'tb-device-check-connectivity-dialog',
templateUrl: './device-check-connectivity-dialog.component.html',
@ -62,7 +65,7 @@ export class DeviceCheckConnectivityDialogComponent extends
latestTelemetry: Array<AttributeData> = [];
commands: {[key: string]: string};
commands: PublishTelemetryCommand;
allowTransportType = new Set<NetworkTransportType>();
selectTransportType: NetworkTransportType;
@ -77,6 +80,45 @@ export class DeviceCheckConnectivityDialogComponent extends
notShowAgain = false;
httpTabIndex = 0;
mqttTabIndex = 0;
coapTabIndex = 0;
readonly installCoap = '```bash\n' +
'git clone https://github.com/obgm/libcoap --recursive\n' +
'{:copy-code}\n' +
'```\n' +
'<br />\n' +
'\n' +
'```bash\n' +
'cd libcoap\n' +
'{:copy-code}\n' +
'```\n' +
'<br />\n' +
'\n' +
'```bash\n' +
'./autogen.sh\n' +
'{:copy-code}\n' +
'```\n' +
'<br />\n' +
'\n' +
'```bash\n' +
'./configure --with-openssl --disable-doxygen --disable-manpages --disable-shared\n' +
'{:copy-code}\n' +
'```\n' +
'<br />\n' +
'\n' +
'```bash\n' +
'make\n' +
'{:copy-code}\n' +
'```\n' +
'<br />\n' +
'\n' +
'```bash\n' +
'sudo make install\n' +
'{:copy-code}\n' +
'```';
private telemetrySubscriber: TelemetrySubscriber;
private currentTime = Date.now();
@ -125,11 +167,21 @@ export class DeviceCheckConnectivityDialogComponent extends
}
}
createMarkDownCommand(command: string): string {
createMarkDownCommand(commands: string | string[]): string {
if (Array.isArray(commands)) {
const formatCommands: Array<string> = [];
commands.forEach(command => formatCommands.push(this.createMarkDownSingleCommand(command)));
return formatCommands.join('<br />\n');
} else {
return this.createMarkDownSingleCommand(commands);
}
}
private createMarkDownSingleCommand(command: string): string {
return '```bash\n' +
command +
'{:copy-code}\n' +
'```';
command +
'{:copy-code}\n' +
'```';
}
private loadCommands() {
@ -144,6 +196,7 @@ export class DeviceCheckConnectivityDialogComponent extends
}
});
this.selectTransportType = this.allowTransportType.values().next().value;
this.selectTabIndexForUserOS();
this.loadedCommand = true;
}
);
@ -180,4 +233,28 @@ export class DeviceCheckConnectivityDialogComponent extends
});
}
private selectTabIndexForUserOS() {
const currentOS = getOS();
switch (currentOS) {
case 'linux':
case 'android':
this.httpTabIndex = 2;
this.mqttTabIndex = 2;
this.coapTabIndex = 1;
break;
case 'macos':
case 'ios':
this.httpTabIndex = 1;
this.mqttTabIndex = 1;
break;
case 'windows':
this.httpTabIndex = 0;
this.mqttTabIndex = 0;
break;
default:
this.mqttTabIndex = this.commands.mqtt?.docker ? 3 : 0;
this.coapTabIndex = this.commands.coap?.docker ? 2 : 1;
}
}
}

25
ui-ngx/src/app/shared/models/device.models.ts

@ -837,6 +837,31 @@ export interface ClaimResult {
response: ClaimResponse;
}
export interface PublishTelemetryCommand {
http?: {
http?: string;
https?: string;
};
mqtt: {
mqtt?: string;
mqtts?: string | Array<string>;
docker?: {
mqtt?: string;
mqtts?: string | Array<string>;
};
};
coap: {
coap?: string;
coaps?: string | Array<string>;
docker?: {
coap?: string;
coaps?: string | Array<string>;
};
};
lwm2m?: string;
snmp?: string;
}
export const dayOfWeekTranslations = new Array<string>(
'device-profile.schedule-day.monday',
'device-profile.schedule-day.tuesday',

1
ui-ngx/src/assets/docker.svg

@ -0,0 +1 @@
<svg width="25" height="24" xmlns="http://www.w3.org/2000/svg"><g clip-path="url(#a)"><path d="M11.75 3a.25.25 0 0 0-.25.25v1.5c0 .138.112.25.25.25h1.5a.25.25 0 0 0 .25-.25v-1.5a.25.25 0 0 0-.25-.25h-1.5Zm-6 3a.25.25 0 0 0-.25.25v1.5c0 .138.112.25.25.25h1.5a.25.25 0 0 0 .25-.25v-1.5A.25.25 0 0 0 7.25 6h-1.5Zm3 0a.25.25 0 0 0-.25.25v1.5c0 .138.112.25.25.25h1.5a.25.25 0 0 0 .25-.25v-1.5a.25.25 0 0 0-.25-.25h-1.5Zm3 0a.25.25 0 0 0-.25.25v1.5c0 .138.112.25.25.25h1.5a.25.25 0 0 0 .25-.25v-1.5a.25.25 0 0 0-.25-.25h-1.5Zm7.49 1.15-.227.326c-.284.437-.49.918-.612 1.423-.23.967-.09 1.874.403 2.65-.596.33-1.611.444-1.804.451H1.5a1 1 0 0 0-1 1c0 1 .217 2.462.693 3.758.545 1.422 1.356 2.47 2.41 3.11 1.18.72 3.1 1.132 5.275 1.132.982.003 1.964-.086 2.93-.265a12.277 12.277 0 0 0 3.823-1.383 10.513 10.513 0 0 0 2.61-2.126c1.252-1.412 1.998-2.985 2.553-4.382l.007-.004c1.498.06 2.405-.519 2.894-1 .31-.292.55-.649.707-1.043l.098-.286-.236-.186c-.065-.051-.673-.509-1.954-.509-.339.002-.677.031-1.01.087-.248-1.692-1.653-2.518-1.716-2.555l-.345-.198ZM2.75 9a.25.25 0 0 0-.25.25v1.5c0 .138.112.25.25.25h1.5a.25.25 0 0 0 .25-.25v-1.5A.25.25 0 0 0 4.25 9h-1.5Zm3 0a.25.25 0 0 0-.25.25v1.5c0 .138.112.25.25.25h1.5a.25.25 0 0 0 .25-.25v-1.5A.25.25 0 0 0 7.25 9h-1.5Zm3 0a.25.25 0 0 0-.25.25v1.5c0 .138.112.25.25.25h1.5a.25.25 0 0 0 .25-.25v-1.5a.25.25 0 0 0-.25-.25h-1.5Zm3 0a.25.25 0 0 0-.25.25v1.5c0 .138.112.25.25.25h1.5a.25.25 0 0 0 .25-.25v-1.5a.25.25 0 0 0-.25-.25h-1.5Zm3 0a.25.25 0 0 0-.25.25v1.5c0 .138.112.25.25.25h1.5a.25.25 0 0 0 .25-.25v-1.5a.25.25 0 0 0-.25-.25h-1.5Z" fill="currentColor" /></g><defs><clipPath id="a"><path fill="currentColor" d="M.5 0h24v24H.5z"/></clipPath></defs></svg>

After

Width:  |  Height:  |  Size: 1.7 KiB

40
ui-ngx/src/assets/help/en_US/device/install_coap_client.md

@ -1,40 +0,0 @@
#### CoAP installation instructions
---
<br />
Install coap client tool on your **Linux/macOS**:
```bash
git clone https://github.com/obgm/libcoap --recursive
{:copy-code}
```
<br />
```bash
cd libcoap
{:copy-code}
```
<br />
```bash
./autogen.sh
{:copy-code}
```
<br />
```bash
./configure --with-openssl --disable-doxygen --disable-manpages --disable-shared
{:copy-code}
```
<br />
```bash
make
{:copy-code}
```
<br />
```bash
sudo make install
{:copy-code}
```

34
ui-ngx/src/assets/help/en_US/device/install_curl.md

@ -1,34 +0,0 @@
#### cURL installation instructions
---
<section style="margin: 18px 0">
<div style="margin: 0 32px">
<tb-toggle-header #publishCommandSteps value="ubuntu" name="publishCommandSteps" useSelectOnMdLg="false" appearance="fill">
<tb-toggle-option value="ubuntu">Ubuntu</tb-toggle-option>
<tb-toggle-option value="macos">MacOS</tb-toggle-option>
<tb-toggle-option value="windows">Windows</tb-toggle-option>
</tb-toggle-header>
</div>
<ng-container [ngSwitch]="publishCommandSteps.value">
<ng-template [ngSwitchCase]="'ubuntu'">
<p style="margin-top: 18px; padding: 0 32px">Install cURL tool:</p>
<tb-markdown usePlainMarkdown containerClass="tb-getting-started-code" data="
```bash
sudo apt-get install curl
{:copy-code}
```
"></tb-markdown>
</ng-template>
<ng-template [ngSwitchCase]="'macos'">
<p style="margin-top: 18px; padding: 0 32px">Install cURL tool:</p>
<tb-markdown usePlainMarkdown containerClass="tb-getting-started-code" data="
```bash
brew install curl
{:copy-code}
```
"></tb-markdown>
</ng-template>
<ng-template [ngSwitchCase]="'windows'">
<div style="margin-top: 18px; padding: 0 32px; width: 404px;">Starting Windows 10 b17063, cURL is available by default.</div>
</ng-template>
</ng-container>
</section>

38
ui-ngx/src/assets/help/en_US/device/install_mqtt_client.md

@ -1,38 +0,0 @@
#### MQTT client tool installation instructions
---
<section style="margin: 18px 0">
<div style="margin: 0 32px">
<tb-toggle-header #publishCommandSteps value="ubuntu" name="publishCommandSteps" useSelectOnMdLg="false" appearance="fill">
<tb-toggle-option value="ubuntu">Ubuntu</tb-toggle-option>
<tb-toggle-option value="macos">MacOS</tb-toggle-option>
<tb-toggle-option value="windows">Windows</tb-toggle-option>
</tb-toggle-header>
</div>
<ng-container [ngSwitch]="publishCommandSteps.value">
<ng-template [ngSwitchCase]="'ubuntu'">
<p style="margin-top: 18px; padding: 0 32px">Install mqtt client tool:</p>
<tb-markdown usePlainMarkdown containerClass="tb-getting-started-code" data="
```bash
sudo apt-get install curl mosquitto-clients
{:copy-code}
```
"></tb-markdown>
</ng-template>
<ng-template [ngSwitchCase]="'macos'">
<p style="margin-top: 18px; padding: 0 32px">Install mqtt client tool:</p>
<tb-markdown usePlainMarkdown containerClass="tb-getting-started-code" data="
```bash
brew install mosquitto-clients
{:copy-code}
```
"></tb-markdown>
</ng-template>
<ng-template [ngSwitchCase]="'windows'">
<p style="margin-top: 18px; padding: 0 32px">Install mqtt client tool:</p>
<a mat-stroked-button color="primary" class="ignore-style-a"
style="margin: 8px 32px"
href="https://thingsboard.io/docs/getting-started-guides/helloworld/?connectdevice=mqtt-windows#step-2-connect-device" target="_blank">
<mat-icon>description</mat-icon>How to install MQTT Box</a>
</ng-template>
</ng-container>
</section>

1
ui-ngx/src/assets/linux.svg

@ -0,0 +1 @@
<svg width="25" height="24" xmlns="http://www.w3.org/2000/svg"><path d="M20.91 18.862c-.652-.267-.931-.621-.904-1.15.028-.618-.323-1.07-.489-1.249.1-.384.394-1.712 0-2.866-.423-1.235-1.715-3.12-3.05-4.975-.545-.761-.57-1.589-.6-2.547-.03-.914-.062-1.95-.571-3.102C14.742 1.72 13.629 1 12.245 1c-.824 0-1.67.257-2.32.706-1.333.92-1.157 2.925-1.04 4.252.015.182.03.353.039.5.078 1.3.007 1.984-.085 2.193-.06.136-.354.523-.665.933-.322.424-.687.904-.986 1.352-.357.539-.645 1.362-.924 2.159-.204.583-.396 1.133-.584 1.462a1.991 1.991 0 0 0-.193 1.496c-.134.093-.329.277-.493.624-.198.423-.6.65-1.437.811-.384.079-.65.24-.788.48-.202.35-.092.79.008 1.09.149.44.056.72-.111 1.227-.04.116-.083.249-.127.395-.07.23-.045.44.074.623.316.483 1.238.653 2.187.765.567.068 1.187.294 1.787.514.587.214 1.195.436 1.747.504.084.01.168.016.248.016.834 0 1.21-.554 1.33-.781.3-.061 1.333-.257 2.398-.283 1.063-.03 2.091.18 2.383.245.091.175.333.575.718.782.212.115.506.182.808.182.322 0 .935-.076 1.42-.587.483-.512 1.692-1.167 2.575-1.644.197-.107.38-.207.542-.297.496-.275.767-.668.742-1.077-.02-.34-.245-.64-.588-.78Zm-10.975-.098c-.062-.435-.62-.866-1.269-1.365-.53-.409-1.13-.871-1.295-1.263-.341-.808-.072-2.23.398-2.962.232-.366.421-.922.605-1.46.198-.58.402-1.18.631-1.442.363-.41.698-1.208.757-1.837.34.324.867.735 1.353.735.075 0 .148-.01.217-.03.333-.095.823-.378 1.296-.652.409-.236.912-.526 1.102-.553.324.466 2.212 4.643 2.405 5.984a6.34 6.34 0 0 1-.09 2.283 1.678 1.678 0 0 0-.225-.016c-.525 0-.665.287-.7.458-.094.445-.104 1.869-.105 2.188-.19.242-1.151 1.38-2.531 1.584a10.96 10.96 0 0 1-1.56.123c-.405 0-.663-.032-.77-.048l-.694-.793c.274-.135.547-.42.475-.934Zm.88-13.085-.064.03a1.292 1.292 0 0 0-.014-.142c-.076-.436-.365-.752-.687-.752a.486.486 0 0 0-.075.005c-.191.032-.342.176-.424.38.072-.448.326-.78.627-.78.354 0 .653.477.653 1.042 0 .07-.005.142-.016.217Zm2.749.336c.032-.103.05-.215.05-.33 0-.512-.325-.913-.74-.913-.404 0-.734.41-.734.913 0 .034.002.068.005.102l-.063-.024a1.395 1.395 0 0 1-.07-.438c0-.612.391-1.11.872-1.11.48 0 .872.498.872 1.11 0 .254-.07.497-.192.69Zm-.354 1.19c-.007.032-.022.045-.185.13a4.979 4.979 0 0 0-.313.174l-.086.052c-.344.209-1.15.697-1.368.726-.149.02-.24-.037-.447-.178a6.4 6.4 0 0 0-.15-.1c-.372-.244-.612-.513-.639-.618.122-.094.423-.329.577-.468.313-.29.628-.486.783-.486.009 0 .016 0 .024.002.183.032.634.212.964.344.153.06.284.113.377.146.292.1.444.229.463.277ZM15.83 20.8c.165-.743.355-1.753.324-2.349-.007-.135-.019-.282-.03-.425-.022-.266-.054-.662-.021-.779a.145.145 0 0 1 .022-.008c.001.34.075 1.02.618 1.257.162.07.347.106.55.106.544 0 1.148-.267 1.395-.514.146-.146.268-.324.354-.465a.56.56 0 0 1 .024.22c-.032.502.212 1.168.676 1.413l.068.036c.165.087.605.317.612.427 0 0-.004.013-.028.035-.11.101-.498.299-.872.49-.665.34-1.418.724-1.757 1.08-.476.501-1.015.838-1.34.838a.354.354 0 0 1-.107-.015c-.353-.11-.644-.62-.487-1.347ZM3.789 18.905c-.036-.168-.064-.301-.034-.43.022-.096.494-.198.696-.242.283-.061.576-.125.767-.241.26-.157.4-.447.523-.702.09-.184.182-.375.292-.438a.061.061 0 0 1 .034-.008c.206 0 .64.434.888.822.064.097.18.293.316.52.406.678.96 1.607 1.25 1.919.262.28.685.818.58 1.28-.076.357-.481.648-.577.713a.59.59 0 0 1-.128.012c-.555 0-1.653-.462-2.243-.71l-.087-.037c-.33-.138-.868-.225-1.388-.309-.414-.067-.98-.159-1.074-.241-.076-.086.012-.364.09-.609.056-.176.114-.358.146-.548.045-.304-.008-.552-.05-.75Z" fill="currentColor"/></svg>

After

Width:  |  Height:  |  Size: 3.3 KiB

15
ui-ngx/src/assets/locale/locale.constant-en_US.json

@ -880,7 +880,8 @@
"loading": "Loading...",
"proceed": "Proceed",
"open-details-page": "Open details page",
"not-found": "Not found"
"not-found": "Not found",
"documentation": "Documentation"
},
"content-type": {
"json": "Json",
@ -1389,16 +1390,10 @@
"device-created-check-connectivity": "Device created. Let's check connectivity!",
"loading-check-connectivity-command": "Loading check connectivity commands...",
"use-following-instructions": "Use the following instructions for sending telemetry on behalf of the device using shell",
"install-curl": "Install cURL tool.",
"install-mqtt-client": "Install mgtt client tool.",
"install-coap-cli": "Install coap-cli tool.",
"http-command": "HTTP (Linux, macOS or Windows)",
"https-command": "HTTPS (Linux, macOS or Windows)",
"mqtt-command": "MQTT (Linux, macOS)",
"mqtts-command": "MQTT over SSL (Linux, macOS)",
"execute-following-command": "Executive the following command",
"install-curl-windows": "Starting Windows 10 b17063, cURL is available by default",
"install-necessary-client-tools": "Install necessary client tools",
"mqtts-x509-command": "Use the following documentation to connect the device via MQTT with authorization X509",
"coap-command": "CoAP (Linux, macOS)",
"coaps-command": "CoAP over DTLS (Linux, macOS)",
"coaps-x509-command": "Use the following documentation to connect the device via CoAP over DTLS with authorization X509",
"snmp-command": "Use the following documentation to connect the device through the SNMP.",
"lwm2m-command": "Use the following documentation to connect the device through the LWM2M."

1
ui-ngx/src/assets/macos.svg

@ -0,0 +1 @@
<svg width="25" height="24" xmlns="http://www.w3.org/2000/svg"><path d="M21.873 16.68c-.517 1.15-.767 1.664-1.432 2.678-.932 1.418-2.247 3.188-3.87 3.199-1.446.013-1.82-.943-3.782-.926-1.961.009-2.37.945-3.818.93-1.625-.015-2.868-1.61-3.8-3.025-2.607-3.97-2.882-8.623-1.272-11.098 1.14-1.755 2.942-2.786 4.635-2.786 1.725 0 2.81.947 4.234.947 1.384 0 2.226-.95 4.22-.95 1.508 0 3.102.822 4.242 2.24-3.727 2.043-3.122 7.366.643 8.791Zm-6.4-12.615C16.2 3.134 16.752 1.82 16.55.48c-1.183.081-2.567.837-3.375 1.815-.733.893-1.34 2.217-1.104 3.497 1.292.042 2.628-.729 3.403-1.727Z" fill="currentColor" /></svg>

After

Width:  |  Height:  |  Size: 607 B

1
ui-ngx/src/assets/windows.svg

@ -0,0 +1 @@
<svg width="25" height="24" xmlns="http://www.w3.org/2000/svg"><path d="M10.1 12.8H2.9V19l7.2.99V12.8Zm0-8.8L2.9 5v6.2h7.2V4Zm1.6-.2v7.4h10.4V2.4L11.7 3.8Zm0 9v7.4l10.4 1.4v-8.8H11.7Z" fill="currentColor" /></svg>

After

Width:  |  Height:  |  Size: 214 B

7
ui-ngx/src/form.scss

@ -144,6 +144,13 @@
&.space-between {
justify-content: space-between;
}
&.no-border {
border: none;
border-radius: 0;
}
&.no-padding {
padding: 0;
}
.mat-divider-vertical {
height: 56px;
margin-top: -7px;

Loading…
Cancel
Save