]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/blob
bbc5ac02d72e3d88fba3b29985cb0b100a3454fb
[ceph.git] /
1 import { Component, Input, OnChanges, SimpleChanges, TemplateRef, ViewChild } from '@angular/core';
2 import { NgbModalRef } from '@ng-bootstrap/ng-bootstrap';
3 import { ActionLabelsI18n } from '~/app/shared/constants/app.constants';
4 import { Icons } from '~/app/shared/enum/icons.enum';
5 import { CdTableAction } from '~/app/shared/models/cd-table-action';
6 import { CdTableColumn } from '~/app/shared/models/cd-table-column';
7 import { CdTableSelection } from '~/app/shared/models/cd-table-selection';
8 import { Permission } from '~/app/shared/models/permissions';
9 import { ModalService } from '~/app/shared/services/modal.service';
10 import { RgwMultisiteService } from '~/app/shared/api/rgw-multisite.service';
11 import { CriticalConfirmationModalComponent } from '~/app/shared/components/critical-confirmation-modal/critical-confirmation-modal.component';
12 import { FinishedTask } from '~/app/shared/models/finished-task';
13 import { Observable, Subscriber, forkJoin as observableForkJoin } from 'rxjs';
14 import { TaskWrapperService } from '~/app/shared/services/task-wrapper.service';
15 import { TableComponent } from '~/app/shared/datatable/table/table.component';
16 import { RgwMultisiteSyncFlowModalComponent } from '../rgw-multisite-sync-flow-modal/rgw-multisite-sync-flow-modal.component';
17 import { FlowType } from '../models/rgw-multisite';
18 import { RgwMultisiteSyncPipeModalComponent } from '../rgw-multisite-sync-pipe-modal/rgw-multisite-sync-pipe-modal.component';
19 import { ModalCdsService } from '~/app/shared/services/modal-cds.service';
20
21 @Component({
22   selector: 'cd-rgw-multisite-sync-policy-details',
23   templateUrl: './rgw-multisite-sync-policy-details.component.html',
24   styleUrls: ['./rgw-multisite-sync-policy-details.component.scss']
25 })
26 export class RgwMultisiteSyncPolicyDetailsComponent implements OnChanges {
27   @Input()
28   expandedRow: any;
29   @Input()
30   permission: Permission;
31
32   @ViewChild(TableComponent)
33   table: TableComponent;
34   @ViewChild('deleteTpl', { static: true })
35   deleteTpl: TemplateRef<any>;
36
37   flowType = FlowType;
38   modalRef: NgbModalRef;
39   symmetricalFlowData: any = [];
40   directionalFlowData: any = [];
41   pipeData: any = [];
42   symmetricalFlowCols: CdTableColumn[];
43   directionalFlowCols: CdTableColumn[];
44   pipeCols: CdTableColumn[];
45   symFlowTableActions: CdTableAction[];
46   dirFlowTableActions: CdTableAction[];
47   pipeTableActions: CdTableAction[];
48   symFlowSelection = new CdTableSelection();
49   dirFlowSelection = new CdTableSelection();
50   pipeSelection = new CdTableSelection();
51
52   constructor(
53     private actionLabels: ActionLabelsI18n,
54     private modalService: ModalService,
55     private rgwMultisiteService: RgwMultisiteService,
56     private taskWrapper: TaskWrapperService,
57     private cdsModalService: ModalCdsService
58   ) {
59     this.symmetricalFlowCols = [
60       {
61         name: 'Name',
62         prop: 'id',
63         flexGrow: 1
64       },
65       {
66         name: 'Zones',
67         prop: 'zones',
68         flexGrow: 1
69       }
70     ];
71     this.directionalFlowCols = [
72       {
73         name: 'Source Zone',
74         prop: 'source_zone',
75         flexGrow: 1
76       },
77       {
78         name: 'Destination Zone',
79         prop: 'dest_zone',
80         flexGrow: 1
81       }
82     ];
83     this.pipeCols = [
84       {
85         name: 'Name',
86         prop: 'id',
87         flexGrow: 1
88       },
89       {
90         name: 'Source Zone',
91         prop: 'source.zones',
92         flexGrow: 1
93       },
94       {
95         name: 'Destination Zone',
96         prop: 'dest.zones',
97         flexGrow: 1
98       },
99       {
100         name: 'Source Bucket',
101         prop: 'source.bucket',
102         flexGrow: 1
103       },
104       {
105         name: 'Destination Bucket',
106         prop: 'dest.bucket',
107         flexGrow: 1
108       }
109     ];
110     const symAddAction: CdTableAction = {
111       permission: 'create',
112       icon: Icons.add,
113       name: this.actionLabels.CREATE,
114       click: () => this.openModal(FlowType.symmetrical),
115       canBePrimary: (selection: CdTableSelection) => !selection.hasSelection
116     };
117     const symEditAction: CdTableAction = {
118       permission: 'update',
119       icon: Icons.edit,
120       name: this.actionLabels.EDIT,
121       click: () => this.openModal(FlowType.symmetrical, true)
122     };
123     const symDeleteAction: CdTableAction = {
124       permission: 'delete',
125       icon: Icons.destroy,
126       disable: () => !this.symFlowSelection.hasSelection,
127       name: this.actionLabels.DELETE,
128       click: () => this.deleteFlow(FlowType.symmetrical),
129       canBePrimary: (selection: CdTableSelection) => selection.hasMultiSelection
130     };
131     this.symFlowTableActions = [symAddAction, symEditAction, symDeleteAction];
132     const dirAddAction: CdTableAction = {
133       permission: 'create',
134       icon: Icons.add,
135       name: this.actionLabels.CREATE,
136       click: () => this.openModal(FlowType.directional),
137       canBePrimary: (selection: CdTableSelection) => !selection.hasSelection
138     };
139     const dirEditAction: CdTableAction = {
140       permission: 'update',
141       icon: Icons.edit,
142       name: this.actionLabels.EDIT,
143       click: () => this.openModal(FlowType.directional, true),
144       disable: () => true // TODO: disabling 'edit' as we are not getting flow ID from backend which is needed for edit
145     };
146     const dirDeleteAction: CdTableAction = {
147       permission: 'delete',
148       icon: Icons.destroy,
149       disable: () => true, // TODO: disabling 'delete' as we are not getting flow ID from backend which is needed for deletion
150       name: this.actionLabels.DELETE,
151       click: () => this.deleteFlow(FlowType.directional),
152       canBePrimary: (selection: CdTableSelection) => selection.hasMultiSelection
153     };
154     this.dirFlowTableActions = [dirAddAction, dirEditAction, dirDeleteAction];
155     const pipeAddAction: CdTableAction = {
156       permission: 'create',
157       icon: Icons.add,
158       name: this.actionLabels.CREATE,
159       click: () => this.openPipeModal(),
160       canBePrimary: (selection: CdTableSelection) => !selection.hasSelection
161     };
162     const pipeEditAction: CdTableAction = {
163       permission: 'update',
164       icon: Icons.edit,
165       name: this.actionLabels.EDIT,
166       click: () => this.openPipeModal(true)
167     };
168     const pipeDeleteAction: CdTableAction = {
169       permission: 'delete',
170       icon: Icons.destroy,
171       disable: () => !this.pipeSelection.hasSelection,
172       name: this.actionLabels.DELETE,
173       click: () => this.deletePipe(),
174       canBePrimary: (selection: CdTableSelection) => selection.hasMultiSelection
175     };
176     this.pipeTableActions = [pipeAddAction, pipeEditAction, pipeDeleteAction];
177   }
178
179   ngOnChanges(changes: SimpleChanges): void {
180     if (changes.expandedRow.currentValue && changes.expandedRow.currentValue.groupName) {
181       this.symmetricalFlowData = [];
182       this.directionalFlowData = [];
183       this.loadData();
184     }
185   }
186
187   loadData(context?: any) {
188     if (this.expandedRow) {
189       this.rgwMultisiteService
190         .getSyncPolicyGroup(this.expandedRow.groupName, this.expandedRow.bucket)
191         .subscribe(
192           (policy: any) => {
193             this.symmetricalFlowData = policy.data_flow[FlowType.symmetrical] || [];
194             this.directionalFlowData = policy.data_flow[FlowType.directional] || [];
195             this.pipeData = policy.pipes || [];
196           },
197           () => {
198             if (context) {
199               context.error();
200             }
201           }
202         );
203     }
204   }
205
206   updateSelection(selection: any, type: FlowType) {
207     if (type === FlowType.directional) {
208       this.dirFlowSelection = selection;
209     } else {
210       this.symFlowSelection = selection;
211     }
212   }
213
214   async openModal(flowType: FlowType, edit = false) {
215     const action = edit ? 'edit' : 'create';
216     const initialState = {
217       groupType: flowType,
218       groupExpandedRow: this.expandedRow,
219       flowSelectedRow:
220         flowType === FlowType.symmetrical
221           ? this.symFlowSelection.first()
222           : this.dirFlowSelection.first(),
223       action: action
224     };
225
226     this.modalRef = this.modalService.show(RgwMultisiteSyncFlowModalComponent, initialState, {
227       size: 'lg'
228     });
229
230     try {
231       const res = await this.modalRef.result;
232       if (res === 'success') {
233         this.loadData();
234       }
235     } catch (err) {}
236   }
237
238   deleteFlow(flowType: FlowType) {
239     let selection = this.symFlowSelection;
240     if (flowType === FlowType.directional) {
241       selection = this.dirFlowSelection;
242     }
243     const flowIds = selection.selected.map((flow: any) => flow.id);
244     this.cdsModalService.show(CriticalConfirmationModalComponent, {
245       itemDescription: selection.hasSingleSelection ? $localize`Flow` : $localize`Flows`,
246       itemNames: flowIds,
247       bodyTemplate: this.deleteTpl,
248       submitActionObservable: () => {
249         return new Observable((observer: Subscriber<any>) => {
250           this.taskWrapper
251             .wrapTaskAroundCall({
252               task: new FinishedTask('rgw/multisite/sync-flow/delete', {
253                 flow_ids: flowIds
254               }),
255               call: observableForkJoin(
256                 selection.selected.map((flow: any) => {
257                   return this.rgwMultisiteService.removeSyncFlow(
258                     flow.id,
259                     flowType,
260                     this.expandedRow.groupName,
261                     this.expandedRow.bucket
262                   );
263                 })
264               )
265             })
266             .subscribe({
267               error: (error: any) => {
268                 // Forward the error to the observer.
269                 observer.error(error);
270                 // Reload the data table content because some deletions might
271                 // have been executed successfully in the meanwhile.
272                 this.table.refreshBtn();
273               },
274               complete: () => {
275                 // Notify the observer that we are done.
276                 observer.complete();
277                 // Reload the data table content.
278                 this.table.refreshBtn();
279               }
280             });
281         });
282       }
283     });
284   }
285
286   async openPipeModal(edit = false) {
287     const action = edit ? 'edit' : 'create';
288     const initialState = {
289       groupExpandedRow: this.expandedRow,
290       pipeSelectedRow: this.pipeSelection.first(),
291       action: action
292     };
293
294     this.modalRef = this.modalService.show(RgwMultisiteSyncPipeModalComponent, initialState, {
295       size: 'lg'
296     });
297
298     try {
299       const res = await this.modalRef.result;
300       if (res === 'success') {
301         this.loadData();
302       }
303     } catch (err) {}
304   }
305
306   deletePipe() {
307     const pipeIds = this.pipeSelection.selected.map((pipe: any) => pipe.id);
308     this.cdsModalService.show(CriticalConfirmationModalComponent, {
309       itemDescription: this.pipeSelection.hasSingleSelection ? $localize`Pipe` : $localize`Pipes`,
310       itemNames: pipeIds,
311       bodyTemplate: this.deleteTpl,
312       submitActionObservable: () => {
313         return new Observable((observer: Subscriber<any>) => {
314           this.taskWrapper
315             .wrapTaskAroundCall({
316               task: new FinishedTask('rgw/multisite/sync-pipe/delete', {
317                 pipe_ids: pipeIds
318               }),
319               call: observableForkJoin(
320                 this.pipeSelection.selected.map((pipe: any) => {
321                   return this.rgwMultisiteService.removeSyncPipe(
322                     pipe.id,
323                     this.expandedRow.groupName,
324                     this.expandedRow.bucket
325                   );
326                 })
327               )
328             })
329             .subscribe({
330               error: (error: any) => {
331                 // Forward the error to the observer.
332                 observer.error(error);
333                 // Reload the data table content because some deletions might
334                 // have been executed successfully in the meanwhile.
335                 this.table.refreshBtn();
336               },
337               complete: () => {
338                 // Notify the observer that we are done.
339                 observer.complete();
340                 // Reload the data table content.
341                 this.table.refreshBtn();
342               }
343             });
344         });
345       }
346     });
347   }
348 }