]> git.apps.os.sepia.ceph.com Git - ceph.git/blob
f95479fc53e012258af2e2668437622000015087
[ceph.git] /
1 import { Component, OnInit } from '@angular/core';
2 import { UntypedFormControl, UntypedFormGroup, ValidatorFn } from '@angular/forms';
3 import { ActivatedRoute, Router } from '@angular/router';
4
5 import _ from 'lodash';
6
7 import { ConfigurationService } from '~/app/shared/api/configuration.service';
8 import { ConfigFormModel } from '~/app/shared/components/config-option/config-option.model';
9 import { ConfigOptionTypes } from '~/app/shared/components/config-option/config-option.types';
10 import { ActionLabelsI18n } from '~/app/shared/constants/app.constants';
11 import { NotificationType } from '~/app/shared/enum/notification-type.enum';
12 import { CdForm } from '~/app/shared/forms/cd-form';
13 import { CdFormGroup } from '~/app/shared/forms/cd-form-group';
14 import { NotificationService } from '~/app/shared/services/notification.service';
15 import { ConfigFormCreateRequestModel } from './configuration-form-create-request.model';
16 import { CriticalConfirmationModalComponent } from '~/app/shared/components/critical-confirmation-modal/critical-confirmation-modal.component';
17 import { ModalService } from '~/app/shared/services/modal.service';
18
19 const RGW = 'rgw';
20
21 @Component({
22   selector: 'cd-configuration-form',
23   templateUrl: './configuration-form.component.html',
24   styleUrls: ['./configuration-form.component.scss']
25 })
26 export class ConfigurationFormComponent extends CdForm implements OnInit {
27   configForm: CdFormGroup;
28   response: ConfigFormModel;
29   type: string;
30   inputType: string;
31   humanReadableType: string;
32   minValue: number;
33   maxValue: number;
34   patternHelpText: string;
35   availSections = ['global', 'mon', 'mgr', 'osd', 'mds', 'client'];
36   forceUpdate: boolean;
37
38   constructor(
39     public actionLabels: ActionLabelsI18n,
40     private route: ActivatedRoute,
41     private router: Router,
42     private configService: ConfigurationService,
43     private notificationService: NotificationService,
44     private modalService: ModalService
45   ) {
46     super();
47     this.createForm();
48   }
49
50   createForm() {
51     const formControls = {
52       name: new UntypedFormControl({ value: null }),
53       desc: new UntypedFormControl({ value: null }),
54       long_desc: new UntypedFormControl({ value: null }),
55       values: new UntypedFormGroup({}),
56       default: new UntypedFormControl({ value: null }),
57       daemon_default: new UntypedFormControl({ value: null }),
58       services: new UntypedFormControl([])
59     };
60
61     this.availSections.forEach((section) => {
62       formControls.values.addControl(section, new UntypedFormControl(null));
63     });
64
65     this.configForm = new CdFormGroup(formControls);
66   }
67
68   ngOnInit() {
69     this.route.params.subscribe((params: { name: string }) => {
70       const configName = params.name;
71       this.configService.get(configName).subscribe((resp: ConfigFormModel) => {
72         this.setResponse(resp);
73         this.loadingReady();
74       });
75     });
76   }
77
78   getValidators(configOption: any): ValidatorFn[] {
79     const typeValidators = ConfigOptionTypes.getTypeValidators(configOption);
80     if (typeValidators) {
81       this.patternHelpText = typeValidators.patternHelpText;
82
83       if ('max' in typeValidators && typeValidators.max !== '') {
84         this.maxValue = typeValidators.max;
85       }
86
87       if ('min' in typeValidators && typeValidators.min !== '') {
88         this.minValue = typeValidators.min;
89       }
90
91       return typeValidators.validators;
92     }
93
94     return undefined;
95   }
96
97   getStep(type: string, value: number): number | undefined {
98     return ConfigOptionTypes.getTypeStep(type, value);
99   }
100
101   setResponse(response: ConfigFormModel) {
102     this.response = response;
103     const validators = this.getValidators(response);
104     this.configForm.get('name').setValue(response.name);
105     this.configForm.get('desc').setValue(response.desc);
106     this.configForm.get('long_desc').setValue(response.long_desc);
107     this.configForm.get('default').setValue(response.default);
108     this.configForm.get('daemon_default').setValue(response.daemon_default);
109     this.configForm.get('services').setValue(response.services);
110
111     if (this.response.value) {
112       this.response.value.forEach((value) => {
113         // Check value type. If it's a boolean value we need to convert it because otherwise we
114         // would use the string representation. That would cause issues for e.g. checkboxes.
115         let sectionValue = null;
116         if (value.value === 'true') {
117           sectionValue = true;
118         } else if (value.value === 'false') {
119           sectionValue = false;
120         } else {
121           sectionValue = value.value;
122         }
123         this.configForm.get('values').get(value.section).setValue(sectionValue);
124       });
125     }
126     this.forceUpdate = !this.response.can_update_at_runtime && response.name.includes(RGW);
127     this.availSections.forEach((section) => {
128       this.configForm.get('values').get(section).setValidators(validators);
129     });
130
131     const currentType = ConfigOptionTypes.getType(response.type);
132     this.type = currentType.name;
133     this.inputType = currentType.inputType;
134     this.humanReadableType = currentType.humanReadable;
135   }
136
137   createRequest(): ConfigFormCreateRequestModel | null {
138     const values: any[] = [];
139
140     this.availSections.forEach((section) => {
141       const sectionValue = this.configForm.getValue(section);
142       if (sectionValue !== null) {
143         values.push({ section: section, value: sectionValue });
144       }
145     });
146
147     if (!_.isEqual(this.response.value, values)) {
148       const request = new ConfigFormCreateRequestModel();
149       request.name = this.configForm.getValue('name');
150       request.value = values;
151       if (this.forceUpdate) {
152         request.force_update = this.forceUpdate;
153       }
154       return request;
155     }
156
157     return null;
158   }
159
160   openCriticalConfirmModal() {
161     this.modalService.show(CriticalConfirmationModalComponent, {
162       buttonText: $localize`Force Edit`,
163       actionDescription: $localize`force edit`,
164       itemDescription: $localize`configuration`,
165       infoMessage: 'Updating this configuration might require restarting the client',
166       submitAction: () => {
167         this.modalService.dismissAll();
168         this.submit();
169       }
170     });
171   }
172
173   submit() {
174     const request = this.createRequest();
175
176     if (request) {
177       this.configService.create(request).subscribe(
178         () => {
179           this.notificationService.show(
180             NotificationType.success,
181             $localize`Updated config option ${request.name}`
182           );
183           this.router.navigate(['/configuration']);
184         },
185         () => {
186           this.configForm.setErrors({ cdSubmitButton: true });
187         }
188       );
189     }
190
191     this.router.navigate(['/configuration']);
192   }
193 }