Skip to content

Commit

Permalink
#102: Burger Menu for toolbar actions on desktop (#103)
Browse files Browse the repository at this point in the history
  • Loading branch information
Laess3r authored Jul 19, 2022
1 parent bf86e4a commit ce5dbc4
Show file tree
Hide file tree
Showing 6 changed files with 146 additions and 46 deletions.
20 changes: 12 additions & 8 deletions projects/material-addons/src/lib/toolbar/toolbar.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -46,25 +46,29 @@
<ng-container *ngIf="hasPermission(action) | async">
<mad-icon-button
(click)="action.action()"
*ngIf="!(isHandset$ | async) || i < (getToolbarActions().length > 2 ? 1 : 2)"
*ngIf="(!(isHandset$ | async) && !getToolbarActionsAlwaysAsMenu()) || i < (getToolbarActions().length > 2 ? 1 : 2)"
[id]="action.matIcon"
[matTooltip]="action.actionName"
type="button"
>
type="button">
<mat-icon
[matBadgeColor]="action.badge ? action.badge.color : 'primary'"
matBadgePosition="below after"
[matBadge]="action.badge ? action.badge.value : null"
>{{ action.matIcon }}</mat-icon
>
>{{ action.matIcon }}</mat-icon>
</mad-icon-button>
</ng-container>
</ng-container>

<ng-container *ngIf="isHandset$ | async">
<ng-container *ngIf="(isHandset$ | async) || getToolbarActionsAlwaysAsMenu()">
<ng-container *ngIf="getToolbarActions().length > 2">
<mad-icon-button type="button" [matMenuTriggerFor]="burgerMenu" matTooltip="More">
<mat-icon>more_vert</mat-icon>
<mad-icon-button type="button" [matMenuTriggerFor]="burgerMenu" [matTooltip]="getToolbarActionsMenuTitle()">
<mat-icon
matBadgeColor="warn"
[matBadge]="showBadgeForMenu() ? '&#8288;' : null"
matBadgeSize="small"
matBadgePosition="above after"
>more_vert
</mat-icon>
</mad-icon-button>
<mat-menu #burgerMenu="matMenu">
<ng-container *ngFor="let action of getToolbarActions(); let i = index">
Expand Down
31 changes: 23 additions & 8 deletions projects/material-addons/src/lib/toolbar/toolbar.component.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import { Component } from '@angular/core';
import { Title } from '@angular/platform-browser';
import { ToolbarService } from './toolbar.service';
import { Observable, of } from 'rxjs';
import { BreakpointObserver, Breakpoints } from '@angular/cdk/layout';
import { map } from 'rxjs/operators';
import { Action, BackAction, MainAction, ToolbarAction } from './toolbar-action.interface';
import {Component} from '@angular/core';
import {Title} from '@angular/platform-browser';
import {ToolbarService} from './toolbar.service';
import {Observable, of} from 'rxjs';
import {BreakpointObserver, Breakpoints} from '@angular/cdk/layout';
import {map} from 'rxjs/operators';
import {Action, BackAction, MainAction, ToolbarAction} from './toolbar-action.interface';

@Component({
selector: 'mad-toolbar',
Expand All @@ -14,7 +14,8 @@ import { Action, BackAction, MainAction, ToolbarAction } from './toolbar-action.
export class ToolbarComponent {
isHandset$: Observable<boolean> = this.breakpointObserver.observe([Breakpoints.Handset]).pipe(map(result => result.matches));

constructor(private breakpointObserver: BreakpointObserver, private titleService: Title, private toolbarService: ToolbarService) {}
constructor(private breakpointObserver: BreakpointObserver, private titleService: Title, private toolbarService: ToolbarService) {
}

getTitle(): string {
const dataTitle = this.toolbarService.getDataTitle();
Expand Down Expand Up @@ -53,4 +54,18 @@ export class ToolbarComponent {
getBackAction(): BackAction {
return this.toolbarService.getBackAction();
}

getToolbarActionsAlwaysAsMenu(): boolean {
return this.toolbarService.getToolbarActionsAlwaysAsMenu();
}

getToolbarActionsMenuTitle(): string {
return this.toolbarService.getToolbarActionsMenuTitle();
}

showBadgeForMenu() {
return this.getToolbarActions()
.slice(1) // the first icon is not shown in menu
.filter(value => value.badge && value.badge.value).length > 0;
}
}
30 changes: 23 additions & 7 deletions projects/material-addons/src/lib/toolbar/toolbar.service.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { Injectable, OnDestroy } from '@angular/core';
import { NavigationEnd, Router } from '@angular/router';
import { Subscription } from 'rxjs';
import { TranslateService } from '@ngx-translate/core';
import { BackAction, MainAction, ToolbarAction } from './toolbar-action.interface';
import {Injectable, OnDestroy} from '@angular/core';
import {NavigationEnd, Router} from '@angular/router';
import {Subscription} from 'rxjs';
import {TranslateService} from '@ngx-translate/core';
import {BackAction, MainAction, ToolbarAction} from './toolbar-action.interface';

@Injectable({
providedIn: 'root',
Expand All @@ -11,11 +11,11 @@ export class ToolbarService implements OnDestroy {
backAction: BackAction;
mainActions: MainAction[] = []; // shown on the left, next to title, as big buttons
toolbarActions: ToolbarAction[] = []; // shown on the right as icons
addNewButtonRoute: string;
liftFabButtonHigher = false;
toolbarActionsAlwaysAsMenu = false; // show the mobile view (burger menu) for toolbar actions
dataTitle: string;
routerSubscription: Subscription;
private title: string;
private toolbarActionsMenuTitle = 'More'; // title of the burger menu

private currentUrl: string;

Expand Down Expand Up @@ -65,6 +65,14 @@ export class ToolbarService implements OnDestroy {
this.dataTitle = dataTitle;
}

setToolbarActionsAlwaysAsMenu(toolbarActionsAlwaysAsMenu: boolean): void {
this.toolbarActionsAlwaysAsMenu = toolbarActionsAlwaysAsMenu;
}

getToolbarActionsAlwaysAsMenu(): boolean {
return this.toolbarActionsAlwaysAsMenu;
}

getDataTitle(): string {
return this.dataTitle;
}
Expand All @@ -81,6 +89,14 @@ export class ToolbarService implements OnDestroy {
return this.backAction;
}

setToolbarActionsMenuTitle(toolbarActionsMenuTitle: string) {
this.toolbarActionsMenuTitle = toolbarActionsMenuTitle;
}

getToolbarActionsMenuTitle() {
return this.toolbarActionsMenuTitle;
}

addMainAction(mainAction: MainAction): void {
this.translate
.get(mainAction.i18nActionKey)
Expand Down
32 changes: 20 additions & 12 deletions src/app/app.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -84,17 +84,24 @@ import { ThrottleClickDemoComponent } from "./component-demos/throttle-click-dem
import { StepperModule } from "../../projects/material-addons/src/lib/stepper/stepper.module";
import { StepperComponent } from "./example-components/stepper/stepper.component";
import { StepperDemoComponent } from "./component-demos/stepper-demo/stepper-demo.component";
import { CdkStepperModule } from "@angular/cdk/stepper";
import { MatStepperModule } from "@angular/material/stepper";
import { QuickListCompactBasicComponent } from "./example-components/quick-list-compact-basic/quick-list-compact-basic.component";
import { PageLayoutsComponent } from "./component-demos/page-layouts/page-layouts.component";
import { FullPageLayoutsModule } from "./full-page-layouts/full-page-layouts.module";
import { ExampleComponentsLayoutComponent } from "./example-components-layout/example-components-layout.component";
import { DataTableCustomColumnsComponent } from "./example-components/data-table-custom-columns/data-table-custom-columns.component";
import { DataTableBatchModeComponent } from "./example-components/data-table-batch-mode/data-table-batch-mode.component";
import { DataTableSingleComponent } from "./example-components/data-table-single/data-table-single.component";
import { DataTableAsyncComponent } from "./example-components/data-table-async/data-table-async.component";
import { DataTableIdGeneratorComponent } from "./example-components/data-table-id-generator/data-table-id-generator.component";
import {CdkStepperModule} from "@angular/cdk/stepper";
import {MatStepperModule} from "@angular/material/stepper";
import {
QuickListCompactBasicComponent
} from "./example-components/quick-list-compact-basic/quick-list-compact-basic.component";
import {PageLayoutsComponent} from "./component-demos/page-layouts/page-layouts.component";
import {FullPageLayoutsModule} from "./full-page-layouts/full-page-layouts.module";
import {ExampleComponentsLayoutComponent} from "./example-components-layout/example-components-layout.component";
import {
DataTableCustomColumnsComponent
} from "./example-components/data-table-custom-columns/data-table-custom-columns.component";
import {DataTableBatchModeComponent} from "./example-components/data-table-batch-mode/data-table-batch-mode.component";
import {DataTableSingleComponent} from "./example-components/data-table-single/data-table-single.component";
import {DataTableAsyncComponent} from "./example-components/data-table-async/data-table-async.component";
import {
DataTableIdGeneratorComponent
} from "./example-components/data-table-id-generator/data-table-id-generator.component";
import {MatSlideToggleModule} from "@angular/material/slide-toggle";

export function HttpLoaderFactory(http: HttpClient): TranslateHttpLoader {
return new TranslateHttpLoader(http, "./assets/i18n/");
Expand Down Expand Up @@ -206,7 +213,8 @@ export function HttpLoaderFactory(http: HttpClient): TranslateHttpLoader {
StepperModule,
ContentPanelModule,
FullPageLayoutsModule,
FlowbarModule
FlowbarModule,
MatSlideToggleModule
],
providers: [],
bootstrap: [AppComponent],
Expand Down
5 changes: 5 additions & 0 deletions src/app/example-components/toolbar/toolbar.component.html
Original file line number Diff line number Diff line change
@@ -1 +1,6 @@
<mat-slide-toggle [(ngModel)]="showToolbarActionsAlwaysAsMenu" (click)="triggerShowToolbarActionsAlwaysAsMenu()">Show
toolbar actions as burger menu
</mat-slide-toggle>
<br>
<br>
<mad-toolbar></mad-toolbar>
74 changes: 63 additions & 11 deletions src/app/example-components/toolbar/toolbar.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ export class ToolbarComponent implements OnInit {
constructor(private toolbarService: ToolbarService) {
}

showToolbarActionsAlwaysAsMenu = false;

ngOnInit(): void {
this.setTitle();
this.configureMainAction();
Expand All @@ -22,6 +24,14 @@ export class ToolbarComponent implements OnInit {
this.toolbarService.toolbarTitle = 'Toolbar Demo Title';
this.toolbarService.setDataTitle('Sub title');
}

triggerShowToolbarActionsAlwaysAsMenu() {
const _this = this;
setTimeout(() => {
_this.toolbarService.setToolbarActionsAlwaysAsMenu(this.showToolbarActionsAlwaysAsMenu);
}, 100);
}

private configureMainAction(): void {
this.toolbarService.addMainAction({
i18nActionKey: 'Main Action',
Expand All @@ -33,10 +43,21 @@ export class ToolbarComponent implements OnInit {
}

private configureToolbarAction(): void {
this.toolbarService.setToolbarActionsMenuTitle('Actions');

this.toolbarService.addToolbarAction({
matIcon: 'help',
showIf: of(true),
i18nActionKey: 'Get some help',
action: () => {
alert('Help action');
},
});

this.toolbarService.addToolbarAction({
matIcon: 'cloud_download',
showIf: of(true),
i18nActionKey: 'Data download toolbar action',
i18nActionKey: 'Data download',
action: () => {
alert('Data download toolbar action');
},
Expand All @@ -51,25 +72,56 @@ export class ToolbarComponent implements OnInit {
},
});

this.toolbarService.addToolbarAction({
matIcon: 'add_alarm',
i18nActionKey: 'Alarm!',
action: () => {
alert('Alarm!');
},
});

this.toolbarService.addToolbarAction({
matIcon: 'comment',
i18nActionKey: 'Comment!',
i18nActionKey: 'Comment',
action: () => {
alert('20 unread comments!');
},
badge: {
value: '20',
value: '5',
color: 'warn',
},
}
});

this.toolbarService.addToolbarAction({
i18nActionKey: 'Change filter',
matIcon: 'filter_alt',
action: () => {
alert('Action');
}
});
this.toolbarService.addToolbarAction({
i18nActionKey: 'Print PDF',
matIcon: 'print',
action: () => {
alert('Action');
}
});

this.toolbarService.addToolbarAction({
matIcon: 'download',
i18nActionKey: 'Excel export',
action: () => {
alert('Action');
}
});
this.toolbarService.addToolbarAction({
matIcon: 'file_upload',
i18nActionKey: 'Excel Import',
action: () => {
alert('Action');
}
});
this.toolbarService.addToolbarAction(({
i18nActionKey: 'Reindex Data',
matIcon: 'biotech',
action: () => {
alert('Action');
}
}));

}

private configureBackAction(): void {
Expand Down

0 comments on commit ce5dbc4

Please sign in to comment.