Browse Source

UI: Improvement view device profile settings

pull/3567/head
Vladyslav_Prykhodko 6 years ago
parent
commit
30a6a462da
  1. 1
      ui-ngx/src/app/modules/home/components/filter/filter-predicate-value.component.html
  2. 2
      ui-ngx/src/app/modules/home/components/filter/filter-predicate-value.component.ts
  3. 3
      ui-ngx/src/app/modules/home/components/home-components.module.ts
  4. 2
      ui-ngx/src/app/modules/home/components/profile/add-device-profile-dialog.component.html
  5. 1
      ui-ngx/src/app/modules/home/components/profile/add-device-profile-dialog.component.scss
  6. 126
      ui-ngx/src/app/modules/home/components/profile/alarm/alarm-rule.component.html
  7. 9
      ui-ngx/src/app/modules/home/components/profile/alarm/alarm-rule.component.ts
  8. 4
      ui-ngx/src/app/modules/home/components/profile/alarm/device-profile-alarms.component.scss
  9. 55
      ui-ngx/src/app/modules/home/components/profile/device-profile-data.component.html
  10. 110
      ui-ngx/src/app/modules/home/components/profile/device-profile-data.component.ts
  11. 17
      ui-ngx/src/app/modules/home/components/profile/device-profile.component.html
  12. 6
      ui-ngx/src/app/modules/home/components/profile/device-profile.component.ts
  13. 6
      ui-ngx/src/app/modules/home/components/profile/device/default-device-profile-configuration.component.html
  14. 6
      ui-ngx/src/app/modules/home/components/profile/device/default-device-profile-transport-configuration.component.html
  15. 2
      ui-ngx/src/app/modules/home/components/profile/device/lwm2m-device-profile-transport-configuration.component.ts
  16. 49
      ui-ngx/src/app/modules/home/pages/device-profile/device-profile-tabs.component.html
  17. 5
      ui-ngx/src/app/modules/home/pages/device-profile/device-profile-tabs.component.ts
  18. 2
      ui-ngx/src/app/modules/home/pages/device-profile/device-profiles-table-config.resolver.ts
  19. 2
      ui-ngx/src/app/modules/home/pages/device/data/lwm2m-device-transport-configuration.component.ts
  20. 34
      ui-ngx/src/app/shared/models/device.models.ts

1
ui-ngx/src/app/modules/home/components/filter/filter-predicate-value.component.html

@ -76,7 +76,6 @@
type="button" type="button"
matTooltip="{{ (dynamicMode ? 'filter.switch-to-default-value' : 'filter.switch-to-dynamic-value') | translate }}" matTooltip="{{ (dynamicMode ? 'filter.switch-to-default-value' : 'filter.switch-to-dynamic-value') | translate }}"
matTooltipPosition="above" matTooltipPosition="above"
*ngIf="allow"
(click)="dynamicMode = !dynamicMode"> (click)="dynamicMode = !dynamicMode">
<mat-icon class="tb-mat-20" [svgIcon]="dynamicMode ? 'mdi:numeric' : 'mdi:variable'"></mat-icon> <mat-icon class="tb-mat-20" [svgIcon]="dynamicMode ? 'mdi:numeric' : 'mdi:variable'"></mat-icon>
</button> </button>

2
ui-ngx/src/app/modules/home/components/filter/filter-predicate-value.component.ts

@ -54,7 +54,7 @@ export class FilterPredicateValueComponent implements ControlValueAccessor, OnIn
if (allow) { if (allow) {
this.dynamicValueSourceTypes.push(DynamicValueSourceType.CURRENT_USER); this.dynamicValueSourceTypes.push(DynamicValueSourceType.CURRENT_USER);
} else { } else {
this.dynamicValueSourceTypes.push(DynamicValueSourceType.CURRENT_DEVICE); this.dynamicValueSourceTypes = [DynamicValueSourceType.CURRENT_DEVICE];
} }
} }

3
ui-ngx/src/app/modules/home/components/home-components.module.ts

@ -90,7 +90,6 @@ import { TenantProfileDialogComponent } from './profile/tenant-profile-dialog.co
import { TenantProfileDataComponent } from './profile/tenant-profile-data.component'; import { TenantProfileDataComponent } from './profile/tenant-profile-data.component';
import { DefaultDeviceProfileConfigurationComponent } from './profile/device/default-device-profile-configuration.component'; import { DefaultDeviceProfileConfigurationComponent } from './profile/device/default-device-profile-configuration.component';
import { DeviceProfileConfigurationComponent } from './profile/device/device-profile-configuration.component'; import { DeviceProfileConfigurationComponent } from './profile/device/device-profile-configuration.component';
import { DeviceProfileDataComponent } from './profile/device-profile-data.component';
import { DeviceProfileComponent } from './profile/device-profile.component'; import { DeviceProfileComponent } from './profile/device-profile.component';
import { DefaultDeviceProfileTransportConfigurationComponent } from './profile/device/default-device-profile-transport-configuration.component'; import { DefaultDeviceProfileTransportConfigurationComponent } from './profile/device/default-device-profile-transport-configuration.component';
import { DeviceProfileTransportConfigurationComponent } from './profile/device/device-profile-transport-configuration.component'; import { DeviceProfileTransportConfigurationComponent } from './profile/device/device-profile-transport-configuration.component';
@ -195,7 +194,6 @@ import { DeviceCredentialsComponent } from './device/device-credentials.componen
AlarmRuleConditionComponent, AlarmRuleConditionComponent,
DeviceProfileAlarmComponent, DeviceProfileAlarmComponent,
DeviceProfileAlarmsComponent, DeviceProfileAlarmsComponent,
DeviceProfileDataComponent,
DeviceProfileComponent, DeviceProfileComponent,
DeviceProfileDialogComponent, DeviceProfileDialogComponent,
AddDeviceProfileDialogComponent, AddDeviceProfileDialogComponent,
@ -277,7 +275,6 @@ import { DeviceCredentialsComponent } from './device/device-credentials.componen
AlarmRuleConditionComponent, AlarmRuleConditionComponent,
DeviceProfileAlarmComponent, DeviceProfileAlarmComponent,
DeviceProfileAlarmsComponent, DeviceProfileAlarmsComponent,
DeviceProfileDataComponent,
DeviceProfileComponent, DeviceProfileComponent,
DeviceProfileDialogComponent, DeviceProfileDialogComponent,
AddDeviceProfileDialogComponent, AddDeviceProfileDialogComponent,

2
ui-ngx/src/app/modules/home/components/profile/add-device-profile-dialog.component.html

@ -45,7 +45,7 @@
labelText="device-profile.default-rule-chain" labelText="device-profile.default-rule-chain"
formControlName="defaultRuleChainId"> formControlName="defaultRuleChainId">
</tb-rule-chain-autocomplete> </tb-rule-chain-autocomplete>
<mat-form-field class="mat-block"> <mat-form-field fxHide class="mat-block">
<mat-label translate>device-profile.type</mat-label> <mat-label translate>device-profile.type</mat-label>
<mat-select formControlName="type" required> <mat-select formControlName="type" required>
<mat-option *ngFor="let type of deviceProfileTypes" [value]="type"> <mat-option *ngFor="let type of deviceProfileTypes" [value]="type">

1
ui-ngx/src/app/modules/home/components/profile/add-device-profile-dialog.component.scss

@ -32,6 +32,7 @@
.mat-stepper-horizontal { .mat-stepper-horizontal {
.mat-horizontal-content-container { .mat-horizontal-content-container {
overflow: auto; overflow: auto;
min-height: 260px;
} }
} }
} }

126
ui-ngx/src/app/modules/home/components/profile/alarm/alarm-rule.component.html

@ -21,74 +21,72 @@
<tb-alarm-rule-condition fxFlex class="row" <tb-alarm-rule-condition fxFlex class="row"
formControlName="condition"> formControlName="condition">
</tb-alarm-rule-condition> </tb-alarm-rule-condition>
<section class="row"> <section formGroupName="spec" class="row">
<div formGroupName="spec"> <mat-form-field class="mat-block" hideRequiredMarker>
<mat-form-field class="mat-block" hideRequiredMarker> <mat-label translate>device-profile.condition-type</mat-label>
<mat-label translate>device-profile.condition-type</mat-label> <mat-select formControlName="type" required>
<mat-select formControlName="type" required> <mat-option *ngFor="let alarmConditionType of alarmConditionTypes" [value]="alarmConditionType">
<mat-option *ngFor="let alarmConditionType of alarmConditionTypes" [value]="alarmConditionType"> {{ alarmConditionTypeTranslation.get(alarmConditionType) | translate }}
{{ alarmConditionTypeTranslation.get(alarmConditionType) | translate }} </mat-option>
</mat-select>
<mat-error *ngIf="alarmRuleFormGroup.get('condition.spec.type').hasError('required')">
{{ 'device-profile.condition-type-required' | translate }}
</mat-error>
</mat-form-field>
<div fxLayout="row" fxLayoutGap="8px" *ngIf="alarmRuleFormGroup.get('condition.spec.type').value == AlarmConditionType.DURATION">
<mat-form-field class="mat-block" hideRequiredMarker fxFlex floatLabel="always">
<mat-label></mat-label>
<input type="number" required
step="1" min="1" max="2147483647" matInput
placeholder="{{ 'device-profile.condition-duration-value' | translate }}"
formControlName="value">
<mat-error *ngIf="alarmRuleFormGroup.get('condition.spec.value').hasError('required')">
{{ 'device-profile.condition-duration-value-required' | translate }}
</mat-error>
<mat-error *ngIf="alarmRuleFormGroup.get('condition.spec.value').hasError('min')">
{{ 'device-profile.condition-duration-value-range' | translate }}
</mat-error>
<mat-error *ngIf="alarmRuleFormGroup.get('condition.spec.value').hasError('max')">
{{ 'device-profile.condition-duration-value-range' | translate }}
</mat-error>
<mat-error *ngIf="alarmRuleFormGroup.get('condition.spec.value').hasError('pattern')">
{{ 'device-profile.condition-duration-value-pattern' | translate }}
</mat-error>
</mat-form-field>
<mat-form-field class="mat-block" hideRequiredMarker fxFlex floatLabel="always">
<mat-label></mat-label>
<mat-select formControlName="unit"
required
placeholder="{{ 'device-profile.condition-duration-time-unit' | translate }}">
<mat-option *ngFor="let timeUnit of timeUnits" [value]="timeUnit">
{{ timeUnitTranslations.get(timeUnit) | translate }}
</mat-option> </mat-option>
</mat-select> </mat-select>
<mat-error *ngIf="alarmRuleFormGroup.get('condition.spec.type').hasError('required')"> <mat-error *ngIf="alarmRuleFormGroup.get('condition.spec.unit').hasError('required')">
{{ 'device-profile.condition-type-required' | translate }} {{ 'device-profile.condition-duration-time-unit-required' | translate }}
</mat-error>
</mat-form-field>
</div>
<div fxLayout="row" fxLayoutGap="8px" *ngIf="alarmRuleFormGroup.get('condition.spec.type').value == AlarmConditionType.REPEATING">
<mat-form-field class="mat-block" hideRequiredMarker fxFlex floatLabel="always">
<mat-label></mat-label>
<input type="number" required
step="1" min="1" max="2147483647" matInput
placeholder="{{ 'device-profile.condition-repeating-value' | translate }}"
formControlName="count">
<mat-error *ngIf="alarmRuleFormGroup.get('condition.spec.count').hasError('required')">
{{ 'device-profile.condition-repeating-value-required' | translate }}
</mat-error>
<mat-error *ngIf="alarmRuleFormGroup.get('condition.spec.count').hasError('min')">
{{ 'device-profile.condition-repeating-value-range' | translate }}
</mat-error>
<mat-error *ngIf="alarmRuleFormGroup.get('condition.spec.count').hasError('max')">
{{ 'device-profile.condition-repeating-value-range' | translate }}
</mat-error>
<mat-error *ngIf="alarmRuleFormGroup.get('condition.spec.count').hasError('pattern')">
{{ 'device-profile.condition-repeating-value-pattern' | translate }}
</mat-error> </mat-error>
</mat-form-field> </mat-form-field>
<div fxLayout="row" fxLayoutGap="8px" *ngIf="alarmRuleFormGroup.get('condition.spec.type').value == AlarmConditionType.DURATION">
<mat-form-field class="mat-block" hideRequiredMarker fxFlex floatLabel="always">
<mat-label></mat-label>
<input type="number" required
step="1" min="1" max="2147483647" matInput
placeholder="{{ 'device-profile.condition-duration-value' | translate }}"
formControlName="value">
<mat-error *ngIf="alarmRuleFormGroup.get('condition.spec.value').hasError('required')">
{{ 'device-profile.condition-duration-value-required' | translate }}
</mat-error>
<mat-error *ngIf="alarmRuleFormGroup.get('condition.spec.value').hasError('min')">
{{ 'device-profile.condition-duration-value-range' | translate }}
</mat-error>
<mat-error *ngIf="alarmRuleFormGroup.get('condition.spec.value').hasError('max')">
{{ 'device-profile.condition-duration-value-range' | translate }}
</mat-error>
<mat-error *ngIf="alarmRuleFormGroup.get('condition.spec.value').hasError('pattern')">
{{ 'device-profile.condition-duration-value-pattern' | translate }}
</mat-error>
</mat-form-field>
<mat-form-field class="mat-block" hideRequiredMarker fxFlex floatLabel="always">
<mat-label></mat-label>
<mat-select formControlName="unit"
required
placeholder="{{ 'device-profile.condition-duration-time-unit' | translate }}">
<mat-option *ngFor="let timeUnit of timeUnits" [value]="timeUnit">
{{ timeUnitTranslations.get(timeUnit) | translate }}
</mat-option>
</mat-select>
<mat-error *ngIf="alarmRuleFormGroup.get('condition.spec.unit').hasError('required')">
{{ 'device-profile.condition-duration-time-unit-required' | translate }}
</mat-error>
</mat-form-field>
</div>
<div fxLayout="row" fxLayoutGap="8px" *ngIf="alarmRuleFormGroup.get('condition.spec.type').value == AlarmConditionType.REPEATING">
<mat-form-field class="mat-block" hideRequiredMarker fxFlex floatLabel="always">
<mat-label></mat-label>
<input type="number" required
step="1" min="1" max="2147483647" matInput
placeholder="{{ 'device-profile.condition-repeating-value' | translate }}"
formControlName="count">
<mat-error *ngIf="alarmRuleFormGroup.get('condition.spec.count').hasError('required')">
{{ 'device-profile.condition-repeating-value-required' | translate }}
</mat-error>
<mat-error *ngIf="alarmRuleFormGroup.get('condition.spec.count').hasError('min')">
{{ 'device-profile.condition-repeating-value-range' | translate }}
</mat-error>
<mat-error *ngIf="alarmRuleFormGroup.get('condition.spec.count').hasError('max')">
{{ 'device-profile.condition-repeating-value-range' | translate }}
</mat-error>
<mat-error *ngIf="alarmRuleFormGroup.get('condition.spec.count').hasError('pattern')">
{{ 'device-profile.condition-repeating-value-pattern' | translate }}
</mat-error>
</mat-form-field>
</div>
</div> </div>
</section> </section>
</mat-tab> </mat-tab>

9
ui-ngx/src/app/modules/home/components/profile/alarm/alarm-rule.component.ts

@ -29,6 +29,7 @@ import { AlarmConditionType, AlarmConditionTypeTranslationMap, AlarmRule } from
import { MatDialog } from '@angular/material/dialog'; import { MatDialog } from '@angular/material/dialog';
import { TimeUnit, timeUnitTranslationMap } from '@shared/models/time/time.models'; import { TimeUnit, timeUnitTranslationMap } from '@shared/models/time/time.models';
import { coerceBooleanProperty } from '@angular/cdk/coercion'; import { coerceBooleanProperty } from '@angular/cdk/coercion';
import { isDefinedAndNotNull } from '@core/utils';
@Component({ @Component({
selector: 'tb-alarm-rule', selector: 'tb-alarm-rule',
@ -117,13 +118,11 @@ export class AlarmRuleComponent implements ControlValueAccessor, OnInit, Validat
writeValue(value: AlarmRule): void { writeValue(value: AlarmRule): void {
this.modelValue = value; this.modelValue = value;
if (this.modelValue?.condition?.spec === null) { if (!isDefinedAndNotNull(this.modelValue?.condition?.spec)) {
this.modelValue.condition.spec = { this.modelValue = Object.assign({}, this.modelValue, {condition: {spec: {type: AlarmConditionType.SIMPLE}}});
type: AlarmConditionType.SIMPLE
};
} }
this.alarmRuleFormGroup.reset(this.modelValue || undefined, {emitEvent: false}); this.alarmRuleFormGroup.reset(this.modelValue || undefined, {emitEvent: false});
this.updateValidators(this.modelValue?.condition?.spec?.type); this.updateValidators(this.modelValue.condition.spec.type);
} }
public validate(c: FormControl) { public validate(c: FormControl) {

4
ui-ngx/src/app/modules/home/components/profile/alarm/device-profile-alarms.component.scss

@ -25,4 +25,8 @@
} }
} }
} }
.tb-prompt{
margin: 30px 0;
}
} }

55
ui-ngx/src/app/modules/home/components/profile/device-profile-data.component.html

@ -1,55 +0,0 @@
<!--
Copyright © 2016-2020 The Thingsboard Authors
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<div [formGroup]="deviceProfileDataFormGroup" style="padding-bottom: 16px;">
<mat-accordion multi="true">
<mat-expansion-panel *ngIf="displayProfileConfiguration" [expanded]="true">
<mat-expansion-panel-header>
<mat-panel-title>
<div translate>device-profile.profile-configuration</div>
</mat-panel-title>
</mat-expansion-panel-header>
<tb-device-profile-configuration
formControlName="configuration"
required>
</tb-device-profile-configuration>
</mat-expansion-panel>
<mat-expansion-panel *ngIf="displayTransportConfiguration" [expanded]="true">
<mat-expansion-panel-header>
<mat-panel-title>
<div translate>device-profile.transport-configuration</div>
</mat-panel-title>
</mat-expansion-panel-header>
<tb-device-profile-transport-configuration
formControlName="transportConfiguration"
required>
</tb-device-profile-transport-configuration>
</mat-expansion-panel>
<mat-expansion-panel [expanded]="true">
<mat-expansion-panel-header>
<mat-panel-title>
<div>{{'device-profile.alarm-rules-with-count' | translate:
{count: deviceProfileDataFormGroup.get('alarms').value ?
deviceProfileDataFormGroup.get('alarms').value.length : 0} }}</div>
</mat-panel-title>
</mat-expansion-panel-header>
<tb-device-profile-alarms
formControlName="alarms">
</tb-device-profile-alarms>
</mat-expansion-panel>
</mat-accordion>
</div>

110
ui-ngx/src/app/modules/home/components/profile/device-profile-data.component.ts

@ -1,110 +0,0 @@
///
/// Copyright © 2016-2020 The Thingsboard Authors
///
/// Licensed under the Apache License, Version 2.0 (the "License");
/// you may not use this file except in compliance with the License.
/// You may obtain a copy of the License at
///
/// http://www.apache.org/licenses/LICENSE-2.0
///
/// Unless required by applicable law or agreed to in writing, software
/// distributed under the License is distributed on an "AS IS" BASIS,
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
/// See the License for the specific language governing permissions and
/// limitations under the License.
///
import { Component, forwardRef, Input, OnInit } from '@angular/core';
import { ControlValueAccessor, FormBuilder, FormGroup, NG_VALUE_ACCESSOR, Validators } from '@angular/forms';
import { Store } from '@ngrx/store';
import { AppState } from '@app/core/core.state';
import { coerceBooleanProperty } from '@angular/cdk/coercion';
import {
DeviceProfileData,
DeviceProfileType,
deviceProfileTypeConfigurationInfoMap,
DeviceTransportType, deviceTransportTypeConfigurationInfoMap
} from '@shared/models/device.models';
@Component({
selector: 'tb-device-profile-data',
templateUrl: './device-profile-data.component.html',
styleUrls: [],
providers: [{
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => DeviceProfileDataComponent),
multi: true
}]
})
export class DeviceProfileDataComponent implements ControlValueAccessor, OnInit {
deviceProfileDataFormGroup: FormGroup;
private requiredValue: boolean;
get required(): boolean {
return this.requiredValue;
}
@Input()
set required(value: boolean) {
this.requiredValue = coerceBooleanProperty(value);
}
@Input()
disabled: boolean;
displayProfileConfiguration: boolean;
displayTransportConfiguration: boolean;
private propagateChange = (v: any) => { };
constructor(private store: Store<AppState>,
private fb: FormBuilder) {
}
registerOnChange(fn: any): void {
this.propagateChange = fn;
}
registerOnTouched(fn: any): void {
}
ngOnInit() {
this.deviceProfileDataFormGroup = this.fb.group({
configuration: [null, Validators.required],
transportConfiguration: [null, Validators.required],
alarms: [null]
});
this.deviceProfileDataFormGroup.valueChanges.subscribe(() => {
this.updateModel();
});
}
setDisabledState(isDisabled: boolean): void {
this.disabled = isDisabled;
if (this.disabled) {
this.deviceProfileDataFormGroup.disable({emitEvent: false});
} else {
this.deviceProfileDataFormGroup.enable({emitEvent: false});
}
}
writeValue(value: DeviceProfileData | null): void {
const deviceProfileType = value?.configuration?.type;
this.displayProfileConfiguration = deviceProfileType &&
deviceProfileTypeConfigurationInfoMap.get(deviceProfileType).hasProfileConfiguration;
const deviceTransportType = value?.transportConfiguration?.type;
this.displayTransportConfiguration = deviceTransportType &&
deviceTransportTypeConfigurationInfoMap.get(deviceTransportType).hasProfileConfiguration;
this.deviceProfileDataFormGroup.patchValue({configuration: value?.configuration}, {emitEvent: false});
this.deviceProfileDataFormGroup.patchValue({transportConfiguration: value?.transportConfiguration}, {emitEvent: false});
this.deviceProfileDataFormGroup.patchValue({alarms: value?.alarms}, {emitEvent: false});
}
private updateModel() {
let deviceProfileData: DeviceProfileData = null;
if (this.deviceProfileDataFormGroup.valid) {
deviceProfileData = this.deviceProfileDataFormGroup.getRawValue();
}
this.propagateChange(deviceProfileData);
}
}

17
ui-ngx/src/app/modules/home/components/profile/device-profile.component.html

@ -53,7 +53,7 @@
labelText="device-profile.default-rule-chain" labelText="device-profile.default-rule-chain"
formControlName="defaultRuleChainId"> formControlName="defaultRuleChainId">
</tb-rule-chain-autocomplete> </tb-rule-chain-autocomplete>
<mat-form-field class="mat-block"> <mat-form-field fxHide class="mat-block">
<mat-label translate>device-profile.type</mat-label> <mat-label translate>device-profile.type</mat-label>
<mat-select formControlName="type" required> <mat-select formControlName="type" required>
<mat-option *ngFor="let type of deviceProfileTypes" [value]="type"> <mat-option *ngFor="let type of deviceProfileTypes" [value]="type">
@ -64,21 +64,6 @@
{{ 'device-profile.type-required' | translate }} {{ 'device-profile.type-required' | translate }}
</mat-error> </mat-error>
</mat-form-field> </mat-form-field>
<mat-form-field class="mat-block">
<mat-label translate>device-profile.transport-type</mat-label>
<mat-select formControlName="transportType" required>
<mat-option *ngFor="let type of deviceTransportTypes" [value]="type">
{{deviceTransportTypeTranslations.get(type) | translate}}
</mat-option>
</mat-select>
<mat-error *ngIf="entityForm.get('transportType').hasError('required')">
{{ 'device-profile.transport-type-required' | translate }}
</mat-error>
</mat-form-field>
<tb-device-profile-data
formControlName="profileData"
required>
</tb-device-profile-data>
<mat-form-field class="mat-block"> <mat-form-field class="mat-block">
<mat-label translate>device-profile.description</mat-label> <mat-label translate>device-profile.description</mat-label>
<textarea matInput formControlName="description" rows="2"></textarea> <textarea matInput formControlName="description" rows="2"></textarea>

6
ui-ngx/src/app/modules/home/components/profile/device-profile.component.ts

@ -77,7 +77,11 @@ export class DeviceProfileComponent extends EntityComponent<DeviceProfile> {
name: [entity ? entity.name : '', [Validators.required]], name: [entity ? entity.name : '', [Validators.required]],
type: [entity ? entity.type : null, [Validators.required]], type: [entity ? entity.type : null, [Validators.required]],
transportType: [entity ? entity.transportType : null, [Validators.required]], transportType: [entity ? entity.transportType : null, [Validators.required]],
profileData: [entity && !this.isAdd ? entity.profileData : {}, []], profileData: this.fb.group({
configuration: [entity && !this.isAdd ? entity.profileData?.configuration : {}, Validators.required],
transportConfiguration: [entity && !this.isAdd ? entity.profileData?.transportConfiguration : {}, Validators.required],
alarms: [entity && !this.isAdd ? entity.profileData?.alarms : []]
}),
defaultRuleChainId: [entity && entity.defaultRuleChainId ? entity.defaultRuleChainId.id : null, []], defaultRuleChainId: [entity && entity.defaultRuleChainId ? entity.defaultRuleChainId.id : null, []],
description: [entity ? entity.description : '', []], description: [entity ? entity.description : '', []],
} }

6
ui-ngx/src/app/modules/home/components/profile/device/default-device-profile-configuration.component.html

@ -16,9 +16,5 @@
--> -->
<form [formGroup]="defaultDeviceProfileConfigurationFormGroup" style="padding-bottom: 16px;"> <form [formGroup]="defaultDeviceProfileConfigurationFormGroup" style="padding-bottom: 16px;">
<tb-json-object-edit
[required]="required"
label="{{ 'device-profile.type-default' | translate }}"
formControlName="configuration">
</tb-json-object-edit>
</form> </form>

6
ui-ngx/src/app/modules/home/components/profile/device/default-device-profile-transport-configuration.component.html

@ -16,9 +16,5 @@
--> -->
<form [formGroup]="defaultDeviceProfileTransportConfigurationFormGroup" style="padding-bottom: 16px;"> <form [formGroup]="defaultDeviceProfileTransportConfigurationFormGroup" style="padding-bottom: 16px;">
<tb-json-object-edit
[required]="required"
label="{{ 'device-profile.transport-type-default' | translate }}"
formControlName="configuration">
</tb-json-object-edit>
</form> </form>

2
ui-ngx/src/app/modules/home/components/profile/device/lwm2m-device-profile-transport-configuration.component.ts

@ -89,7 +89,7 @@ export class Lwm2mDeviceProfileTransportConfigurationComponent implements Contro
let configuration: DeviceProfileTransportConfiguration = null; let configuration: DeviceProfileTransportConfiguration = null;
if (this.lwm2mDeviceProfileTransportConfigurationFormGroup.valid) { if (this.lwm2mDeviceProfileTransportConfigurationFormGroup.valid) {
configuration = this.lwm2mDeviceProfileTransportConfigurationFormGroup.getRawValue().configuration; configuration = this.lwm2mDeviceProfileTransportConfigurationFormGroup.getRawValue().configuration;
configuration.type = DeviceTransportType.LWM2M; // configuration.type = DeviceTransportType.LWM2M;
} }
this.propagateChange(configuration); this.propagateChange(configuration);
} }

49
ui-ngx/src/app/modules/home/pages/device-profile/device-profile-tabs.component.html

@ -16,6 +16,49 @@
--> -->
<mat-tab *ngIf="entity" <mat-tab *ngIf="entity"
label="{{ 'device-profile.transport-configuration' | translate }}" #transportType="matTab">
<div class="mat-padding" [formGroup]="detailsForm">
<mat-form-field class="mat-block">
<mat-label translate>device-profile.transport-type</mat-label>
<mat-select formControlName="transportType" required>
<mat-option *ngFor="let type of deviceTransportTypes" [value]="type">
{{deviceTransportTypeTranslations.get(type) | translate}}
</mat-option>
</mat-select>
<mat-error *ngIf="detailsForm.get('transportType').hasError('required')">
{{ 'device-profile.transport-type-required' | translate }}
</mat-error>
</mat-form-field>
<div formGroupName="profileData">
<tb-device-profile-transport-configuration
formControlName="transportConfiguration"
required>
</tb-device-profile-transport-configuration>
</div>
</div>
</mat-tab>
<mat-tab *ngIf="entity"
label="{{'device-profile.alarm-rules' | translate:
{count: entity.profileData.alarms.length ?
entity.profileData.alarms.length : 0} }}" #alarmRules="matTab">
<div class="mat-padding" [formGroup]="detailsForm">
<div formGroupName="profileData">
<tb-device-profile-alarms formControlName="alarms"></tb-device-profile-alarms>
</div>
</div>
</mat-tab>
<mat-tab *ngIf="false"
label="{{'device-profile.profile-configuration' | translate }}" #deviceProfile="matTab">
<div class="mat-padding" [formGroup]="detailsForm">
<div formGroupName="profileData">
<tb-device-profile-configuration
formControlName="configuration"
required>
</tb-device-profile-configuration>
</div>
</div>
</mat-tab>
<mat-tab *ngIf="entity && !isEdit"
label="{{ 'attribute.attributes' | translate }}" #attributesTab="matTab"> label="{{ 'attribute.attributes' | translate }}" #attributesTab="matTab">
<tb-attribute-table [defaultAttributeScope]="attributeScopes.SERVER_SCOPE" <tb-attribute-table [defaultAttributeScope]="attributeScopes.SERVER_SCOPE"
[active]="attributesTab.isActive" [active]="attributesTab.isActive"
@ -23,7 +66,7 @@
[entityName]="entity.name"> [entityName]="entity.name">
</tb-attribute-table> </tb-attribute-table>
</mat-tab> </mat-tab>
<mat-tab *ngIf="entity" <mat-tab *ngIf="entity && !isEdit"
label="{{ 'attribute.latest-telemetry' | translate }}" #telemetryTab="matTab"> label="{{ 'attribute.latest-telemetry' | translate }}" #telemetryTab="matTab">
<tb-attribute-table [defaultAttributeScope]="latestTelemetryTypes.LATEST_TELEMETRY" <tb-attribute-table [defaultAttributeScope]="latestTelemetryTypes.LATEST_TELEMETRY"
disableAttributeScopeSelection disableAttributeScopeSelection
@ -32,11 +75,11 @@
[entityName]="entity.name"> [entityName]="entity.name">
</tb-attribute-table> </tb-attribute-table>
</mat-tab> </mat-tab>
<mat-tab *ngIf="entity" <mat-tab *ngIf="entity && !isEdit"
label="{{ 'alarm.alarms' | translate }}" #alarmsTab="matTab"> label="{{ 'alarm.alarms' | translate }}" #alarmsTab="matTab">
<tb-alarm-table [active]="alarmsTab.isActive" [entityId]="entity.id"></tb-alarm-table> <tb-alarm-table [active]="alarmsTab.isActive" [entityId]="entity.id"></tb-alarm-table>
</mat-tab> </mat-tab>
<mat-tab *ngIf="entity" <mat-tab *ngIf="entity && !isEdit"
label="{{ 'tenant.events' | translate }}" #eventsTab="matTab"> label="{{ 'tenant.events' | translate }}" #eventsTab="matTab">
<tb-event-table [defaultEventType]="eventTypes.ERROR" [active]="eventsTab.isActive" [tenantId]="nullUid" <tb-event-table [defaultEventType]="eventTypes.ERROR" [active]="eventsTab.isActive" [tenantId]="nullUid"
[entityId]="entity.id"></tb-event-table> [entityId]="entity.id"></tb-event-table>

5
ui-ngx/src/app/modules/home/pages/device-profile/device-profile-tabs.component.ts

@ -18,7 +18,7 @@ import { Component } 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 { EntityTabsComponent } from '../../components/entity/entity-tabs.component'; import { EntityTabsComponent } from '../../components/entity/entity-tabs.component';
import { DeviceProfile } from '@shared/models/device.models'; import { DeviceProfile, DeviceTransportType, deviceTransportTypeTranslationMap } from '@shared/models/device.models';
@Component({ @Component({
selector: 'tb-device-profile-tabs', selector: 'tb-device-profile-tabs',
@ -27,6 +27,9 @@ import { DeviceProfile } from '@shared/models/device.models';
}) })
export class DeviceProfileTabsComponent extends EntityTabsComponent<DeviceProfile> { export class DeviceProfileTabsComponent extends EntityTabsComponent<DeviceProfile> {
deviceTransportTypes = Object.keys(DeviceTransportType);
deviceTransportTypeTranslations = deviceTransportTypeTranslationMap;
constructor(protected store: Store<AppState>) { constructor(protected store: Store<AppState>) {
super(store); super(store);
} }

2
ui-ngx/src/app/modules/home/pages/device-profile/device-profiles-table-config.resolver.ts

@ -59,6 +59,8 @@ export class DeviceProfilesTableConfigResolver implements Resolve<EntityTableCon
this.config.entityTranslations = entityTypeTranslations.get(EntityType.DEVICE_PROFILE); this.config.entityTranslations = entityTypeTranslations.get(EntityType.DEVICE_PROFILE);
this.config.entityResources = entityTypeResources.get(EntityType.DEVICE_PROFILE); this.config.entityResources = entityTypeResources.get(EntityType.DEVICE_PROFILE);
this.config.hideDetailsTabsOnEdit = false;
this.config.addDialogStyle = {width: '1000px'}; this.config.addDialogStyle = {width: '1000px'};
this.config.columns.push( this.config.columns.push(

2
ui-ngx/src/app/modules/home/pages/device/data/lwm2m-device-transport-configuration.component.ts

@ -89,7 +89,7 @@ export class Lwm2mDeviceTransportConfigurationComponent implements ControlValueA
let configuration: DeviceTransportConfiguration = null; let configuration: DeviceTransportConfiguration = null;
if (this.lwm2mDeviceTransportConfigurationFormGroup.valid) { if (this.lwm2mDeviceTransportConfigurationFormGroup.valid) {
configuration = this.lwm2mDeviceTransportConfigurationFormGroup.getRawValue().configuration; configuration = this.lwm2mDeviceTransportConfigurationFormGroup.getRawValue().configuration;
configuration.type = DeviceTransportType.LWM2M; // configuration.type = DeviceTransportType.LWM2M;
} }
this.propagateChange(configuration); this.propagateChange(configuration);
} }

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

@ -33,7 +33,7 @@ export enum DeviceProfileType {
export enum DeviceTransportType { export enum DeviceTransportType {
DEFAULT = 'DEFAULT', DEFAULT = 'DEFAULT',
MQTT = 'MQTT', MQTT = 'MQTT',
LWM2M = 'LWM2M' // LWM2M = 'LWM2M'
} }
export enum MqttTransportPayloadType { export enum MqttTransportPayloadType {
@ -68,7 +68,7 @@ export const deviceTransportTypeTranslationMap = new Map<DeviceTransportType, st
[ [
[DeviceTransportType.DEFAULT, 'device-profile.transport-type-default'], [DeviceTransportType.DEFAULT, 'device-profile.transport-type-default'],
[DeviceTransportType.MQTT, 'device-profile.transport-type-mqtt'], [DeviceTransportType.MQTT, 'device-profile.transport-type-mqtt'],
[DeviceTransportType.LWM2M, 'device-profile.transport-type-lwm2m'] // [DeviceTransportType.LWM2M, 'device-profile.transport-type-lwm2m']
] ]
); );
@ -104,13 +104,13 @@ export const deviceTransportTypeConfigurationInfoMap = new Map<DeviceTransportTy
hasDeviceConfiguration: true, hasDeviceConfiguration: true,
} }
], ],
[ // [
DeviceTransportType.LWM2M, // DeviceTransportType.LWM2M,
{ // {
hasProfileConfiguration: true, // hasProfileConfiguration: true,
hasDeviceConfiguration: true, // hasDeviceConfiguration: true,
} // }
] // ]
] ]
); );
@ -188,10 +188,10 @@ export function createDeviceProfileTransportConfiguration(type: DeviceTransportT
}; };
transportConfiguration = {...mqttTransportConfiguration, type: DeviceTransportType.MQTT}; transportConfiguration = {...mqttTransportConfiguration, type: DeviceTransportType.MQTT};
break; break;
case DeviceTransportType.LWM2M: // case DeviceTransportType.LWM2M:
const lwm2mTransportConfiguration: Lwm2mDeviceProfileTransportConfiguration = {}; // const lwm2mTransportConfiguration: Lwm2mDeviceProfileTransportConfiguration = {};
transportConfiguration = {...lwm2mTransportConfiguration, type: DeviceTransportType.LWM2M}; // transportConfiguration = {...lwm2mTransportConfiguration, type: DeviceTransportType.LWM2M};
break; // break;
} }
} }
return transportConfiguration; return transportConfiguration;
@ -209,10 +209,10 @@ export function createDeviceTransportConfiguration(type: DeviceTransportType): D
const mqttTransportConfiguration: MqttDeviceTransportConfiguration = {}; const mqttTransportConfiguration: MqttDeviceTransportConfiguration = {};
transportConfiguration = {...mqttTransportConfiguration, type: DeviceTransportType.MQTT}; transportConfiguration = {...mqttTransportConfiguration, type: DeviceTransportType.MQTT};
break; break;
case DeviceTransportType.LWM2M: // case DeviceTransportType.LWM2M:
const lwm2mTransportConfiguration: Lwm2mDeviceTransportConfiguration = {}; // const lwm2mTransportConfiguration: Lwm2mDeviceTransportConfiguration = {};
transportConfiguration = {...lwm2mTransportConfiguration, type: DeviceTransportType.LWM2M}; // transportConfiguration = {...lwm2mTransportConfiguration, type: DeviceTransportType.LWM2M};
break; // break;
} }
} }
return transportConfiguration; return transportConfiguration;

Loading…
Cancel
Save