1 import { Component, Input, OnChanges, OnInit, TemplateRef, ViewChild } from '@angular/core';
3 import * as _ from 'lodash';
4 import { BsModalRef, BsModalService } from 'ngx-bootstrap';
6 import { RbdService } from '../../../shared/api/rbd.service';
7 import { DeletionModalComponent } from '../../../shared/components/deletion-modal/deletion-modal.component';
8 import { CellTemplate } from '../../../shared/enum/cell-template.enum';
9 import { CdTableColumn } from '../../../shared/models/cd-table-column';
10 import { CdTableSelection } from '../../../shared/models/cd-table-selection';
11 import { ExecutingTask } from '../../../shared/models/executing-task';
12 import { FinishedTask } from '../../../shared/models/finished-task';
13 import { CdDatePipe } from '../../../shared/pipes/cd-date.pipe';
14 import { DimlessBinaryPipe } from '../../../shared/pipes/dimless-binary.pipe';
15 import { NotificationService } from '../../../shared/services/notification.service';
16 import { TaskManagerService } from '../../../shared/services/task-manager.service';
17 import { RbdSnapshotFormComponent } from '../rbd-snapshot-form/rbd-snapshot-form.component';
18 import { RollbackConfirmationModalComponent } from '../rollback-confirmation-modal/rollback-confimation-modal.component';
19 import { RbdSnapshotModel } from './rbd-snapshot.model';
22 selector: 'cd-rbd-snapshot-list',
23 templateUrl: './rbd-snapshot-list.component.html',
24 styleUrls: ['./rbd-snapshot-list.component.scss']
26 export class RbdSnapshotListComponent implements OnInit, OnChanges {
27 @Input() snapshots: RbdSnapshotModel[] = [];
28 @Input() poolName: string;
29 @Input() rbdName: string;
30 @Input() executingTasks: ExecutingTask[] = [];
32 @ViewChild('nameTpl') nameTpl: TemplateRef<any>;
33 @ViewChild('protectTpl') protectTpl: TemplateRef<any>;
35 data: RbdSnapshotModel[];
37 columns: CdTableColumn[];
41 selection = new CdTableSelection();
44 private modalService: BsModalService,
45 private dimlessBinaryPipe: DimlessBinaryPipe,
46 private cdDatePipe: CdDatePipe,
47 private rbdService: RbdService,
48 private taskManagerService: TaskManagerService,
49 private notificationService: NotificationService
57 cellTransformation: CellTemplate.executing,
64 cellClass: 'text-right',
65 pipe: this.dimlessBinaryPipe
71 cellClass: 'text-right',
72 pipe: this.dimlessBinaryPipe
78 cellClass: 'text-center',
79 cellTemplate: this.protectTpl
91 this.data = this.merge(this.snapshots, this.executingTasks);
94 private merge(snapshots: RbdSnapshotModel[], executingTasks: ExecutingTask[] = []) {
95 const resultSnapshots = _.clone(snapshots);
96 executingTasks.forEach((executingTask) => {
97 const snapshotExecuting = resultSnapshots.find((snapshot) => {
98 return snapshot.name === executingTask.metadata['snapshot_name'];
100 if (snapshotExecuting) {
101 if (executingTask.name === 'rbd/snap/delete') {
102 snapshotExecuting.cdExecuting = 'deleting';
103 } else if (executingTask.name === 'rbd/snap/edit') {
104 snapshotExecuting.cdExecuting = 'updating';
105 } else if (executingTask.name === 'rbd/snap/rollback') {
106 snapshotExecuting.cdExecuting = 'rolling back';
108 } else if (executingTask.name === 'rbd/snap/create') {
109 const rbdSnapshotModel = new RbdSnapshotModel();
110 rbdSnapshotModel.name = executingTask.metadata['snapshot_name'];
111 rbdSnapshotModel.cdExecuting = 'creating';
112 this.pushIfNotExists(resultSnapshots, rbdSnapshotModel);
115 return resultSnapshots;
118 private pushIfNotExists(resultSnapshots: RbdSnapshotModel[], rbdSnapshotModel: RbdSnapshotModel) {
119 const exists = resultSnapshots.some((resultSnapshot) => {
120 return resultSnapshot.name === rbdSnapshotModel.name;
123 resultSnapshots.push(rbdSnapshotModel);
127 private openSnapshotModal(taskName: string, oldSnapshotName: string = null) {
128 this.modalRef = this.modalService.show(RbdSnapshotFormComponent);
129 this.modalRef.content.poolName = this.poolName;
130 this.modalRef.content.imageName = this.rbdName;
131 if (oldSnapshotName) {
132 this.modalRef.content.setSnapName(this.selection.first().name);
134 this.modalRef.content.onSubmit.subscribe((snapshotName: string) => {
135 const executingTask = new ExecutingTask();
136 executingTask.name = taskName;
137 executingTask.metadata = { snapshot_name: snapshotName };
138 this.executingTasks.push(executingTask);
143 openCreateSnapshotModal() {
144 this.openSnapshotModal('rbd/snap/create');
147 openEditSnapshotModal() {
148 this.openSnapshotModal('rbd/snap/edit', this.selection.first().name);
152 const snapshotName = this.selection.first().name;
153 const isProtected = this.selection.first().is_protected;
154 const finishedTask = new FinishedTask();
155 finishedTask.name = 'rbd/snap/edit';
156 finishedTask.metadata = {
157 pool_name: this.poolName,
158 image_name: this.rbdName,
159 snapshot_name: snapshotName
162 .protectSnapshot(this.poolName, this.rbdName, snapshotName, !isProtected)
165 const executingTask = new ExecutingTask();
166 executingTask.name = finishedTask.name;
167 executingTask.metadata = finishedTask.metadata;
168 this.executingTasks.push(executingTask);
170 this.taskManagerService.subscribe(
172 finishedTask.metadata,
173 (asyncFinishedTask: FinishedTask) => {
174 this.notificationService.notifyTask(asyncFinishedTask);
180 _asyncTask(task: string, taskName: string, snapshotName: string) {
181 const finishedTask = new FinishedTask();
182 finishedTask.name = taskName;
183 finishedTask.metadata = {
184 pool_name: this.poolName,
185 image_name: this.rbdName,
186 snapshot_name: snapshotName
188 this.rbdService[task](this.poolName, this.rbdName, snapshotName)
191 const executingTask = new ExecutingTask();
192 executingTask.name = finishedTask.name;
193 executingTask.metadata = finishedTask.metadata;
194 this.executingTasks.push(executingTask);
195 this.modalRef.hide();
197 this.taskManagerService.subscribe(
199 executingTask.metadata,
200 (asyncFinishedTask: FinishedTask) => {
201 this.notificationService.notifyTask(asyncFinishedTask);
206 this.modalRef.content.stopLoadingSpinner();
211 const snapshotName = this.selection.selected[0].name;
212 this.modalRef = this.modalService.show(RollbackConfirmationModalComponent);
213 this.modalRef.content.snapName = `${this.poolName}/${this.rbdName}@${snapshotName}`;
214 this.modalRef.content.onSubmit.subscribe((itemName: string) => {
215 this._asyncTask('rollbackSnapshot', 'rbd/snap/rollback', snapshotName);
219 deleteSnapshotModal() {
220 const snapshotName = this.selection.selected[0].name;
221 this.modalRef = this.modalService.show(DeletionModalComponent);
222 this.modalRef.content.setUp({
223 metaType: 'RBD snapshot',
224 pattern: snapshotName,
225 deletionMethod: () => this._asyncTask('deleteSnapshot', 'rbd/snap/delete', snapshotName),
226 modalRef: this.modalRef
230 updateSelection(selection: CdTableSelection) {
231 this.selection = selection;