diff --git a/projects/aca-content/src/lib/components/header-actions/header-actions.component.html b/projects/aca-content/src/lib/components/header-actions/header-actions.component.html index a5bd756ab..0cd351796 100644 --- a/projects/aca-content/src/lib/components/header-actions/header-actions.component.html +++ b/projects/aca-content/src/lib/components/header-actions/header-actions.component.html @@ -24,8 +24,6 @@ - - diff --git a/projects/aca-content/src/lib/components/header-actions/header-actions.component.scss b/projects/aca-content/src/lib/components/header-actions/header-actions.component.scss index 46124d3ac..6474ee252 100644 --- a/projects/aca-content/src/lib/components/header-actions/header-actions.component.scss +++ b/projects/aca-content/src/lib/components/header-actions/header-actions.component.scss @@ -1,80 +1,55 @@ .aca-page-layout-header { - // display: flex; - // align-items: center; - // flex: 0 0 65px; - // flex-basis: 96px; - // background: var(--theme-page-layout-header-background-color); - // border-bottom: 1px solid var(--theme-border-color, rgba(0, 0, 0, 0.07)); - // padding: 0 24px; - .adf-breadcrumb-item { - font-size: 20px !important; - font-weight: 400 !important; - letter-spacing: 0.15px !important; - } + .app-search-input { + background: none; + } - .app-search-input { - background: none; - } - - .action-bar { - display: flex; - flex: auto; - height: 32px; - margin-left: 24px; + .action-bar { + display: flex; + flex: auto; + height: 32px; + margin-left: 24px; - adf-toolbar-divider { - width: 24px !important; - height: 32px !important; - margin: 4px 0 0 12px !important; - } - } - - .aca-mat-button { - display: flex; - flex-direction: column; - justify-content: center; - align-items: center; - letter-spacing: 0.25px; - font-weight: 500; - font-size: 14px; - font-style: normal; - border-radius: 6px; - border: none; - } - - .aca-create-button { - width: 71px !important; - min-width: 71px; - height: 32px; - background-color: var(--theme-create-button-background-color); - color: var(--theme-create-button-text-color); - text-overflow: ellipsis; - display: flex; - padding: 0; - } - - .aca-upload-button { - width: 73px !important; - min-width: 73px; - height: 32px; - background-color: var(--theme-upload-button-background-color); - color: var(--theme-upload-button-text-color); - text-overflow: ellipsis; - display: flex; - padding: 0; - margin-left: 12px; - } - - // .aca-process-button { - // width: 130px !important; - // min-width: 130px; - // height: 32px; - // background-color: var(--theme-upload-button-background-color); - // color: var(--theme-upload-button-text-color); - // text-overflow: ellipsis; - // display: flex; - // padding: 0; - // margin-left: 12px; - // } - } \ No newline at end of file + adf-toolbar-divider { + width: 24px !important; + height: 32px !important; + margin: 4px 0 0 12px !important; + } + } + + .aca-mat-button { + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; + letter-spacing: 0.25px; + font-weight: 500; + font-size: 14px; + font-style: normal; + border-radius: 6px; + border: none; + } + + .aca-create-button { + width: 71px !important; + min-width: 71px; + height: 32px; + background-color: var(--theme-create-button-background-color); + color: var(--theme-create-button-text-color); + text-overflow: ellipsis; + display: flex; + padding: 0; + } + + .aca-upload-button { + width: 73px !important; + min-width: 73px; + height: 32px; + background-color: var(--theme-upload-button-background-color); + color: var(--theme-upload-button-text-color); + text-overflow: ellipsis; + display: flex; + padding: 0; + margin-left: 12px; + } +} \ No newline at end of file diff --git a/projects/aca-content/src/lib/components/header-actions/header-actions.component.spec.ts b/projects/aca-content/src/lib/components/header-actions/header-actions.component.spec.ts index 6b11a89a6..6ae91a4e4 100644 --- a/projects/aca-content/src/lib/components/header-actions/header-actions.component.spec.ts +++ b/projects/aca-content/src/lib/components/header-actions/header-actions.component.spec.ts @@ -17,93 +17,125 @@ import { ComponentFixture, TestBed } from '@angular/core/testing'; import { AppTestingModule } from '../../testing/app-testing.module'; -import { HeaderActionsComponent } from './header-actions.component'; -import { HarnessLoader } from '@angular/cdk/testing'; -import { TestbedHarnessEnvironment } from '@angular/cdk/testing/testbed'; -import { MatButtonHarness } from '@angular/material/button/testing'; -import { MatMenuHarness } from '@angular/material/menu/testing'; -import { NoopAnimationsModule } from '@angular/platform-browser/animations'; -import { MatButtonModule } from '@angular/material/button'; -import { MatMenuModule } from '@angular/material/menu'; +import { HeaderActionsComponent } from './header-actions.component' +import { ContentActionType } from '@alfresco/adf-extensions'; +import { AppExtensionService } from '@alfresco/aca-shared'; +import { of } from 'rxjs'; import { By } from '@angular/platform-browser'; +import { CoreModule } from '@alfresco/adf-core'; +import { AppHeaderActionsModule } from './header-actions.module'; describe('HeaderActionsComponent', () => { let component: HeaderActionsComponent; let fixture: ComponentFixture; - let loader: HarnessLoader; + + let extensionService: AppExtensionService; + let getCreateActionsSpy: jasmine.Spy; + let getUploadActionsSpy: jasmine.Spy; beforeEach(() => { TestBed.configureTestingModule({ - imports: [AppTestingModule, NoopAnimationsModule, MatButtonModule, MatMenuModule], + imports: [AppTestingModule, CoreModule.forRoot(), AppHeaderActionsModule], declarations: [HeaderActionsComponent] }); fixture = TestBed.createComponent(HeaderActionsComponent); component = fixture.componentInstance; - loader = TestbedHarnessEnvironment.loader(fixture); + extensionService = TestBed.inject(AppExtensionService); + + getCreateActionsSpy = spyOn(extensionService, 'getCreateActions'); + getCreateActionsSpy.and.returnValue( + of([ + { + id: 'action1', + type: ContentActionType.button, + title: 'create action one' + }, + { + id: 'action2', + type: ContentActionType.button, + title: 'create action two' + } + ]) + ); + + getUploadActionsSpy = spyOn(extensionService, 'getUploadActions'); + getUploadActionsSpy.and.returnValue( + of([ + { + id: 'action3', + type: ContentActionType.button, + title: 'upload action one' + } + ]) + ); + + fixture = TestBed.createComponent(HeaderActionsComponent); + component = fixture.componentInstance; + fixture.detectChanges(); }); it('total number of buttons in header should be 2 if route is personal-files', async () => { spyOn(component, 'isPersonalFilesRoute').and.returnValue(true); - const buttons = await loader.getAllHarnesses(MatButtonHarness); - const createButton = await loader.getAllHarnesses(MatButtonHarness.with({text: 'APP.HEADER.BUTTONS.CREATE'})); - const uploadButton = await loader.getAllHarnesses(MatButtonHarness.with({text: 'APP.HEADER.BUTTONS.UPLOAD'})); + fixture.detectChanges(); + + const buttons = fixture.debugElement.queryAll(By.css('.action-bar > .aca-mat-button')); + const createButton: HTMLButtonElement = fixture.debugElement.query(By.css('[data-automation-id="create-button"]')).nativeElement; + const uploadButton: HTMLButtonElement = fixture.debugElement.query(By.css('[data-automation-id="upload-button"]')).nativeElement; expect(buttons.length).toBe(2); - expect(createButton.length).toBe(1); - expect(uploadButton.length).toBe(1); + expect(createButton).toBeTruthy(); + expect(uploadButton).toBeTruthy(); }); it('total number of buttons in header should be 1 if route is libraries', async () => { spyOn(component, 'isLibrariesRoute').and.returnValue(true); - const buttons = await loader.getAllHarnesses(MatButtonHarness); - const createButton = await loader.getAllHarnesses(MatButtonHarness.with({text: 'APP.HEADER.BUTTONS.CREATE'})); + fixture.detectChanges(); + + const buttons = fixture.debugElement.queryAll(By.css('.action-bar > .aca-mat-button')); + const createButton: HTMLButtonElement = fixture.debugElement.query(By.css('[data-automation-id="create-button"]')).nativeElement; expect(buttons.length).toBe(1); - expect(createButton.length).toBe(1); + expect(createButton).toBeTruthy(); }); - it('should open and close the create menu', async () => { + async function clickCreateMenu() { + fixture.detectChanges(); + await fixture.whenStable(); + + const button: HTMLButtonElement = fixture.debugElement.query(By.css('[data-automation-id="create-button"]')).nativeElement; + button.click(); + } + + async function clickUploadMenu() { + fixture.detectChanges(); + await fixture.whenStable(); + + const button: HTMLButtonElement = fixture.debugElement.query(By.css('[data-automation-id="upload-button"]')).nativeElement; + button.click(); + } + + it('should render menu items when create menu is opened' , async () => { spyOn(component, 'isPersonalFilesRoute').and.returnValue(true); - const createMenu = await loader.getHarness(MatMenuHarness.with({ triggerText: 'APP.HEADER.BUTTONS.CREATE' })); + await clickCreateMenu(); - expect(await createMenu.isOpen()).toBe(false); - await createMenu.open(); - expect(await createMenu.isOpen()).toBe(true); + const menuItems = fixture.debugElement.queryAll(By.css('.app-toolbar-menu-item')); + expect(menuItems.length).toBe(2); - await createMenu.close(); - expect(await createMenu.isOpen()).toBe(false); + const menuItemOne: HTMLSpanElement = (menuItems[0].nativeElement as HTMLButtonElement).querySelector('[data-automation-id="menu-item-title"]'); + const menuItemTwo: HTMLSpanElement = (menuItems[1].nativeElement as HTMLButtonElement).querySelector('[data-automation-id="menu-item-title"]'); + expect(menuItemOne.innerText).toBe('create action one'); + expect(menuItemTwo.innerText).toBe('create action two'); }); - it('should open and close the upload menu', async () => { + it('should render menu items when upload menu is opened', async () => { spyOn(component, 'isPersonalFilesRoute').and.returnValue(true); - const uploadMenu = await loader.getHarness(MatMenuHarness.with({ triggerText: 'APP.HEADER.BUTTONS.UPLOAD' })); + await clickUploadMenu(); - expect(await uploadMenu.isOpen()).toBe(false); - await uploadMenu.open(); - expect(await uploadMenu.isOpen()).toBe(true); + const menuItems = fixture.debugElement.queryAll(By.css('.app-toolbar-menu-item')); + expect(menuItems.length).toBe(1); - await uploadMenu.close(); - expect(await uploadMenu.isOpen()).toBe(false); - }); - - it('should load create menu on click of create button', async () => { - spyOn(component, 'isPersonalFilesRoute').and.returnValue(true); - - const buttons = await loader.getHarness(MatButtonHarness.with({ selector: '.aca-create-button' })); - buttons.click(); - - const createMenu = fixture.debugElement.queryAll(By.css('.app-create-menu__root-menu app-create-menu__sub-menu')); - expect(createMenu).toBeTruthy(); - }); - - it('should load upload menu on click of upload button', async () => { - spyOn(component, 'isPersonalFilesRoute').and.returnValue(true); - - const buttons = await loader.getHarness(MatButtonHarness.with({ selector: '.aca-upload-button' })); - buttons.click(); - - const uploadMenu = fixture.debugElement.queryAll(By.css('.app-upload-menu__root-menu app-upload-menu__sub-menu')); - expect(uploadMenu).toBeTruthy(); + const menuItemOne: HTMLSpanElement = (menuItems[0].nativeElement as HTMLButtonElement).querySelector('[data-automation-id="menu-item-title"]'); + expect(menuItemOne.innerText).toBe('upload action one'); }); }); diff --git a/projects/aca-content/src/lib/components/header-actions/header-actions.component.ts b/projects/aca-content/src/lib/components/header-actions/header-actions.component.ts index 1aebc00ab..c3371dbd5 100644 --- a/projects/aca-content/src/lib/components/header-actions/header-actions.component.ts +++ b/projects/aca-content/src/lib/components/header-actions/header-actions.component.ts @@ -85,12 +85,4 @@ export class HeaderActionsComponent extends PageComponent implements OnInit, OnD return false; } } - - isTasksRoute(): boolean { - return this.router.url.includes('/tasks'); - } - - isProcessesRoute(): boolean { - return this.router.url.includes('/processes'); - } } diff --git a/projects/aca-shared/src/lib/components/document-base-page/document-base-page.component.ts b/projects/aca-shared/src/lib/components/document-base-page/document-base-page.component.ts index cdaf73f5e..0c50837a6 100644 --- a/projects/aca-shared/src/lib/components/document-base-page/document-base-page.component.ts +++ b/projects/aca-shared/src/lib/components/document-base-page/document-base-page.component.ts @@ -25,7 +25,7 @@ import { DocumentListComponent, ShareDataRow } from '@alfresco/adf-content-services'; import { ShowHeaderMode } from '@alfresco/adf-core'; -import { ContentActionRef, ContentActionType, DocumentListPresetRef, SelectionState } from '@alfresco/adf-extensions'; +import { ContentActionRef, DocumentListPresetRef, SelectionState } from '@alfresco/adf-extensions'; import { OnDestroy, OnInit, OnChanges, ViewChild, SimpleChanges, Directive } from '@angular/core'; import { Store } from '@ngrx/store'; import { MinimalNodeEntity, MinimalNodeEntryEntity, NodePaging } from '@alfresco/js-api'; @@ -70,15 +70,12 @@ export abstract class PageComponent implements OnInit, OnDestroy, OnChanges { filterSorting = 'name-asc'; createActions: Array = []; uploadActions: Array = []; - mainAction$: Observable; - actionTypes = ContentActionType; protected subscriptions: Subscription[] = []; protected constructor(protected store: Store, protected extensions: AppExtensionService, protected content: DocumentBasePageService) {} ngOnInit() { - this.mainAction$ = this.extensions.getMainAction().pipe(takeUntil(this.onDestroy$)); this.extensions .getCreateActions() @@ -93,7 +90,7 @@ export abstract class PageComponent implements OnInit, OnDestroy, OnChanges { .subscribe((actions) => { this.uploadActions = actions; }); - + this.sharedPreviewUrl$ = this.store.select(getSharedUrl); this.infoDrawerOpened$ = this.store.select(isInfoDrawerOpened).pipe(map((infoDrawerState) => !this.isOutletPreviewUrl() && infoDrawerState)); @@ -144,10 +141,6 @@ export abstract class PageComponent implements OnInit, OnDestroy, OnChanges { this.store.dispatch(new SetSelectedNodesAction([])); } - runAction(action: string): void { - this.extensions.runActionById(action); - } - showPreview(node: MinimalNodeEntity, extras?: ViewNodeExtras) { if (node && node.entry) { let id: string; diff --git a/projects/aca-shared/src/lib/components/page-layout/page-layout.component.scss b/projects/aca-shared/src/lib/components/page-layout/page-layout.component.scss index 2220d999f..bc1027425 100644 --- a/projects/aca-shared/src/lib/components/page-layout/page-layout.component.scss +++ b/projects/aca-shared/src/lib/components/page-layout/page-layout.component.scss @@ -11,6 +11,12 @@ background: var(--theme-page-layout-header-background-color); border-bottom: 1px solid var(--theme-border-color, rgba(0, 0, 0, 0.07)); padding: 0 24px; + + .adf-breadcrumb-item { + font-size: 20px !important; + font-weight: 400 !important; + letter-spacing: 0.15px !important; + } } .aca-page-layout-content {