[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 {
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 {
width: 100%;
height: 37.5px;
@@ -34,6 +22,16 @@
height: 20px;
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 {
@@ -52,42 +50,47 @@
outline: none;
color: var(--theme-secondary-text-color);
cursor: pointer;
&:hover {
color: var(--theme-accent-color);
}
margin: 0;
border: none;
background: none;
&:not(.app-create-menu-secondary-button) {
.app-create-menu--icon {
color: var(--theme-accent-color);
}
&:hover {
color: var(--theme-accent-color);
}
}
}
.app-create-menu--icon {
color: var(--theme-accent-color);
}
&__sub-menu {
.mat-menu-item {
display: flex;
flex-direction: row;
align-items: center;
font-size: 14px;
color: var(--theme-secondary-text-color);
line-height: 48px;
box-shadow: none;
transform: none;
transition: unset;
font-weight: normal;
&__sub-menu {
.mat-menu-item {
display: flex;
flex-direction: row;
align-items: center;
font-size: 14px;
color: var(--theme-secondary-text-color);
line-height: 48px;
box-shadow: none;
transform: none;
transition: unset;
font-weight: normal;
&:hover {
color: var(--theme-primary-color);
&:hover {
color: var(--theme-primary-color);
}
}
}
.mat-menu-item[disabled],
.mat-menu-item[disabled]:hover {
color: var(--theme-text-disabled-color);
.mat-icon {
.mat-menu-item[disabled],
.mat-menu-item[disabled]:hover {
color: var(--theme-text-disabled-color);
.mat-icon {
color: var(--theme-text-disabled-color);
}
}
}
}

View File

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

View File

@@ -4,3 +4,7 @@
background-color: var(--theme-accent-color);
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', () => {
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 appExtensionService: AppExtensionServiceMock;
@@ -52,47 +55,103 @@ describe('MainActionComponent', () => {
fixture = TestBed.createComponent(MainActionComponent);
mainActionComponent = fixture.componentInstance;
fixture.detectChanges();
});
it('should display button if main action is configured', () => {
const button = fixture.debugElement.nativeElement.querySelector('.app-main-action-button');
expect(button).toBeTruthy();
expect(button.textContent.trim()).toBe(ACTION_TITLE);
describe('component is in expanded mode', () => {
beforeEach(async () => {
mainActionComponent.expanded = true;
fixture.detectChanges();
});
it('should display button if main action is configured', () => {
const buttonMainAction = fixture.debugElement.nativeElement.querySelector(buttonQuery);
const iconMainAction = fixture.debugElement.nativeElement.querySelector(iconQuery);
expect(iconMainAction).toBeFalsy();
expect(buttonMainAction.textContent.trim()).toBe(ACTION_TITLE);
});
it('should not display button if main action is not configured', () => {
spyOn(appExtensionService, 'getMainAction').and.returnValue(of(undefined));
mainActionComponent.ngOnInit();
fixture.detectChanges();
const button = fixture.debugElement.nativeElement.querySelector(buttonQuery);
expect(button).toBeFalsy();
});
it('should call extension action', () => {
const runExtensionActionSpy = spyOn(appExtensionService, 'runActionById');
const button = fixture.debugElement.nativeElement.querySelector(buttonQuery);
button.click();
expect(runExtensionActionSpy).toHaveBeenCalledWith(ACTION_CLICK);
});
it('should not call button 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(buttonQuery);
button.click();
expect(runAction).not.toHaveBeenCalled();
});
});
it('should not display button if main action is not configured', () => {
spyOn(appExtensionService, 'getMainAction').and.returnValue(of(undefined));
mainActionComponent.ngOnInit();
fixture.detectChanges();
describe('component is displayed as icon', () => {
beforeEach(async () => {
mainActionComponent.expanded = false;
fixture.detectChanges();
});
const button = fixture.debugElement.nativeElement.querySelector('.app-main-action-button');
expect(button).toBeFalsy();
});
it('should display icon if main action is configured', () => {
const buttonMainAction = fixture.debugElement.nativeElement.querySelector(buttonQuery);
const iconMainAction = fixture.debugElement.nativeElement.querySelector(iconQuery);
it('should call extension action', () => {
const runExtensionActionSpy = spyOn(appExtensionService, 'runActionById');
expect(buttonMainAction).toBeFalsy();
expect(iconMainAction).toBeTruthy();
});
const button = fixture.debugElement.nativeElement.querySelector('button');
button.click();
it('should not display icon if main action is not configured', () => {
spyOn(appExtensionService, 'getMainAction').and.returnValue(of(undefined));
mainActionComponent.ngOnInit();
fixture.detectChanges();
expect(runExtensionActionSpy).toHaveBeenCalledWith(ACTION_CLICK);
});
const mainAction = fixture.debugElement.nativeElement.querySelector(iconQuery);
expect(mainAction).toBeFalsy();
});
it('should not call button if main action is disabled', () => {
const disabledMainActionRef = getContentActionRef();
disabledMainActionRef.disabled = true;
it('should call extension action', () => {
const runExtensionActionSpy = spyOn(appExtensionService, 'runActionById');
spyOn(appExtensionService, 'getMainAction').and.returnValue(of(disabledMainActionRef));
const runAction = spyOn(mainActionComponent, 'runAction');
const mainAction = fixture.debugElement.nativeElement.querySelector(iconQuery);
mainAction.click();
mainActionComponent.ngOnInit();
fixture.detectChanges();
expect(runExtensionActionSpy).toHaveBeenCalledWith(ACTION_CLICK);
});
const button = fixture.debugElement.nativeElement.querySelector(`#${disabledMainActionRef.id}`);
button.click();
it('should not call icon if main action is disabled', () => {
const disabledMainActionRef = getContentActionRef();
disabledMainActionRef.disabled = true;
expect(runAction).not.toHaveBeenCalled();
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 { 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 { takeUntil } from 'rxjs/operators';
@@ -35,6 +35,8 @@ import { takeUntil } from 'rxjs/operators';
styleUrls: ['./main-action.component.scss']
})
export class MainActionComponent implements OnInit, OnDestroy {
@Input() expanded: boolean;
mainAction$: Observable<ContentActionRef>;
actionTypes = ContentActionType;

View File

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

View File

@@ -1,8 +1,7 @@
<div class="sidenav">
<ng-container [ngSwitch]="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>
</div>