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