Commit 30a6a462da5d42a63c2a1e4f56f27f7f53cf1175
1 parent
c7b57ca5
UI: Improvement view device profile settings
Showing
20 changed files
with
152 additions
and
290 deletions
... | ... | @@ -76,7 +76,6 @@ |
76 | 76 | type="button" |
77 | 77 | matTooltip="{{ (dynamicMode ? 'filter.switch-to-default-value' : 'filter.switch-to-dynamic-value') | translate }}" |
78 | 78 | matTooltipPosition="above" |
79 | - *ngIf="allow" | |
80 | 79 | (click)="dynamicMode = !dynamicMode"> |
81 | 80 | <mat-icon class="tb-mat-20" [svgIcon]="dynamicMode ? 'mdi:numeric' : 'mdi:variable'"></mat-icon> |
82 | 81 | </button> | ... | ... |
... | ... | @@ -54,7 +54,7 @@ export class FilterPredicateValueComponent implements ControlValueAccessor, OnIn |
54 | 54 | if (allow) { |
55 | 55 | this.dynamicValueSourceTypes.push(DynamicValueSourceType.CURRENT_USER); |
56 | 56 | } else { |
57 | - this.dynamicValueSourceTypes.push(DynamicValueSourceType.CURRENT_DEVICE); | |
57 | + this.dynamicValueSourceTypes = [DynamicValueSourceType.CURRENT_DEVICE]; | |
58 | 58 | } |
59 | 59 | } |
60 | 60 | ... | ... |
... | ... | @@ -90,7 +90,6 @@ import { TenantProfileDialogComponent } from './profile/tenant-profile-dialog.co |
90 | 90 | import { TenantProfileDataComponent } from './profile/tenant-profile-data.component'; |
91 | 91 | import { DefaultDeviceProfileConfigurationComponent } from './profile/device/default-device-profile-configuration.component'; |
92 | 92 | import { DeviceProfileConfigurationComponent } from './profile/device/device-profile-configuration.component'; |
93 | -import { DeviceProfileDataComponent } from './profile/device-profile-data.component'; | |
94 | 93 | import { DeviceProfileComponent } from './profile/device-profile.component'; |
95 | 94 | import { DefaultDeviceProfileTransportConfigurationComponent } from './profile/device/default-device-profile-transport-configuration.component'; |
96 | 95 | import { DeviceProfileTransportConfigurationComponent } from './profile/device/device-profile-transport-configuration.component'; |
... | ... | @@ -195,7 +194,6 @@ import { DeviceCredentialsComponent } from './device/device-credentials.componen |
195 | 194 | AlarmRuleConditionComponent, |
196 | 195 | DeviceProfileAlarmComponent, |
197 | 196 | DeviceProfileAlarmsComponent, |
198 | - DeviceProfileDataComponent, | |
199 | 197 | DeviceProfileComponent, |
200 | 198 | DeviceProfileDialogComponent, |
201 | 199 | AddDeviceProfileDialogComponent, |
... | ... | @@ -277,7 +275,6 @@ import { DeviceCredentialsComponent } from './device/device-credentials.componen |
277 | 275 | AlarmRuleConditionComponent, |
278 | 276 | DeviceProfileAlarmComponent, |
279 | 277 | DeviceProfileAlarmsComponent, |
280 | - DeviceProfileDataComponent, | |
281 | 278 | DeviceProfileComponent, |
282 | 279 | DeviceProfileDialogComponent, |
283 | 280 | AddDeviceProfileDialogComponent, | ... | ... |
... | ... | @@ -45,7 +45,7 @@ |
45 | 45 | labelText="device-profile.default-rule-chain" |
46 | 46 | formControlName="defaultRuleChainId"> |
47 | 47 | </tb-rule-chain-autocomplete> |
48 | - <mat-form-field class="mat-block"> | |
48 | + <mat-form-field fxHide class="mat-block"> | |
49 | 49 | <mat-label translate>device-profile.type</mat-label> |
50 | 50 | <mat-select formControlName="type" required> |
51 | 51 | <mat-option *ngFor="let type of deviceProfileTypes" [value]="type"> | ... | ... |
... | ... | @@ -21,74 +21,72 @@ |
21 | 21 | <tb-alarm-rule-condition fxFlex class="row" |
22 | 22 | formControlName="condition"> |
23 | 23 | </tb-alarm-rule-condition> |
24 | - <section class="row"> | |
25 | - <div formGroupName="spec"> | |
26 | - <mat-form-field class="mat-block" hideRequiredMarker> | |
27 | - <mat-label translate>device-profile.condition-type</mat-label> | |
28 | - <mat-select formControlName="type" required> | |
29 | - <mat-option *ngFor="let alarmConditionType of alarmConditionTypes" [value]="alarmConditionType"> | |
30 | - {{ alarmConditionTypeTranslation.get(alarmConditionType) | translate }} | |
24 | + <section formGroupName="spec" class="row"> | |
25 | + <mat-form-field class="mat-block" hideRequiredMarker> | |
26 | + <mat-label translate>device-profile.condition-type</mat-label> | |
27 | + <mat-select formControlName="type" required> | |
28 | + <mat-option *ngFor="let alarmConditionType of alarmConditionTypes" [value]="alarmConditionType"> | |
29 | + {{ alarmConditionTypeTranslation.get(alarmConditionType) | translate }} | |
30 | + </mat-option> | |
31 | + </mat-select> | |
32 | + <mat-error *ngIf="alarmRuleFormGroup.get('condition.spec.type').hasError('required')"> | |
33 | + {{ 'device-profile.condition-type-required' | translate }} | |
34 | + </mat-error> | |
35 | + </mat-form-field> | |
36 | + <div fxLayout="row" fxLayoutGap="8px" *ngIf="alarmRuleFormGroup.get('condition.spec.type').value == AlarmConditionType.DURATION"> | |
37 | + <mat-form-field class="mat-block" hideRequiredMarker fxFlex floatLabel="always"> | |
38 | + <mat-label></mat-label> | |
39 | + <input type="number" required | |
40 | + step="1" min="1" max="2147483647" matInput | |
41 | + placeholder="{{ 'device-profile.condition-duration-value' | translate }}" | |
42 | + formControlName="value"> | |
43 | + <mat-error *ngIf="alarmRuleFormGroup.get('condition.spec.value').hasError('required')"> | |
44 | + {{ 'device-profile.condition-duration-value-required' | translate }} | |
45 | + </mat-error> | |
46 | + <mat-error *ngIf="alarmRuleFormGroup.get('condition.spec.value').hasError('min')"> | |
47 | + {{ 'device-profile.condition-duration-value-range' | translate }} | |
48 | + </mat-error> | |
49 | + <mat-error *ngIf="alarmRuleFormGroup.get('condition.spec.value').hasError('max')"> | |
50 | + {{ 'device-profile.condition-duration-value-range' | translate }} | |
51 | + </mat-error> | |
52 | + <mat-error *ngIf="alarmRuleFormGroup.get('condition.spec.value').hasError('pattern')"> | |
53 | + {{ 'device-profile.condition-duration-value-pattern' | translate }} | |
54 | + </mat-error> | |
55 | + </mat-form-field> | |
56 | + <mat-form-field class="mat-block" hideRequiredMarker fxFlex floatLabel="always"> | |
57 | + <mat-label></mat-label> | |
58 | + <mat-select formControlName="unit" | |
59 | + required | |
60 | + placeholder="{{ 'device-profile.condition-duration-time-unit' | translate }}"> | |
61 | + <mat-option *ngFor="let timeUnit of timeUnits" [value]="timeUnit"> | |
62 | + {{ timeUnitTranslations.get(timeUnit) | translate }} | |
31 | 63 | </mat-option> |
32 | 64 | </mat-select> |
33 | - <mat-error *ngIf="alarmRuleFormGroup.get('condition.spec.type').hasError('required')"> | |
34 | - {{ 'device-profile.condition-type-required' | translate }} | |
65 | + <mat-error *ngIf="alarmRuleFormGroup.get('condition.spec.unit').hasError('required')"> | |
66 | + {{ 'device-profile.condition-duration-time-unit-required' | translate }} | |
67 | + </mat-error> | |
68 | + </mat-form-field> | |
69 | + </div> | |
70 | + <div fxLayout="row" fxLayoutGap="8px" *ngIf="alarmRuleFormGroup.get('condition.spec.type').value == AlarmConditionType.REPEATING"> | |
71 | + <mat-form-field class="mat-block" hideRequiredMarker fxFlex floatLabel="always"> | |
72 | + <mat-label></mat-label> | |
73 | + <input type="number" required | |
74 | + step="1" min="1" max="2147483647" matInput | |
75 | + placeholder="{{ 'device-profile.condition-repeating-value' | translate }}" | |
76 | + formControlName="count"> | |
77 | + <mat-error *ngIf="alarmRuleFormGroup.get('condition.spec.count').hasError('required')"> | |
78 | + {{ 'device-profile.condition-repeating-value-required' | translate }} | |
79 | + </mat-error> | |
80 | + <mat-error *ngIf="alarmRuleFormGroup.get('condition.spec.count').hasError('min')"> | |
81 | + {{ 'device-profile.condition-repeating-value-range' | translate }} | |
82 | + </mat-error> | |
83 | + <mat-error *ngIf="alarmRuleFormGroup.get('condition.spec.count').hasError('max')"> | |
84 | + {{ 'device-profile.condition-repeating-value-range' | translate }} | |
85 | + </mat-error> | |
86 | + <mat-error *ngIf="alarmRuleFormGroup.get('condition.spec.count').hasError('pattern')"> | |
87 | + {{ 'device-profile.condition-repeating-value-pattern' | translate }} | |
35 | 88 | </mat-error> |
36 | 89 | </mat-form-field> |
37 | - <div fxLayout="row" fxLayoutGap="8px" *ngIf="alarmRuleFormGroup.get('condition.spec.type').value == AlarmConditionType.DURATION"> | |
38 | - <mat-form-field class="mat-block" hideRequiredMarker fxFlex floatLabel="always"> | |
39 | - <mat-label></mat-label> | |
40 | - <input type="number" required | |
41 | - step="1" min="1" max="2147483647" matInput | |
42 | - placeholder="{{ 'device-profile.condition-duration-value' | translate }}" | |
43 | - formControlName="value"> | |
44 | - <mat-error *ngIf="alarmRuleFormGroup.get('condition.spec.value').hasError('required')"> | |
45 | - {{ 'device-profile.condition-duration-value-required' | translate }} | |
46 | - </mat-error> | |
47 | - <mat-error *ngIf="alarmRuleFormGroup.get('condition.spec.value').hasError('min')"> | |
48 | - {{ 'device-profile.condition-duration-value-range' | translate }} | |
49 | - </mat-error> | |
50 | - <mat-error *ngIf="alarmRuleFormGroup.get('condition.spec.value').hasError('max')"> | |
51 | - {{ 'device-profile.condition-duration-value-range' | translate }} | |
52 | - </mat-error> | |
53 | - <mat-error *ngIf="alarmRuleFormGroup.get('condition.spec.value').hasError('pattern')"> | |
54 | - {{ 'device-profile.condition-duration-value-pattern' | translate }} | |
55 | - </mat-error> | |
56 | - </mat-form-field> | |
57 | - <mat-form-field class="mat-block" hideRequiredMarker fxFlex floatLabel="always"> | |
58 | - <mat-label></mat-label> | |
59 | - <mat-select formControlName="unit" | |
60 | - required | |
61 | - placeholder="{{ 'device-profile.condition-duration-time-unit' | translate }}"> | |
62 | - <mat-option *ngFor="let timeUnit of timeUnits" [value]="timeUnit"> | |
63 | - {{ timeUnitTranslations.get(timeUnit) | translate }} | |
64 | - </mat-option> | |
65 | - </mat-select> | |
66 | - <mat-error *ngIf="alarmRuleFormGroup.get('condition.spec.unit').hasError('required')"> | |
67 | - {{ 'device-profile.condition-duration-time-unit-required' | translate }} | |
68 | - </mat-error> | |
69 | - </mat-form-field> | |
70 | - </div> | |
71 | - <div fxLayout="row" fxLayoutGap="8px" *ngIf="alarmRuleFormGroup.get('condition.spec.type').value == AlarmConditionType.REPEATING"> | |
72 | - <mat-form-field class="mat-block" hideRequiredMarker fxFlex floatLabel="always"> | |
73 | - <mat-label></mat-label> | |
74 | - <input type="number" required | |
75 | - step="1" min="1" max="2147483647" matInput | |
76 | - placeholder="{{ 'device-profile.condition-repeating-value' | translate }}" | |
77 | - formControlName="count"> | |
78 | - <mat-error *ngIf="alarmRuleFormGroup.get('condition.spec.count').hasError('required')"> | |
79 | - {{ 'device-profile.condition-repeating-value-required' | translate }} | |
80 | - </mat-error> | |
81 | - <mat-error *ngIf="alarmRuleFormGroup.get('condition.spec.count').hasError('min')"> | |
82 | - {{ 'device-profile.condition-repeating-value-range' | translate }} | |
83 | - </mat-error> | |
84 | - <mat-error *ngIf="alarmRuleFormGroup.get('condition.spec.count').hasError('max')"> | |
85 | - {{ 'device-profile.condition-repeating-value-range' | translate }} | |
86 | - </mat-error> | |
87 | - <mat-error *ngIf="alarmRuleFormGroup.get('condition.spec.count').hasError('pattern')"> | |
88 | - {{ 'device-profile.condition-repeating-value-pattern' | translate }} | |
89 | - </mat-error> | |
90 | - </mat-form-field> | |
91 | - </div> | |
92 | 90 | </div> |
93 | 91 | </section> |
94 | 92 | </mat-tab> | ... | ... |
... | ... | @@ -29,6 +29,7 @@ import { AlarmConditionType, AlarmConditionTypeTranslationMap, AlarmRule } from |
29 | 29 | import { MatDialog } from '@angular/material/dialog'; |
30 | 30 | import { TimeUnit, timeUnitTranslationMap } from '@shared/models/time/time.models'; |
31 | 31 | import { coerceBooleanProperty } from '@angular/cdk/coercion'; |
32 | +import { isDefinedAndNotNull } from '@core/utils'; | |
32 | 33 | |
33 | 34 | @Component({ |
34 | 35 | selector: 'tb-alarm-rule', |
... | ... | @@ -117,13 +118,11 @@ export class AlarmRuleComponent implements ControlValueAccessor, OnInit, Validat |
117 | 118 | |
118 | 119 | writeValue(value: AlarmRule): void { |
119 | 120 | this.modelValue = value; |
120 | - if (this.modelValue?.condition?.spec === null) { | |
121 | - this.modelValue.condition.spec = { | |
122 | - type: AlarmConditionType.SIMPLE | |
123 | - }; | |
121 | + if (!isDefinedAndNotNull(this.modelValue?.condition?.spec)) { | |
122 | + this.modelValue = Object.assign({}, this.modelValue, {condition: {spec: {type: AlarmConditionType.SIMPLE}}}); | |
124 | 123 | } |
125 | 124 | this.alarmRuleFormGroup.reset(this.modelValue || undefined, {emitEvent: false}); |
126 | - this.updateValidators(this.modelValue?.condition?.spec?.type); | |
125 | + this.updateValidators(this.modelValue.condition.spec.type); | |
127 | 126 | } |
128 | 127 | |
129 | 128 | public validate(c: FormControl) { | ... | ... |
1 | -<!-- | |
2 | - | |
3 | - Copyright © 2016-2020 The Thingsboard Authors | |
4 | - | |
5 | - Licensed under the Apache License, Version 2.0 (the "License"); | |
6 | - you may not use this file except in compliance with the License. | |
7 | - You may obtain a copy of the License at | |
8 | - | |
9 | - http://www.apache.org/licenses/LICENSE-2.0 | |
10 | - | |
11 | - Unless required by applicable law or agreed to in writing, software | |
12 | - distributed under the License is distributed on an "AS IS" BASIS, | |
13 | - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
14 | - See the License for the specific language governing permissions and | |
15 | - limitations under the License. | |
16 | - | |
17 | ---> | |
18 | -<div [formGroup]="deviceProfileDataFormGroup" style="padding-bottom: 16px;"> | |
19 | - <mat-accordion multi="true"> | |
20 | - <mat-expansion-panel *ngIf="displayProfileConfiguration" [expanded]="true"> | |
21 | - <mat-expansion-panel-header> | |
22 | - <mat-panel-title> | |
23 | - <div translate>device-profile.profile-configuration</div> | |
24 | - </mat-panel-title> | |
25 | - </mat-expansion-panel-header> | |
26 | - <tb-device-profile-configuration | |
27 | - formControlName="configuration" | |
28 | - required> | |
29 | - </tb-device-profile-configuration> | |
30 | - </mat-expansion-panel> | |
31 | - <mat-expansion-panel *ngIf="displayTransportConfiguration" [expanded]="true"> | |
32 | - <mat-expansion-panel-header> | |
33 | - <mat-panel-title> | |
34 | - <div translate>device-profile.transport-configuration</div> | |
35 | - </mat-panel-title> | |
36 | - </mat-expansion-panel-header> | |
37 | - <tb-device-profile-transport-configuration | |
38 | - formControlName="transportConfiguration" | |
39 | - required> | |
40 | - </tb-device-profile-transport-configuration> | |
41 | - </mat-expansion-panel> | |
42 | - <mat-expansion-panel [expanded]="true"> | |
43 | - <mat-expansion-panel-header> | |
44 | - <mat-panel-title> | |
45 | - <div>{{'device-profile.alarm-rules-with-count' | translate: | |
46 | - {count: deviceProfileDataFormGroup.get('alarms').value ? | |
47 | - deviceProfileDataFormGroup.get('alarms').value.length : 0} }}</div> | |
48 | - </mat-panel-title> | |
49 | - </mat-expansion-panel-header> | |
50 | - <tb-device-profile-alarms | |
51 | - formControlName="alarms"> | |
52 | - </tb-device-profile-alarms> | |
53 | - </mat-expansion-panel> | |
54 | - </mat-accordion> | |
55 | -</div> |
1 | -/// | |
2 | -/// Copyright © 2016-2020 The Thingsboard Authors | |
3 | -/// | |
4 | -/// Licensed under the Apache License, Version 2.0 (the "License"); | |
5 | -/// you may not use this file except in compliance with the License. | |
6 | -/// You may obtain a copy of the License at | |
7 | -/// | |
8 | -/// http://www.apache.org/licenses/LICENSE-2.0 | |
9 | -/// | |
10 | -/// Unless required by applicable law or agreed to in writing, software | |
11 | -/// distributed under the License is distributed on an "AS IS" BASIS, | |
12 | -/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
13 | -/// See the License for the specific language governing permissions and | |
14 | -/// limitations under the License. | |
15 | -/// | |
16 | - | |
17 | -import { Component, forwardRef, Input, OnInit } from '@angular/core'; | |
18 | -import { ControlValueAccessor, FormBuilder, FormGroup, NG_VALUE_ACCESSOR, Validators } from '@angular/forms'; | |
19 | -import { Store } from '@ngrx/store'; | |
20 | -import { AppState } from '@app/core/core.state'; | |
21 | -import { coerceBooleanProperty } from '@angular/cdk/coercion'; | |
22 | -import { | |
23 | - DeviceProfileData, | |
24 | - DeviceProfileType, | |
25 | - deviceProfileTypeConfigurationInfoMap, | |
26 | - DeviceTransportType, deviceTransportTypeConfigurationInfoMap | |
27 | -} from '@shared/models/device.models'; | |
28 | - | |
29 | -@Component({ | |
30 | - selector: 'tb-device-profile-data', | |
31 | - templateUrl: './device-profile-data.component.html', | |
32 | - styleUrls: [], | |
33 | - providers: [{ | |
34 | - provide: NG_VALUE_ACCESSOR, | |
35 | - useExisting: forwardRef(() => DeviceProfileDataComponent), | |
36 | - multi: true | |
37 | - }] | |
38 | -}) | |
39 | -export class DeviceProfileDataComponent implements ControlValueAccessor, OnInit { | |
40 | - | |
41 | - deviceProfileDataFormGroup: FormGroup; | |
42 | - | |
43 | - private requiredValue: boolean; | |
44 | - get required(): boolean { | |
45 | - return this.requiredValue; | |
46 | - } | |
47 | - @Input() | |
48 | - set required(value: boolean) { | |
49 | - this.requiredValue = coerceBooleanProperty(value); | |
50 | - } | |
51 | - | |
52 | - @Input() | |
53 | - disabled: boolean; | |
54 | - | |
55 | - displayProfileConfiguration: boolean; | |
56 | - displayTransportConfiguration: boolean; | |
57 | - | |
58 | - private propagateChange = (v: any) => { }; | |
59 | - | |
60 | - constructor(private store: Store<AppState>, | |
61 | - private fb: FormBuilder) { | |
62 | - } | |
63 | - | |
64 | - registerOnChange(fn: any): void { | |
65 | - this.propagateChange = fn; | |
66 | - } | |
67 | - | |
68 | - registerOnTouched(fn: any): void { | |
69 | - } | |
70 | - | |
71 | - ngOnInit() { | |
72 | - this.deviceProfileDataFormGroup = this.fb.group({ | |
73 | - configuration: [null, Validators.required], | |
74 | - transportConfiguration: [null, Validators.required], | |
75 | - alarms: [null] | |
76 | - }); | |
77 | - this.deviceProfileDataFormGroup.valueChanges.subscribe(() => { | |
78 | - this.updateModel(); | |
79 | - }); | |
80 | - } | |
81 | - | |
82 | - setDisabledState(isDisabled: boolean): void { | |
83 | - this.disabled = isDisabled; | |
84 | - if (this.disabled) { | |
85 | - this.deviceProfileDataFormGroup.disable({emitEvent: false}); | |
86 | - } else { | |
87 | - this.deviceProfileDataFormGroup.enable({emitEvent: false}); | |
88 | - } | |
89 | - } | |
90 | - | |
91 | - writeValue(value: DeviceProfileData | null): void { | |
92 | - const deviceProfileType = value?.configuration?.type; | |
93 | - this.displayProfileConfiguration = deviceProfileType && | |
94 | - deviceProfileTypeConfigurationInfoMap.get(deviceProfileType).hasProfileConfiguration; | |
95 | - const deviceTransportType = value?.transportConfiguration?.type; | |
96 | - this.displayTransportConfiguration = deviceTransportType && | |
97 | - deviceTransportTypeConfigurationInfoMap.get(deviceTransportType).hasProfileConfiguration; | |
98 | - this.deviceProfileDataFormGroup.patchValue({configuration: value?.configuration}, {emitEvent: false}); | |
99 | - this.deviceProfileDataFormGroup.patchValue({transportConfiguration: value?.transportConfiguration}, {emitEvent: false}); | |
100 | - this.deviceProfileDataFormGroup.patchValue({alarms: value?.alarms}, {emitEvent: false}); | |
101 | - } | |
102 | - | |
103 | - private updateModel() { | |
104 | - let deviceProfileData: DeviceProfileData = null; | |
105 | - if (this.deviceProfileDataFormGroup.valid) { | |
106 | - deviceProfileData = this.deviceProfileDataFormGroup.getRawValue(); | |
107 | - } | |
108 | - this.propagateChange(deviceProfileData); | |
109 | - } | |
110 | -} |
... | ... | @@ -53,7 +53,7 @@ |
53 | 53 | labelText="device-profile.default-rule-chain" |
54 | 54 | formControlName="defaultRuleChainId"> |
55 | 55 | </tb-rule-chain-autocomplete> |
56 | - <mat-form-field class="mat-block"> | |
56 | + <mat-form-field fxHide class="mat-block"> | |
57 | 57 | <mat-label translate>device-profile.type</mat-label> |
58 | 58 | <mat-select formControlName="type" required> |
59 | 59 | <mat-option *ngFor="let type of deviceProfileTypes" [value]="type"> |
... | ... | @@ -65,21 +65,6 @@ |
65 | 65 | </mat-error> |
66 | 66 | </mat-form-field> |
67 | 67 | <mat-form-field class="mat-block"> |
68 | - <mat-label translate>device-profile.transport-type</mat-label> | |
69 | - <mat-select formControlName="transportType" required> | |
70 | - <mat-option *ngFor="let type of deviceTransportTypes" [value]="type"> | |
71 | - {{deviceTransportTypeTranslations.get(type) | translate}} | |
72 | - </mat-option> | |
73 | - </mat-select> | |
74 | - <mat-error *ngIf="entityForm.get('transportType').hasError('required')"> | |
75 | - {{ 'device-profile.transport-type-required' | translate }} | |
76 | - </mat-error> | |
77 | - </mat-form-field> | |
78 | - <tb-device-profile-data | |
79 | - formControlName="profileData" | |
80 | - required> | |
81 | - </tb-device-profile-data> | |
82 | - <mat-form-field class="mat-block"> | |
83 | 68 | <mat-label translate>device-profile.description</mat-label> |
84 | 69 | <textarea matInput formControlName="description" rows="2"></textarea> |
85 | 70 | </mat-form-field> | ... | ... |
... | ... | @@ -77,7 +77,11 @@ export class DeviceProfileComponent extends EntityComponent<DeviceProfile> { |
77 | 77 | name: [entity ? entity.name : '', [Validators.required]], |
78 | 78 | type: [entity ? entity.type : null, [Validators.required]], |
79 | 79 | transportType: [entity ? entity.transportType : null, [Validators.required]], |
80 | - profileData: [entity && !this.isAdd ? entity.profileData : {}, []], | |
80 | + profileData: this.fb.group({ | |
81 | + configuration: [entity && !this.isAdd ? entity.profileData?.configuration : {}, Validators.required], | |
82 | + transportConfiguration: [entity && !this.isAdd ? entity.profileData?.transportConfiguration : {}, Validators.required], | |
83 | + alarms: [entity && !this.isAdd ? entity.profileData?.alarms : []] | |
84 | + }), | |
81 | 85 | defaultRuleChainId: [entity && entity.defaultRuleChainId ? entity.defaultRuleChainId.id : null, []], |
82 | 86 | description: [entity ? entity.description : '', []], |
83 | 87 | } | ... | ... |
... | ... | @@ -16,9 +16,5 @@ |
16 | 16 | |
17 | 17 | --> |
18 | 18 | <form [formGroup]="defaultDeviceProfileConfigurationFormGroup" style="padding-bottom: 16px;"> |
19 | - <tb-json-object-edit | |
20 | - [required]="required" | |
21 | - label="{{ 'device-profile.type-default' | translate }}" | |
22 | - formControlName="configuration"> | |
23 | - </tb-json-object-edit> | |
19 | + | |
24 | 20 | </form> | ... | ... |
... | ... | @@ -16,9 +16,5 @@ |
16 | 16 | |
17 | 17 | --> |
18 | 18 | <form [formGroup]="defaultDeviceProfileTransportConfigurationFormGroup" style="padding-bottom: 16px;"> |
19 | - <tb-json-object-edit | |
20 | - [required]="required" | |
21 | - label="{{ 'device-profile.transport-type-default' | translate }}" | |
22 | - formControlName="configuration"> | |
23 | - </tb-json-object-edit> | |
19 | + | |
24 | 20 | </form> | ... | ... |
... | ... | @@ -89,7 +89,7 @@ export class Lwm2mDeviceProfileTransportConfigurationComponent implements Contro |
89 | 89 | let configuration: DeviceProfileTransportConfiguration = null; |
90 | 90 | if (this.lwm2mDeviceProfileTransportConfigurationFormGroup.valid) { |
91 | 91 | configuration = this.lwm2mDeviceProfileTransportConfigurationFormGroup.getRawValue().configuration; |
92 | - configuration.type = DeviceTransportType.LWM2M; | |
92 | + // configuration.type = DeviceTransportType.LWM2M; | |
93 | 93 | } |
94 | 94 | this.propagateChange(configuration); |
95 | 95 | } | ... | ... |
... | ... | @@ -16,6 +16,49 @@ |
16 | 16 | |
17 | 17 | --> |
18 | 18 | <mat-tab *ngIf="entity" |
19 | + label="{{ 'device-profile.transport-configuration' | translate }}" #transportType="matTab"> | |
20 | + <div class="mat-padding" [formGroup]="detailsForm"> | |
21 | + <mat-form-field class="mat-block"> | |
22 | + <mat-label translate>device-profile.transport-type</mat-label> | |
23 | + <mat-select formControlName="transportType" required> | |
24 | + <mat-option *ngFor="let type of deviceTransportTypes" [value]="type"> | |
25 | + {{deviceTransportTypeTranslations.get(type) | translate}} | |
26 | + </mat-option> | |
27 | + </mat-select> | |
28 | + <mat-error *ngIf="detailsForm.get('transportType').hasError('required')"> | |
29 | + {{ 'device-profile.transport-type-required' | translate }} | |
30 | + </mat-error> | |
31 | + </mat-form-field> | |
32 | + <div formGroupName="profileData"> | |
33 | + <tb-device-profile-transport-configuration | |
34 | + formControlName="transportConfiguration" | |
35 | + required> | |
36 | + </tb-device-profile-transport-configuration> | |
37 | + </div> | |
38 | + </div> | |
39 | +</mat-tab> | |
40 | +<mat-tab *ngIf="entity" | |
41 | + label="{{'device-profile.alarm-rules' | translate: | |
42 | + {count: entity.profileData.alarms.length ? | |
43 | + entity.profileData.alarms.length : 0} }}" #alarmRules="matTab"> | |
44 | + <div class="mat-padding" [formGroup]="detailsForm"> | |
45 | + <div formGroupName="profileData"> | |
46 | + <tb-device-profile-alarms formControlName="alarms"></tb-device-profile-alarms> | |
47 | + </div> | |
48 | + </div> | |
49 | +</mat-tab> | |
50 | +<mat-tab *ngIf="false" | |
51 | + label="{{'device-profile.profile-configuration' | translate }}" #deviceProfile="matTab"> | |
52 | + <div class="mat-padding" [formGroup]="detailsForm"> | |
53 | + <div formGroupName="profileData"> | |
54 | + <tb-device-profile-configuration | |
55 | + formControlName="configuration" | |
56 | + required> | |
57 | + </tb-device-profile-configuration> | |
58 | + </div> | |
59 | + </div> | |
60 | +</mat-tab> | |
61 | +<mat-tab *ngIf="entity && !isEdit" | |
19 | 62 | label="{{ 'attribute.attributes' | translate }}" #attributesTab="matTab"> |
20 | 63 | <tb-attribute-table [defaultAttributeScope]="attributeScopes.SERVER_SCOPE" |
21 | 64 | [active]="attributesTab.isActive" |
... | ... | @@ -23,7 +66,7 @@ |
23 | 66 | [entityName]="entity.name"> |
24 | 67 | </tb-attribute-table> |
25 | 68 | </mat-tab> |
26 | -<mat-tab *ngIf="entity" | |
69 | +<mat-tab *ngIf="entity && !isEdit" | |
27 | 70 | label="{{ 'attribute.latest-telemetry' | translate }}" #telemetryTab="matTab"> |
28 | 71 | <tb-attribute-table [defaultAttributeScope]="latestTelemetryTypes.LATEST_TELEMETRY" |
29 | 72 | disableAttributeScopeSelection |
... | ... | @@ -32,11 +75,11 @@ |
32 | 75 | [entityName]="entity.name"> |
33 | 76 | </tb-attribute-table> |
34 | 77 | </mat-tab> |
35 | -<mat-tab *ngIf="entity" | |
78 | +<mat-tab *ngIf="entity && !isEdit" | |
36 | 79 | label="{{ 'alarm.alarms' | translate }}" #alarmsTab="matTab"> |
37 | 80 | <tb-alarm-table [active]="alarmsTab.isActive" [entityId]="entity.id"></tb-alarm-table> |
38 | 81 | </mat-tab> |
39 | -<mat-tab *ngIf="entity" | |
82 | +<mat-tab *ngIf="entity && !isEdit" | |
40 | 83 | label="{{ 'tenant.events' | translate }}" #eventsTab="matTab"> |
41 | 84 | <tb-event-table [defaultEventType]="eventTypes.ERROR" [active]="eventsTab.isActive" [tenantId]="nullUid" |
42 | 85 | [entityId]="entity.id"></tb-event-table> | ... | ... |
... | ... | @@ -18,7 +18,7 @@ import { Component } from '@angular/core'; |
18 | 18 | import { Store } from '@ngrx/store'; |
19 | 19 | import { AppState } from '@core/core.state'; |
20 | 20 | import { EntityTabsComponent } from '../../components/entity/entity-tabs.component'; |
21 | -import { DeviceProfile } from '@shared/models/device.models'; | |
21 | +import { DeviceProfile, DeviceTransportType, deviceTransportTypeTranslationMap } from '@shared/models/device.models'; | |
22 | 22 | |
23 | 23 | @Component({ |
24 | 24 | selector: 'tb-device-profile-tabs', |
... | ... | @@ -27,6 +27,9 @@ import { DeviceProfile } from '@shared/models/device.models'; |
27 | 27 | }) |
28 | 28 | export class DeviceProfileTabsComponent extends EntityTabsComponent<DeviceProfile> { |
29 | 29 | |
30 | + deviceTransportTypes = Object.keys(DeviceTransportType); | |
31 | + deviceTransportTypeTranslations = deviceTransportTypeTranslationMap; | |
32 | + | |
30 | 33 | constructor(protected store: Store<AppState>) { |
31 | 34 | super(store); |
32 | 35 | } | ... | ... |
... | ... | @@ -59,6 +59,8 @@ export class DeviceProfilesTableConfigResolver implements Resolve<EntityTableCon |
59 | 59 | this.config.entityTranslations = entityTypeTranslations.get(EntityType.DEVICE_PROFILE); |
60 | 60 | this.config.entityResources = entityTypeResources.get(EntityType.DEVICE_PROFILE); |
61 | 61 | |
62 | + this.config.hideDetailsTabsOnEdit = false; | |
63 | + | |
62 | 64 | this.config.addDialogStyle = {width: '1000px'}; |
63 | 65 | |
64 | 66 | this.config.columns.push( | ... | ... |
... | ... | @@ -89,7 +89,7 @@ export class Lwm2mDeviceTransportConfigurationComponent implements ControlValueA |
89 | 89 | let configuration: DeviceTransportConfiguration = null; |
90 | 90 | if (this.lwm2mDeviceTransportConfigurationFormGroup.valid) { |
91 | 91 | configuration = this.lwm2mDeviceTransportConfigurationFormGroup.getRawValue().configuration; |
92 | - configuration.type = DeviceTransportType.LWM2M; | |
92 | + // configuration.type = DeviceTransportType.LWM2M; | |
93 | 93 | } |
94 | 94 | this.propagateChange(configuration); |
95 | 95 | } | ... | ... |
... | ... | @@ -33,7 +33,7 @@ export enum DeviceProfileType { |
33 | 33 | export enum DeviceTransportType { |
34 | 34 | DEFAULT = 'DEFAULT', |
35 | 35 | MQTT = 'MQTT', |
36 | - LWM2M = 'LWM2M' | |
36 | + // LWM2M = 'LWM2M' | |
37 | 37 | } |
38 | 38 | |
39 | 39 | export enum MqttTransportPayloadType { |
... | ... | @@ -68,7 +68,7 @@ export const deviceTransportTypeTranslationMap = new Map<DeviceTransportType, st |
68 | 68 | [ |
69 | 69 | [DeviceTransportType.DEFAULT, 'device-profile.transport-type-default'], |
70 | 70 | [DeviceTransportType.MQTT, 'device-profile.transport-type-mqtt'], |
71 | - [DeviceTransportType.LWM2M, 'device-profile.transport-type-lwm2m'] | |
71 | + // [DeviceTransportType.LWM2M, 'device-profile.transport-type-lwm2m'] | |
72 | 72 | ] |
73 | 73 | ); |
74 | 74 | |
... | ... | @@ -104,13 +104,13 @@ export const deviceTransportTypeConfigurationInfoMap = new Map<DeviceTransportTy |
104 | 104 | hasDeviceConfiguration: true, |
105 | 105 | } |
106 | 106 | ], |
107 | - [ | |
108 | - DeviceTransportType.LWM2M, | |
109 | - { | |
110 | - hasProfileConfiguration: true, | |
111 | - hasDeviceConfiguration: true, | |
112 | - } | |
113 | - ] | |
107 | + // [ | |
108 | + // DeviceTransportType.LWM2M, | |
109 | + // { | |
110 | + // hasProfileConfiguration: true, | |
111 | + // hasDeviceConfiguration: true, | |
112 | + // } | |
113 | + // ] | |
114 | 114 | ] |
115 | 115 | ); |
116 | 116 | |
... | ... | @@ -188,10 +188,10 @@ export function createDeviceProfileTransportConfiguration(type: DeviceTransportT |
188 | 188 | }; |
189 | 189 | transportConfiguration = {...mqttTransportConfiguration, type: DeviceTransportType.MQTT}; |
190 | 190 | break; |
191 | - case DeviceTransportType.LWM2M: | |
192 | - const lwm2mTransportConfiguration: Lwm2mDeviceProfileTransportConfiguration = {}; | |
193 | - transportConfiguration = {...lwm2mTransportConfiguration, type: DeviceTransportType.LWM2M}; | |
194 | - break; | |
191 | + // case DeviceTransportType.LWM2M: | |
192 | + // const lwm2mTransportConfiguration: Lwm2mDeviceProfileTransportConfiguration = {}; | |
193 | + // transportConfiguration = {...lwm2mTransportConfiguration, type: DeviceTransportType.LWM2M}; | |
194 | + // break; | |
195 | 195 | } |
196 | 196 | } |
197 | 197 | return transportConfiguration; |
... | ... | @@ -209,10 +209,10 @@ export function createDeviceTransportConfiguration(type: DeviceTransportType): D |
209 | 209 | const mqttTransportConfiguration: MqttDeviceTransportConfiguration = {}; |
210 | 210 | transportConfiguration = {...mqttTransportConfiguration, type: DeviceTransportType.MQTT}; |
211 | 211 | break; |
212 | - case DeviceTransportType.LWM2M: | |
213 | - const lwm2mTransportConfiguration: Lwm2mDeviceTransportConfiguration = {}; | |
214 | - transportConfiguration = {...lwm2mTransportConfiguration, type: DeviceTransportType.LWM2M}; | |
215 | - break; | |
212 | + // case DeviceTransportType.LWM2M: | |
213 | + // const lwm2mTransportConfiguration: Lwm2mDeviceTransportConfiguration = {}; | |
214 | + // transportConfiguration = {...lwm2mTransportConfiguration, type: DeviceTransportType.LWM2M}; | |
215 | + // break; | |
216 | 216 | } |
217 | 217 | } |
218 | 218 | return transportConfiguration; | ... | ... |