Skip to content

Commit

Permalink
[58454] Sidebar menu should be hidden when page width is reduced (#17003
Browse files Browse the repository at this point in the history
)

* on resizing the window hide the menu if the new window size is small

* close menu when the screen is resized and its size is less than 1012px

* show the menu if the window size is greater than 1012px

* add comment

* fix closing menu when the user close it and then refresh the page again

* fix eslint errors

* set focus on first element of menu

* check if the screen is a large screen and menu is hidden because the screen size was resized to a small one

* set toggle title
  • Loading branch information
bsatarnejad authored Dec 11, 2024
1 parent 3fc1250 commit 48a2f39
Showing 1 changed file with 60 additions and 46 deletions.
106 changes: 60 additions & 46 deletions frontend/src/app/core/main-menu/main-menu-toggle.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -66,12 +66,18 @@ export class MainMenuToggleService {
private changeData = new BehaviorSubject<any>({});

public changeData$ = this.changeData.asObservable();
private wasHiddenDueToResize = false;

private wasCollapsedByUser = false;

constructor(
protected I18n:I18nService,
public injector:Injector,
readonly deviceService:DeviceService,
) {
this.initializeMenu();
// Add resize event listener
window.addEventListener('resize', this.onWindowResize.bind(this));
}

public initializeMenu():void {
Expand All @@ -80,45 +86,57 @@ export class MainMenuToggleService {
}

this.elementWidth = parseInt(window.OpenProject.guardedLocalStorage(this.localStorageKey) as string);
const menuCollapsed = window.OpenProject.guardedLocalStorage(this.localStorageStateKey) as string;
const menuCollapsed = window.OpenProject.guardedLocalStorage(this.localStorageStateKey) === 'true';

// Set the initial value of the collapse tracking flag
this.wasCollapsedByUser = menuCollapsed;

if (!this.elementWidth) {
this.saveWidth(this.mainMenu.offsetWidth);
} else if (menuCollapsed && JSON.parse(menuCollapsed)) {
} else if (menuCollapsed) {
this.closeMenu();
} else {
this.setWidth();
}

const currentProject:CurrentProjectService = this.injector.get(CurrentProjectService);
if (jQuery(document.body).hasClass('controller-my') && this.elementWidth === 0 || currentProject.id === null) {
this.saveWidth(this.defaultWidth);
}
this.adjustMenuVisibility();
}

// small desktop version default: hide menu on initialization
this.closeWhenOnSmallDesktop();
private onWindowResize():void {
this.adjustMenuVisibility();
}

private adjustMenuVisibility():void {
if (window.innerWidth >= 1012) {
// On larger screens, reopen the menu if it was hidden only due to screen resizing
if (this.wasHiddenDueToResize && !this.wasCollapsedByUser) {
this.setWidth(this.defaultWidth);
this.wasHiddenDueToResize = false; // Reset the flag since the menu is now shown
}
} else if (this.showNavigation) {
this.closeMenu();
this.wasHiddenDueToResize = true; // Indicate that the menu was hidden due to resize
}
}

// click on arrow or hamburger icon
public toggleNavigation(event?:JQuery.TriggeredEvent|Event):void {
if (event) {
event.stopPropagation();
event.preventDefault();
}

if (!this.showNavigation) { // sidebar is hidden -> show menu
if (this.deviceService.isSmallDesktop) { // small desktop version
this.setWidth(window.innerWidth);
} else { // desktop version
const savedWidth = parseInt(window.OpenProject.guardedLocalStorage(this.localStorageKey) as string);
const widthToSave = savedWidth >= this.elementMinWidth ? savedWidth : this.defaultWidth;
// Update the user collapse flag and clear `wasHiddenDueToResize`
this.wasCollapsedByUser = this.showNavigation;
this.wasHiddenDueToResize = false; // Reset because a manual toggle overrides any resize behavior

this.saveWidth(widthToSave);
}
} else { // sidebar is expanded -> close menu
if (this.showNavigation) {
this.closeMenu();
} else {
this.openMenu();
}

// Save the collapsed state in localStorage
window.OpenProject.guardedLocalStorage(this.localStorageStateKey, String(!this.showNavigation));
// Set focus on first visible main menu item.
// This needs to be called after AngularJS has rendered the menu, which happens some when after(!) we leave this
// method here. So we need to set the focus after a timeout.
Expand All @@ -129,48 +147,43 @@ export class MainMenuToggleService {

public closeMenu():void {
this.setWidth(0);
window.OpenProject.guardedLocalStorage(this.localStorageStateKey, 'true');
jQuery('.searchable-menu--search-input').blur();
}

public closeWhenOnSmallDesktop():void {
if (this.deviceService.isSmallDesktop) {
this.closeMenu();
window.OpenProject.guardedLocalStorage(this.localStorageStateKey, 'false');
}
}

public saveWidth(width?:number):void {
this.setWidth(width);
window.OpenProject.guardedLocalStorage(this.localStorageKey, String(this.elementWidth));
window.OpenProject.guardedLocalStorage(this.localStorageStateKey, String(this.elementWidth === 0));
public openMenu():void {
this.setWidth(this.defaultWidth);
}

public setWidth(width?:any):void {
public setWidth(width?:number):void {
if (width !== undefined) {
// Leave a minimum amount of space for space for the content
const maxMenuWidth = this.deviceService.isSmallDesktop ? window.innerWidth - 120 : window.innerWidth - 520;
if (width > maxMenuWidth) {
this.elementWidth = maxMenuWidth;
} else {
this.elementWidth = width as number;
}
this.elementWidth = width;
}

// Apply the width directly to the main menu
this.mainMenu.style.width = `${this.elementWidth}px`;

// Apply to root CSS variable for any related layout adjustments
this.htmlNode.style.setProperty('--main-menu-width', `${this.elementWidth}px`);

// Check if menu is open or closed and apply CSS class if needed
this.toggleClassHidden();
this.snapBack();
this.setToggleTitle();
this.toggleClassHidden();

this.global.showNavigation = this.showNavigation;
this.htmlNode.style.setProperty('--main-menu-width', `${this.elementWidth}px`);
// Save the width if it's open
if (this.elementWidth > 0) {
window.OpenProject.guardedLocalStorage(this.localStorageKey, String(this.elementWidth));
}
}

// Send change event when size of menu is changing (menu toggled or resized)
const changeEvent = jQuery.Event('change');
this.changeData.next(changeEvent);
public saveWidth(width?:number):void {
this.setWidth(width);
window.OpenProject.guardedLocalStorage(this.localStorageKey, String(this.elementWidth));
window.OpenProject.guardedLocalStorage(this.localStorageStateKey, String(this.elementWidth === 0));
}

public get showNavigation():boolean {
return (this.elementWidth >= this.elementMinWidth);
return this.elementWidth >= this.elementMinWidth;
}

private snapBack():void {
Expand All @@ -189,6 +202,7 @@ export class MainMenuToggleService {
}

private toggleClassHidden():void {
this.hideElements.toggleClass('hidden-navigation', !this.showNavigation);
const isHidden = this.elementWidth < this.elementMinWidth;
this.hideElements.toggleClass('hidden-navigation', isHidden);
}
}

0 comments on commit 48a2f39

Please sign in to comment.