1 import { Component, OnInit } from '@angular/core';
2 import { FormControl, FormGroup, ValidatorFn, Validators } from '@angular/forms';
3 import { ActivatedRoute, Router } from '@angular/router';
5 import { I18n } from '@ngx-translate/i18n-polyfill';
6 import * as _ from 'lodash';
8 import { ConfigurationService } from '../../../../shared/api/configuration.service';
9 import { NotificationType } from '../../../../shared/enum/notification-type.enum';
10 import { CdFormGroup } from '../../../../shared/forms/cd-form-group';
11 import { CdValidators } from '../../../../shared/forms/cd-validators';
12 import { NotificationService } from '../../../../shared/services/notification.service';
13 import { ConfigFormCreateRequestModel } from './configuration-form-create-request.model';
14 import { ConfigFormModel } from './configuration-form.model';
17 selector: 'cd-configuration-form',
18 templateUrl: './configuration-form.component.html',
19 styleUrls: ['./configuration-form.component.scss']
21 export class ConfigurationFormComponent implements OnInit {
22 configForm: CdFormGroup;
23 response: ConfigFormModel;
26 humanReadableType: string;
29 patternHelpText: string;
30 availSections = ['global', 'mon', 'mgr', 'osd', 'mds', 'client'];
33 private route: ActivatedRoute,
34 private router: Router,
35 private configService: ConfigurationService,
36 private notificationService: NotificationService,
43 const formControls = {
44 name: new FormControl({ value: null }),
45 desc: new FormControl({ value: null }),
46 long_desc: new FormControl({ value: null }),
47 values: new FormGroup({}),
48 default: new FormControl({ value: null }),
49 daemon_default: new FormControl({ value: null }),
50 services: new FormControl([])
53 this.availSections.forEach((section) => {
54 formControls.values.addControl(section, new FormControl(null));
57 this.configForm = new CdFormGroup(formControls);
61 this.route.params.subscribe((params: { name: string }) => {
62 const configName = params.name;
63 this.configService.get(configName).subscribe((resp: ConfigFormModel) => {
64 this.setResponse(resp);
69 getType(type: string): any {
74 humanReadable: this.i18n('Positive integer value'),
76 patternHelpText: this.i18n('The entered value needs to be a positive number.'),
83 humanReadable: this.i18n('Integer value'),
84 patternHelpText: this.i18n('The entered value needs to be a number.'),
91 humanReadable: this.i18n('Positive integer value (size)'),
93 patternHelpText: this.i18n('The entered value needs to be a positive number.'),
100 humanReadable: this.i18n('Positive integer value (secs)'),
102 patternHelpText: this.i18n('The entered value needs to be a positive number.'),
104 allowsNegative: false
109 humanReadable: this.i18n('Decimal value'),
110 patternHelpText: this.i18n('The entered value needs to be a number or decimal.'),
117 humanReadable: this.i18n('Text'),
123 humanReadable: this.i18n('IPv4 or IPv6 address'),
124 patternHelpText: this.i18n('The entered value needs to be a valid IP address.'),
130 humanReadable: this.i18n('UUID'),
131 patternHelpText: this.i18n(
132 'The entered value is not a valid UUID, e.g.: 67dcac9f-2c03-4d6c-b7bd-1210b3a259a8'
138 inputType: 'checkbox',
139 humanReadable: this.i18n('Boolean value'),
144 let currentType = null;
146 knownTypes.forEach((knownType) => {
147 if (knownType.name === type) {
148 currentType = knownType;
152 if (currentType !== null) {
156 throw new Error('Found unknown type "' + type + '" for config option.');
159 getValidators(configOption: any): ValidatorFn[] {
160 const typeParams = this.getType(configOption.type);
161 this.patternHelpText = typeParams.patternHelpText;
163 if (typeParams.isNumberType) {
164 const validators = [];
166 if (configOption.max && configOption.max !== '') {
167 this.maxValue = configOption.max;
168 validators.push(Validators.max(configOption.max));
171 if ('min' in configOption && configOption.min !== '') {
172 this.minValue = configOption.min;
173 validators.push(Validators.min(configOption.min));
174 } else if ('defaultMin' in typeParams) {
175 this.minValue = typeParams.defaultMin;
176 validators.push(Validators.min(typeParams.defaultMin));
179 if (configOption.type === 'float') {
180 validators.push(CdValidators.decimalNumber());
182 validators.push(CdValidators.number(typeParams.allowsNegative));
186 } else if (configOption.type === 'addr') {
187 return [CdValidators.ip()];
188 } else if (configOption.type === 'uuid') {
189 return [CdValidators.uuid()];
193 getStep(type: string, value: number): number | undefined {
194 const numberTypes = ['uint', 'int', 'size', 'secs'];
196 if (numberTypes.includes(type)) {
200 if (type === 'float') {
201 if (value !== null) {
202 const stringVal = value.toString();
203 if (stringVal.indexOf('.') !== -1) {
204 // Value type float and contains decimal characters
205 const decimal = value.toString().split('.');
206 return Math.pow(10, -decimal[1].length);
216 setResponse(response: ConfigFormModel) {
217 this.response = response;
218 const validators = this.getValidators(response);
220 this.configForm.get('name').setValue(response.name);
221 this.configForm.get('desc').setValue(response.desc);
222 this.configForm.get('long_desc').setValue(response.long_desc);
223 this.configForm.get('default').setValue(response.default);
224 this.configForm.get('daemon_default').setValue(response.daemon_default);
225 this.configForm.get('services').setValue(response.services);
227 if (this.response.value) {
228 this.response.value.forEach((value) => {
229 // Check value type. If it's a boolean value we need to convert it because otherwise we
230 // would use the string representation. That would cause issues for e.g. checkboxes.
231 let sectionValue = null;
232 if (value.value === 'true') {
234 } else if (value.value === 'false') {
235 sectionValue = false;
237 sectionValue = value.value;
242 .setValue(sectionValue);
246 this.availSections.forEach((section) => {
250 .setValidators(validators);
253 const currentType = this.getType(response.type);
254 this.type = currentType.name;
255 this.inputType = currentType.inputType;
256 this.humanReadableType = currentType.humanReadable;
259 createRequest(): ConfigFormCreateRequestModel | null {
262 this.availSections.forEach((section) => {
263 const sectionValue = this.configForm.getValue(section);
265 values.push({ section: section, value: sectionValue });
269 if (!_.isEqual(this.response.value, values)) {
270 const request = new ConfigFormCreateRequestModel();
271 request.name = this.configForm.getValue('name');
272 request.value = values;
280 const request = this.createRequest();
283 this.configService.create(request).subscribe(
285 this.notificationService.show(
286 NotificationType.success,
287 this.i18n('Config option {{name}} has been updated.', { name: request.name }),
288 this.i18n('Update config option')
290 this.router.navigate(['/configuration']);
293 this.configForm.setErrors({ cdSubmitButton: true });
298 this.router.navigate(['/configuration']);