Browse Source

UI: Improved view and text general settings - device connectivty

pull/9457/head
Vladyslav_Prykhodko 3 years ago
parent
commit
1ba3465dac
  1. 119
      ui-ngx/src/app/modules/home/pages/admin/general-settings.component.html
  2. 17
      ui-ngx/src/app/modules/home/pages/admin/general-settings.component.scss
  3. 95
      ui-ngx/src/app/modules/home/pages/admin/general-settings.component.ts
  4. 16
      ui-ngx/src/assets/locale/locale.constant-en_US.json

119
ui-ngx/src/app/modules/home/pages/admin/general-settings.component.html

@ -27,8 +27,8 @@
</mat-progress-bar> </mat-progress-bar>
<div style="height: 4px;" *ngIf="!(isLoading$ | async)"></div> <div style="height: 4px;" *ngIf="!(isLoading$ | async)"></div>
<mat-card-content> <mat-card-content>
<form [formGroup]="generalSettings" (ngSubmit)="save()"> <form [formGroup]="generalSettings" (ngSubmit)="save()" class="tb-form-panel no-border no-padding">
<fieldset [disabled]="isLoading$ | async" class="margin-bottom"> <fieldset [disabled]="isLoading$ | async">
<mat-form-field class="mat-block"> <mat-form-field class="mat-block">
<mat-label translate>admin.base-url</mat-label> <mat-label translate>admin.base-url</mat-label>
<input matInput formControlName="baseUrl" required/> <input matInput formControlName="baseUrl" required/>
@ -37,7 +37,7 @@
</mat-error> </mat-error>
</mat-form-field> </mat-form-field>
<div class="tb-form-row" tb-hint-tooltip-icon="{{ 'admin.prohibit-different-url-hint' | translate }}"> <div class="tb-form-row" tb-hint-tooltip-icon="{{ 'admin.prohibit-different-url-hint' | translate }}">
<mat-slide-toggle class="mat-slide" formControlName="prohibitDifferentUrl"> <mat-slide-toggle class="mat-slide margin" formControlName="prohibitDifferentUrl">
{{ 'admin.prohibit-different-url' | translate }} {{ 'admin.prohibit-different-url' | translate }}
</mat-slide-toggle> </mat-slide-toggle>
</div> </div>
@ -58,67 +58,72 @@
<mat-card appearance="outlined" class="settings-card"> <mat-card appearance="outlined" class="settings-card">
<mat-card-header> <mat-card-header>
<mat-card-title> <mat-card-title>
<span class="mat-headline-5" translate>admin.device-connectivity.device-connectivity</span> <div class="mat-headline-5" translate>admin.device-connectivity.device-connectivity</div>
</mat-card-title> </mat-card-title>
</mat-card-header> </mat-card-header>
<mat-progress-bar color="warn" mode="indeterminate" *ngIf="isLoading$ | async"> <mat-progress-bar color="warn" mode="indeterminate" *ngIf="isLoading$ | async">
</mat-progress-bar> </mat-progress-bar>
<div style="height: 4px;" *ngIf="!(isLoading$ | async)"></div> <div style="height: 4px;" *ngIf="!(isLoading$ | async)"></div>
<mat-card-content style="padding-top: 16px"> <mat-card-content>
<tb-toggle-select class="toggle-group margin-bottom" appearance="fill" selectMediaBreakpoint="xs" [(ngModel)]="protocol"> <section class="tb-form-panel no-border no-padding">
<tb-toggle-option value="http">{{ "admin.device-connectivity.http-https" | translate }}</tb-toggle-option> <div class="tb-form-panel no-border no-padding toggle-group">
<tb-toggle-option value="mqtt">{{ 'admin.device-connectivity.mqtt-mqtts' | translate }}</tb-toggle-option> <tb-toggle-select appearance="fill" [(ngModel)]="protocol">
<tb-toggle-option value="coap">{{ 'admin.device-connectivity.coap-coaps' | translate }}</tb-toggle-option> <tb-toggle-option value="http">{{ "admin.device-connectivity.http-s" | translate }}</tb-toggle-option>
</tb-toggle-select> <tb-toggle-option value="mqtt">{{ 'admin.device-connectivity.mqtt-s' | translate }}</tb-toggle-option>
<div class="tb-form-hint tb-primary-fill margin-bottom">{{ 'admin.device-connectivity.hint' | translate }}</div> <tb-toggle-option value="coap">{{ 'admin.device-connectivity.coap-s' | translate }}</tb-toggle-option>
<form [formGroup]="deviceConnectivitySettingsForm" (ngSubmit)="saveDeviceConnectivitySettings()"> </tb-toggle-select>
<ng-container *ngIf="protocol === 'http'"> <div class="tb-form-hint tb-primary-fill">{{ 'admin.device-connectivity.hint' | translate }}</div>
<ng-container *ngTemplateOutlet="connectivitySettings; context:{protocol: protocol}"></ng-container> </div>
<ng-container *ngTemplateOutlet="connectivitySettings; context:{protocol: protocol + 's'}"></ng-container> <form [formGroup]="deviceConnectivitySettingsForm" (ngSubmit)="saveDeviceConnectivitySettings()"
</ng-container> class="tb-form-panel no-border no-padding">
<ng-container *ngIf="protocol === 'mqtt'"> <ng-container *ngIf="protocol === 'http'">
<ng-container *ngTemplateOutlet="connectivitySettings; context:{protocol: protocol}"></ng-container> <ng-container *ngTemplateOutlet="connectivitySettings; context:{protocol: protocol}"></ng-container>
<ng-container *ngTemplateOutlet="connectivitySettings; context:{protocol: protocol + 's'}"></ng-container> <ng-container *ngTemplateOutlet="connectivitySettings; context:{protocol: protocol + 's'}"></ng-container>
</ng-container> </ng-container>
<ng-container *ngIf="protocol === 'coap'"> <ng-container *ngIf="protocol === 'mqtt'">
<ng-container *ngTemplateOutlet="connectivitySettings; context:{protocol: protocol}"></ng-container> <ng-container *ngTemplateOutlet="connectivitySettings; context:{protocol: protocol}"></ng-container>
<ng-container *ngTemplateOutlet="connectivitySettings; context:{protocol: protocol + 's'}"></ng-container> <ng-container *ngTemplateOutlet="connectivitySettings; context:{protocol: protocol + 's'}"></ng-container>
</ng-container> </ng-container>
<ng-template #connectivitySettings let-protocol="protocol"> <ng-container *ngIf="protocol === 'coap'">
<div class="tb-form-panel stroked margin-bottom" [formGroupName]="protocol"> <ng-container *ngTemplateOutlet="connectivitySettings; context:{protocol: protocol}"></ng-container>
<mat-slide-toggle class="mat-slide" formControlName="enabled"> <ng-container *ngTemplateOutlet="connectivitySettings; context:{protocol: protocol + 's'}"></ng-container>
{{ 'admin.device-connectivity.' + protocol | translate }} </ng-container>
</mat-slide-toggle> <ng-template #connectivitySettings let-protocol="protocol">
<div class="tb-form-row column-xs no-border no-padding tb-standard-fields"> <div class="tb-form-panel stroked no-padding-bottom" [formGroupName]="protocol">
<mat-form-field fxFlex> <mat-slide-toggle class="mat-slide" formControlName="enabled">
<mat-label translate>admin.device-connectivity.host</mat-label> {{ 'admin.device-connectivity.' + protocol | translate }}
<input matInput formControlName="host"/> </mat-slide-toggle>
</mat-form-field> <div class="tb-form-row column-xs no-border no-padding tb-standard-fields">
<mat-form-field fxFlex> <mat-form-field fxFlex>
<mat-label translate>admin.device-connectivity.port</mat-label> <mat-label translate>admin.device-connectivity.host</mat-label>
<input matInput type="number" min="0" max="65535" formControlName="port"/> <input matInput formControlName="host"/>
<mat-error *ngIf="deviceConnectivitySettingsForm.get(protocol + '.port').hasError('pattern')"> </mat-form-field>
{{ 'admin.device-connectivity.port-pattern' | translate }} <mat-form-field fxFlex>
</mat-error> <mat-label translate>admin.device-connectivity.port</mat-label>
<mat-error *ngIf="deviceConnectivitySettingsForm.get(protocol + '.port').hasError('min') || <input matInput type="number" min="0" max="65535" formControlName="port"/>
<mat-error *ngIf="deviceConnectivitySettingsForm.get(protocol + '.port').hasError('pattern')">
{{ 'admin.device-connectivity.port-pattern' | translate }}
</mat-error>
<mat-error *ngIf="deviceConnectivitySettingsForm.get(protocol + '.port').hasError('min') ||
deviceConnectivitySettingsForm.get(protocol + '.port').hasError('max')"> deviceConnectivitySettingsForm.get(protocol + '.port').hasError('max')">
{{ 'admin.device-connectivity.port-range' | translate }} {{ 'admin.device-connectivity.port-range' | translate }}
</mat-error> </mat-error>
</mat-form-field> </mat-form-field>
</div>
</div> </div>
</ng-template>
<div fxLayout="row" fxLayoutAlign="end center" fxLayoutGap="8px" class="layout-wrap">
<button mat-button color="primary"
[disabled]="deviceConnectivitySettingsForm.pristine"
(click)="discardDeviceConnectivitySettings()"
type="button">{{'action.undo' | translate}}
</button>
<button mat-raised-button color="primary"
[disabled]="(isLoading$ | async) || deviceConnectivitySettingsForm.invalid || !deviceConnectivitySettingsForm.dirty"
type="submit">{{'action.save' | translate}}
</button>
</div> </div>
</ng-template> </form>
<div fxLayout="row" fxLayoutAlign="end center" fxLayoutGap="8px" class="layout-wrap"> </section>
<button mat-button color="primary"
[disabled]="deviceConnectivitySettingsForm.pristine"
(click)="discardDeviceConnectivitySettings()"
type="button">{{'action.undo' | translate}}
</button>
<button mat-raised-button color="primary"
[disabled]="(isLoading$ | async) || deviceConnectivitySettingsForm.invalid || !deviceConnectivitySettingsForm.dirty"
type="submit">{{'action.save' | translate}}
</button>
</div>
</form>
</mat-card-content> </mat-card-content>
</mat-card> </mat-card>

17
ui-ngx/src/app/modules/home/pages/admin/general-settings.component.scss

@ -13,13 +13,24 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
@import "../../../../../scss/constants";
:host { :host {
.settings-card { .settings-card {
.toggle-group { .toggle-group {
display: block; max-width: 670px;
width: 100%;
margin: 0 auto;
.tb-form-hint {
text-align: center;
}
} }
.margin-bottom {
margin-bottom: 12px; @media #{$mat-xs} {
.tb-form-row {
gap: 0;
}
} }
} }
} }

95
ui-ngx/src/app/modules/home/pages/admin/general-settings.component.ts

@ -14,12 +14,11 @@
/// limitations under the License. /// limitations under the License.
/// ///
import { Component } from '@angular/core'; import { Component, OnDestroy } from '@angular/core';
import { Store } from '@ngrx/store'; import { Store } from '@ngrx/store';
import { AppState } from '@core/core.state'; import { AppState } from '@core/core.state';
import { PageComponent } from '@shared/components/page.component'; import { PageComponent } from '@shared/components/page.component';
import { Router } from '@angular/router'; import { FormBuilder, FormGroup, Validators } from '@angular/forms';
import { UntypedFormBuilder, UntypedFormGroup, Validators } from '@angular/forms';
import { import {
AdminSettings, AdminSettings,
DeviceConnectivityProtocol, DeviceConnectivityProtocol,
@ -28,26 +27,29 @@ import {
} from '@shared/models/settings.models'; } from '@shared/models/settings.models';
import { AdminService } from '@core/http/admin.service'; import { AdminService } from '@core/http/admin.service';
import { HasConfirmForm } from '@core/guards/confirm-on-exit.guard'; import { HasConfirmForm } from '@core/guards/confirm-on-exit.guard';
import { Subject } from 'rxjs';
import { takeUntil } from 'rxjs/operators';
@Component({ @Component({
selector: 'tb-general-settings', selector: 'tb-general-settings',
templateUrl: './general-settings.component.html', templateUrl: './general-settings.component.html',
styleUrls: ['./general-settings.component.scss', './settings-card.scss'] styleUrls: ['./general-settings.component.scss', './settings-card.scss']
}) })
export class GeneralSettingsComponent extends PageComponent implements HasConfirmForm { export class GeneralSettingsComponent extends PageComponent implements HasConfirmForm, OnDestroy {
generalSettings: UntypedFormGroup; generalSettings: FormGroup;
private adminSettings: AdminSettings<GeneralSettings>; deviceConnectivitySettingsForm: FormGroup;
protocol: DeviceConnectivityProtocol = 'http';
deviceConnectivitySettingsForm: UntypedFormGroup; private adminSettings: AdminSettings<GeneralSettings>;
private deviceConnectivitySettings: AdminSettings<DeviceConnectivitySettings>; private deviceConnectivitySettings: AdminSettings<DeviceConnectivitySettings>;
protocol: DeviceConnectivityProtocol = 'http'; private readonly destroy$ = new Subject<void>();
constructor(protected store: Store<AppState>, constructor(protected store: Store<AppState>,
private router: Router,
private adminService: AdminService, private adminService: AdminService,
public fb: UntypedFormBuilder) { public fb: FormBuilder) {
super(store); super(store);
this.buildGeneralServerSettingsForm(); this.buildGeneralServerSettingsForm();
this.adminService.getAdminSettings<GeneralSettings>('general') this.adminService.getAdminSettings<GeneralSettings>('general')
@ -57,46 +59,48 @@ export class GeneralSettingsComponent extends PageComponent implements HasConfir
.subscribe(deviceConnectivitySettings => this.processDeviceConnectivitySettings(deviceConnectivitySettings)); .subscribe(deviceConnectivitySettings => this.processDeviceConnectivitySettings(deviceConnectivitySettings));
} }
buildGeneralServerSettingsForm() { ngOnDestroy() {
super.ngOnDestroy();
this.destroy$.next();
this.destroy$.complete();
}
private buildGeneralServerSettingsForm() {
this.generalSettings = this.fb.group({ this.generalSettings = this.fb.group({
baseUrl: ['', [Validators.required]], baseUrl: ['', [Validators.required]],
prohibitDifferentUrl: ['',[]] prohibitDifferentUrl: ['',[]]
}); });
} }
buildDeviceConnectivitySettingsForm() { private buildDeviceConnectivitySettingsForm() {
this.deviceConnectivitySettingsForm = this.fb.group({ this.deviceConnectivitySettingsForm = this.fb.group({
http: this.fb.group({ http: this.buildDeviceConnectivityInfoForm(),
enabled: [false, []], https: this.buildDeviceConnectivityInfoForm(),
host: ['', []], mqtt: this.buildDeviceConnectivityInfoForm(),
port: [null, [Validators.min(1), Validators.max(65535), Validators.pattern('[0-9]*')]] mqtts: this.buildDeviceConnectivityInfoForm(),
}), coap: this.buildDeviceConnectivityInfoForm(),
https: this.fb.group({ coaps: this.buildDeviceConnectivityInfoForm()
enabled: [false, []], });
host: ['', []], }
port: [null, [Validators.min(1), Validators.max(65535), Validators.pattern('[0-9]*')]]
}), private buildDeviceConnectivityInfoForm(): FormGroup {
mqtt: this.fb.group({ const formGroup = this.fb.group({
enabled: [false, []], enabled: [false, []],
host: ['', []], host: [{value: '', disabled: true}],
port: [null, [Validators.min(1), Validators.max(65535), Validators.pattern('[0-9]*')]] port: [{value: null, disabled: true}, [Validators.min(1), Validators.max(65535), Validators.pattern('[0-9]*')]]
}), });
mqtts: this.fb.group({ formGroup.get('enabled').valueChanges.pipe(
enabled: [false, []], takeUntil(this.destroy$)
host: ['', []], ).subscribe(value => {
port: [null, [Validators.min(1), Validators.max(65535), Validators.pattern('[0-9]*')]] if (value) {
}), formGroup.get('host').enable({emitEvent: false});
coap: this.fb.group({ formGroup.get('port').enable({emitEvent: false});
enabled: [false, []], } else {
host: ['', []], formGroup.get('host').disable({emitEvent: false});
port: [null, [Validators.min(1), Validators.max(65535), Validators.pattern('[0-9]*')]] formGroup.get('port').disable({emitEvent: false});
}), }
coaps: this.fb.group({
enabled: [false, []],
host: ['', []],
port: [null, [Validators.min(1), Validators.max(65535), Validators.pattern('[0-9]*')]]
}),
}); });
return formGroup;
} }
save(): void { save(): void {
@ -106,7 +110,10 @@ export class GeneralSettingsComponent extends PageComponent implements HasConfir
} }
saveDeviceConnectivitySettings(): void { saveDeviceConnectivitySettings(): void {
this.deviceConnectivitySettings.jsonValue = {...this.deviceConnectivitySettings.jsonValue, ...this.deviceConnectivitySettingsForm.value}; this.deviceConnectivitySettings.jsonValue = {
...this.deviceConnectivitySettings.jsonValue,
...this.deviceConnectivitySettingsForm.value
};
this.adminService.saveAdminSettings<DeviceConnectivitySettings>(this.deviceConnectivitySettings) this.adminService.saveAdminSettings<DeviceConnectivitySettings>(this.deviceConnectivitySettings)
.subscribe(deviceConnectivitySettings => this.processDeviceConnectivitySettings(deviceConnectivitySettings)); .subscribe(deviceConnectivitySettings => this.processDeviceConnectivitySettings(deviceConnectivitySettings));
} }
@ -129,7 +136,7 @@ export class GeneralSettingsComponent extends PageComponent implements HasConfir
this.deviceConnectivitySettingsForm.reset(this.deviceConnectivitySettings.jsonValue); this.deviceConnectivitySettingsForm.reset(this.deviceConnectivitySettings.jsonValue);
} }
confirmForm(): UntypedFormGroup { confirmForm(): FormGroup {
return this.generalSettings.dirty ? this.generalSettings : this.deviceConnectivitySettingsForm; return this.generalSettings.dirty ? this.generalSettings : this.deviceConnectivitySettingsForm;
} }

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

@ -107,16 +107,16 @@
"prohibit-different-url-hint": "This setting should be enabled for production environments. May cause security issues when disabled", "prohibit-different-url-hint": "This setting should be enabled for production environments. May cause security issues when disabled",
"device-connectivity": { "device-connectivity": {
"device-connectivity": "Device connectivity", "device-connectivity": "Device connectivity",
"http-https": "HTTP/HTTPS", "http-s": "HTTP(s)",
"mqtt-mqtts": "MQTT/MQTTS", "mqtt-s": "MQTT(s)",
"coap-coaps": "COAP/COAPS", "coap-s": "COAP(s)",
"http": "HTPP", "http": "HTTP",
"https": "HTTPS", "https": "HTTPs",
"mqtt": "MQTT", "mqtt": "MQTT",
"mqtts": "MQTTS", "mqtts": "MQTTs",
"coap": "COAP", "coap": "COAP",
"coaps": "COAPS", "coaps": "COAPs",
"hint": "If host or port fields are empty will be used default protocol value.", "hint": "If host or port fields are empty, default protocol value will be used.",
"host": "Host", "host": "Host",
"port": "Port", "port": "Port",
"port-pattern": "Port must be a positive integer.", "port-pattern": "Port must be a positive integer.",

Loading…
Cancel
Save