[AAE-6309] Fix for displaying main action on collapsed menu (#2369)

* [AAE-6309] Fix for displaying main action on collapsed sidenav

* [AAE-6309] Cleaning code

* Fix after rebase

* [AAE-6309] Fix tests
This commit is contained in:
Bartosz Sekuła
2021-12-02 13:05:43 +01:00
committed by GitHub
parent 3ed95559a7
commit 16835ce179
7 changed files with 163 additions and 82 deletions

View File

@@ -3,18 +3,6 @@
} }
.app-create-menu { .app-create-menu {
width: 100%;
.mat-stroked-button:not(.app-create-menu-secondary-button) {
background-color: var(--theme-accent-color);
color: var(--theme-primary-color-default-contrast);
margin-top: 0px;
.mat-icon {
color: var(--theme-primary-color-default-contrast);
}
}
.mat-stroked-button { .mat-stroked-button {
width: 100%; width: 100%;
height: 37.5px; height: 37.5px;
@@ -34,6 +22,16 @@
height: 20px; height: 20px;
text-align: left; text-align: left;
} }
&:not(.app-create-menu-secondary-button) {
background-color: var(--theme-accent-color);
color: var(--theme-primary-color-default-contrast);
margin-top: 0px;
.mat-icon {
color: var(--theme-primary-color-default-contrast);
}
}
} }
&__root-menu { &__root-menu {
@@ -52,18 +50,22 @@
outline: none; outline: none;
color: var(--theme-secondary-text-color); color: var(--theme-secondary-text-color);
cursor: pointer; cursor: pointer;
&:hover {
color: var(--theme-accent-color);
}
margin: 0; margin: 0;
border: none; border: none;
background: none; background: none;
}
&:not(.app-create-menu-secondary-button) {
.app-create-menu--icon { .app-create-menu--icon {
color: var(--theme-accent-color); color: var(--theme-accent-color);
} }
&:hover {
color: var(--theme-accent-color);
}
}
}
.app-create-menu--icon {
&__sub-menu { &__sub-menu {
.mat-menu-item { .mat-menu-item {
display: flex; display: flex;
@@ -91,4 +93,5 @@
} }
} }
} }
}
} }

View File

@@ -1,15 +1,28 @@
<ng-container *ngIf="(mainAction$ | async) as action"> <ng-container *ngIf="(mainAction$ | async) as action">
<ng-container [ngSwitch]="action.type"> <ng-container [ngSwitch]="action.type">
<ng-container *ngSwitchCase="actionTypes.button">
<button <button
*ngSwitchCase="actionTypes.button" *ngIf="expanded"
mat-stroked-button mat-stroked-button
[id]="action.id"
[disabled]="action.disabled"
(click)="runAction(action.actions.click)" (click)="runAction(action.actions.click)"
[disabled]="action.disabled"
class="app-main-action-button" class="app-main-action-button"
data-automation-id="app-main-action-button"
> >
{{action.title | translate}} {{action.title | translate}}
</button> </button>
<button
*ngIf="expanded === false"
mat-icon-button
(click)="runAction(action.actions.click)"
[disabled]="action.disabled"
data-automation-id="app-main-action-icon"
title="{{ action.title| translate }}"
>
<mat-icon class="main-action-menu-icon">{{action.icon}}</mat-icon>
</button>
</ng-container>
</ng-container> </ng-container>
</ng-container> </ng-container>

View File

@@ -4,3 +4,7 @@
background-color: var(--theme-accent-color); background-color: var(--theme-accent-color);
color: var(--theme-primary-color-default-contrast); color: var(--theme-primary-color-default-contrast);
} }
.main-action-menu-icon {
color: var(--theme-accent-color);
}

View File

@@ -36,6 +36,9 @@ import { TranslateModule } from '@ngx-translate/core';
describe('MainActionComponent', () => { describe('MainActionComponent', () => {
let mainActionComponent: MainActionComponent; let mainActionComponent: MainActionComponent;
const buttonQuery = '[data-automation-id="app-main-action-button"]';
const iconQuery = '[data-automation-id="app-main-action-icon"]';
let fixture: ComponentFixture<MainActionComponent>; let fixture: ComponentFixture<MainActionComponent>;
let appExtensionService: AppExtensionServiceMock; let appExtensionService: AppExtensionServiceMock;
@@ -52,14 +55,20 @@ describe('MainActionComponent', () => {
fixture = TestBed.createComponent(MainActionComponent); fixture = TestBed.createComponent(MainActionComponent);
mainActionComponent = fixture.componentInstance; mainActionComponent = fixture.componentInstance;
});
describe('component is in expanded mode', () => {
beforeEach(async () => {
mainActionComponent.expanded = true;
fixture.detectChanges(); fixture.detectChanges();
}); });
it('should display button if main action is configured', () => { it('should display button if main action is configured', () => {
const button = fixture.debugElement.nativeElement.querySelector('.app-main-action-button'); const buttonMainAction = fixture.debugElement.nativeElement.querySelector(buttonQuery);
expect(button).toBeTruthy(); const iconMainAction = fixture.debugElement.nativeElement.querySelector(iconQuery);
expect(button.textContent.trim()).toBe(ACTION_TITLE);
expect(iconMainAction).toBeFalsy();
expect(buttonMainAction.textContent.trim()).toBe(ACTION_TITLE);
}); });
it('should not display button if main action is not configured', () => { it('should not display button if main action is not configured', () => {
@@ -67,14 +76,14 @@ describe('MainActionComponent', () => {
mainActionComponent.ngOnInit(); mainActionComponent.ngOnInit();
fixture.detectChanges(); fixture.detectChanges();
const button = fixture.debugElement.nativeElement.querySelector('.app-main-action-button'); const button = fixture.debugElement.nativeElement.querySelector(buttonQuery);
expect(button).toBeFalsy(); expect(button).toBeFalsy();
}); });
it('should call extension action', () => { it('should call extension action', () => {
const runExtensionActionSpy = spyOn(appExtensionService, 'runActionById'); const runExtensionActionSpy = spyOn(appExtensionService, 'runActionById');
const button = fixture.debugElement.nativeElement.querySelector('button'); const button = fixture.debugElement.nativeElement.querySelector(buttonQuery);
button.click(); button.click();
expect(runExtensionActionSpy).toHaveBeenCalledWith(ACTION_CLICK); expect(runExtensionActionSpy).toHaveBeenCalledWith(ACTION_CLICK);
@@ -90,9 +99,59 @@ describe('MainActionComponent', () => {
mainActionComponent.ngOnInit(); mainActionComponent.ngOnInit();
fixture.detectChanges(); fixture.detectChanges();
const button = fixture.debugElement.nativeElement.querySelector(`#${disabledMainActionRef.id}`); const button = fixture.debugElement.nativeElement.querySelector(buttonQuery);
button.click(); button.click();
expect(runAction).not.toHaveBeenCalled(); expect(runAction).not.toHaveBeenCalled();
}); });
});
describe('component is displayed as icon', () => {
beforeEach(async () => {
mainActionComponent.expanded = false;
fixture.detectChanges();
});
it('should display icon if main action is configured', () => {
const buttonMainAction = fixture.debugElement.nativeElement.querySelector(buttonQuery);
const iconMainAction = fixture.debugElement.nativeElement.querySelector(iconQuery);
expect(buttonMainAction).toBeFalsy();
expect(iconMainAction).toBeTruthy();
});
it('should not display icon if main action is not configured', () => {
spyOn(appExtensionService, 'getMainAction').and.returnValue(of(undefined));
mainActionComponent.ngOnInit();
fixture.detectChanges();
const mainAction = fixture.debugElement.nativeElement.querySelector(iconQuery);
expect(mainAction).toBeFalsy();
});
it('should call extension action', () => {
const runExtensionActionSpy = spyOn(appExtensionService, 'runActionById');
const mainAction = fixture.debugElement.nativeElement.querySelector(iconQuery);
mainAction.click();
expect(runExtensionActionSpy).toHaveBeenCalledWith(ACTION_CLICK);
});
it('should not call icon if main action is disabled', () => {
const disabledMainActionRef = getContentActionRef();
disabledMainActionRef.disabled = true;
spyOn(appExtensionService, 'getMainAction').and.returnValue(of(disabledMainActionRef));
const runAction = spyOn(mainActionComponent, 'runAction');
mainActionComponent.ngOnInit();
fixture.detectChanges();
const button = fixture.debugElement.nativeElement.querySelector(iconQuery);
button.click();
expect(runAction).not.toHaveBeenCalled();
});
});
}); });

View File

@@ -25,7 +25,7 @@
import { AppExtensionService } from '@alfresco/aca-shared'; import { AppExtensionService } from '@alfresco/aca-shared';
import { ContentActionRef, ContentActionType } from '@alfresco/adf-extensions'; import { ContentActionRef, ContentActionType } from '@alfresco/adf-extensions';
import { Component, OnDestroy, OnInit } from '@angular/core'; import { Component, Input, OnDestroy, OnInit } from '@angular/core';
import { Observable, Subject } from 'rxjs'; import { Observable, Subject } from 'rxjs';
import { takeUntil } from 'rxjs/operators'; import { takeUntil } from 'rxjs/operators';
@@ -35,6 +35,8 @@ import { takeUntil } from 'rxjs/operators';
styleUrls: ['./main-action.component.scss'] styleUrls: ['./main-action.component.scss']
}) })
export class MainActionComponent implements OnInit, OnDestroy { export class MainActionComponent implements OnInit, OnDestroy {
@Input() expanded: boolean;
mainAction$: Observable<ContentActionRef>; mainAction$: Observable<ContentActionRef>;
actionTypes = ContentActionType; actionTypes = ContentActionType;

View File

@@ -28,9 +28,10 @@ import { CommonModule } from '@angular/common';
import { MatButtonModule } from '@angular/material/button'; import { MatButtonModule } from '@angular/material/button';
import { TranslateModule } from '@ngx-translate/core'; import { TranslateModule } from '@ngx-translate/core';
import { MainActionComponent } from './main-action.component'; import { MainActionComponent } from './main-action.component';
import { MatIconModule } from '@angular/material/icon';
@NgModule({ @NgModule({
imports: [CommonModule, MatButtonModule, TranslateModule.forChild()], imports: [CommonModule, MatButtonModule, MatIconModule, TranslateModule.forChild()],
exports: [MainActionComponent], exports: [MainActionComponent],
declarations: [MainActionComponent] declarations: [MainActionComponent]
}) })

View File

@@ -1,8 +1,7 @@
<div class="sidenav"> <div class="sidenav">
<ng-container [ngSwitch]="mode"> <ng-container [ngSwitch]="mode">
<div class="section action-menu" [ngClass]="'section--' + mode"> <div class="section action-menu" [ngClass]="'section--' + mode">
<app-main-action></app-main-action> <app-main-action [expanded]="mode === 'expanded'"></app-main-action>
<app-create-menu [expanded]="mode === 'expanded'"></app-create-menu> <app-create-menu [expanded]="mode === 'expanded'"></app-create-menu>
</div> </div>