From ce5dbc4dc6b357fc11286826f0848c79383d80f6 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Stefan=20L=C3=A4sser?=
<3459599+Laess3r@users.noreply.github.com>
Date: Tue, 19 Jul 2022 07:57:19 +0200
Subject: [PATCH] #102: Burger Menu for toolbar actions on desktop (#103)
---
.../src/lib/toolbar/toolbar.component.html | 20 +++--
.../src/lib/toolbar/toolbar.component.ts | 31 ++++++--
.../src/lib/toolbar/toolbar.service.ts | 30 ++++++--
src/app/app.module.ts | 32 +++++---
.../toolbar/toolbar.component.html | 5 ++
.../toolbar/toolbar.component.ts | 74 ++++++++++++++++---
6 files changed, 146 insertions(+), 46 deletions(-)
diff --git a/projects/material-addons/src/lib/toolbar/toolbar.component.html b/projects/material-addons/src/lib/toolbar/toolbar.component.html
index 531ce34a..fc414b26 100644
--- a/projects/material-addons/src/lib/toolbar/toolbar.component.html
+++ b/projects/material-addons/src/lib/toolbar/toolbar.component.html
@@ -46,25 +46,29 @@
2 ? 1 : 2)"
+ *ngIf="(!(isHandset$ | async) && !getToolbarActionsAlwaysAsMenu()) || i < (getToolbarActions().length > 2 ? 1 : 2)"
[id]="action.matIcon"
[matTooltip]="action.actionName"
- type="button"
- >
+ type="button">
{{ action.matIcon }}
+ >{{ action.matIcon }}
-
+
2">
-
- more_vert
+
+ more_vert
+
diff --git a/projects/material-addons/src/lib/toolbar/toolbar.component.ts b/projects/material-addons/src/lib/toolbar/toolbar.component.ts
index 02db3538..91cc1ed1 100644
--- a/projects/material-addons/src/lib/toolbar/toolbar.component.ts
+++ b/projects/material-addons/src/lib/toolbar/toolbar.component.ts
@@ -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',
@@ -14,7 +14,8 @@ import { Action, BackAction, MainAction, ToolbarAction } from './toolbar-action.
export class ToolbarComponent {
isHandset$: Observable = 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();
@@ -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;
+ }
}
diff --git a/projects/material-addons/src/lib/toolbar/toolbar.service.ts b/projects/material-addons/src/lib/toolbar/toolbar.service.ts
index 5c14c310..c91c4603 100644
--- a/projects/material-addons/src/lib/toolbar/toolbar.service.ts
+++ b/projects/material-addons/src/lib/toolbar/toolbar.service.ts
@@ -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',
@@ -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;
@@ -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;
}
@@ -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)
diff --git a/src/app/app.module.ts b/src/app/app.module.ts
index a4ed00a3..78d2751a 100644
--- a/src/app/app.module.ts
+++ b/src/app/app.module.ts
@@ -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/");
@@ -206,7 +213,8 @@ export function HttpLoaderFactory(http: HttpClient): TranslateHttpLoader {
StepperModule,
ContentPanelModule,
FullPageLayoutsModule,
- FlowbarModule
+ FlowbarModule,
+ MatSlideToggleModule
],
providers: [],
bootstrap: [AppComponent],
diff --git a/src/app/example-components/toolbar/toolbar.component.html b/src/app/example-components/toolbar/toolbar.component.html
index 90431f70..a6f41fd2 100644
--- a/src/app/example-components/toolbar/toolbar.component.html
+++ b/src/app/example-components/toolbar/toolbar.component.html
@@ -1 +1,6 @@
+Show
+ toolbar actions as burger menu
+
+
+
diff --git a/src/app/example-components/toolbar/toolbar.component.ts b/src/app/example-components/toolbar/toolbar.component.ts
index 37d0bf7a..15ef0ab1 100644
--- a/src/app/example-components/toolbar/toolbar.component.ts
+++ b/src/app/example-components/toolbar/toolbar.component.ts
@@ -11,6 +11,8 @@ export class ToolbarComponent implements OnInit {
constructor(private toolbarService: ToolbarService) {
}
+ showToolbarActionsAlwaysAsMenu = false;
+
ngOnInit(): void {
this.setTitle();
this.configureMainAction();
@@ -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',
@@ -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');
},
@@ -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 {