9 } from '@angular/core';
10 import { NgbModalRef } from '@ng-bootstrap/ng-bootstrap';
11 import { BehaviorSubject, Observable, Subscription, of, timer } from 'rxjs';
12 import { finalize, map, shareReplay, switchMap } from 'rxjs/operators';
13 import { CephfsSnapshotScheduleService } from '~/app/shared/api/cephfs-snapshot-schedule.service';
14 import { CdForm } from '~/app/shared/forms/cd-form';
15 import { CdTableAction } from '~/app/shared/models/cd-table-action';
16 import { CdTableColumn } from '~/app/shared/models/cd-table-column';
17 import { CdTableFetchDataContext } from '~/app/shared/models/cd-table-fetch-data-context';
18 import { CdTableSelection } from '~/app/shared/models/cd-table-selection';
19 import { Permissions } from '~/app/shared/models/permissions';
20 import { SnapshotSchedule } from '~/app/shared/models/snapshot-schedule';
21 import { AuthStorageService } from '~/app/shared/services/auth-storage.service';
22 import { ModalService } from '~/app/shared/services/modal.service';
23 import { Icons } from '~/app/shared/enum/icons.enum';
24 import { CellTemplate } from '~/app/shared/enum/cell-template.enum';
25 import { MgrModuleService } from '~/app/shared/api/mgr-module.service';
26 import { NotificationService } from '~/app/shared/services/notification.service';
27 import { BlockUI, NgBlockUI } from 'ng-block-ui';
28 import { NotificationType } from '~/app/shared/enum/notification-type.enum';
29 import { ActionLabelsI18n } from '~/app/shared/constants/app.constants';
30 import { CephfsSnapshotscheduleFormComponent } from '../cephfs-snapshotschedule-form/cephfs-snapshotschedule-form.component';
33 selector: 'cd-cephfs-snapshotschedule-list',
34 templateUrl: './cephfs-snapshotschedule-list.component.html',
35 styleUrls: ['./cephfs-snapshotschedule-list.component.scss']
37 export class CephfsSnapshotscheduleListComponent
39 implements OnInit, OnChanges, OnDestroy {
40 @Input() fsName!: string;
43 @ViewChild('pathTpl', { static: true })
49 snapshotSchedules$!: Observable<SnapshotSchedule[]>;
50 subject$ = new BehaviorSubject<SnapshotSchedule[]>([]);
51 snapScheduleModuleStatus$ = new BehaviorSubject<boolean>(false);
52 moduleServiceListSub!: Subscription;
53 columns: CdTableColumn[] = [];
54 tableActions: CdTableAction[] = [];
55 context!: CdTableFetchDataContext;
56 selection = new CdTableSelection();
57 permissions!: Permissions;
58 modalRef!: NgbModalRef;
59 errorMessage: string = '';
60 selectedName: string = '';
63 MODULE_NAME = 'snap_schedule';
64 ENABLE_MODULE_TIMER = 2 * 1000;
67 private snapshotScheduleService: CephfsSnapshotScheduleService,
68 private authStorageService: AuthStorageService,
69 private modalService: ModalService,
70 private mgrModuleService: MgrModuleService,
71 private notificationService: NotificationService,
72 private actionLables: ActionLabelsI18n
75 this.permissions = this.authStorageService.getPermissions();
78 ngOnChanges(changes: SimpleChanges): void {
80 this.subject$.next([]);
85 this.moduleServiceListSub = this.mgrModuleService
88 map((modules: any[]) => modules.find((module) => module?.['name'] === this.MODULE_NAME))
91 next: (module: any) => this.snapScheduleModuleStatus$.next(module?.enabled)
94 this.snapshotSchedules$ = this.subject$.pipe(
96 this.snapScheduleModuleStatus$.pipe(
97 switchMap((status) => {
101 return this.snapshotScheduleService.getSnapshotScheduleList('/', this.fsName);
109 { prop: 'path', name: $localize`Path`, flexGrow: 3, cellTemplate: this.pathTpl },
110 { prop: 'subvol', name: $localize`Subvolume` },
111 { prop: 'schedule', name: $localize`Repeat interval` },
112 { prop: 'retention', name: $localize`Retention policy` },
113 { prop: 'created_count', name: $localize`Created Count` },
114 { prop: 'pruned_count', name: $localize`Deleted Count` },
115 { prop: 'start', name: $localize`Start time`, cellTransformation: CellTemplate.timeAgo },
116 { prop: 'created', name: $localize`Created`, cellTransformation: CellTemplate.timeAgo }
119 this.tableActions = [
121 name: this.actionLables.CREATE,
122 permission: 'create',
124 click: () => this.openModal(false)
127 name: this.actionLables.EDIT,
128 permission: 'update',
130 click: () => this.openModal(true)
135 ngOnDestroy(): void {
136 this.moduleServiceListSub.unsubscribe();
140 this.subject$.next([]);
143 updateSelection(selection: CdTableSelection) {
144 this.selection = selection;
147 openModal(edit = false) {
148 this.modalService.show(
149 CephfsSnapshotscheduleFormComponent,
153 path: this.selection?.first()?.path,
154 schedule: this.selection?.first()?.schedule,
155 retention: this.selection?.first()?.retention,
156 start: this.selection?.first()?.start,
157 status: this.selection?.first()?.status,
164 enableSnapshotSchedule() {
166 const fnWaitUntilReconnected = () => {
167 timer(this.ENABLE_MODULE_TIMER).subscribe(() => {
168 // Trigger an API request to check if the connection is
170 this.mgrModuleService.list().subscribe(
172 // Resume showing the notification toasties.
173 this.notificationService.suspendToasties(false);
174 // Unblock the whole UI.
176 // Reload the data table content.
177 this.notificationService.show(
178 NotificationType.success,
179 $localize`Enabled Snapshot Schedule Module`
181 // Reload the data table content.
184 fnWaitUntilReconnected();
190 if (!this.snapScheduleModuleStatus$.value) {
191 $obs = this.mgrModuleService
192 .enable(this.MODULE_NAME)
193 .pipe(finalize(() => this.snapScheduleModuleStatus$.next(true)));
198 // Suspend showing the notification toasties.
199 this.notificationService.suspendToasties(true);
200 // Block the whole UI to prevent user interactions until
201 // the connection to the backend is reestablished
202 this.blockUI.start($localize`Reconnecting, please wait ...`);
203 fnWaitUntilReconnected();