From 58d2f7735d4500066c66017859e31ce577a70921 Mon Sep 17 00:00:00 2001 From: Henry Taeschner Date: Mon, 30 Dec 2024 18:47:22 +0100 Subject: [PATCH] fix: tuning menu layout - colors --- src/app/_ws-mixins.scss | 8 ++ .../workspace-menu/menu.component.html | 33 +++--- .../workspace-menu/menu.component.scss | 37 ++++--- .../workspace-menu/menu.component.spec.ts | 100 +++++++++++------- .../workspace-menu/menu.component.ts | 5 +- .../workspace-search.component.spec.ts | 22 ++-- 6 files changed, 124 insertions(+), 81 deletions(-) diff --git a/src/app/_ws-mixins.scss b/src/app/_ws-mixins.scss index 66c7bb94..5425e9e8 100644 --- a/src/app/_ws-mixins.scss +++ b/src/app/_ws-mixins.scss @@ -60,6 +60,14 @@ } } } +@mixin readable-disabled-components { + :host ::ng-deep { + .p-component:disabled, + .p-disabled { + opacity: unset; + } + } +} @mixin compact-dropdown-list-items { :host ::ng-deep { diff --git a/src/app/workspace/workspace-menu/menu.component.html b/src/app/workspace/workspace-menu/menu.component.html index 282ff6e9..b898463e 100644 --- a/src/app/workspace/workspace-menu/menu.component.html +++ b/src/app/workspace/workspace-menu/menu.component.html @@ -23,7 +23,7 @@ -
+
- + + - + - + - + + { +fdescribe('MenuComponent', () => { let component: MenuComponent let fixture: ComponentFixture @@ -125,9 +125,8 @@ describe('MenuComponent', () => { const mockUserService = jasmine.createSpyObj('UserService', ['hasPermission']) mockUserService.hasPermission.and.callFake((permission: string) => { - return ['MENU#VIEW', 'MENU#EDIT', 'MENU#GRANT', 'WORKSPACE_ROLE#EDIT'].includes(permission) + return ['MENU#VIEW', 'MENU#CREATE', 'MENU#EDIT', 'MENU#GRANT', 'WORKSPACE_ROLE#EDIT'].includes(permission) }) - const mockActivatedRouteSnapshot: Partial = { params: { id: 'mockId' } } @@ -188,56 +187,75 @@ describe('MenuComponent', () => { assgmtApiServiceSpy.searchAssignments.and.returnValue(of({})) }) - it('should create', () => { - expect(component).toBeTruthy() - }) + describe('Initialize:', () => { + it('should create', () => { + expect(component).toBeTruthy() + }) - it('it should push permissions to array if userService has them', () => { - expect(component.myPermissions).toContain('MENU#VIEW') - expect(component.myPermissions).toContain('MENU#EDIT') - expect(component.myPermissions).toContain('MENU#GRANT') - expect(component.myPermissions).toContain('WORKSPACE_ROLE#EDIT') + it('it should push permissions to array if userService has them', () => { + expect(component.myPermissions).toContain('MENU#VIEW') + expect(component.myPermissions).toContain('MENU#CREATE') + expect(component.myPermissions).toContain('MENU#EDIT') + expect(component.myPermissions).toContain('MENU#GRANT') + expect(component.myPermissions).toContain('WORKSPACE_ROLE#EDIT') + }) }) - describe('prepare page actions', () => { - it('should have prepared action buttons onInit: onClose, and called it', () => { + fdescribe('Page actions:', () => { + beforeEach(() => { component.ngOnInit() + }) + it('should have BACK navigation', () => { if (component.actions$) { component.actions$.subscribe((actions) => { const action = actions[0] action.actionCallback() + expect(locationSpy.back).toHaveBeenCalled() }) } }) - it('should have prepared action buttons onInit: hide Export button due to no menu items', () => { - spyOn(component, 'onExportMenu') - - component.ngOnInit() + it('should call CREATE', () => { + spyOn(component, 'onCreateMenu') if (component.actions$) { component.actions$.subscribe((actions) => { const action = actions[1] action.actionCallback() - expect(component.onExportMenu).toHaveBeenCalled() + + expect(action.permission).toEqual('MENU#CREATE') + //expect(component.changeMode).toEqual('CREATE') + expect(component.onCreateMenu).toHaveBeenCalled() + //expect(component.displayMenuDetail).toBeTrue() + }) + } + }) + + it('should call EXPORT: hide button if there are no menu items', () => { + spyOn(component, 'onExportMenu') + + if (component.actions$) { + component.actions$.subscribe((actions) => { + const action = actions[2] + action.actionCallback() + expect(action.permission).toEqual('MENU#EXPORT') expect(action.showCondition).toBeFalse() + expect(component.onExportMenu).toHaveBeenCalled() expect(component.menuItems).toEqual([]) expect(component.menuItems?.length).toBe(0) }) } }) - it('should have prepared action buttons onInit: hide Export button due to no menu items', () => { + it('should call EXPORT', () => { spyOn(component, 'onExportMenu') - - component.ngOnInit() component.menuItems = mockMenuItems if (component.actions$) { component.actions$.subscribe((actions) => { - const action = actions[1] + const action = actions[2] action.actionCallback() expect(component.onExportMenu).toHaveBeenCalled() expect(action.permission).toEqual('MENU#EXPORT') @@ -246,25 +264,24 @@ describe('MenuComponent', () => { }) } }) - it('should have exclude some actions', () => { + + it('should call EXPORT: hide on conditions', () => { component.menuItems = undefined component.prepareActionButtons() if (component.actions$) { component.actions$.subscribe((actions) => { - expect(actions[1].showCondition).toBeFalse() + expect(actions[2].showCondition).toBeFalse() }) } }) - it('should have prepared action buttons onInit: onImportMenu', () => { + it('should call IMPORT', () => { spyOn(component, 'onImportMenu') - component.ngOnInit() - if (component.actions$) { component.actions$.subscribe((actions) => { - const action = actions[2] + const action = actions[3] action.actionCallback() expect(component.onImportMenu).toHaveBeenCalled() }) @@ -510,18 +527,23 @@ describe('MenuComponent', () => { expect(component.displayMenuDetail).toBeFalse() }) - it('should handle onCreateMenu correctly', () => { - const mockEvent = jasmine.createSpyObj('MouseEvent', ['stopPropagation']) - const mockParent = { - key: '1-1', - id: 'id1' - } - component.onCreateMenu(mockEvent, mockParent) + describe('create menu item', () => { + it('should handle onCreateMenu correctly: with parent', () => { + const mockParent = { key: '1-1', id: 'id1' } + component.onCreateMenu(mockParent) - expect(mockEvent.stopPropagation).toHaveBeenCalled() - expect(component.changeMode).toEqual('CREATE') - expect(component.menuItem).toEqual(mockParent) - expect(component.displayMenuDetail).toBeTrue() + expect(component.changeMode).toEqual('CREATE') + expect(component.menuItem).toEqual(mockParent) + expect(component.displayMenuDetail).toBeTrue() + }) + + it('should handle onCreateMenu correctly: without parent', () => { + component.onCreateMenu() + + expect(component.changeMode).toEqual('CREATE') + expect(component.menuItem).toEqual(undefined) + expect(component.displayMenuDetail).toBeTrue() + }) }) it('should removeNodeFromTree if key is present and refresh menuNodes if delete displayed onMenuItemChanged', () => { diff --git a/src/app/workspace/workspace-menu/menu.component.ts b/src/app/workspace/workspace-menu/menu.component.ts index 1311e956..0627902f 100644 --- a/src/app/workspace/workspace-menu/menu.component.ts +++ b/src/app/workspace/workspace-menu/menu.component.ts @@ -98,7 +98,7 @@ export class MenuComponent implements OnInit, OnDestroy { public parentItems!: SelectItem[] public usedLanguages: Map = new Map() // detail - public changeMode: ChangeMode = 'EDIT' + public changeMode: ChangeMode = 'VIEW' public displayMenuDetail = false public displayMenuImport = false public displayMenuDelete = false @@ -124,6 +124,7 @@ export class MenuComponent implements OnInit, OnDestroy { this.menuItems = state.workspaceMenuItems // simplify permission checks if (this.userService.hasPermission('MENU#VIEW')) this.myPermissions.push('MENU#VIEW') + if (this.userService.hasPermission('MENU#VIEW')) this.myPermissions.push('MENU#CREATE') if (this.userService.hasPermission('MENU#EDIT')) this.myPermissions.push('MENU#EDIT') if (this.userService.hasPermission('MENU#GRANT')) this.myPermissions.push('MENU#GRANT') if (this.userService.hasPermission('WORKSPACE_ROLE#EDIT')) this.myPermissions.push('WORKSPACE_ROLE#EDIT') @@ -276,6 +277,7 @@ export class MenuComponent implements OnInit, OnDestroy { public onToggleTreeTableContent(ev: any): void { this.displayRoles = ev.checked + if (!this.displayRoles) this.onResetRoleFilter() this.loadRolesAndAssignments() } public isObjectEmpty(obj: object) { @@ -336,6 +338,7 @@ export class MenuComponent implements OnInit, OnDestroy { this.menuItem = parent this.displayMenuDetail = true } + // triggered by change event in menu detail dialog public onMenuItemChanged(changed: boolean): void { if (changed) { diff --git a/src/app/workspace/workspace-search/workspace-search.component.spec.ts b/src/app/workspace/workspace-search/workspace-search.component.spec.ts index 611008a4..f22a9351 100644 --- a/src/app/workspace/workspace-search/workspace-search.component.spec.ts +++ b/src/app/workspace/workspace-search/workspace-search.component.spec.ts @@ -16,9 +16,9 @@ import { WorkspaceSearchComponent } from './workspace-search.component' describe('WorkspaceSearchComponent', () => { let component: WorkspaceSearchComponent let fixture: ComponentFixture + let mockActivatedRoute: ActivatedRoute const mockRouter = { navigate: jasmine.createSpy('navigate') } - const accSpy = { getLocation: jasmine.createSpy('getLocation').and.returnValue({ deploymentPath: '/path' }) } @@ -49,12 +49,6 @@ describe('WorkspaceSearchComponent', () => { { provide: Accelerator.getLocation, useValue: accSpy.getLocation } ] }).compileComponents() - // to spy data: reset - msgServiceSpy.info.calls.reset() - msgServiceSpy.error.calls.reset() - wApiServiceSpy.searchWorkspaces.calls.reset() - // to spy data: refill with neutral data - wApiServiceSpy.searchWorkspaces.and.returnValue(of({})) })) beforeEach(() => { @@ -62,6 +56,12 @@ describe('WorkspaceSearchComponent', () => { accSpy.getLocation() component = fixture.componentInstance fixture.detectChanges() + // to spy data: reset + msgServiceSpy.info.calls.reset() + msgServiceSpy.error.calls.reset() + wApiServiceSpy.searchWorkspaces.calls.reset() + // to spy data: refill with neutral data + wApiServiceSpy.searchWorkspaces.and.returnValue(of({})) }) describe('initialize', () => { @@ -208,8 +208,8 @@ describe('WorkspaceSearchComponent', () => { if (component.actions$) { component.actions$.subscribe((actions) => { - const firstAction = actions[0] - firstAction.actionCallback() + const action = actions[0] + action.actionCallback() expect(component.toggleShowCreateDialog).toHaveBeenCalled() }) } @@ -222,8 +222,8 @@ describe('WorkspaceSearchComponent', () => { if (component.actions$) { component.actions$.subscribe((actions) => { - const firstAction = actions[1] - firstAction.actionCallback() + const action = actions[1] + action.actionCallback() expect(component.toggleShowImportDialog).toHaveBeenCalled() }) }