8 } from '@angular/core';
10 import * as _ from 'lodash';
11 import { ToastsManager } from 'ng2-toastr';
12 import { BsModalRef, BsModalService } from 'ngx-bootstrap';
16 } from '../../../shared/api/rbd.service';
18 DeletionModalComponent
19 } from '../../../shared/components/deletion-modal/deletion-modal.component';
20 import { CellTemplate } from '../../../shared/enum/cell-template.enum';
21 import { CdTableColumn } from '../../../shared/models/cd-table-column';
22 import { CdTableSelection } from '../../../shared/models/cd-table-selection';
23 import { ExecutingTask } from '../../../shared/models/executing-task';
24 import { FinishedTask } from '../../../shared/models/finished-task';
25 import { CdDatePipe } from '../../../shared/pipes/cd-date.pipe';
26 import { DimlessBinaryPipe } from '../../../shared/pipes/dimless-binary.pipe';
29 } from '../../../shared/services/notification.service';
30 import { TaskManagerService } from '../../../shared/services/task-manager.service';
31 import { RbdSnapshotFormComponent } from '../rbd-snapshot-form/rbd-snapshot-form.component';
33 RollbackConfirmationModalComponent
34 } from '../rollback-confirmation-modal/rollback-confimation-modal.component';
35 import { RbdSnapshotModel } from './rbd-snapshot.model';
38 selector: 'cd-rbd-snapshot-list',
39 templateUrl: './rbd-snapshot-list.component.html',
40 styleUrls: ['./rbd-snapshot-list.component.scss']
42 export class RbdSnapshotListComponent implements OnInit, OnChanges {
44 @Input() snapshots: RbdSnapshotModel[] = [];
45 @Input() poolName: string;
46 @Input() rbdName: string;
47 @Input() executingTasks: ExecutingTask[] = [];
49 @ViewChild('nameTpl') nameTpl: TemplateRef<any>;
50 @ViewChild('protectTpl') protectTpl: TemplateRef<any>;
52 data: RbdSnapshotModel[];
54 columns: CdTableColumn[];
58 selection = new CdTableSelection();
60 constructor(private modalService: BsModalService,
61 private dimlessBinaryPipe: DimlessBinaryPipe,
62 private cdDatePipe: CdDatePipe,
63 private rbdService: RbdService,
64 private toastr: ToastsManager,
65 private taskManagerService: TaskManagerService,
66 private notificationService: NotificationService) { }
73 cellTransformation: CellTemplate.executing,
80 cellClass: 'text-right',
81 pipe: this.dimlessBinaryPipe
87 cellClass: 'text-right',
88 pipe: this.dimlessBinaryPipe
94 cellClass: 'text-center',
95 cellTemplate: this.protectTpl
101 pipe: this.cdDatePipe
107 this.data = this.merge(this.snapshots, this.executingTasks);
110 private merge(snapshots: RbdSnapshotModel[], executingTasks: ExecutingTask[] = []) {
111 const resultSnapshots = _.clone(snapshots);
112 executingTasks.forEach((executingTask) => {
113 const snapshotExecuting = resultSnapshots.find((snapshot) => {
114 return snapshot.name === executingTask.metadata['snapshot_name'];
116 if (snapshotExecuting) {
117 if (executingTask.name === 'rbd/snap/delete') {
118 snapshotExecuting.cdExecuting = 'deleting';
120 } else if (executingTask.name === 'rbd/snap/edit') {
121 snapshotExecuting.cdExecuting = 'updating';
123 } else if (executingTask.name === 'rbd/snap/rollback') {
124 snapshotExecuting.cdExecuting = 'rolling back';
126 } else if (executingTask.name === 'rbd/snap/create') {
127 const rbdSnapshotModel = new RbdSnapshotModel();
128 rbdSnapshotModel.name = executingTask.metadata['snapshot_name'];
129 rbdSnapshotModel.cdExecuting = 'creating';
130 this.pushIfNotExists(resultSnapshots, rbdSnapshotModel);
133 return resultSnapshots;
136 private pushIfNotExists(resultSnapshots: RbdSnapshotModel[], rbdSnapshotModel: RbdSnapshotModel) {
137 const exists = resultSnapshots.some((resultSnapshot) => {
138 return resultSnapshot.name === rbdSnapshotModel.name;
141 resultSnapshots.push(rbdSnapshotModel);
145 private openSnapshotModal(taskName: string, oldSnapshotName: string = null) {
146 this.modalRef = this.modalService.show(RbdSnapshotFormComponent);
147 this.modalRef.content.poolName = this.poolName;
148 this.modalRef.content.imageName = this.rbdName;
149 if (oldSnapshotName) {
150 this.modalRef.content.setSnapName(this.selection.first().name);
152 this.modalRef.content.onSubmit.subscribe((snapshotName: string) => {
153 const executingTask = new ExecutingTask();
154 executingTask.name = taskName;
155 executingTask.metadata = {'snapshot_name': snapshotName};
156 this.executingTasks.push(executingTask);
161 openCreateSnapshotModal() {
162 this.openSnapshotModal('rbd/snap/create');
165 openEditSnapshotModal() {
166 this.openSnapshotModal('rbd/snap/edit', this.selection.first().name);
170 const snapshotName = this.selection.first().name;
171 const isProtected = this.selection.first().is_protected;
172 const finishedTask = new FinishedTask();
173 finishedTask.name = 'rbd/snap/edit';
174 finishedTask.metadata = {
175 'pool_name': this.poolName,
176 'image_name': this.rbdName,
177 'snapshot_name': snapshotName
179 this.rbdService.protectSnapshot(this.poolName, this.rbdName, snapshotName, !isProtected)
180 .toPromise().then((resp) => {
181 const executingTask = new ExecutingTask();
182 executingTask.name = finishedTask.name;
183 executingTask.metadata = finishedTask.metadata;
184 this.executingTasks.push(executingTask);
186 this.taskManagerService.subscribe(finishedTask.name, finishedTask.metadata,
187 (asyncFinishedTask: FinishedTask) => {
188 this.notificationService.notifyTask(asyncFinishedTask);
193 _asyncTask(task: string, taskName: string, snapshotName: string) {
194 const finishedTask = new FinishedTask();
195 finishedTask.name = taskName;
196 finishedTask.metadata = {
197 'pool_name': this.poolName,
198 'image_name': this.rbdName,
199 'snapshot_name': snapshotName
201 this.rbdService[task](this.poolName, this.rbdName, snapshotName)
202 .toPromise().then(() => {
203 const executingTask = new ExecutingTask();
204 executingTask.name = finishedTask.name;
205 executingTask.metadata = finishedTask.metadata;
206 this.executingTasks.push(executingTask);
207 this.modalRef.hide();
209 this.taskManagerService.subscribe(executingTask.name, executingTask.metadata,
210 (asyncFinishedTask: FinishedTask) => {
211 this.notificationService.notifyTask(asyncFinishedTask);
215 this.modalRef.content.stopLoadingSpinner();
220 const snapshotName = this.selection.selected[0].name;
221 this.modalRef = this.modalService.show(RollbackConfirmationModalComponent);
222 this.modalRef.content.snapName = `${this.poolName}/${this.rbdName}@${snapshotName}`;
223 this.modalRef.content.onSubmit.subscribe((itemName: string) => {
224 this._asyncTask('rollbackSnapshot', 'rbd/snap/rollback', snapshotName);
228 deleteSnapshotModal() {
229 const snapshotName = this.selection.selected[0].name;
230 this.modalRef = this.modalService.show(DeletionModalComponent);
231 this.modalRef.content.setUp({
232 metaType: 'RBD snapshot',
233 pattern: snapshotName,
234 deletionMethod: () => this._asyncTask('deleteSnapshot', 'rbd/snap/delete', snapshotName),
235 modalRef: this.modalRef
239 updateSelection(selection: CdTableSelection) {
240 this.selection = selection;