]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph-ci.git/blob
047acda346af464d44e027b5c5a0247e738a494a
[ceph-ci.git] /
1 import { Component, Input, OnChanges, OnInit, TemplateRef, ViewChild } from '@angular/core';
2 import { Observable, ReplaySubject, of } from 'rxjs';
3 import { catchError, shareReplay, switchMap } from 'rxjs/operators';
4 import { CephfsSubvolumeService } from '~/app/shared/api/cephfs-subvolume.service';
5 import { ActionLabelsI18n } from '~/app/shared/constants/app.constants';
6 import { CellTemplate } from '~/app/shared/enum/cell-template.enum';
7 import { Icons } from '~/app/shared/enum/icons.enum';
8 import { CdTableAction } from '~/app/shared/models/cd-table-action';
9 import { CdTableColumn } from '~/app/shared/models/cd-table-column';
10 import { CdTableFetchDataContext } from '~/app/shared/models/cd-table-fetch-data-context';
11 import { CdTableSelection } from '~/app/shared/models/cd-table-selection';
12 import { CephfsSubvolume } from '~/app/shared/models/cephfs-subvolume.model';
13 import { ModalService } from '~/app/shared/services/modal.service';
14 import { CephfsSubvolumeFormComponent } from '../cephfs-subvolume-form/cephfs-subvolume-form.component';
15 import { AuthStorageService } from '~/app/shared/services/auth-storage.service';
16 import { Permissions } from '~/app/shared/models/permissions';
17 import { TaskWrapperService } from '~/app/shared/services/task-wrapper.service';
18 import { FinishedTask } from '~/app/shared/models/finished-task';
19 import { NgbModalRef } from '@ng-bootstrap/ng-bootstrap';
20 import { FormControl } from '@angular/forms';
21 import { CdFormGroup } from '~/app/shared/forms/cd-form-group';
22 import { CdForm } from '~/app/shared/forms/cd-form';
23 import { CriticalConfirmationModalComponent } from '~/app/shared/components/critical-confirmation-modal/critical-confirmation-modal.component';
24
25 @Component({
26   selector: 'cd-cephfs-subvolume-list',
27   templateUrl: './cephfs-subvolume-list.component.html',
28   styleUrls: ['./cephfs-subvolume-list.component.scss']
29 })
30 export class CephfsSubvolumeListComponent extends CdForm implements OnInit, OnChanges {
31   @ViewChild('quotaUsageTpl', { static: true })
32   quotaUsageTpl: any;
33
34   @ViewChild('typeTpl', { static: true })
35   typeTpl: any;
36
37   @ViewChild('modeToHumanReadableTpl', { static: true })
38   modeToHumanReadableTpl: any;
39
40   @ViewChild('nameTpl', { static: true })
41   nameTpl: any;
42
43   @ViewChild('quotaSizeTpl', { static: true })
44   quotaSizeTpl: any;
45
46   @ViewChild('removeTmpl', { static: true })
47   removeTmpl: TemplateRef<any>;
48
49   @Input() fsName: string;
50   @Input() pools: any[];
51
52   columns: CdTableColumn[] = [];
53   tableActions: CdTableAction[];
54   context: CdTableFetchDataContext;
55   selection = new CdTableSelection();
56   removeForm: CdFormGroup;
57   icons = Icons;
58   permissions: Permissions;
59   modalRef: NgbModalRef;
60   errorMessage: string = '';
61   selectedName: string = '';
62
63   subVolumes$: Observable<CephfsSubvolume[]>;
64   subject = new ReplaySubject<CephfsSubvolume[]>();
65
66   constructor(
67     private cephfsSubVolume: CephfsSubvolumeService,
68     private actionLabels: ActionLabelsI18n,
69     private modalService: ModalService,
70     private authStorageService: AuthStorageService,
71     private taskWrapper: TaskWrapperService
72   ) {
73     super();
74     this.permissions = this.authStorageService.getPermissions();
75   }
76
77   ngOnInit(): void {
78     this.columns = [
79       {
80         name: $localize`Name`,
81         prop: 'name',
82         flexGrow: 1,
83         cellTemplate: this.nameTpl
84       },
85       {
86         name: $localize`Data Pool`,
87         prop: 'info.data_pool',
88         flexGrow: 0.7,
89         cellTransformation: CellTemplate.badge,
90         customTemplateConfig: {
91           class: 'badge-background-primary'
92         }
93       },
94       {
95         name: $localize`Usage`,
96         prop: 'info.bytes_pcent',
97         flexGrow: 0.7,
98         cellTemplate: this.quotaUsageTpl,
99         cellClass: 'text-right'
100       },
101       {
102         name: $localize`Path`,
103         prop: 'info.path',
104         flexGrow: 1,
105         cellTransformation: CellTemplate.path
106       },
107       {
108         name: $localize`Mode`,
109         prop: 'info.mode',
110         flexGrow: 0.5,
111         cellTemplate: this.modeToHumanReadableTpl
112       },
113       {
114         name: $localize`Created`,
115         prop: 'info.created_at',
116         flexGrow: 0.5,
117         cellTransformation: CellTemplate.timeAgo
118       }
119     ];
120
121     this.tableActions = [
122       {
123         name: this.actionLabels.CREATE,
124         permission: 'create',
125         icon: Icons.add,
126         click: () =>
127           this.modalService.show(
128             CephfsSubvolumeFormComponent,
129             {
130               fsName: this.fsName,
131               pools: this.pools
132             },
133             { size: 'lg' }
134           )
135       },
136       {
137         name: this.actionLabels.EDIT,
138         permission: 'update',
139         icon: Icons.edit,
140         click: () => this.openModal(true)
141       },
142       {
143         name: this.actionLabels.REMOVE,
144         permission: 'delete',
145         icon: Icons.destroy,
146         click: () => this.removeSubVolumeModal()
147       }
148     ];
149
150     this.subVolumes$ = this.subject.pipe(
151       switchMap(() =>
152         this.cephfsSubVolume.get(this.fsName).pipe(
153           catchError(() => {
154             this.context.error();
155             return of(null);
156           })
157         )
158       ),
159       shareReplay(1)
160     );
161   }
162
163   fetchData() {
164     this.subject.next();
165   }
166
167   ngOnChanges() {
168     this.subject.next();
169   }
170
171   updateSelection(selection: CdTableSelection) {
172     this.selection = selection;
173   }
174
175   openModal(edit = false) {
176     this.modalService.show(
177       CephfsSubvolumeFormComponent,
178       {
179         fsName: this.fsName,
180         subVolumeName: this.selection?.first()?.name,
181         pools: this.pools,
182         isEdit: edit
183       },
184       { size: 'lg' }
185     );
186   }
187
188   removeSubVolumeModal() {
189     this.removeForm = new CdFormGroup({
190       retainSnapshots: new FormControl(false)
191     });
192     this.errorMessage = '';
193     this.selectedName = this.selection.first().name;
194     this.modalRef = this.modalService.show(CriticalConfirmationModalComponent, {
195       actionDescription: 'Remove',
196       itemNames: [this.selectedName],
197       itemDescription: 'Subvolume',
198       childFormGroup: this.removeForm,
199       childFormGroupTemplate: this.removeTmpl,
200       submitAction: () =>
201         this.taskWrapper
202           .wrapTaskAroundCall({
203             task: new FinishedTask('cephfs/subvolume/remove', { subVolumeName: this.selectedName }),
204             call: this.cephfsSubVolume.remove(
205               this.fsName,
206               this.selectedName,
207               this.removeForm.getValue('retainSnapshots')
208             )
209           })
210           .subscribe({
211             complete: () => this.modalRef.close(),
212             error: (error) => {
213               this.modalRef.componentInstance.stopLoadingSpinner();
214               this.errorMessage = error.error.detail;
215             }
216           })
217     });
218   }
219 }