mirror of
https://github.com/Alfresco/alfresco-content-app.git
synced 2025-09-17 14:21:14 +00:00
[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:
@@ -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,43 +50,48 @@
|
|||||||
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 {
|
||||||
|
color: var(--theme-accent-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
color: var(--theme-accent-color);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.app-create-menu--icon {
|
.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 {
|
&:hover {
|
||||||
.mat-menu-item {
|
color: var(--theme-primary-color);
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
.mat-menu-item[disabled],
|
.mat-menu-item[disabled],
|
||||||
.mat-menu-item[disabled]:hover {
|
.mat-menu-item[disabled]:hover {
|
||||||
color: var(--theme-text-disabled-color);
|
|
||||||
|
|
||||||
.mat-icon {
|
|
||||||
color: var(--theme-text-disabled-color);
|
color: var(--theme-text-disabled-color);
|
||||||
|
|
||||||
|
.mat-icon {
|
||||||
|
color: var(--theme-text-disabled-color);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@@ -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">
|
||||||
<button
|
<ng-container *ngSwitchCase="actionTypes.button">
|
||||||
*ngSwitchCase="actionTypes.button"
|
<button
|
||||||
mat-stroked-button
|
*ngIf="expanded"
|
||||||
[id]="action.id"
|
mat-stroked-button
|
||||||
[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}}
|
>
|
||||||
</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>
|
||||||
</ng-container>
|
</ng-container>
|
||||||
|
|
||||||
|
@@ -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);
|
||||||
|
}
|
||||||
|
@@ -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,47 +55,103 @@ describe('MainActionComponent', () => {
|
|||||||
|
|
||||||
fixture = TestBed.createComponent(MainActionComponent);
|
fixture = TestBed.createComponent(MainActionComponent);
|
||||||
mainActionComponent = fixture.componentInstance;
|
mainActionComponent = fixture.componentInstance;
|
||||||
|
|
||||||
fixture.detectChanges();
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should display button if main action is configured', () => {
|
describe('component is in expanded mode', () => {
|
||||||
const button = fixture.debugElement.nativeElement.querySelector('.app-main-action-button');
|
beforeEach(async () => {
|
||||||
expect(button).toBeTruthy();
|
mainActionComponent.expanded = true;
|
||||||
expect(button.textContent.trim()).toBe(ACTION_TITLE);
|
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', () => {
|
describe('component is displayed as icon', () => {
|
||||||
spyOn(appExtensionService, 'getMainAction').and.returnValue(of(undefined));
|
beforeEach(async () => {
|
||||||
mainActionComponent.ngOnInit();
|
mainActionComponent.expanded = false;
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
|
});
|
||||||
|
|
||||||
const button = fixture.debugElement.nativeElement.querySelector('.app-main-action-button');
|
it('should display icon if main action is configured', () => {
|
||||||
expect(button).toBeFalsy();
|
const buttonMainAction = fixture.debugElement.nativeElement.querySelector(buttonQuery);
|
||||||
});
|
const iconMainAction = fixture.debugElement.nativeElement.querySelector(iconQuery);
|
||||||
|
|
||||||
it('should call extension action', () => {
|
expect(buttonMainAction).toBeFalsy();
|
||||||
const runExtensionActionSpy = spyOn(appExtensionService, 'runActionById');
|
expect(iconMainAction).toBeTruthy();
|
||||||
|
});
|
||||||
|
|
||||||
const button = fixture.debugElement.nativeElement.querySelector('button');
|
it('should not display icon if main action is not configured', () => {
|
||||||
button.click();
|
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', () => {
|
it('should call extension action', () => {
|
||||||
const disabledMainActionRef = getContentActionRef();
|
const runExtensionActionSpy = spyOn(appExtensionService, 'runActionById');
|
||||||
disabledMainActionRef.disabled = true;
|
|
||||||
|
|
||||||
spyOn(appExtensionService, 'getMainAction').and.returnValue(of(disabledMainActionRef));
|
const mainAction = fixture.debugElement.nativeElement.querySelector(iconQuery);
|
||||||
const runAction = spyOn(mainActionComponent, 'runAction');
|
mainAction.click();
|
||||||
|
|
||||||
mainActionComponent.ngOnInit();
|
expect(runExtensionActionSpy).toHaveBeenCalledWith(ACTION_CLICK);
|
||||||
fixture.detectChanges();
|
});
|
||||||
|
|
||||||
const button = fixture.debugElement.nativeElement.querySelector(`#${disabledMainActionRef.id}`);
|
it('should not call icon if main action is disabled', () => {
|
||||||
button.click();
|
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();
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@@ -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;
|
||||||
|
@@ -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]
|
||||||
})
|
})
|
||||||
|
@@ -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>
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user