Skip to content

Commit 41e6945

Browse files
authored
Merge pull request DSpace#1902 from 4Science/CST-7119
Fix issues with user menu on different screen sizes
2 parents c876055 + dd4d709 commit 41e6945

18 files changed

Lines changed: 112 additions & 40 deletions

src/app/navbar/expandable-navbar-section/expandable-navbar-section.component.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
<div class="nav-item dropdown expandable-navbar-section"
1+
<div class="nav-item dropdown expandable-navbar-section text-md-center"
22
*ngVar="(active | async) as isActive"
33
(keyup.enter)="isActive ? deactivateSection($event) : activateSection($event)"
44
(keyup.space)="isActive ? deactivateSection($event) : activateSection($event)"

src/app/navbar/expandable-navbar-section/expandable-navbar-section.component.scss

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,10 @@
1+
.expandable-navbar-section {
2+
display: flex;
3+
height: 100%;
4+
flex-direction: column;
5+
justify-content: center;
6+
}
7+
18
.dropdown-menu {
29
overflow: hidden;
310
min-width: 100%;
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
1-
<div class="nav-item navbar-section">
1+
<div class="nav-item navbar-section text-md-center">
22
<ng-container *ngComponentOutlet="(sectionMap$ | async).get(section.id).component; injector: (sectionMap$ | async).get(section.id).injector;"></ng-container>
3-
</div>
3+
</div>
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
.navbar-section {
2+
display: flex;
3+
align-items: center;
4+
height: 100%;
5+
}

src/app/navbar/navbar.component.html

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,13 @@
11
<nav [ngClass]="{'open': !(menuCollapsed | async)}" [@slideMobileNav]="!(windowService.isXsOrSm() | async) ? 'default' : ((menuCollapsed | async) ? 'collapsed' : 'expanded')"
22
class="navbar navbar-light navbar-expand-md p-md-0 navbar-container" role="navigation" [attr.aria-label]="'nav.main.description' | translate">
33
<!-- TODO remove navbar-container class when https://github.com/twbs/bootstrap/issues/24726 is fixed -->
4-
<div class="container">
4+
<div class="navbar-inner-container w-100" [class.container]="!(isXsOrSm$ | async)">
55
<div class="reset-padding-md w-100">
66
<div id="collapsingNav">
77
<ul class="navbar-nav navbar-navigation mr-auto shadow-none">
8+
<li *ngIf="(isXsOrSm$ | async) && (isAuthenticated$ | async)">
9+
<ds-user-menu [inExpandableNavbar]="true"></ds-user-menu>
10+
</li>
811
<ng-container *ngFor="let section of (sections | async)">
912
<ng-container *ngComponentOutlet="(sectionMap$ | async).get(section.id)?.component; injector: (sectionMap$ | async).get(section.id)?.injector;"></ng-container>
1013
</ng-container>

src/app/navbar/navbar.component.scss

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,14 @@ nav.navbar {
66
/** Mobile menu styling **/
77
@media screen and (max-width: map-get($grid-breakpoints, md)-0.02) {
88
.navbar {
9-
width: 100vw;
9+
width: 100%;
1010
background-color: var(--bs-white);
1111
position: absolute;
1212
overflow: hidden;
1313
height: 0;
1414
&.open {
15-
height: 100vh; //doesn't matter because wrapper is sticky
15+
height: auto;
16+
min-height: 100vh; //doesn't matter because wrapper is sticky
1617
}
1718
}
1819
}
@@ -27,7 +28,7 @@ nav.navbar {
2728
/* TODO remove when https://github.com/twbs/bootstrap/issues/24726 is fixed */
2829
.navbar-expand-md.navbar-container {
2930
@media screen and (max-width: map-get($grid-breakpoints, md)-0.02) {
30-
> .container {
31+
> .navbar-inner-container {
3132
padding: 0 var(--bs-spacer);
3233
}
3334
padding: 0;

src/app/navbar/navbar.component.spec.ts

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,17 @@ import { Item } from '../core/shared/item.model';
2222
import { AuthorizationDataService } from '../core/data/feature-authorization/authorization-data.service';
2323
import { ThemeService } from '../shared/theme-support/theme.service';
2424
import { getMockThemeService } from '../shared/mocks/theme-service.mock';
25+
import { Store, StoreModule } from '@ngrx/store';
26+
import { AppState, storeModuleConfig } from '../app.reducer';
27+
import { authReducer } from '../core/auth/auth.reducer';
28+
import { provideMockStore } from '@ngrx/store/testing';
29+
import { AuthTokenInfo } from '../core/auth/models/auth-token-info.model';
30+
import { EPersonMock } from '../shared/testing/eperson.mock';
2531

2632
let comp: NavbarComponent;
2733
let fixture: ComponentFixture<NavbarComponent>;
34+
let store: Store<AppState>;
35+
let initialState: any;
2836

2937
const authorizationService = jasmine.createSpyObj('authorizationService', {
3038
isAuthorized: observableOf(true)
@@ -83,10 +91,24 @@ describe('NavbarComponent', () => {
8391
}
8492
),
8593
];
94+
initialState = {
95+
core: {
96+
auth: {
97+
authenticated: true,
98+
loaded: true,
99+
blocking: false,
100+
loading: false,
101+
authToken: new AuthTokenInfo('test_token'),
102+
userId: EPersonMock.id,
103+
authMethods: []
104+
}
105+
}
106+
};
86107

87108
TestBed.configureTestingModule({
88109
imports: [
89110
TranslateModule.forRoot(),
111+
StoreModule.forRoot({ auth: authReducer }, storeModuleConfig),
90112
NoopAnimationsModule,
91113
ReactiveFormsModule,
92114
RouterTestingModule],
@@ -99,6 +121,7 @@ describe('NavbarComponent', () => {
99121
{ provide: ActivatedRoute, useValue: routeStub },
100122
{ provide: BrowseService, useValue: { getBrowseDefinitions: createSuccessfulRemoteDataObject$(buildPaginatedList(undefined, browseDefinitions)) } },
101123
{ provide: AuthorizationDataService, useValue: authorizationService },
124+
provideMockStore({ initialState }),
102125
],
103126
schemas: [NO_ERRORS_SCHEMA]
104127
})
@@ -107,7 +130,7 @@ describe('NavbarComponent', () => {
107130

108131
// synchronous beforeEach
109132
beforeEach(() => {
110-
133+
store = TestBed.inject(Store);
111134
fixture = TestBed.createComponent(NavbarComponent);
112135

113136
comp = fixture.componentInstance;

src/app/navbar/navbar.component.ts

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,10 @@ import { ActivatedRoute } from '@angular/router';
88
import { AuthorizationDataService } from '../core/data/feature-authorization/authorization-data.service';
99
import { MenuID } from '../shared/menu/menu-id.model';
1010
import { ThemeService } from '../shared/theme-support/theme.service';
11+
import { Observable } from 'rxjs';
12+
import { select, Store } from '@ngrx/store';
13+
import { AppState } from '../app.reducer';
14+
import { isAuthenticated } from '../core/auth/selectors';
1115

1216
/**
1317
* Component representing the public navbar
@@ -25,18 +29,29 @@ export class NavbarComponent extends MenuComponent {
2529
*/
2630
menuID = MenuID.PUBLIC;
2731

32+
/**
33+
* Whether user is authenticated.
34+
* @type {Observable<string>}
35+
*/
36+
public isAuthenticated$: Observable<boolean>;
37+
38+
public isXsOrSm$: Observable<boolean>;
39+
2840
constructor(protected menuService: MenuService,
2941
protected injector: Injector,
3042
public windowService: HostWindowService,
3143
public browseService: BrowseService,
3244
public authorizationService: AuthorizationDataService,
3345
public route: ActivatedRoute,
34-
protected themeService: ThemeService
46+
protected themeService: ThemeService,
47+
private store: Store<AppState>,
3548
) {
3649
super(menuService, injector, authorizationService, route, themeService);
3750
}
3851

3952
ngOnInit(): void {
4053
super.ngOnInit();
54+
this.isXsOrSm$ = this.windowService.isXsOrSm();
55+
this.isAuthenticated$ = this.store.pipe(select(isAuthenticated));
4156
}
4257
}

src/app/root/root.component.html

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
1-
<div class="outer-wrapper" [class.d-none]="shouldShowFullscreenLoader">
2-
<ds-themed-admin-sidebar></ds-themed-admin-sidebar>
3-
<div class="inner-wrapper" [@slideSidebarPadding]="{
1+
<div class="outer-wrapper" [class.d-none]="shouldShowFullscreenLoader" [@slideSidebarPadding]="{
42
value: (!(sidebarVisible | async) ? 'hidden' : (slideSidebarOver | async) ? 'shown' : 'expanded'),
53
params: {collapsedSidebarWidth: (collapsedSidebarWidth | async), totalSidebarWidth: (totalSidebarWidth | async)}
64
}">
5+
<ds-themed-admin-sidebar></ds-themed-admin-sidebar>
6+
<div class="inner-wrapper">
77
<ds-themed-header-navbar-wrapper></ds-themed-header-navbar-wrapper>
88
<main class="main-content">
99
<ds-themed-breadcrumbs></ds-themed-breadcrumbs>

src/app/shared/animations/slide.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ export const slide = trigger('slide', [
1212

1313
export const slideMobileNav = trigger('slideMobileNav', [
1414

15-
state('expanded', style({ height: '100vh' })),
15+
state('expanded', style({ height: 'auto', 'min-height': '100vh' })),
1616

1717
state('collapsed', style({ height: 0 })),
1818

0 commit comments

Comments
 (0)