diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-details/rbd-details.component.html b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-details/rbd-details.component.html index 21956cb39a6..fa42aa8edb5 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-details/rbd-details.component.html +++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-details/rbd-details.component.html @@ -118,6 +118,7 @@ diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-snapshot-list/rbd-snapshot-actions.model.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-snapshot-list/rbd-snapshot-actions.model.ts index 2b7fed607e6..bf3e89a6809 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-snapshot-list/rbd-snapshot-actions.model.ts +++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-snapshot-list/rbd-snapshot-actions.model.ts @@ -1,4 +1,5 @@ import { I18n } from '@ngx-translate/i18n-polyfill'; +import * as _ from 'lodash'; import { ActionLabelsI18n } from '../../../shared/constants/app.constants'; import { Icons } from '../../../shared/enum/icons.enum'; @@ -18,7 +19,7 @@ export class RbdSnapshotActionsModel { deleteSnap: CdTableAction; ordering: CdTableAction[]; - constructor(i18n: I18n, actionLabels: ActionLabelsI18n) { + constructor(i18n: I18n, actionLabels: ActionLabelsI18n, featuresName: string[]) { this.i18n = i18n; this.create = { @@ -49,7 +50,10 @@ export class RbdSnapshotActionsModel { permission: 'create', canBePrimary: (selection: CdTableSelection) => selection.hasSingleSelection, disable: (selection: CdTableSelection) => - !selection.hasSingleSelection || selection.first().cdExecuting, + !selection.hasSingleSelection || + selection.first().cdExecuting || + !_.isUndefined(this.getCloneDisableDesc(featuresName)), + disableDesc: () => this.getCloneDisableDesc(featuresName), icon: Icons.clone, name: actionLabels.CLONE }; @@ -87,4 +91,10 @@ export class RbdSnapshotActionsModel { this.deleteSnap ]; } + + getCloneDisableDesc(featuresName: string[]): string | undefined { + if (!featuresName.includes('layering')) { + return this.i18n('Parent image must support Layering'); + } + } } diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-snapshot-list/rbd-snapshot-list.component.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-snapshot-list/rbd-snapshot-list.component.spec.ts index 0d805c27dde..2044a784f26 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-snapshot-list/rbd-snapshot-list.component.spec.ts +++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-snapshot-list/rbd-snapshot-list.component.spec.ts @@ -64,6 +64,7 @@ describe('RbdSnapshotListComponent', () => { beforeEach(() => { fixture = TestBed.createComponent(RbdSnapshotListComponent); component = fixture.componentInstance; + component.ngOnChanges(); summaryService = TestBed.get(SummaryService); }); diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-snapshot-list/rbd-snapshot-list.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-snapshot-list/rbd-snapshot-list.component.ts index 1ac6f3c94e6..b77a6944456 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-snapshot-list/rbd-snapshot-list.component.ts +++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-snapshot-list/rbd-snapshot-list.component.ts @@ -37,6 +37,8 @@ export class RbdSnapshotListComponent implements OnInit, OnChanges { @Input() snapshots: RbdSnapshotModel[] = []; @Input() + featuresName: string[]; + @Input() poolName: string; @Input() rbdName: string; @@ -79,21 +81,6 @@ export class RbdSnapshotListComponent implements OnInit, OnChanges { private actionLabels: ActionLabelsI18n ) { this.permission = this.authStorageService.getPermissions().rbdImage; - const actions = new RbdSnapshotActionsModel(this.i18n, this.actionLabels); - actions.create.click = () => this.openCreateSnapshotModal(); - actions.rename.click = () => this.openEditSnapshotModal(); - actions.protect.click = () => this.toggleProtection(); - actions.unprotect.click = () => this.toggleProtection(); - const getImageUri = () => - this.selection.first() && - `${encodeURIComponent(this.poolName)}/${encodeURIComponent( - this.rbdName - )}/${encodeURIComponent(this.selection.first().name)}`; - actions.clone.routerLink = () => `/block/rbd/clone/${getImageUri()}`; - actions.copy.routerLink = () => `/block/rbd/copy/${getImageUri()}`; - actions.rollback.click = () => this.rollbackModal(); - actions.deleteSnap.click = () => this.deleteSnapshotModal(); - this.tableActions = actions.ordering; } ngOnInit() { @@ -135,6 +122,22 @@ export class RbdSnapshotListComponent implements OnInit, OnChanges { } ngOnChanges() { + const actions = new RbdSnapshotActionsModel(this.i18n, this.actionLabels, this.featuresName); + actions.create.click = () => this.openCreateSnapshotModal(); + actions.rename.click = () => this.openEditSnapshotModal(); + actions.protect.click = () => this.toggleProtection(); + actions.unprotect.click = () => this.toggleProtection(); + const getImageUri = () => + this.selection.first() && + `${encodeURIComponent(this.poolName)}/${encodeURIComponent( + this.rbdName + )}/${encodeURIComponent(this.selection.first().name)}`; + actions.clone.routerLink = () => `/block/rbd/clone/${getImageUri()}`; + actions.copy.routerLink = () => `/block/rbd/copy/${getImageUri()}`; + actions.rollback.click = () => this.rollbackModal(); + actions.deleteSnap.click = () => this.deleteSnapshotModal(); + this.tableActions = actions.ordering; + const itemFilter = (entry, task) => { return entry.name === task.metadata['snapshot_name']; };