]> git.proxmox.com Git - ceph.git/blob - ceph/src/pybind/mgr/dashboard/frontend/src/app/shared/components/form-modal/form-modal.component.ts
update ceph source to reef 18.2.1
[ceph.git] / ceph / src / pybind / mgr / dashboard / frontend / src / app / shared / components / form-modal / form-modal.component.ts
1 import { Component, OnInit } from '@angular/core';
2 import { UntypedFormControl, ValidatorFn, Validators } from '@angular/forms';
3
4 import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap';
5 import _ from 'lodash';
6
7 import { CdFormBuilder } from '~/app/shared/forms/cd-form-builder';
8 import { CdFormGroup } from '~/app/shared/forms/cd-form-group';
9 import { CdFormModalFieldConfig } from '~/app/shared/models/cd-form-modal-field-config';
10 import { DimlessBinaryPipe } from '~/app/shared/pipes/dimless-binary.pipe';
11 import { FormatterService } from '~/app/shared/services/formatter.service';
12
13 @Component({
14 selector: 'cd-form-modal',
15 templateUrl: './form-modal.component.html',
16 styleUrls: ['./form-modal.component.scss']
17 })
18 export class FormModalComponent implements OnInit {
19 // Input
20 titleText: string;
21 message: string;
22 fields: CdFormModalFieldConfig[];
23 submitButtonText: string;
24 onSubmit: Function;
25
26 // Internal
27 formGroup: CdFormGroup;
28
29 constructor(
30 public activeModal: NgbActiveModal,
31 private formBuilder: CdFormBuilder,
32 private formatter: FormatterService,
33 private dimlessBinaryPipe: DimlessBinaryPipe
34 ) {}
35
36 ngOnInit() {
37 this.createForm();
38 }
39
40 createForm() {
41 const controlsConfig: Record<string, UntypedFormControl> = {};
42 this.fields.forEach((field) => {
43 controlsConfig[field.name] = this.createFormControl(field);
44 });
45 this.formGroup = this.formBuilder.group(controlsConfig);
46 }
47
48 private createFormControl(field: CdFormModalFieldConfig): UntypedFormControl {
49 let validators: ValidatorFn[] = [];
50 if (_.isBoolean(field.required) && field.required) {
51 validators.push(Validators.required);
52 }
53 if (field.validators) {
54 validators = validators.concat(field.validators);
55 }
56 return new UntypedFormControl(
57 _.defaultTo(
58 field.type === 'binary' ? this.dimlessBinaryPipe.transform(field.value) : field.value,
59 null
60 ),
61 { validators }
62 );
63 }
64
65 getError(field: CdFormModalFieldConfig): string {
66 const formErrors = this.formGroup.get(field.name).errors;
67 const errors = Object.keys(formErrors).map((key) => {
68 return this.getErrorMessage(key, formErrors[key], field.errors);
69 });
70 return errors.join('<br>');
71 }
72
73 private getErrorMessage(
74 error: string,
75 errorContext: any,
76 fieldErrors: { [error: string]: string }
77 ): string {
78 if (fieldErrors) {
79 const customError = fieldErrors[error];
80 if (customError) {
81 return customError;
82 }
83 }
84 if (['binaryMin', 'binaryMax'].includes(error)) {
85 // binaryMin and binaryMax return a function that take I18n to
86 // provide a translated error message.
87 return errorContext();
88 }
89 if (error === 'required') {
90 return $localize`This field is required.`;
91 }
92 if (error === 'pattern') {
93 return $localize`Size must be a number or in a valid format. eg: 5 GiB`;
94 }
95 return $localize`An error occurred.`;
96 }
97
98 onSubmitForm(values: any) {
99 const binaries = this.fields
100 .filter((field) => field.type === 'binary')
101 .map((field) => field.name);
102 binaries.forEach((key) => {
103 const value = values[key];
104 if (value) {
105 values[key] = this.formatter.toBytes(value);
106 }
107 });
108 this.activeModal.close();
109 if (_.isFunction(this.onSubmit)) {
110 this.onSubmit(values);
111 }
112 }
113 }