24 changed files with 1251 additions and 3 deletions
@ -0,0 +1,19 @@ |
|||||
|
<!-- |
||||
|
|
||||
|
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 fxLayout="row" [formGroup]="alarmRuleConditionFormGroup"> |
||||
|
</div> |
||||
@ -0,0 +1,112 @@ |
|||||
|
///
|
||||
|
/// 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, |
||||
|
FormControl, |
||||
|
FormGroup, |
||||
|
NG_VALIDATORS, |
||||
|
NG_VALUE_ACCESSOR, |
||||
|
Validator, |
||||
|
Validators |
||||
|
} from '@angular/forms'; |
||||
|
import { AlarmCondition } from '@shared/models/device.models'; |
||||
|
import { MatDialog } from '@angular/material/dialog'; |
||||
|
|
||||
|
@Component({ |
||||
|
selector: 'tb-alarm-rule-condition', |
||||
|
templateUrl: './alarm-rule-condition.component.html', |
||||
|
styleUrls: [], |
||||
|
providers: [ |
||||
|
{ |
||||
|
provide: NG_VALUE_ACCESSOR, |
||||
|
useExisting: forwardRef(() => AlarmRuleConditionComponent), |
||||
|
multi: true |
||||
|
}, |
||||
|
{ |
||||
|
provide: NG_VALIDATORS, |
||||
|
useExisting: forwardRef(() => AlarmRuleConditionComponent), |
||||
|
multi: true, |
||||
|
} |
||||
|
] |
||||
|
}) |
||||
|
export class AlarmRuleConditionComponent implements ControlValueAccessor, OnInit, Validator { |
||||
|
|
||||
|
@Input() |
||||
|
disabled: boolean; |
||||
|
|
||||
|
private modelValue: AlarmCondition; |
||||
|
|
||||
|
alarmRuleConditionFormGroup: FormGroup; |
||||
|
|
||||
|
private propagateChange = (v: any) => { }; |
||||
|
|
||||
|
constructor(private dialog: MatDialog, |
||||
|
private fb: FormBuilder) { |
||||
|
} |
||||
|
|
||||
|
registerOnChange(fn: any): void { |
||||
|
this.propagateChange = fn; |
||||
|
} |
||||
|
|
||||
|
registerOnTouched(fn: any): void { |
||||
|
} |
||||
|
|
||||
|
ngOnInit() { |
||||
|
this.alarmRuleConditionFormGroup = this.fb.group({ |
||||
|
condition: [null, Validators.required], |
||||
|
durationUnit: [null], |
||||
|
durationValue: [null] |
||||
|
}); |
||||
|
this.alarmRuleConditionFormGroup.valueChanges.subscribe(() => { |
||||
|
this.updateModel(); |
||||
|
}); |
||||
|
} |
||||
|
|
||||
|
setDisabledState(isDisabled: boolean): void { |
||||
|
this.disabled = isDisabled; |
||||
|
if (this.disabled) { |
||||
|
this.alarmRuleConditionFormGroup.disable({emitEvent: false}); |
||||
|
} else { |
||||
|
this.alarmRuleConditionFormGroup.enable({emitEvent: false}); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
writeValue(value: AlarmCondition): void { |
||||
|
this.modelValue = value; |
||||
|
this.alarmRuleConditionFormGroup.reset(this.modelValue, {emitEvent: false}); |
||||
|
} |
||||
|
|
||||
|
public validate(c: FormControl) { |
||||
|
return (this.alarmRuleConditionFormGroup.valid) ? null : { |
||||
|
alarmRuleCondition: { |
||||
|
valid: false, |
||||
|
}, |
||||
|
}; |
||||
|
} |
||||
|
|
||||
|
private updateModel() { |
||||
|
if (this.alarmRuleConditionFormGroup.valid) { |
||||
|
const value = this.alarmRuleConditionFormGroup.value; |
||||
|
this.modelValue = {...this.modelValue, ...value}; |
||||
|
this.propagateChange(this.modelValue); |
||||
|
} else { |
||||
|
this.propagateChange(null); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,22 @@ |
|||||
|
<!-- |
||||
|
|
||||
|
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 fxLayout="row" [formGroup]="alarmRuleFormGroup"> |
||||
|
<tb-alarm-rule-condition |
||||
|
formControlName="condition"> |
||||
|
</tb-alarm-rule-condition> |
||||
|
</div> |
||||
@ -0,0 +1,111 @@ |
|||||
|
///
|
||||
|
/// 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, |
||||
|
FormControl, |
||||
|
FormGroup, |
||||
|
NG_VALIDATORS, |
||||
|
NG_VALUE_ACCESSOR, |
||||
|
Validator, |
||||
|
Validators |
||||
|
} from '@angular/forms'; |
||||
|
import { AlarmRule } from '@shared/models/device.models'; |
||||
|
import { MatDialog } from '@angular/material/dialog'; |
||||
|
|
||||
|
@Component({ |
||||
|
selector: 'tb-alarm-rule', |
||||
|
templateUrl: './alarm-rule.component.html', |
||||
|
styleUrls: [], |
||||
|
providers: [ |
||||
|
{ |
||||
|
provide: NG_VALUE_ACCESSOR, |
||||
|
useExisting: forwardRef(() => AlarmRuleComponent), |
||||
|
multi: true |
||||
|
}, |
||||
|
{ |
||||
|
provide: NG_VALIDATORS, |
||||
|
useExisting: forwardRef(() => AlarmRuleComponent), |
||||
|
multi: true, |
||||
|
} |
||||
|
] |
||||
|
}) |
||||
|
export class AlarmRuleComponent implements ControlValueAccessor, OnInit, Validator { |
||||
|
|
||||
|
@Input() |
||||
|
disabled: boolean; |
||||
|
|
||||
|
private modelValue: AlarmRule; |
||||
|
|
||||
|
alarmRuleFormGroup: FormGroup; |
||||
|
|
||||
|
private propagateChange = (v: any) => { }; |
||||
|
|
||||
|
constructor(private dialog: MatDialog, |
||||
|
private fb: FormBuilder) { |
||||
|
} |
||||
|
|
||||
|
registerOnChange(fn: any): void { |
||||
|
this.propagateChange = fn; |
||||
|
} |
||||
|
|
||||
|
registerOnTouched(fn: any): void { |
||||
|
} |
||||
|
|
||||
|
ngOnInit() { |
||||
|
this.alarmRuleFormGroup = this.fb.group({ |
||||
|
condition: [null, Validators.required], |
||||
|
alarmDetails: [null] |
||||
|
}); |
||||
|
this.alarmRuleFormGroup.valueChanges.subscribe(() => { |
||||
|
this.updateModel(); |
||||
|
}); |
||||
|
} |
||||
|
|
||||
|
setDisabledState(isDisabled: boolean): void { |
||||
|
this.disabled = isDisabled; |
||||
|
if (this.disabled) { |
||||
|
this.alarmRuleFormGroup.disable({emitEvent: false}); |
||||
|
} else { |
||||
|
this.alarmRuleFormGroup.enable({emitEvent: false}); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
writeValue(value: AlarmRule): void { |
||||
|
this.modelValue = value; |
||||
|
this.alarmRuleFormGroup.reset(this.modelValue, {emitEvent: false}); |
||||
|
} |
||||
|
|
||||
|
public validate(c: FormControl) { |
||||
|
return (this.alarmRuleFormGroup.valid) ? null : { |
||||
|
alarmRule: { |
||||
|
valid: false, |
||||
|
}, |
||||
|
}; |
||||
|
} |
||||
|
|
||||
|
private updateModel() { |
||||
|
if (this.alarmRuleFormGroup.valid) { |
||||
|
const value = this.alarmRuleFormGroup.value; |
||||
|
this.modelValue = {...this.modelValue, ...value}; |
||||
|
this.propagateChange(this.modelValue); |
||||
|
} else { |
||||
|
this.propagateChange(null); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,54 @@ |
|||||
|
<!-- |
||||
|
|
||||
|
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 fxFlex fxLayout="column"> |
||||
|
<div *ngFor="let createAlarmRuleControl of createAlarmRulesFormArray().controls; let $index = index; |
||||
|
last as isLast;" fxLayout="row" style="padding-left: 20px;" [formGroup]="createAlarmRuleControl"> |
||||
|
<mat-form-field class="mat-block" floatLabel="always" hideRequiredMarker> |
||||
|
<mat-label translate></mat-label> |
||||
|
<mat-select formControlName="severity" |
||||
|
required |
||||
|
placeholder="{{ 'device-profile.select-alarm-severity' | translate }}"> |
||||
|
<mat-option *ngFor="let alarmSeverity of alarmSeverities" [value]="alarmSeverity"> |
||||
|
{{ alarmSeverityTranslationMap.get(alarmSeverityEnum[alarmSeverity]) | translate }} |
||||
|
</mat-option> |
||||
|
</mat-select> |
||||
|
<mat-error *ngIf="createAlarmRuleControl.get('severity').hasError('required')"> |
||||
|
{{ 'device-profile.alarm-severity-required' | translate }} |
||||
|
</mat-error> |
||||
|
</mat-form-field> |
||||
|
<tb-alarm-rule formControlName="alarmRule"> |
||||
|
</tb-alarm-rule> |
||||
|
<button *ngIf="!disabled && createAlarmRulesFormArray().controls.length > 1" |
||||
|
mat-icon-button color="primary" style="min-width: 40px;" |
||||
|
type="button" |
||||
|
(click)="removeCreateAlarmRule($index)" |
||||
|
matTooltip="{{ 'action.remove' | translate }}" |
||||
|
matTooltipPosition="above"> |
||||
|
<mat-icon>close</mat-icon> |
||||
|
</button> |
||||
|
</div> |
||||
|
<div *ngIf="!disabled" fxFlex fxLayout="row" fxLayoutAlign="start center"> |
||||
|
<button mat-icon-button color="primary" |
||||
|
type="button" |
||||
|
(click)="addCreateAlarmRule()" |
||||
|
matTooltip="{{ 'device-profile.add-create-alarm-rule' | translate }}" |
||||
|
matTooltipPosition="above"> |
||||
|
<mat-icon>add</mat-icon> |
||||
|
</button> |
||||
|
</div> |
||||
|
</div> |
||||
@ -0,0 +1,18 @@ |
|||||
|
/** |
||||
|
* 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. |
||||
|
*/ |
||||
|
:host { |
||||
|
|
||||
|
} |
||||
@ -0,0 +1,164 @@ |
|||||
|
///
|
||||
|
/// 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 { |
||||
|
AbstractControl, |
||||
|
ControlValueAccessor, |
||||
|
FormArray, |
||||
|
FormBuilder, |
||||
|
FormControl, |
||||
|
FormGroup, |
||||
|
NG_VALIDATORS, |
||||
|
NG_VALUE_ACCESSOR, |
||||
|
Validator, |
||||
|
Validators |
||||
|
} from '@angular/forms'; |
||||
|
import { AlarmRule } from '@shared/models/device.models'; |
||||
|
import { MatDialog } from '@angular/material/dialog'; |
||||
|
import { Subscription } from 'rxjs'; |
||||
|
import { AlarmSeverity, alarmSeverityTranslations } from '../../../../../shared/models/alarm.models'; |
||||
|
|
||||
|
@Component({ |
||||
|
selector: 'tb-create-alarm-rules', |
||||
|
templateUrl: './create-alarm-rules.component.html', |
||||
|
styleUrls: ['./create-alarm-rules.component.scss'], |
||||
|
providers: [ |
||||
|
{ |
||||
|
provide: NG_VALUE_ACCESSOR, |
||||
|
useExisting: forwardRef(() => CreateAlarmRulesComponent), |
||||
|
multi: true |
||||
|
}, |
||||
|
{ |
||||
|
provide: NG_VALIDATORS, |
||||
|
useExisting: forwardRef(() => CreateAlarmRulesComponent), |
||||
|
multi: true, |
||||
|
} |
||||
|
] |
||||
|
}) |
||||
|
export class CreateAlarmRulesComponent implements ControlValueAccessor, OnInit, Validator { |
||||
|
|
||||
|
alarmSeverities = Object.keys(AlarmSeverity); |
||||
|
alarmSeverityEnum = AlarmSeverity; |
||||
|
|
||||
|
alarmSeverityTranslationMap = alarmSeverityTranslations; |
||||
|
|
||||
|
@Input() |
||||
|
disabled: boolean; |
||||
|
|
||||
|
createAlarmRulesFormGroup: FormGroup; |
||||
|
|
||||
|
private valueChangeSubscription: Subscription = null; |
||||
|
|
||||
|
private propagateChange = (v: any) => { }; |
||||
|
|
||||
|
constructor(private dialog: MatDialog, |
||||
|
private fb: FormBuilder) { |
||||
|
} |
||||
|
|
||||
|
registerOnChange(fn: any): void { |
||||
|
this.propagateChange = fn; |
||||
|
} |
||||
|
|
||||
|
registerOnTouched(fn: any): void { |
||||
|
} |
||||
|
|
||||
|
ngOnInit() { |
||||
|
this.createAlarmRulesFormGroup = this.fb.group({ |
||||
|
createAlarmRules: this.fb.array([]) |
||||
|
}); |
||||
|
} |
||||
|
|
||||
|
createAlarmRulesFormArray(): FormArray { |
||||
|
return this.createAlarmRulesFormGroup.get('createAlarmRules') as FormArray; |
||||
|
} |
||||
|
|
||||
|
setDisabledState(isDisabled: boolean): void { |
||||
|
this.disabled = isDisabled; |
||||
|
if (this.disabled) { |
||||
|
this.createAlarmRulesFormGroup.disable({emitEvent: false}); |
||||
|
} else { |
||||
|
this.createAlarmRulesFormGroup.enable({emitEvent: false}); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
writeValue(createAlarmRules: {[severity: string]: AlarmRule}): void { |
||||
|
if (this.valueChangeSubscription) { |
||||
|
this.valueChangeSubscription.unsubscribe(); |
||||
|
} |
||||
|
const createAlarmRulesControls: Array<AbstractControl> = []; |
||||
|
if (createAlarmRules) { |
||||
|
Object.keys(createAlarmRules).forEach((severity) => { |
||||
|
const createAlarmRule = createAlarmRules[severity]; |
||||
|
if (severity === 'empty') { |
||||
|
severity = null; |
||||
|
} |
||||
|
createAlarmRulesControls.push(this.fb.group({ |
||||
|
severity: [severity, Validators.required], |
||||
|
alarmRule: [createAlarmRule, Validators.required] |
||||
|
})); |
||||
|
}); |
||||
|
} |
||||
|
this.createAlarmRulesFormGroup.setControl('createAlarmRules', this.fb.array(createAlarmRulesControls)); |
||||
|
if (this.disabled) { |
||||
|
this.createAlarmRulesFormGroup.disable({emitEvent: false}); |
||||
|
} else { |
||||
|
this.createAlarmRulesFormGroup.enable({emitEvent: false}); |
||||
|
} |
||||
|
this.valueChangeSubscription = this.createAlarmRulesFormGroup.valueChanges.subscribe(() => { |
||||
|
this.updateModel(); |
||||
|
}); |
||||
|
} |
||||
|
|
||||
|
public removeCreateAlarmRule(index: number) { |
||||
|
(this.createAlarmRulesFormGroup.get('createAlarmRules') as FormArray).removeAt(index); |
||||
|
} |
||||
|
|
||||
|
public addCreateAlarmRule() { |
||||
|
const createAlarmRule: AlarmRule = { |
||||
|
condition: { |
||||
|
condition: [] |
||||
|
} |
||||
|
}; |
||||
|
const createAlarmRulesArray = this.createAlarmRulesFormGroup.get('createAlarmRules') as FormArray; |
||||
|
createAlarmRulesArray.push(this.fb.group({ |
||||
|
severity: [null, Validators.required], |
||||
|
alarmRule: [createAlarmRule, Validators.required] |
||||
|
})); |
||||
|
this.createAlarmRulesFormGroup.updateValueAndValidity(); |
||||
|
} |
||||
|
|
||||
|
public validate(c: FormControl) { |
||||
|
return (this.createAlarmRulesFormGroup.valid && this.createAlarmRulesFormGroup.get('createAlarmRules').value.length) ? null : { |
||||
|
createAlarmRules: { |
||||
|
valid: false, |
||||
|
}, |
||||
|
}; |
||||
|
} |
||||
|
|
||||
|
private updateModel() { |
||||
|
if (this.createAlarmRulesFormGroup.valid) { |
||||
|
const value: {severity: string, alarmRule: AlarmRule}[] = this.createAlarmRulesFormGroup.get('createAlarmRules').value; |
||||
|
const createAlarmRules: {[severity: string]: AlarmRule} = {}; |
||||
|
value.forEach(v => { |
||||
|
createAlarmRules[v.severity] = v.alarmRule; |
||||
|
}); |
||||
|
this.propagateChange(createAlarmRules); |
||||
|
} else { |
||||
|
this.propagateChange(null); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,65 @@ |
|||||
|
<!-- |
||||
|
|
||||
|
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. |
||||
|
|
||||
|
--> |
||||
|
<form [formGroup]="alarmFormGroup" (ngSubmit)="save()" style="min-width: 600px;"> |
||||
|
<mat-toolbar fxLayout="row" color="primary"> |
||||
|
<h2>{{ (isReadOnly ? 'device-profile.alarm-rule-details' : (isAdd ? 'device-profile.add-alarm-rule' : 'device-profile.edit-alarm-rule')) | translate }}</h2> |
||||
|
<span fxFlex></span> |
||||
|
<button mat-button mat-icon-button |
||||
|
(click)="cancel()" |
||||
|
type="button"> |
||||
|
<mat-icon class="material-icons">close</mat-icon> |
||||
|
</button> |
||||
|
</mat-toolbar> |
||||
|
<mat-progress-bar color="warn" mode="indeterminate" *ngIf="isLoading$ | async"> |
||||
|
</mat-progress-bar> |
||||
|
<div style="height: 4px;" *ngIf="!(isLoading$ | async)"></div> |
||||
|
<div mat-dialog-content> |
||||
|
<fieldset [disabled]="(isLoading$ | async) || isReadOnly" fxLayout="column"> |
||||
|
<mat-form-field fxFlex class="mat-block"> |
||||
|
<mat-label translate>device-profile.alarm-type</mat-label> |
||||
|
<input required matInput formControlName="alarmType"> |
||||
|
<mat-error *ngIf="alarmFormGroup.get('alarmType').hasError('required')"> |
||||
|
{{ 'device-profile.alarm-type-required' | translate }} |
||||
|
</mat-error> |
||||
|
<mat-hint innerHTML="{{ 'device-profile.alarm-type-pattern-hint' | translate }}"></mat-hint> |
||||
|
</mat-form-field> |
||||
|
<fieldset> |
||||
|
<legend translate>device-profile.create-alarm-rules</legend> |
||||
|
</fieldset> |
||||
|
<fieldset> |
||||
|
<legend translate>device-profile.clear-alarm-rule</legend> |
||||
|
</fieldset> |
||||
|
</fieldset> |
||||
|
</div> |
||||
|
<div mat-dialog-actions fxLayout="row"> |
||||
|
<span fxFlex></span> |
||||
|
<button *ngIf="!isReadOnly" mat-button mat-raised-button color="primary" |
||||
|
type="submit" |
||||
|
[disabled]="(isLoading$ | async) || alarmFormGroup.invalid |
||||
|
|| !alarmFormGroup.dirty"> |
||||
|
{{ (isAdd ? 'action.add' : 'action.save') | translate }} |
||||
|
</button> |
||||
|
<button mat-button color="primary" |
||||
|
style="margin-right: 20px;" |
||||
|
type="button" |
||||
|
[disabled]="(isLoading$ | async)" |
||||
|
(click)="cancel()" cdkFocusInitial> |
||||
|
{{ (isReadOnly ? 'action.close' : 'action.cancel') | translate }} |
||||
|
</button> |
||||
|
</div> |
||||
|
</form> |
||||
@ -0,0 +1,99 @@ |
|||||
|
///
|
||||
|
/// 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, |
||||
|
Inject, |
||||
|
OnInit, |
||||
|
SkipSelf |
||||
|
} from '@angular/core'; |
||||
|
import { ErrorStateMatcher } from '@angular/material/core'; |
||||
|
import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog'; |
||||
|
import { Store } from '@ngrx/store'; |
||||
|
import { AppState } from '@core/core.state'; |
||||
|
import { FormBuilder, FormControl, FormGroup, FormGroupDirective, NgForm, Validators } from '@angular/forms'; |
||||
|
import { DialogComponent } from '@shared/components/dialog.component'; |
||||
|
import { Router } from '@angular/router'; |
||||
|
import { DeviceProfileAlarm } from '@shared/models/device.models'; |
||||
|
|
||||
|
export interface DeviceProfileAlarmDialogData { |
||||
|
alarm: DeviceProfileAlarm; |
||||
|
isAdd: boolean; |
||||
|
isReadOnly: boolean; |
||||
|
} |
||||
|
|
||||
|
@Component({ |
||||
|
selector: 'tb-device-profile-alarm-dialog', |
||||
|
templateUrl: './device-profile-alarm-dialog.component.html', |
||||
|
providers: [{provide: ErrorStateMatcher, useExisting: DeviceProfileAlarmDialogComponent}], |
||||
|
styleUrls: [] |
||||
|
}) |
||||
|
export class DeviceProfileAlarmDialogComponent extends |
||||
|
DialogComponent<DeviceProfileAlarmDialogComponent, DeviceProfileAlarm> implements OnInit, ErrorStateMatcher { |
||||
|
|
||||
|
alarmFormGroup: FormGroup; |
||||
|
|
||||
|
isReadOnly = this.data.isReadOnly; |
||||
|
alarm = this.data.alarm; |
||||
|
isAdd = this.data.isAdd; |
||||
|
|
||||
|
submitted = false; |
||||
|
|
||||
|
constructor(protected store: Store<AppState>, |
||||
|
protected router: Router, |
||||
|
@Inject(MAT_DIALOG_DATA) public data: DeviceProfileAlarmDialogData, |
||||
|
public dialogRef: MatDialogRef<DeviceProfileAlarmDialogComponent, DeviceProfileAlarm>, |
||||
|
@SkipSelf() private errorStateMatcher: ErrorStateMatcher, |
||||
|
public fb: FormBuilder) { |
||||
|
super(store, router, dialogRef); |
||||
|
this.isAdd = this.data.isAdd; |
||||
|
this.alarm = this.data.alarm; |
||||
|
} |
||||
|
|
||||
|
ngOnInit(): void { |
||||
|
this.alarmFormGroup = this.fb.group({ |
||||
|
id: [null, Validators.required], |
||||
|
alarmType: [null, Validators.required], |
||||
|
createRules: [null], |
||||
|
clearRule: [null], |
||||
|
propagate: [null], |
||||
|
propagateRelationTypes: [null] |
||||
|
}); |
||||
|
this.alarmFormGroup.reset(this.alarm, {emitEvent: false}); |
||||
|
if (this.isReadOnly) { |
||||
|
this.alarmFormGroup.disable({emitEvent: false}); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
isErrorState(control: FormControl | null, form: FormGroupDirective | NgForm | null): boolean { |
||||
|
const originalErrorState = this.errorStateMatcher.isErrorState(control, form); |
||||
|
const customErrorState = !!(control && control.invalid && this.submitted); |
||||
|
return originalErrorState || customErrorState; |
||||
|
} |
||||
|
|
||||
|
cancel(): void { |
||||
|
this.dialogRef.close(null); |
||||
|
} |
||||
|
|
||||
|
save(): void { |
||||
|
this.submitted = true; |
||||
|
if (this.alarmFormGroup.valid) { |
||||
|
this.alarm = {...this.alarm, ...this.alarmFormGroup.value}; |
||||
|
this.dialogRef.close(this.alarm); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
} |
||||
@ -0,0 +1,47 @@ |
|||||
|
<!-- |
||||
|
|
||||
|
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. |
||||
|
|
||||
|
--> |
||||
|
<fieldset [formGroup]="alarmFormGroup" class="fields-group tb-device-profile-alarm" fxFlex |
||||
|
style="position: relative;"> |
||||
|
<button *ngIf="!disabled" mat-icon-button color="primary" style="min-width: 40px;" |
||||
|
type="button" |
||||
|
style="position: absolute; top: 0; right: 0;" |
||||
|
(click)="removeAlarm.emit()" |
||||
|
matTooltip="{{ 'action.remove' | translate }}" |
||||
|
matTooltipPosition="above"> |
||||
|
<mat-icon>close</mat-icon> |
||||
|
</button> |
||||
|
<legend> |
||||
|
<mat-form-field floatLabel="always" |
||||
|
matTooltip="{{ 'device-profile.alarm-type-pattern-hint' | translate }}"> |
||||
|
<mat-label>{{'device-profile.alarm-type' | translate}}</mat-label> |
||||
|
<input required matInput formControlName="alarmType" placeholder="Enter alarm type"> |
||||
|
<mat-error *ngIf="alarmFormGroup.get('alarmType').hasError('required')"> |
||||
|
{{ 'device-profile.alarm-type-required' | translate }} |
||||
|
</mat-error> |
||||
|
<!--mat-hint innerHTML="{{ 'device-profile.alarm-type-pattern-hint' | translate }}"></mat-hint--> |
||||
|
</mat-form-field> |
||||
|
</legend> |
||||
|
<div fxFlex fxLayout="column"> |
||||
|
<div translate class="tb-small" style="font-weight: 500;">device-profile.create-alarm-rules</div> |
||||
|
<mat-divider></mat-divider> |
||||
|
<tb-create-alarm-rules formControlName="createRules"> |
||||
|
</tb-create-alarm-rules> |
||||
|
<div translate class="tb-small" style="font-weight: 500;">device-profile.clear-alarm-rule</div> |
||||
|
<mat-divider></mat-divider> |
||||
|
</div> |
||||
|
</fieldset> |
||||
@ -0,0 +1,48 @@ |
|||||
|
/** |
||||
|
* 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 '../scss/constants'; |
||||
|
|
||||
|
:host { |
||||
|
display: block; |
||||
|
.tb-device-profile-alarm { |
||||
|
&.mat-padding { |
||||
|
padding: 8px; |
||||
|
@media #{$mat-gt-sm} { |
||||
|
padding: 16px; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
a.mat-icon-button { |
||||
|
&:hover, &:focus { |
||||
|
border-bottom: none; |
||||
|
} |
||||
|
} |
||||
|
.fields-group { |
||||
|
padding: 8px; |
||||
|
margin: 10px 0; |
||||
|
border: 1px groove rgba(0, 0, 0, .25); |
||||
|
border-radius: 4px; |
||||
|
|
||||
|
legend { |
||||
|
padding-left: 8px; |
||||
|
padding-right: 8px; |
||||
|
margin-bottom: -30px; |
||||
|
.mat-form-field { |
||||
|
margin-bottom: 21px; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,144 @@ |
|||||
|
///
|
||||
|
/// 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, EventEmitter, forwardRef, Input, OnInit, Output } from '@angular/core'; |
||||
|
import { |
||||
|
ControlValueAccessor, |
||||
|
FormBuilder, |
||||
|
FormControl, |
||||
|
FormGroup, NG_VALIDATORS, |
||||
|
NG_VALUE_ACCESSOR, Validator, |
||||
|
Validators |
||||
|
} from '@angular/forms'; |
||||
|
import { DeviceProfileAlarm } from '@shared/models/device.models'; |
||||
|
import { deepClone } from '@core/utils'; |
||||
|
import { MatDialog } from '@angular/material/dialog'; |
||||
|
import { |
||||
|
DeviceProfileAlarmDialogComponent, |
||||
|
DeviceProfileAlarmDialogData |
||||
|
} from './device-profile-alarm-dialog.component'; |
||||
|
|
||||
|
@Component({ |
||||
|
selector: 'tb-device-profile-alarm', |
||||
|
templateUrl: './device-profile-alarm.component.html', |
||||
|
styleUrls: ['./device-profile-alarm.component.scss'], |
||||
|
providers: [ |
||||
|
{ |
||||
|
provide: NG_VALUE_ACCESSOR, |
||||
|
useExisting: forwardRef(() => DeviceProfileAlarmComponent), |
||||
|
multi: true |
||||
|
}, |
||||
|
{ |
||||
|
provide: NG_VALIDATORS, |
||||
|
useExisting: forwardRef(() => DeviceProfileAlarmComponent), |
||||
|
multi: true, |
||||
|
} |
||||
|
] |
||||
|
}) |
||||
|
export class DeviceProfileAlarmComponent implements ControlValueAccessor, OnInit, Validator { |
||||
|
|
||||
|
@Input() |
||||
|
disabled: boolean; |
||||
|
|
||||
|
@Output() |
||||
|
removeAlarm = new EventEmitter(); |
||||
|
|
||||
|
private modelValue: DeviceProfileAlarm; |
||||
|
|
||||
|
alarmFormGroup: FormGroup; |
||||
|
|
||||
|
private propagateChange = (v: any) => { }; |
||||
|
|
||||
|
constructor(private dialog: MatDialog, |
||||
|
private fb: FormBuilder) { |
||||
|
} |
||||
|
|
||||
|
registerOnChange(fn: any): void { |
||||
|
this.propagateChange = fn; |
||||
|
} |
||||
|
|
||||
|
registerOnTouched(fn: any): void { |
||||
|
} |
||||
|
|
||||
|
ngOnInit() { |
||||
|
this.alarmFormGroup = this.fb.group({ |
||||
|
id: [null, Validators.required], |
||||
|
alarmType: [null, Validators.required], |
||||
|
createRules: [null], |
||||
|
clearRule: [null], |
||||
|
propagate: [null], |
||||
|
propagateRelationTypes: [null] |
||||
|
}); |
||||
|
this.alarmFormGroup.valueChanges.subscribe(() => { |
||||
|
this.updateModel(); |
||||
|
}); |
||||
|
} |
||||
|
|
||||
|
setDisabledState(isDisabled: boolean): void { |
||||
|
this.disabled = isDisabled; |
||||
|
if (this.disabled) { |
||||
|
this.alarmFormGroup.disable({emitEvent: false}); |
||||
|
} else { |
||||
|
this.alarmFormGroup.enable({emitEvent: false}); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
writeValue(value: DeviceProfileAlarm): void { |
||||
|
this.modelValue = value; |
||||
|
this.alarmFormGroup.reset(this.modelValue, {emitEvent: false}); |
||||
|
} |
||||
|
|
||||
|
/* openAlarm($event: Event) { |
||||
|
if ($event) { |
||||
|
$event.stopPropagation(); |
||||
|
} |
||||
|
this.dialog.open<DeviceProfileAlarmDialogComponent, DeviceProfileAlarmDialogData, |
||||
|
DeviceProfileAlarm>(DeviceProfileAlarmDialogComponent, { |
||||
|
disableClose: true, |
||||
|
panelClass: ['tb-dialog', 'tb-fullscreen-dialog'], |
||||
|
data: { |
||||
|
isAdd: false, |
||||
|
alarm: this.disabled ? this.modelValue : deepClone(this.modelValue), |
||||
|
isReadOnly: this.disabled |
||||
|
} |
||||
|
}).afterClosed().subscribe( |
||||
|
(deviceProfileAlarm) => { |
||||
|
if (deviceProfileAlarm) { |
||||
|
this.modelValue = deviceProfileAlarm; |
||||
|
this.updateModel(); |
||||
|
} |
||||
|
} |
||||
|
); |
||||
|
} */ |
||||
|
|
||||
|
public validate(c: FormControl) { |
||||
|
return (this.alarmFormGroup.valid) ? null : { |
||||
|
alarm: { |
||||
|
valid: false, |
||||
|
}, |
||||
|
}; |
||||
|
} |
||||
|
|
||||
|
private updateModel() { |
||||
|
if (this.alarmFormGroup.valid) { |
||||
|
const value = this.alarmFormGroup.value; |
||||
|
this.modelValue = {...this.modelValue, ...value}; |
||||
|
this.propagateChange(this.modelValue); |
||||
|
} else { |
||||
|
this.propagateChange(null); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,38 @@ |
|||||
|
<!-- |
||||
|
|
||||
|
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 fxLayout="column"> |
||||
|
<div class="tb-device-profile-alarms"> |
||||
|
<div *ngFor="let alarmControl of alarmsFormArray().controls; let $index = index; last as isLast;" |
||||
|
fxLayout="column"> |
||||
|
<tb-device-profile-alarm [formControl]="alarmControl" |
||||
|
(removeAlarm)="removeAlarm($index)"> |
||||
|
</tb-device-profile-alarm> |
||||
|
</div> |
||||
|
</div> |
||||
|
<div *ngIf="!disabled" fxFlex fxLayout="row" fxLayoutAlign="end center" |
||||
|
style="padding-top: 16px;"> |
||||
|
<button mat-raised-button color="primary" |
||||
|
type="button" |
||||
|
(click)="addAlarm()" |
||||
|
matTooltip="{{ 'device-profile.add-alarm-rule' | translate }}" |
||||
|
matTooltipPosition="above"> |
||||
|
<mat-icon>add</mat-icon> |
||||
|
<span translate>action.add</span> |
||||
|
</button> |
||||
|
</div> |
||||
|
</div> |
||||
@ -0,0 +1,29 @@ |
|||||
|
/** |
||||
|
* 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 '../scss/constants'; |
||||
|
|
||||
|
:host { |
||||
|
.tb-device-profile-alarms { |
||||
|
max-height: 400px; |
||||
|
overflow-y: auto; |
||||
|
&.mat-padding { |
||||
|
padding: 8px; |
||||
|
@media #{$mat-gt-sm} { |
||||
|
padding: 16px; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,181 @@ |
|||||
|
///
|
||||
|
/// 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 { |
||||
|
AbstractControl, |
||||
|
ControlValueAccessor, |
||||
|
FormArray, |
||||
|
FormBuilder, FormControl, |
||||
|
FormGroup, NG_VALIDATORS, |
||||
|
NG_VALUE_ACCESSOR, Validator, |
||||
|
Validators |
||||
|
} from '@angular/forms'; |
||||
|
import { Store } from '@ngrx/store'; |
||||
|
import { AppState } from '@app/core/core.state'; |
||||
|
import { coerceBooleanProperty } from '@angular/cdk/coercion'; |
||||
|
import { DeviceProfileAlarm } from '@shared/models/device.models'; |
||||
|
import { guid } from '@core/utils'; |
||||
|
import { Subscription } from 'rxjs'; |
||||
|
import { |
||||
|
DeviceProfileAlarmDialogComponent, |
||||
|
DeviceProfileAlarmDialogData |
||||
|
} from './device-profile-alarm-dialog.component'; |
||||
|
import { MatDialog } from '@angular/material/dialog'; |
||||
|
|
||||
|
@Component({ |
||||
|
selector: 'tb-device-profile-alarms', |
||||
|
templateUrl: './device-profile-alarms.component.html', |
||||
|
styleUrls: ['./device-profile-alarms.component.scss'], |
||||
|
providers: [ |
||||
|
{ |
||||
|
provide: NG_VALUE_ACCESSOR, |
||||
|
useExisting: forwardRef(() => DeviceProfileAlarmsComponent), |
||||
|
multi: true |
||||
|
}, |
||||
|
{ |
||||
|
provide: NG_VALIDATORS, |
||||
|
useExisting: forwardRef(() => DeviceProfileAlarmsComponent), |
||||
|
multi: true, |
||||
|
} |
||||
|
] |
||||
|
}) |
||||
|
export class DeviceProfileAlarmsComponent implements ControlValueAccessor, OnInit, Validator { |
||||
|
|
||||
|
deviceProfileAlarmsFormGroup: FormGroup; |
||||
|
|
||||
|
private requiredValue: boolean; |
||||
|
get required(): boolean { |
||||
|
return this.requiredValue; |
||||
|
} |
||||
|
@Input() |
||||
|
set required(value: boolean) { |
||||
|
this.requiredValue = coerceBooleanProperty(value); |
||||
|
} |
||||
|
|
||||
|
@Input() |
||||
|
disabled: boolean; |
||||
|
|
||||
|
private valueChangeSubscription: Subscription = null; |
||||
|
|
||||
|
private propagateChange = (v: any) => { }; |
||||
|
|
||||
|
constructor(private store: Store<AppState>, |
||||
|
private fb: FormBuilder, |
||||
|
private dialog: MatDialog) { |
||||
|
} |
||||
|
|
||||
|
registerOnChange(fn: any): void { |
||||
|
this.propagateChange = fn; |
||||
|
} |
||||
|
|
||||
|
registerOnTouched(fn: any): void { |
||||
|
} |
||||
|
|
||||
|
ngOnInit() { |
||||
|
this.deviceProfileAlarmsFormGroup = this.fb.group({ |
||||
|
alarms: this.fb.array([]) |
||||
|
}); |
||||
|
} |
||||
|
|
||||
|
alarmsFormArray(): FormArray { |
||||
|
return this.deviceProfileAlarmsFormGroup.get('alarms') as FormArray; |
||||
|
} |
||||
|
|
||||
|
setDisabledState(isDisabled: boolean): void { |
||||
|
this.disabled = isDisabled; |
||||
|
if (this.disabled) { |
||||
|
this.deviceProfileAlarmsFormGroup.disable({emitEvent: false}); |
||||
|
} else { |
||||
|
this.deviceProfileAlarmsFormGroup.enable({emitEvent: false}); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
writeValue(alarms: Array<DeviceProfileAlarm> | null): void { |
||||
|
if (this.valueChangeSubscription) { |
||||
|
this.valueChangeSubscription.unsubscribe(); |
||||
|
} |
||||
|
const alarmsControls: Array<AbstractControl> = []; |
||||
|
if (alarms) { |
||||
|
alarms.forEach((alarm) => { |
||||
|
alarmsControls.push(this.fb.control(alarm, [Validators.required])); |
||||
|
}); |
||||
|
} |
||||
|
this.deviceProfileAlarmsFormGroup.setControl('alarms', this.fb.array(alarmsControls)); |
||||
|
if (this.disabled) { |
||||
|
this.deviceProfileAlarmsFormGroup.disable({emitEvent: false}); |
||||
|
} else { |
||||
|
this.deviceProfileAlarmsFormGroup.enable({emitEvent: false}); |
||||
|
} |
||||
|
this.valueChangeSubscription = this.deviceProfileAlarmsFormGroup.valueChanges.subscribe(() => { |
||||
|
this.updateModel(); |
||||
|
}); |
||||
|
} |
||||
|
|
||||
|
public removeAlarm(index: number) { |
||||
|
(this.deviceProfileAlarmsFormGroup.get('alarms') as FormArray).removeAt(index); |
||||
|
} |
||||
|
|
||||
|
public addAlarm() { |
||||
|
const alarm: DeviceProfileAlarm = { |
||||
|
id: guid(), |
||||
|
alarmType: '', |
||||
|
createRules: { |
||||
|
empty: { |
||||
|
condition: { |
||||
|
condition: [] |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
}; |
||||
|
const alarmsArray = this.deviceProfileAlarmsFormGroup.get('alarms') as FormArray; |
||||
|
alarmsArray.push(this.fb.control(alarm, [Validators.required])); |
||||
|
this.deviceProfileAlarmsFormGroup.updateValueAndValidity(); |
||||
|
|
||||
|
/* this.dialog.open<DeviceProfileAlarmDialogComponent, DeviceProfileAlarmDialogData, |
||||
|
DeviceProfileAlarm>(DeviceProfileAlarmDialogComponent, { |
||||
|
disableClose: true, |
||||
|
panelClass: ['tb-dialog', 'tb-fullscreen-dialog'], |
||||
|
data: { |
||||
|
isAdd: true, |
||||
|
alarm, |
||||
|
isReadOnly: false |
||||
|
} |
||||
|
}).afterClosed().subscribe( |
||||
|
(deviceProfileAlarm) => { |
||||
|
if (deviceProfileAlarm) { |
||||
|
} |
||||
|
} |
||||
|
); */ |
||||
|
} |
||||
|
|
||||
|
public validate(c: FormControl) { |
||||
|
return (this.deviceProfileAlarmsFormGroup.valid) ? null : { |
||||
|
alarms: { |
||||
|
valid: false, |
||||
|
}, |
||||
|
}; |
||||
|
} |
||||
|
|
||||
|
private updateModel() { |
||||
|
if (this.deviceProfileAlarmsFormGroup.valid) { |
||||
|
const alarms: Array<DeviceProfileAlarm> = this.deviceProfileAlarmsFormGroup.get('alarms').value; |
||||
|
this.propagateChange(alarms); |
||||
|
} else { |
||||
|
this.propagateChange(null); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
Loading…
Reference in new issue