]>
Commit | Line | Data |
---|---|---|
11fdf7f2 | 1 | import { Component, OnInit } from '@angular/core'; |
a4b75251 | 2 | import { Validators } from '@angular/forms'; |
11fdf7f2 TL |
3 | import { ActivatedRoute, Router } from '@angular/router'; |
4 | ||
f67539c2 | 5 | import _ from 'lodash'; |
a4b75251 | 6 | import { forkJoin } from 'rxjs'; |
11fdf7f2 | 7 | |
f67539c2 TL |
8 | import { RgwBucketService } from '~/app/shared/api/rgw-bucket.service'; |
9 | import { RgwSiteService } from '~/app/shared/api/rgw-site.service'; | |
10 | import { RgwUserService } from '~/app/shared/api/rgw-user.service'; | |
11 | import { ActionLabelsI18n, URLVerbs } from '~/app/shared/constants/app.constants'; | |
12 | import { Icons } from '~/app/shared/enum/icons.enum'; | |
13 | import { NotificationType } from '~/app/shared/enum/notification-type.enum'; | |
14 | import { CdForm } from '~/app/shared/forms/cd-form'; | |
15 | import { CdFormBuilder } from '~/app/shared/forms/cd-form-builder'; | |
16 | import { CdFormGroup } from '~/app/shared/forms/cd-form-group'; | |
17 | import { CdValidators } from '~/app/shared/forms/cd-validators'; | |
18 | import { NotificationService } from '~/app/shared/services/notification.service'; | |
9f95a23c TL |
19 | import { RgwBucketMfaDelete } from '../models/rgw-bucket-mfa-delete'; |
20 | import { RgwBucketVersioning } from '../models/rgw-bucket-versioning'; | |
11fdf7f2 TL |
21 | |
22 | @Component({ | |
23 | selector: 'cd-rgw-bucket-form', | |
24 | templateUrl: './rgw-bucket-form.component.html', | |
25 | styleUrls: ['./rgw-bucket-form.component.scss'] | |
26 | }) | |
f67539c2 | 27 | export class RgwBucketFormComponent extends CdForm implements OnInit { |
11fdf7f2 TL |
28 | bucketForm: CdFormGroup; |
29 | editing = false; | |
9f95a23c | 30 | owners: string[] = null; |
11fdf7f2 TL |
31 | action: string; |
32 | resource: string; | |
9f95a23c TL |
33 | zonegroup: string; |
34 | placementTargets: object[] = []; | |
9f95a23c | 35 | isVersioningAlreadyEnabled = false; |
9f95a23c TL |
36 | isMfaDeleteAlreadyEnabled = false; |
37 | icons = Icons; | |
11fdf7f2 | 38 | |
f67539c2 TL |
39 | get isVersioningEnabled(): boolean { |
40 | return this.bucketForm.getValue('versioning'); | |
41 | } | |
42 | get isMfaDeleteEnabled(): boolean { | |
43 | return this.bucketForm.getValue('mfa-delete'); | |
44 | } | |
45 | ||
11fdf7f2 TL |
46 | constructor( |
47 | private route: ActivatedRoute, | |
48 | private router: Router, | |
49 | private formBuilder: CdFormBuilder, | |
50 | private rgwBucketService: RgwBucketService, | |
9f95a23c | 51 | private rgwSiteService: RgwSiteService, |
11fdf7f2 TL |
52 | private rgwUserService: RgwUserService, |
53 | private notificationService: NotificationService, | |
11fdf7f2 TL |
54 | public actionLabels: ActionLabelsI18n |
55 | ) { | |
f67539c2 | 56 | super(); |
11fdf7f2 TL |
57 | this.editing = this.router.url.startsWith(`/rgw/bucket/${URLVerbs.EDIT}`); |
58 | this.action = this.editing ? this.actionLabels.EDIT : this.actionLabels.CREATE; | |
f67539c2 | 59 | this.resource = $localize`bucket`; |
11fdf7f2 TL |
60 | this.createForm(); |
61 | } | |
62 | ||
63 | createForm() { | |
9f95a23c | 64 | const self = this; |
b3b6e05e | 65 | const lockDaysValidator = CdValidators.custom('lockDays', () => { |
9f95a23c TL |
66 | if (!self.bucketForm || !_.get(self.bucketForm.getRawValue(), 'lock_enabled')) { |
67 | return false; | |
68 | } | |
b3b6e05e TL |
69 | const lockDays = Number(self.bucketForm.getValue('lock_retention_period_days')); |
70 | return !Number.isInteger(lockDays) || lockDays === 0; | |
9f95a23c | 71 | }); |
11fdf7f2 TL |
72 | this.bucketForm = this.formBuilder.group({ |
73 | id: [null], | |
a4b75251 TL |
74 | bid: [ |
75 | null, | |
76 | [Validators.required], | |
77 | this.editing | |
78 | ? [] | |
79 | : [CdValidators.bucketName(), CdValidators.bucketExistence(false, this.rgwBucketService)] | |
80 | ], | |
9f95a23c TL |
81 | owner: [null, [Validators.required]], |
82 | 'placement-target': [null, this.editing ? [] : [Validators.required]], | |
83 | versioning: [null], | |
84 | 'mfa-delete': [null], | |
85 | 'mfa-token-serial': [''], | |
86 | 'mfa-token-pin': [''], | |
87 | lock_enabled: [{ value: false, disabled: this.editing }], | |
88 | lock_mode: ['COMPLIANCE'], | |
b3b6e05e | 89 | lock_retention_period_days: [0, [CdValidators.number(false), lockDaysValidator]] |
11fdf7f2 TL |
90 | }); |
91 | } | |
92 | ||
93 | ngOnInit() { | |
f67539c2 TL |
94 | const promises = { |
95 | owners: this.rgwUserService.enumerate() | |
96 | }; | |
11fdf7f2 | 97 | |
9f95a23c | 98 | if (!this.editing) { |
f67539c2 | 99 | promises['getPlacementTargets'] = this.rgwSiteService.get('placement-targets'); |
9f95a23c TL |
100 | } |
101 | ||
102 | // Process route parameters. | |
103 | this.route.params.subscribe((params: { bid: string }) => { | |
f67539c2 TL |
104 | if (params.hasOwnProperty('bid')) { |
105 | const bid = decodeURIComponent(params.bid); | |
106 | promises['getBid'] = this.rgwBucketService.get(bid); | |
11fdf7f2 | 107 | } |
9f95a23c | 108 | |
f67539c2 TL |
109 | forkJoin(promises).subscribe((data: any) => { |
110 | // Get the list of possible owners. | |
111 | this.owners = (<string[]>data.owners).sort(); | |
112 | ||
113 | // Get placement targets: | |
114 | if (data['getPlacementTargets']) { | |
115 | const placementTargets = data['getPlacementTargets']; | |
116 | this.zonegroup = placementTargets['zonegroup']; | |
117 | _.forEach(placementTargets['placement_targets'], (placementTarget) => { | |
118 | placementTarget['description'] = `${placementTarget['name']} (${$localize`pool`}: ${ | |
119 | placementTarget['data_pool'] | |
120 | })`; | |
121 | this.placementTargets.push(placementTarget); | |
122 | }); | |
123 | ||
124 | // If there is only 1 placement target, select it by default: | |
125 | if (this.placementTargets.length === 1) { | |
126 | this.bucketForm.get('placement-target').setValue(this.placementTargets[0]['name']); | |
127 | } | |
128 | } | |
129 | ||
130 | if (data['getBid']) { | |
131 | const bidResp = data['getBid']; | |
132 | // Get the default values (incl. the values from disabled fields). | |
133 | const defaults = _.clone(this.bucketForm.getRawValue()); | |
134 | ||
135 | // Get the values displayed in the form. We need to do that to | |
136 | // extract those key/value pairs from the response data, otherwise | |
137 | // the Angular react framework will throw an error if there is no | |
138 | // field for a given key. | |
139 | let value: object = _.pick(bidResp, _.keys(defaults)); | |
b3b6e05e | 140 | value['lock_retention_period_days'] = this.rgwBucketService.getLockDays(bidResp); |
f67539c2 TL |
141 | value['placement-target'] = bidResp['placement_rule']; |
142 | value['versioning'] = bidResp['versioning'] === RgwBucketVersioning.ENABLED; | |
143 | value['mfa-delete'] = bidResp['mfa_delete'] === RgwBucketMfaDelete.ENABLED; | |
144 | ||
145 | // Append default values. | |
146 | value = _.merge(defaults, value); | |
147 | ||
148 | // Update the form. | |
149 | this.bucketForm.setValue(value); | |
150 | if (this.editing) { | |
151 | this.isVersioningAlreadyEnabled = this.isVersioningEnabled; | |
152 | this.isMfaDeleteAlreadyEnabled = this.isMfaDeleteEnabled; | |
153 | this.setMfaDeleteValidators(); | |
b3b6e05e TL |
154 | if (value['lock_enabled']) { |
155 | this.bucketForm.controls['versioning'].disable(); | |
156 | } | |
f67539c2 | 157 | } |
9f95a23c | 158 | } |
f67539c2 TL |
159 | |
160 | this.loadingReady(); | |
9f95a23c TL |
161 | }); |
162 | }); | |
11fdf7f2 TL |
163 | } |
164 | ||
165 | goToListView() { | |
166 | this.router.navigate(['/rgw/bucket']); | |
167 | } | |
168 | ||
169 | submit() { | |
170 | // Exit immediately if the form isn't dirty. | |
171 | if (this.bucketForm.pristine) { | |
172 | this.goToListView(); | |
173 | return; | |
174 | } | |
9f95a23c | 175 | const values = this.bucketForm.value; |
11fdf7f2 TL |
176 | if (this.editing) { |
177 | // Edit | |
9f95a23c TL |
178 | const versioning = this.getVersioningStatus(); |
179 | const mfaDelete = this.getMfaDeleteStatus(); | |
180 | this.rgwBucketService | |
181 | .update( | |
182 | values['bid'], | |
183 | values['id'], | |
184 | values['owner'], | |
185 | versioning, | |
186 | mfaDelete, | |
187 | values['mfa-token-serial'], | |
188 | values['mfa-token-pin'], | |
189 | values['lock_mode'], | |
b3b6e05e | 190 | values['lock_retention_period_days'] |
9f95a23c TL |
191 | ) |
192 | .subscribe( | |
193 | () => { | |
194 | this.notificationService.show( | |
195 | NotificationType.success, | |
f67539c2 | 196 | $localize`Updated Object Gateway bucket '${values.bid}'.` |
9f95a23c TL |
197 | ); |
198 | this.goToListView(); | |
199 | }, | |
200 | () => { | |
201 | // Reset the 'Submit' button. | |
202 | this.bucketForm.setErrors({ cdSubmitButton: true }); | |
203 | } | |
204 | ); | |
11fdf7f2 TL |
205 | } else { |
206 | // Add | |
9f95a23c TL |
207 | this.rgwBucketService |
208 | .create( | |
209 | values['bid'], | |
210 | values['owner'], | |
211 | this.zonegroup, | |
212 | values['placement-target'], | |
213 | values['lock_enabled'], | |
214 | values['lock_mode'], | |
b3b6e05e | 215 | values['lock_retention_period_days'] |
9f95a23c TL |
216 | ) |
217 | .subscribe( | |
218 | () => { | |
219 | this.notificationService.show( | |
220 | NotificationType.success, | |
f67539c2 | 221 | $localize`Created Object Gateway bucket '${values.bid}'` |
9f95a23c TL |
222 | ); |
223 | this.goToListView(); | |
224 | }, | |
225 | () => { | |
226 | // Reset the 'Submit' button. | |
227 | this.bucketForm.setErrors({ cdSubmitButton: true }); | |
228 | } | |
229 | ); | |
11fdf7f2 TL |
230 | } |
231 | } | |
232 | ||
9f95a23c TL |
233 | areMfaCredentialsRequired() { |
234 | return ( | |
235 | this.isMfaDeleteEnabled !== this.isMfaDeleteAlreadyEnabled || | |
236 | (this.isMfaDeleteAlreadyEnabled && | |
237 | this.isVersioningEnabled !== this.isVersioningAlreadyEnabled) | |
238 | ); | |
239 | } | |
240 | ||
241 | setMfaDeleteValidators() { | |
242 | const mfaTokenSerialControl = this.bucketForm.get('mfa-token-serial'); | |
243 | const mfaTokenPinControl = this.bucketForm.get('mfa-token-pin'); | |
244 | ||
245 | if (this.areMfaCredentialsRequired()) { | |
246 | mfaTokenSerialControl.setValidators(Validators.required); | |
247 | mfaTokenPinControl.setValidators(Validators.required); | |
248 | } else { | |
249 | mfaTokenSerialControl.setValidators(null); | |
250 | mfaTokenPinControl.setValidators(null); | |
251 | } | |
252 | ||
253 | mfaTokenSerialControl.updateValueAndValidity(); | |
254 | mfaTokenPinControl.updateValueAndValidity(); | |
255 | } | |
256 | ||
257 | getVersioningStatus() { | |
258 | return this.isVersioningEnabled ? RgwBucketVersioning.ENABLED : RgwBucketVersioning.SUSPENDED; | |
259 | } | |
260 | ||
9f95a23c TL |
261 | getMfaDeleteStatus() { |
262 | return this.isMfaDeleteEnabled ? RgwBucketMfaDelete.ENABLED : RgwBucketMfaDelete.DISABLED; | |
263 | } | |
11fdf7f2 | 264 | } |