]> git.apps.os.sepia.ceph.com Git - ceph.git/blob
9970d598887986bd89a65d6463e8d988f2ee02d7
[ceph.git] /
1 import { Component, Input, OnChanges, OnInit, SimpleChanges } from '@angular/core';
2 import { BehaviorSubject, Observable, forkJoin, of } from 'rxjs';
3 import { catchError, shareReplay, switchMap, tap } from 'rxjs/operators';
4 import { CephfsSubvolumeGroupService } from '~/app/shared/api/cephfs-subvolume-group.service';
5 import { CephfsSubvolumeService } from '~/app/shared/api/cephfs-subvolume.service';
6 import { ActionLabelsI18n } from '~/app/shared/constants/app.constants';
7 import { CellTemplate } from '~/app/shared/enum/cell-template.enum';
8 import { Icons } from '~/app/shared/enum/icons.enum';
9 import { CdTableAction } from '~/app/shared/models/cd-table-action';
10 import { CdTableColumn } from '~/app/shared/models/cd-table-column';
11 import { CdTableFetchDataContext } from '~/app/shared/models/cd-table-fetch-data-context';
12 import { CephfsSubvolume, SubvolumeSnapshot } from '~/app/shared/models/cephfs-subvolume.model';
13 import { CephfsSubvolumeSnapshotsFormComponent } from './cephfs-subvolume-snapshots-form/cephfs-subvolume-snapshots-form.component';
14 import { ModalService } from '~/app/shared/services/modal.service';
15 import { AuthStorageService } from '~/app/shared/services/auth-storage.service';
16 import { Permissions } from '~/app/shared/models/permissions';
17 import { CdTableSelection } from '~/app/shared/models/cd-table-selection';
18 import { CdDatePipe } from '~/app/shared/pipes/cd-date.pipe';
19
20 @Component({
21   selector: 'cd-cephfs-subvolume-snapshots-list',
22   templateUrl: './cephfs-subvolume-snapshots-list.component.html',
23   styleUrls: ['./cephfs-subvolume-snapshots-list.component.scss']
24 })
25 export class CephfsSubvolumeSnapshotsListComponent implements OnInit, OnChanges {
26   @Input() fsName: string;
27
28   context: CdTableFetchDataContext;
29   columns: CdTableColumn[] = [];
30   tableActions: CdTableAction[];
31   selection = new CdTableSelection();
32   permissions: Permissions;
33
34   subVolumes$: Observable<CephfsSubvolume[]>;
35   snapshots$: Observable<any[]>;
36   snapshotSubject = new BehaviorSubject<SubvolumeSnapshot[]>([]);
37   subVolumeSubject = new BehaviorSubject<CephfsSubvolume[]>([]);
38
39   subvolumeGroupList: string[] = [];
40   subVolumesList: string[];
41
42   activeGroupName = '';
43   activeSubVolumeName = '';
44
45   isSubVolumesAvailable = false;
46   isLoading = true;
47
48   observables: any = [];
49
50   constructor(
51     private cephfsSubvolumeGroupService: CephfsSubvolumeGroupService,
52     private cephfsSubvolumeService: CephfsSubvolumeService,
53     private actionLabels: ActionLabelsI18n,
54     private modalService: ModalService,
55     private authStorageService: AuthStorageService,
56     private cdDatePipe: CdDatePipe
57   ) {
58     this.permissions = this.authStorageService.getPermissions();
59   }
60
61   ngOnInit(): void {
62     this.columns = [
63       {
64         name: $localize`Name`,
65         prop: 'name',
66         flexGrow: 1
67       },
68       {
69         name: $localize`Created`,
70         prop: 'info.created_at',
71         flexGrow: 1,
72         pipe: this.cdDatePipe
73       },
74       {
75         name: $localize`Pending Clones`,
76         prop: 'info.has_pending_clones',
77         flexGrow: 0.5,
78         cellTransformation: CellTemplate.badge,
79         customTemplateConfig: {
80           map: {
81             no: { class: 'badge-success' },
82             yes: { class: 'badge-info' }
83           }
84         }
85       }
86     ];
87
88     this.tableActions = [
89       {
90         name: this.actionLabels.CREATE,
91         permission: 'create',
92         icon: Icons.add,
93         click: () => this.openModal()
94       }
95     ];
96
97     this.cephfsSubvolumeGroupService
98       .get(this.fsName)
99       .pipe(
100         switchMap((groups) => {
101           // manually adding the group '_nogroup' to the list.
102           groups.unshift({ name: '' });
103
104           const observables = groups.map((group) =>
105             this.cephfsSubvolumeService.existsInFs(this.fsName, group.name).pipe(
106               switchMap((resp) => {
107                 if (resp) {
108                   this.subvolumeGroupList.push(group.name);
109                 }
110                 return of(resp); // Emit the response
111               })
112             )
113           );
114
115           return forkJoin(observables);
116         })
117       )
118       .subscribe(() => {
119         if (this.subvolumeGroupList.length) {
120           this.isSubVolumesAvailable = true;
121         }
122         this.isLoading = false;
123       });
124   }
125
126   ngOnChanges(changes: SimpleChanges): void {
127     if (changes.fsName) {
128       this.subVolumeSubject.next([]);
129     }
130   }
131
132   selectSubVolumeGroup(subVolumeGroupName: string) {
133     this.activeGroupName = subVolumeGroupName;
134     this.getSubVolumes();
135   }
136
137   selectSubVolume(subVolumeName: string) {
138     this.activeSubVolumeName = subVolumeName;
139     this.getSubVolumesSnapshot();
140   }
141
142   getSubVolumes() {
143     this.subVolumes$ = this.subVolumeSubject.pipe(
144       switchMap(() =>
145         this.cephfsSubvolumeService.get(this.fsName, this.activeGroupName, false).pipe(
146           tap((resp) => {
147             this.subVolumesList = resp.map((subVolume) => subVolume.name);
148             this.activeSubVolumeName = resp[0].name;
149             this.getSubVolumesSnapshot();
150           })
151         )
152       )
153     );
154   }
155
156   getSubVolumesSnapshot() {
157     this.snapshots$ = this.snapshotSubject.pipe(
158       switchMap(() =>
159         this.cephfsSubvolumeService
160           .getSnapshots(this.fsName, this.activeSubVolumeName, this.activeGroupName)
161           .pipe(
162             catchError(() => {
163               this.context.error();
164               return of(null);
165             })
166           )
167       ),
168       shareReplay(1)
169     );
170   }
171
172   fetchData() {
173     this.snapshotSubject.next([]);
174   }
175
176   openModal(edit = false) {
177     this.modalService.show(
178       CephfsSubvolumeSnapshotsFormComponent,
179       {
180         fsName: this.fsName,
181         subVolumeName: this.activeSubVolumeName,
182         subVolumeGroupName: this.activeGroupName,
183         subVolumeGroups: this.subvolumeGroupList,
184         isEdit: edit
185       },
186       { size: 'lg' }
187     );
188   }
189
190   updateSelection(selection: CdTableSelection) {
191     this.selection = selection;
192   }
193 }