forceIdentifier="true"
selectionType="single"
(updateSelection)="updateSelection($event)">
- <div class="table-actions">
- <div class="btn-group"
- dropdown>
- <button type="button"
- class="btn btn-sm btn-primary"
- *ngIf="permission.create && (!permission.update || !selection.hasSingleSelection)"
- routerLink="/block/rbd/add">
- <i class="fa fa-fw fa-plus"></i><span i18n>Add</span>
- </button>
- <button type="button"
- class="btn btn-sm btn-primary"
- *ngIf="permission.update && (!permission.create || permission.create && selection.hasSingleSelection)"
- [ngClass]="{'disabled': !selection.hasSingleSelection || selection.first().cdExecuting}"
- routerLink="/block/rbd/edit/{{ selection.first()?.pool_name | encodeUri }}/{{ selection.first()?.name | encodeUri }}">
- <i class="fa fa-fw fa-pencil"></i>
- <span i18n>Edit</span>
- </button>
- <button type="button"
- class="btn btn-sm btn-primary"
- *ngIf="permission.delete && !permission.update && !permission.create"
- [ngClass]="{'disabled': !selection.hasSingleSelection || selection.first().cdExecuting}"
- (click)="deleteRbdModal()">
- <i class="fa fa-fw fa-trash-o"></i><span i18n>Delete</span>
- </button>
- <button type="button"
- dropdownToggle
- class="btn btn-sm btn-primary dropdown-toggle dropdown-toggle-split"
- *ngIf="permission.create || permission.update">
- <span class="caret"></span>
- <span class="sr-only"></span>
- </button>
- <ul *dropdownMenu
- class="dropdown-menu"
- role="menu">
- <li role="menuitem"
- *ngIf="permission.create">
- <a class="dropdown-item"
- routerLink="/block/rbd/add">
- <i class="fa fa-fw fa-plus"></i>
- <span i18n>Add</span>
- </a>
- </li>
- <li role="menuitem"
- *ngIf="permission.update"
- [ngClass]="{'disabled': !selection.hasSingleSelection || selection.first().cdExecuting}">
- <a class="dropdown-item"
- routerLink="/block/rbd/edit/{{ selection.first()?.pool_name | encodeUri }}/{{ selection.first()?.name | encodeUri }}">
- <i class="fa fa-fw fa-pencil"></i>
- <span i18n>Edit</span>
- </a>
- </li>
- <li role="menuitem"
- *ngIf="permission.create"
- [ngClass]="{'disabled': !selection.hasSingleSelection || selection.first().cdExecuting}">
- <a class="dropdown-item"
- routerLink="/block/rbd/copy/{{ selection.first()?.pool_name | encodeUri }}/{{ selection.first()?.name | encodeUri }}">
- <i class="fa fa-fw fa-copy"></i>
- <span i18n>Copy</span>
- </a>
- </li>
- <li role="menuitem"
- *ngIf="permission.update"
- [ngClass]="{'disabled': !selection.hasSingleSelection || selection.first().cdExecuting || !selection.first().parent}">
- <a class="dropdown-item"
- (click)="flattenRbdModal()">
- <i class="fa fa-fw fa-chain-broken"></i>
- <span i18n>Flatten</span>
- </a>
- </li>
- <li role="menuitem"
- *ngIf="permission.delete"
- [ngClass]="{'disabled': !selection.hasSingleSelection || selection.first().cdExecuting}">
- <a class="dropdown-item"
- (click)="deleteRbdModal()">
- <i class="fa fa-fw fa-trash-o"></i>
- <span i18n>Delete</span>
- </a>
- </li>
- </ul>
- </div>
- </div>
+ <cd-table-actions class="table-actions"
+ [permission]="permission"
+ [selection]="selection"
+ [tableActions]="tableActions">
+ </cd-table-actions>
<cd-rbd-details cdTableDetail
[selection]="selection">
</cd-rbd-details>
import { HttpClientTestingModule } from '@angular/common/http/testing';
import { ComponentFixture, TestBed } from '@angular/core/testing';
+import { By } from '@angular/platform-browser';
import { RouterTestingModule } from '@angular/router/testing';
import { ToastModule } from 'ng2-toastr';
} from 'ngx-bootstrap';
import { BehaviorSubject, of } from 'rxjs';
-import { configureTestBed } from '../../../../testing/unit-test-helper';
+import { configureTestBed, PermissionHelper } from '../../../../testing/unit-test-helper';
import { RbdService } from '../../../shared/api/rbd.service';
import { ComponentsModule } from '../../../shared/components/components.module';
+import { TableActionsComponent } from '../../../shared/datatable/table-actions/table-actions.component';
import { ViewCacheStatus } from '../../../shared/enum/view-cache-status.enum';
import { ExecutingTask } from '../../../shared/models/executing-task';
import { SummaryService } from '../../../shared/services/summary.service';
expectImageTasks(component.images[2], 'Flattening');
});
});
+
+ describe('show action buttons and drop down actions depending on permissions', () => {
+ let tableActions: TableActionsComponent;
+ let scenario: { fn; empty; single };
+ let permissionHelper: PermissionHelper;
+
+ const getTableActionComponent = (): TableActionsComponent => {
+ fixture.detectChanges();
+ return fixture.debugElement.query(By.directive(TableActionsComponent)).componentInstance;
+ };
+
+ beforeEach(() => {
+ permissionHelper = new PermissionHelper(component.permission, () =>
+ getTableActionComponent()
+ );
+ scenario = {
+ fn: () => tableActions.getCurrentButton().name,
+ single: 'Edit',
+ empty: 'Add'
+ };
+ });
+
+ describe('with all', () => {
+ beforeEach(() => {
+ tableActions = permissionHelper.setPermissionsAndGetActions(1, 1, 1);
+ });
+
+ it(`shows 'Edit' for single selection else 'Add' as main action`, () =>
+ permissionHelper.testScenarios(scenario));
+
+ it('shows all actions', () => {
+ expect(tableActions.tableActions.length).toBe(5);
+ expect(tableActions.tableActions).toEqual(component.tableActions);
+ });
+ });
+
+ describe('with read, create and update', () => {
+ beforeEach(() => {
+ tableActions = permissionHelper.setPermissionsAndGetActions(1, 1, 0);
+ });
+
+ it(`shows 'Edit' for single selection else 'Add' as main action`, () =>
+ permissionHelper.testScenarios(scenario));
+
+ it(`shows all actions except for 'Delete'`, () => {
+ expect(tableActions.tableActions.length).toBe(4);
+ component.tableActions.pop();
+ expect(tableActions.tableActions).toEqual(component.tableActions);
+ });
+ });
+
+ describe('with read, create and delete', () => {
+ beforeEach(() => {
+ tableActions = permissionHelper.setPermissionsAndGetActions(1, 0, 1);
+ });
+
+ it(`shows 'Copy' for single selection else 'Add' as main action`, () => {
+ scenario.single = 'Copy';
+ permissionHelper.testScenarios(scenario);
+ });
+
+ it(`shows 'Add', 'Copy' and 'Delete' action`, () => {
+ expect(tableActions.tableActions.length).toBe(3);
+ expect(tableActions.tableActions).toEqual([
+ component.tableActions[0],
+ component.tableActions[2],
+ component.tableActions[4]
+ ]);
+ });
+ });
+
+ describe('with read, edit and delete', () => {
+ beforeEach(() => {
+ tableActions = permissionHelper.setPermissionsAndGetActions(0, 1, 1);
+ });
+
+ it(`shows always 'Edit' as main action`, () => {
+ scenario.empty = 'Edit';
+ permissionHelper.testScenarios(scenario);
+ });
+
+ it(`shows 'Edit', 'Flatten' and 'Delete' action`, () => {
+ expect(tableActions.tableActions.length).toBe(3);
+ expect(tableActions.tableActions).toEqual([
+ component.tableActions[1],
+ component.tableActions[3],
+ component.tableActions[4]
+ ]);
+ });
+ });
+
+ describe('with read and create', () => {
+ beforeEach(() => {
+ tableActions = permissionHelper.setPermissionsAndGetActions(1, 0, 0);
+ });
+
+ it(`shows 'Copy' for single selection else 'Add' as main action`, () => {
+ scenario.single = 'Copy';
+ permissionHelper.testScenarios(scenario);
+ });
+
+ it(`shows 'Copy' and 'Add' actions`, () => {
+ expect(tableActions.tableActions.length).toBe(2);
+ expect(tableActions.tableActions).toEqual([
+ component.tableActions[0],
+ component.tableActions[2]
+ ]);
+ });
+ });
+
+ describe('with read and edit', () => {
+ beforeEach(() => {
+ tableActions = permissionHelper.setPermissionsAndGetActions(0, 1, 0);
+ });
+
+ it(`shows always 'Edit' as main action`, () => {
+ scenario.empty = 'Edit';
+ permissionHelper.testScenarios(scenario);
+ });
+
+ it(`shows 'Edit' and 'Flatten' actions`, () => {
+ expect(tableActions.tableActions.length).toBe(2);
+ expect(tableActions.tableActions).toEqual([
+ component.tableActions[1],
+ component.tableActions[3]
+ ]);
+ });
+ });
+
+ describe('with read and delete', () => {
+ beforeEach(() => {
+ tableActions = permissionHelper.setPermissionsAndGetActions(0, 0, 1);
+ });
+
+ it(`shows always 'Delete' as main action`, () => {
+ scenario.single = 'Delete';
+ scenario.empty = 'Delete';
+ permissionHelper.testScenarios(scenario);
+ });
+
+ it(`shows only 'Delete' action`, () => {
+ expect(tableActions.tableActions.length).toBe(1);
+ expect(tableActions.tableActions).toEqual([component.tableActions[4]]);
+ });
+ });
+
+ describe('with only read', () => {
+ beforeEach(() => {
+ tableActions = permissionHelper.setPermissionsAndGetActions(0, 0, 0);
+ });
+
+ it('shows no main action', () => {
+ permissionHelper.testScenarios({
+ fn: () => tableActions.getCurrentButton(),
+ single: undefined,
+ empty: undefined
+ });
+ });
+
+ it('shows no actions', () => {
+ expect(tableActions.tableActions.length).toBe(0);
+ expect(tableActions.tableActions).toEqual([]);
+ });
+ });
+ });
});
import { TableComponent } from '../../../shared/datatable/table/table.component';
import { CellTemplate } from '../../../shared/enum/cell-template.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 { FinishedTask } from '../../../shared/models/finished-task';
flattenTpl: TemplateRef<any>;
permission: Permission;
+ tableActions: CdTableAction[];
images: any;
columns: CdTableColumn[];
retries: number;
private taskListService: TaskListService
) {
this.permission = this.authStorageService.getPermissions().rbdImage;
+ const getImageUri = () =>
+ this.selection.first() &&
+ `${encodeURI(this.selection.first().pool_name)}/${encodeURI(this.selection.first().name)}`;
+ const addAction: CdTableAction = {
+ permission: 'create',
+ icon: 'fa-plus',
+ routerLink: () => '/block/rbd/add',
+ buttonCondition: (selection: CdTableSelection) => !selection.hasSingleSelection,
+ name: 'Add'
+ };
+ const editAction: CdTableAction = {
+ permission: 'update',
+ icon: 'fa-pencil',
+ routerLink: () => `/block/rbd/edit/${getImageUri()}`,
+ name: 'Edit'
+ };
+ const deleteAction: CdTableAction = {
+ permission: 'delete',
+ icon: 'fa-trash-o',
+ click: () => this.deleteRbdModal(),
+ name: 'Delete'
+ };
+ const copyAction: CdTableAction = {
+ permission: 'create',
+ buttonCondition: (selection: CdTableSelection) => selection.hasSingleSelection,
+ disable: (selection: CdTableSelection) => !selection.hasSingleSelection,
+ icon: 'fa-copy',
+ routerLink: () => `/block/rbd/copy/${getImageUri()}`,
+ name: 'Copy'
+ };
+ const flattenAction: CdTableAction = {
+ permission: 'update',
+ disable: (selection: CdTableSelection) =>
+ !selection.hasSingleSelection || selection.first().cdExecuting || !selection.first().parent,
+ icon: 'fa-chain-broken',
+ click: () => this.flattenRbdModal(),
+ name: 'Flatten'
+ };
+ this.tableActions = [addAction, editAction, copyAction, flattenAction, deleteAction];
}
ngOnInit() {