]> git.apps.os.sepia.ceph.com Git - ceph.git/blob
2ed1ec0f7e2c26e583ca22ac8502b08bb42ae4fb
[ceph.git] /
1 import { TitleCasePipe } from '@angular/common';
2 import { Component, OnInit, TemplateRef, ViewChild } from '@angular/core';
3 import { forkJoin as observableForkJoin, Observable, Subscriber } from 'rxjs';
4 import { RgwMultisiteService } from '~/app/shared/api/rgw-multisite.service';
5 import { CriticalConfirmationModalComponent } from '~/app/shared/components/critical-confirmation-modal/critical-confirmation-modal.component';
6 import { ActionLabelsI18n } from '~/app/shared/constants/app.constants';
7 import { TableComponent } from '~/app/shared/datatable/table/table.component';
8 import { CellTemplate } from '~/app/shared/enum/cell-template.enum';
9 import { Icons } from '~/app/shared/enum/icons.enum';
10 import { CdTableAction } from '~/app/shared/models/cd-table-action';
11 import { CdTableColumn } from '~/app/shared/models/cd-table-column';
12 import { CdTableFetchDataContext } from '~/app/shared/models/cd-table-fetch-data-context';
13 import { CdTableSelection } from '~/app/shared/models/cd-table-selection';
14 import { FinishedTask } from '~/app/shared/models/finished-task';
15 import { Permission } from '~/app/shared/models/permissions';
16 import { AuthStorageService } from '~/app/shared/services/auth-storage.service';
17 import { ModalService } from '~/app/shared/services/modal.service';
18 import { TaskWrapperService } from '~/app/shared/services/task-wrapper.service';
19 import { URLBuilderService } from '~/app/shared/services/url-builder.service';
20
21 const BASE_URL = 'rgw/multisite/sync-policy';
22
23 @Component({
24   selector: 'cd-rgw-multisite-sync-policy',
25   templateUrl: './rgw-multisite-sync-policy.component.html',
26   styleUrls: ['./rgw-multisite-sync-policy.component.scss'],
27   providers: [{ provide: URLBuilderService, useValue: new URLBuilderService(BASE_URL) }]
28 })
29 export class RgwMultisiteSyncPolicyComponent implements OnInit {
30   @ViewChild(TableComponent, { static: true })
31   table: TableComponent;
32   @ViewChild('deleteTpl', { static: true })
33   deleteTpl: TemplateRef<any>;
34
35   columns: Array<CdTableColumn> = [];
36   syncPolicyData: any = [];
37   tableActions: CdTableAction[];
38   selection = new CdTableSelection();
39   permission: Permission;
40
41   constructor(
42     private rgwMultisiteService: RgwMultisiteService,
43     private titleCasePipe: TitleCasePipe,
44     private actionLabels: ActionLabelsI18n,
45     private urlBuilder: URLBuilderService,
46     private authStorageService: AuthStorageService,
47     private modalService: ModalService,
48     private taskWrapper: TaskWrapperService
49   ) {}
50
51   ngOnInit(): void {
52     this.permission = this.authStorageService.getPermissions().rgw;
53     this.columns = [
54       {
55         prop: 'uniqueId',
56         isHidden: true
57       },
58       {
59         name: $localize`Group Name`,
60         prop: 'groupName',
61         flexGrow: 1
62       },
63       {
64         name: $localize`Status`,
65         prop: 'status',
66         flexGrow: 1,
67         cellTransformation: CellTemplate.tooltip,
68         customTemplateConfig: {
69           map: {
70             Enabled: { class: 'badge-success', tooltip: 'sync is allowed and enabled' },
71             Allowed: { class: 'badge-info', tooltip: 'sync is allowed' },
72             Forbidden: {
73               class: 'badge-warning',
74               tooltip:
75                 'sync (as defined by this group) is not allowed and can override other groups'
76             }
77           }
78         },
79         pipe: this.titleCasePipe
80       },
81       {
82         name: $localize`Zonegroup`,
83         prop: 'zonegroup',
84         flexGrow: 1
85       },
86       {
87         name: $localize`Bucket`,
88         prop: 'bucket',
89         flexGrow: 1
90       }
91     ];
92     const getSyncGroupName = () => {
93       if (this.selection.first() && this.selection.first().groupName) {
94         if (this.selection.first().bucket) {
95           return `${encodeURIComponent(this.selection.first().groupName)}/${encodeURIComponent(
96             this.selection.first().bucket
97           )}`;
98         }
99         return `${encodeURIComponent(this.selection.first().groupName)}`;
100       }
101       return '';
102     };
103     const addAction: CdTableAction = {
104       permission: 'create',
105       icon: Icons.add,
106       routerLink: () => this.urlBuilder.getCreate(),
107       name: this.actionLabels.CREATE,
108       canBePrimary: (selection: CdTableSelection) => !selection.hasSelection
109     };
110     const editAction: CdTableAction = {
111       permission: 'update',
112       icon: Icons.edit,
113       routerLink: () => this.urlBuilder.getEdit(getSyncGroupName()),
114       name: this.actionLabels.EDIT
115     };
116     const deleteAction: CdTableAction = {
117       permission: 'delete',
118       icon: Icons.destroy,
119       click: () => this.deleteAction(),
120       disable: () => !this.selection.hasSelection,
121       name: this.actionLabels.DELETE,
122       canBePrimary: (selection: CdTableSelection) => selection.hasMultiSelection
123     };
124     this.tableActions = [addAction, editAction, deleteAction];
125   }
126
127   transformSyncPolicyData(allSyncPolicyData: any) {
128     if (allSyncPolicyData && allSyncPolicyData.length > 0) {
129       allSyncPolicyData.forEach((policy: any) => {
130         this.syncPolicyData.push({
131           uniqueId: policy['id'] + (policy['bucketName'] ? policy['bucketName'] : ''),
132           groupName: policy['id'],
133           status: policy['status'],
134           bucket: policy['bucketName'],
135           zonegroup: ''
136         });
137       });
138       this.syncPolicyData = [...this.syncPolicyData];
139     }
140   }
141
142   updateSelection(selection: CdTableSelection) {
143     this.selection = selection;
144   }
145
146   getPolicyList(context: CdTableFetchDataContext) {
147     this.rgwMultisiteService.getSyncPolicy('', '', true).subscribe(
148       (resp: object[]) => {
149         this.syncPolicyData = [];
150         this.transformSyncPolicyData(resp);
151       },
152       () => {
153         context.error();
154       }
155     );
156   }
157
158   deleteAction() {
159     const groupNames = this.selection.selected.map((policy: any) => policy.groupName);
160     this.modalService.show(CriticalConfirmationModalComponent, {
161       itemDescription: this.selection.hasSingleSelection
162         ? $localize`Policy Group`
163         : $localize`Policy Groups`,
164       itemNames: groupNames,
165       bodyTemplate: this.deleteTpl,
166       submitActionObservable: () => {
167         return new Observable((observer: Subscriber<any>) => {
168           this.taskWrapper
169             .wrapTaskAroundCall({
170               task: new FinishedTask('rgw/multisite/sync-policy/delete', {
171                 group_names: groupNames
172               }),
173               call: observableForkJoin(
174                 this.selection.selected.map((policy: any) => {
175                   return this.rgwMultisiteService.removeSyncPolicyGroup(
176                     policy.groupName,
177                     policy.bucket
178                   );
179                 })
180               )
181             })
182             .subscribe({
183               error: (error: any) => {
184                 // Forward the error to the observer.
185                 observer.error(error);
186                 // Reload the data table content because some deletions might
187                 // have been executed successfully in the meanwhile.
188                 this.table.refreshBtn();
189               },
190               complete: () => {
191                 // Notify the observer that we are done.
192                 observer.complete();
193                 // Reload the data table content.
194                 this.table.refreshBtn();
195               }
196             });
197         });
198       }
199     });
200   }
201 }