Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion src/app/app.effects.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@

import { NavbarEffects } from './navbar/navbar.effects';
import { RelationshipEffects } from './shared/form/builder/ds-dynamic-form-ui/relation-lookup-modal/relationship.effects';
import { MenuEffects } from './shared/menu/menu.effects';
Expand Down
20 changes: 14 additions & 6 deletions src/app/core/cookies/orejime-configuration.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,16 @@
import { LANG_COOKIE } from '@dspace/core/locale/locale.service';
import { NativeWindowRef } from '@dspace/core/services/window.service';

import {
CAPTCHA_COOKIE,
CAPTCHA_NAME,
} from '../../core/google-recaptcha/google-recaptcha.service';
import { PINNED_MENU_COOKIE } from '../../shared/menu/menu.service';
import {
IMPERSONATING_COOKIE,
REDIRECT_COOKIE,
} from '../auth/auth.service';
import { TOKENITEM } from '../auth/models/auth-token-info.model';
import {
CAPTCHA_COOKIE,
CAPTCHA_NAME,
} from '../google-recaptcha/google-recaptcha.service';
import { LANG_COOKIE } from '../locale/locale.service';
import { NativeWindowRef } from '../services/window.service';
import { ACCESSIBILITY_COOKIE } from './accessibility-cookie';

/**
Expand Down Expand Up @@ -230,6 +232,12 @@ export function getOrejimeConfiguration(_window: NativeWindowRef): any {
cookies: [ACCESSIBILITY_COOKIE],
onlyOnce: false,
},
{
name: 'menu-state',
purposes: ['functional'],
required: false,
cookies: [PINNED_MENU_COOKIE],
},
],
};
}
5 changes: 5 additions & 0 deletions src/app/init.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -227,4 +227,9 @@ export abstract class InitService {
find((b: boolean) => b === false),
);
}

protected configureMenuCollapsedState(): void {
this.menuService.syncMenuCollapsedState();
}

}
13 changes: 7 additions & 6 deletions src/app/shared/host-window.service.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ describe('HostWindowService', () => {
beforeEach(() => {
const _initialState: Partial<AppState> = { hostWindow: { width: 1600, height: 770 } };
store = createMockStore({ initialState: _initialState });
service = new HostWindowService(store, new CSSVariableServiceStub() as any);
service = new HostWindowService(store, new CSSVariableServiceStub() as any, 'browser');
});

it('isXs() should return false with width = 1600', () => {
Expand Down Expand Up @@ -64,7 +64,7 @@ describe('HostWindowService', () => {
beforeEach(() => {
const _initialState: Partial<AppState> = { hostWindow: { width: 1100, height: 770 } };
store = createMockStore({ initialState: _initialState });
service = new HostWindowService(store, new CSSVariableServiceStub() as any);
service = new HostWindowService(store, new CSSVariableServiceStub() as any, 'browser');
});

it('isXs() should return false with width = 1100', () => {
Expand Down Expand Up @@ -100,7 +100,7 @@ describe('HostWindowService', () => {
beforeEach(() => {
const _initialState = { hostWindow: { width: 800, height: 770 } };
store = createMockStore({ initialState: _initialState });
service = new HostWindowService(store, new CSSVariableServiceStub() as any);
service = new HostWindowService(store, new CSSVariableServiceStub() as any, 'browser');
});

it('isXs() should return false with width = 800', () => {
Expand Down Expand Up @@ -136,7 +136,7 @@ describe('HostWindowService', () => {
beforeEach(() => {
const _initialState = { hostWindow: { width: 600, height: 770 } };
store = createMockStore({ initialState: _initialState });
service = new HostWindowService(store, new CSSVariableServiceStub() as any);
service = new HostWindowService(store, new CSSVariableServiceStub() as any, 'browser');
});

it('isXs() should return false with width = 600', () => {
Expand Down Expand Up @@ -172,7 +172,7 @@ describe('HostWindowService', () => {
beforeEach(() => {
const _initialState = { hostWindow: { width: 400, height: 770 } };
store = createMockStore({ initialState: _initialState });
service = new HostWindowService(store, new CSSVariableServiceStub() as any);
service = new HostWindowService(store, new CSSVariableServiceStub() as any, 'browser');
});

it('isXs() should return true with width = 400', () => {
Expand Down Expand Up @@ -206,7 +206,8 @@ describe('HostWindowService', () => {

describe('widthCategory', () => {
beforeEach(() => {
service = new HostWindowService({} as Store<AppState>, new CSSVariableServiceStub() as any);
service = new HostWindowService({} as Store<AppState>, new CSSVariableServiceStub() as any,
'browser');
});

it('should call getWithObs to get the current width', () => {
Expand Down
14 changes: 13 additions & 1 deletion src/app/shared/host-window.service.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@
import { Injectable } from '@angular/core';
import { isPlatformServer } from '@angular/common';
import {
Inject,
Injectable,
PLATFORM_ID,
} from '@angular/core';
import {
maxMobileWidth,
WidthCategory,
Expand All @@ -12,6 +17,7 @@ import {
import {
combineLatest as observableCombineLatest,
Observable,
of,
} from 'rxjs';
import {
distinctUntilChanged,
Expand All @@ -33,6 +39,7 @@ export class HostWindowService {
constructor(
private store: Store<AppState>,
private variableService: CSSVariableService,
@Inject(PLATFORM_ID) private platformId: any,
) {
/* See _exposed_variables.scss */
variableService.getAllVariables()
Expand All @@ -52,6 +59,11 @@ export class HostWindowService {
}

get widthCategory(): Observable<WidthCategory> {
if (isPlatformServer(this.platformId)) {
// During SSR we won't know the viewport width -- assume we're rendering for desktop
return of(WidthCategory.XL);
}

return this.getWidthObs().pipe(
map((width: number) => {
if (width < this.breakPoints.SM_MIN) {
Expand Down
7 changes: 5 additions & 2 deletions src/app/shared/menu/menu.component.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,9 @@ import {
import { NoopAnimationsModule } from '@angular/platform-browser/animations';
import { ActivatedRoute } from '@angular/router';
import { RouterTestingModule } from '@angular/router/testing';
import { authReducer } from '@dspace/core/auth/auth.reducer';
import { AuthorizationDataService } from '@dspace/core/data/feature-authorization/authorization-data.service';
import { CookieService } from '@dspace/core/cookies/cookie.service';
import { Item } from '@dspace/core/shared/item.model';
import { CookieServiceMock } from '@dspace/core/testing/cookie.service.mock';
import { createSuccessfulRemoteDataObject } from '@dspace/core/utilities/remote-data.utils';
import {
Store,
Expand All @@ -37,6 +37,8 @@ import {
AppState,
storeModuleConfig,
} from '../../app.reducer';
import { authReducer } from '../../core/auth/auth.reducer';
import { AuthorizationDataService } from '../../core/data/feature-authorization/authorization-data.service';
import { getMockThemeService } from '../theme-support/test/theme-service.mock';
import { ThemeService } from '../theme-support/theme.service';
import { MenuComponent } from './menu.component';
Expand Down Expand Up @@ -148,6 +150,7 @@ describe('MenuComponent', () => {
Injector,
{ provide: ThemeService, useValue: getMockThemeService() },
MenuService,
{ provide: CookieService, useValue: CookieServiceMock },
provideMockStore({ initialState }),
{ provide: AuthorizationDataService, useValue: authorizationService },
{ provide: ActivatedRoute, useValue: routeStub },
Expand Down
3 changes: 3 additions & 0 deletions src/app/shared/menu/menu.effects.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ import { Observable } from 'rxjs';
import { StoreAction } from '../../store.actions';
import { ReinitMenuAction } from './menu.actions';
import { MenuEffects } from './menu.effects';
import { MenuService } from './menu.service';
import { MenuServiceStub } from './menu-service.stub';

describe('MenuEffects', () => {
let menuEffects: MenuEffects;
Expand All @@ -22,6 +24,7 @@ describe('MenuEffects', () => {
providers: [
MenuEffects,
provideMockActions(() => actions),
{ provide: MenuService, useValue: new MenuServiceStub() },
],
});
}));
Expand Down
34 changes: 31 additions & 3 deletions src/app/shared/menu/menu.effects.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,19 @@ import {
createEffect,
ofType,
} from '@ngrx/effects';
import { map } from 'rxjs/operators';
import {
map,
tap,
} from 'rxjs/operators';

import { ReinitMenuAction } from './menu.actions';
import {
CollapseMenuAction,
ExpandMenuAction,
MenuActionTypes,
ReinitMenuAction,
ToggleMenuAction,
} from './menu.actions';
import { MenuService } from './menu.service';

@Injectable()
export class MenuEffects {
Expand All @@ -21,7 +31,25 @@ export class MenuEffects {
map(() => new ReinitMenuAction()),
));

constructor(private actions$: Actions) {
menuCollapsedStateToggle$ = createEffect(() => this.actions$.pipe(
ofType(MenuActionTypes.TOGGLE_MENU),
tap((action: ToggleMenuAction) => this.menuService.toggleMenuCollapsedState(action.menuID)),
), { dispatch: false });

menuCollapsedStateCollapse$ = createEffect(() => this.actions$.pipe(
ofType(MenuActionTypes.COLLAPSE_MENU),
tap((action: CollapseMenuAction) => this.menuService.setMenuCollapsedState(action.menuID, true)),
), { dispatch: false });

menuCollapsedStateExpand$ = createEffect(() => this.actions$.pipe(
ofType(MenuActionTypes.EXPAND_MENU),
tap((action: ExpandMenuAction) => this.menuService.setMenuCollapsedState(action.menuID, false)),
), { dispatch: false });

constructor(
private actions$: Actions,
private menuService: MenuService,
) {
}

}
46 changes: 44 additions & 2 deletions src/app/shared/menu/menu.service.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ import {
waitForAsync,
} from '@angular/core/testing';
import { NavigationEnd } from '@angular/router';
import { CookieService } from '@dspace/core/cookies/cookie.service';
import { CookieServiceMock } from '@dspace/core/testing/cookie.service.mock';
import {
Store,
StoreModule,
Expand All @@ -27,7 +29,10 @@ import {
ToggleMenuAction,
} from './menu.actions';
import { menusReducer } from './menu.reducer';
import { MenuService } from './menu.service';
import {
MenuService,
PINNED_MENU_COOKIE,
} from './menu.service';
import { MenuID } from './menu-id.model';
import { LinkMenuItemModel } from './menu-item/models/link.model';
import { MenuItemType } from './menu-item-type.model';
Expand All @@ -50,6 +55,7 @@ describe('MenuService', () => {
let alreadyPresentMenuSection: MenuSection;
let route;
let router;
let cookieService;


function init() {
Expand Down Expand Up @@ -181,6 +187,8 @@ describe('MenuService', () => {
router = {
events: of(new NavigationEnd(1, 'test-url', 'test-url')),
};

cookieService = new CookieServiceMock();
}

beforeEach(waitForAsync(() => {
Expand All @@ -192,13 +200,14 @@ describe('MenuService', () => {
providers: [
provideMockStore({ initialState }),
{ provide: MenuService, useValue: service },
{ provide: CookieService, useClass: CookieServiceMock },
],
}).compileComponents();
}));

beforeEach(() => {
store = TestBed.inject(Store);
service = new MenuService(store, route, router);
service = new MenuService(store, route, router, cookieService);
spyOn(store, 'dispatch');
});

Expand Down Expand Up @@ -525,6 +534,39 @@ describe('MenuService', () => {
});
});

describe('toggleMenuCollapsedState', () => {
it('should update the collapsed state of the given menu in the cookie', () => {
service.toggleMenuCollapsedState(MenuID.ADMIN);
expect(cookieService.get(PINNED_MENU_COOKIE)[MenuID.ADMIN]).toEqual(false);
});
});

describe('syncMenuCollapsedState', () => {
it('should call expandMenu when a menu is collapsed in the store but expanded in the cookie', () => {
spyOn(service, 'expandMenu');
let cookieWithExpandedAdmin: object = {
[MenuID.ADMIN]: false,
[MenuID.PUBLIC]: false,
[MenuID.DSO_EDIT]: false,
};
cookieService.set(PINNED_MENU_COOKIE, cookieWithExpandedAdmin);
service.syncMenuCollapsedState();
expect(service.expandMenu).toHaveBeenCalledWith(MenuID.ADMIN);
});

it('should call collapseMenu when a menu is expanded in the store but collapsed in the cookie', () => {
spyOn(service, 'collapseMenu');
let cookieWithCollapsedAdmin: object = {
[MenuID.ADMIN]: true,
[MenuID.PUBLIC]: false,
[MenuID.DSO_EDIT]: false,
};
cookieService.set(PINNED_MENU_COOKIE, cookieWithCollapsedAdmin);
service.syncMenuCollapsedState();
expect(service.collapseMenu).toHaveBeenCalledWith(MenuID.ADMIN);
});
});

describe('toggleActiveSection', () => {
it('should dispatch an ToggleActiveMenuSectionAction with the correct arguments', () => {
service.toggleActiveSection(MenuID.ADMIN, 'fakeID');
Expand Down
Loading
Loading