1 import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core';
2 import { FormControl, Validators } from '@angular/forms';
4 import _ from 'lodash';
5 import { ReplaySubject } from 'rxjs';
7 import { Icons } from '~/app/shared/enum/icons.enum';
8 import { CdFormGroup } from '~/app/shared/forms/cd-form-group';
10 RbdConfigurationEntry,
11 RbdConfigurationSourceField,
13 } from '~/app/shared/models/configuration';
14 import { FormatterService } from '~/app/shared/services/formatter.service';
15 import { RbdConfigurationService } from '~/app/shared/services/rbd-configuration.service';
18 selector: 'cd-rbd-configuration-form',
19 templateUrl: './rbd-configuration-form.component.html',
20 styleUrls: ['./rbd-configuration-form.component.scss']
22 export class RbdConfigurationFormComponent implements OnInit {
26 initializeData = new ReplaySubject<{
27 initialData: RbdConfigurationEntry[];
28 sourceType: RbdConfigurationSourceField;
31 changes = new EventEmitter<any>();
35 ngDataReady = new EventEmitter<any>();
36 initialData: RbdConfigurationEntry[];
37 configurationType = RbdConfigurationType;
38 sectionVisibility: { [key: string]: boolean } = {};
41 public formatterService: FormatterService,
42 public rbdConfigurationService: RbdConfigurationService
46 const configFormGroup = this.createConfigurationFormGroup();
47 this.form.addControl('configuration', configFormGroup);
49 // Listen to changes and emit the values to the parent component
50 configFormGroup.valueChanges.subscribe(() => {
51 this.changes.emit(this.getDirtyValues.bind(this));
54 if (this.initializeData) {
55 this.initializeData.subscribe((data: Record<string, any>) => {
56 this.initialData = data.initialData;
57 const dataType = data.sourceType;
58 this.rbdConfigurationService.getWritableOptionFields().forEach((option) => {
59 const optionData = data.initialData
60 .filter((entry: Record<string, any>) => entry.name === option.name)
62 if (optionData && optionData['source'] === dataType) {
63 this.form.get(`configuration.${option.name}`).setValue(optionData['value']);
66 this.ngDataReady.emit();
70 this.rbdConfigurationService
71 .getWritableSections()
72 .forEach((section) => (this.sectionVisibility[section.class] = false));
75 getDirtyValues(includeLocalValues = false, localFieldType?: RbdConfigurationSourceField) {
76 if (includeLocalValues && !localFieldType) {
78 'ProgrammingError: If local values shall be included, a proper localFieldType argument has to be provided, too';
83 this.rbdConfigurationService.getWritableOptionFields().forEach((config) => {
84 const control: any = this.form.get('configuration').get(config.name);
85 const dirty = control.dirty;
87 if (this.initialData && this.initialData[config.name] === control.value) {
88 return; // Skip controls with initial data loaded
91 if (dirty || (includeLocalValues && control['source'] === localFieldType)) {
92 if (control.value === null) {
93 result[config.name] = control.value;
94 } else if (config.type === RbdConfigurationType.bps) {
95 result[config.name] = this.formatterService.toBytes(control.value);
96 } else if (config.type === RbdConfigurationType.milliseconds) {
97 result[config.name] = this.formatterService.toMilliseconds(control.value);
98 } else if (config.type === RbdConfigurationType.iops) {
99 result[config.name] = this.formatterService.toIops(control.value);
101 result[config.name] = control.value;
110 * Dynamically create form controls.
112 private createConfigurationFormGroup() {
113 const configFormGroup = new CdFormGroup({});
115 this.rbdConfigurationService.getWritableOptionFields().forEach((c) => {
116 let control: FormControl;
118 c.type === RbdConfigurationType.milliseconds ||
119 c.type === RbdConfigurationType.iops ||
120 c.type === RbdConfigurationType.bps
122 let initialValue = 0;
123 _.forEach(this.initialData, (configList) => {
124 if (configList['name'] === c.name) {
125 initialValue = configList['value'];
128 control = new FormControl(initialValue, Validators.min(0));
131 `Type ${c.type} is unknown, you may need to add it to RbdConfiguration class`
134 configFormGroup.addControl(c.name, control);
137 return configFormGroup;
141 * Reset the value. The inherited value will be used instead.
143 reset(optionName: string) {
144 const formControl: any = this.form.get('configuration').get(optionName);
145 if (formControl.disabled) {
146 formControl.setValue(formControl['previousValue'] || 0);
147 formControl.enable();
148 if (!formControl['previousValue']) {
149 formControl.markAsPristine();
152 formControl['previousValue'] = formControl.value;
153 formControl.setValue(null);
154 formControl.markAsDirty();
155 formControl.disable();
159 isDisabled(optionName: string) {
160 return this.form.get('configuration').get(optionName).disabled;
163 toggleSectionVisibility(className: string) {
164 this.sectionVisibility[className] = !this.sectionVisibility[className];