]> git.proxmox.com Git - ceph.git/blobdiff - ceph/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-trash-list/rbd-trash-list.component.ts
import 15.2.0 Octopus source
[ceph.git] / ceph / src / pybind / mgr / dashboard / frontend / src / app / ceph / block / rbd-trash-list / rbd-trash-list.component.ts
index 62f8b2b3dce12bc76381b86e014812c21300cd95..ebbf28768c446b4679ec355ecc3e3728103bc8e4 100644 (file)
@@ -10,13 +10,16 @@ import { CriticalConfirmationModalComponent } from '../../../shared/components/c
 import { ActionLabelsI18n } from '../../../shared/constants/app.constants';
 import { TableComponent } from '../../../shared/datatable/table/table.component';
 import { CellTemplate } from '../../../shared/enum/cell-template.enum';
+import { Icons } from '../../../shared/enum/icons.enum';
 import { ViewCacheStatus } from '../../../shared/enum/view-cache-status.enum';
 import { CdTableAction } from '../../../shared/models/cd-table-action';
 import { CdTableColumn } from '../../../shared/models/cd-table-column';
 import { CdTableSelection } from '../../../shared/models/cd-table-selection';
 import { ExecutingTask } from '../../../shared/models/executing-task';
 import { FinishedTask } from '../../../shared/models/finished-task';
+import { ImageSpec } from '../../../shared/models/image-spec';
 import { Permission } from '../../../shared/models/permissions';
+import { Task } from '../../../shared/models/task';
 import { CdDatePipe } from '../../../shared/pipes/cd-date.pipe';
 import { AuthStorageService } from '../../../shared/services/auth-storage.service';
 import { TaskListService } from '../../../shared/services/task-list.service';
@@ -31,13 +34,15 @@ import { RbdTrashRestoreModalComponent } from '../rbd-trash-restore-modal/rbd-tr
   providers: [TaskListService]
 })
 export class RbdTrashListComponent implements OnInit {
-  @ViewChild(TableComponent)
+  @ViewChild(TableComponent, { static: true })
   table: TableComponent;
-  @ViewChild('expiresTpl')
+  @ViewChild('expiresTpl', { static: true })
   expiresTpl: TemplateRef<any>;
-  @ViewChild('deleteTpl')
+  @ViewChild('deleteTpl', { static: true })
   deleteTpl: TemplateRef<any>;
 
+  icons = Icons;
+
   columns: CdTableColumn[];
   executingTasks: ExecutingTask[] = [];
   images: any;
@@ -47,6 +52,7 @@ export class RbdTrashListComponent implements OnInit {
   selection = new CdTableSelection();
   tableActions: CdTableAction[];
   viewCacheStatusList: any[];
+  disablePurgeBtn = true;
 
   constructor(
     private authStorageService: AuthStorageService,
@@ -59,16 +65,15 @@ export class RbdTrashListComponent implements OnInit {
     public actionLabels: ActionLabelsI18n
   ) {
     this.permission = this.authStorageService.getPermissions().rbdImage;
-
     const restoreAction: CdTableAction = {
       permission: 'update',
-      icon: 'fa-undo',
+      icon: Icons.undo,
       click: () => this.restoreModal(),
       name: this.actionLabels.RESTORE
     };
     const deleteAction: CdTableAction = {
       permission: 'delete',
-      icon: 'fa-times',
+      icon: Icons.destroy,
       click: () => this.deleteModal(),
       name: this.actionLabels.DELETE
     };
@@ -93,6 +98,11 @@ export class RbdTrashListComponent implements OnInit {
         prop: 'pool_name',
         flexGrow: 1
       },
+      {
+        name: this.i18n('Namespace'),
+        prop: 'namespace',
+        flexGrow: 1
+      },
       {
         name: this.i18n('Status'),
         prop: 'deferment_end_time',
@@ -107,29 +117,39 @@ export class RbdTrashListComponent implements OnInit {
       }
     ];
 
+    const itemFilter = (entry: any, task: Task) => {
+      const imageSpec = new ImageSpec(entry.pool_name, entry.namespace, entry.id);
+      return imageSpec.toString() === task.metadata['image_id_spec'];
+    };
+
+    const taskFilter = (task: Task) => {
+      return ['rbd/trash/remove', 'rbd/trash/restore'].includes(task.name);
+    };
+
     this.taskListService.init(
       () => this.rbdService.listTrash(),
       (resp) => this.prepareResponse(resp),
       (images) => (this.images = images),
       () => this.onFetchError(),
-      this.taskFilter,
-      this.itemFilter,
+      taskFilter,
+      itemFilter,
       undefined
     );
   }
 
   prepareResponse(resp: any[]): any[] {
-    let images = [];
+    let images: any[] = [];
     const viewCacheStatusMap = {};
-    resp.forEach((pool) => {
+    resp.forEach((pool: Record<string, any>) => {
       if (_.isUndefined(viewCacheStatusMap[pool.status])) {
         viewCacheStatusMap[pool.status] = [];
       }
       viewCacheStatusMap[pool.status].push(pool.pool_name);
       images = images.concat(pool.value);
+      this.disablePurgeBtn = !images.length;
     });
 
-    const viewCacheStatusList = [];
+    const viewCacheStatusList: any[] = [];
     _.forEach(viewCacheStatusMap, (value: any, key) => {
       viewCacheStatusList.push({
         status: parseInt(key, 10),
@@ -152,22 +172,14 @@ export class RbdTrashListComponent implements OnInit {
     this.viewCacheStatusList = [{ status: ViewCacheStatus.ValueException }];
   }
 
-  itemFilter(entry, task) {
-    return entry.id === task.metadata['image_id'];
-  }
-
-  taskFilter(task) {
-    return ['rbd/trash/remove', 'rbd/trash/restore'].includes(task.name);
-  }
-
   updateSelection(selection: CdTableSelection) {
     this.selection = selection;
   }
 
   restoreModal() {
     const initialState = {
-      metaType: 'RBD',
       poolName: this.selection.first().pool_name,
+      namespace: this.selection.first().namespace,
       imageName: this.selection.first().name,
       imageId: this.selection.first().id
     };
@@ -177,30 +189,29 @@ export class RbdTrashListComponent implements OnInit {
 
   deleteModal() {
     const poolName = this.selection.first().pool_name;
-    const imageName = this.selection.first().name;
+    const namespace = this.selection.first().namespace;
     const imageId = this.selection.first().id;
     const expiresAt = this.selection.first().deferment_end_time;
+    const imageIdSpec = new ImageSpec(poolName, namespace, imageId);
 
     this.modalRef = this.modalService.show(CriticalConfirmationModalComponent, {
       initialState: {
         itemDescription: 'RBD',
-        itemNames: [`${poolName}/${imageName}`],
+        itemNames: [imageIdSpec],
         bodyTemplate: this.deleteTpl,
         bodyContext: { $implicit: expiresAt },
         submitActionObservable: () =>
           this.taskWrapper.wrapTaskAroundCall({
             task: new FinishedTask('rbd/trash/remove', {
-              pool_name: poolName,
-              image_id: imageId,
-              image_name: imageName
+              image_id_spec: imageIdSpec.toString()
             }),
-            call: this.rbdService.removeTrash(poolName, imageId, imageName, true)
+            call: this.rbdService.removeTrash(imageIdSpec, true)
           })
       }
     });
   }
 
-  isExpired(expiresAt): boolean {
+  isExpired(expiresAt: string): boolean {
     return moment().isAfter(expiresAt);
   }