File
Constructor
constructor(viewportService: NxViewportService, _channel: CHANNEL)
|
|
Parameters :
Name |
Type |
Optional |
viewportService |
NxViewportService
|
No
|
_channel |
CHANNEL
|
No
|
|
Methods
toggleNavigation
|
toggleNavigation(force?: boolean)
|
|
Parameters :
Name |
Type |
Optional |
force |
boolean
|
Yes
|
|
collapseNavigationUser$
|
Type : Observable<boolean>
|
|
compactNavigationBreakpoint$
|
Type : Observable<boolean>
|
|
hideSidebarBreakpoint$
|
Type : Observable<boolean>
|
|
isStackedLayoutObservable
|
Type : Observable<boolean>
|
|
import { CHANNEL, CHANNEL_TOKEN } from '@allianz/taly-core';
import { Inject, Injectable } from '@angular/core';
import { NxBreakpoints, NxViewportService } from '@aposin/ng-aquila/utils';
import { Observable, Subject } from 'rxjs';
import { distinctUntilChanged, map, scan, startWith } from 'rxjs/operators';
const createBreakpointFactory = (service: NxViewportService) => (breakpoint: NxBreakpoints) => {
return service
.max(breakpoint)
.pipe(startWith(window.innerWidth <= breakpoint), distinctUntilChanged());
};
@Injectable()
export class TalyFrameLayoutService {
isStackedLayoutObservable!: Observable<boolean>;
compactNavigationBreakpoint$!: Observable<boolean>;
private _collapseNavigationUser$ = new Subject<boolean | undefined>();
collapseNavigationUser$!: Observable<boolean>;
hideSidebarBreakpoint$!: Observable<boolean>;
constructor(
private viewportService: NxViewportService,
@Inject(CHANNEL_TOKEN) private _channel: CHANNEL
) {
this.init();
}
init() {
const breakpointFactory = createBreakpointFactory(this.viewportService);
/**
* this will be forwarded to the navigation to make it very compact when the screen is far too small
* for any other view (vertical or horizontal, determined by the being stacked or not value, see observable below)
*/
this.compactNavigationBreakpoint$ = breakpointFactory(NxBreakpoints.BREAKPOINT_MEDIUM);
/**
* this will take care of the overall layout and is consumed in the frame component itself
* to assign different css classes to swap the layout
*/
const collapseLayoutBreakpoint$ = breakpointFactory(NxBreakpoints.BREAKPOINT_LARGE);
this.isStackedLayoutObservable = createStackedLayoutObservable(
collapseLayoutBreakpoint$,
this._channel
);
this.hideSidebarBreakpoint$ = breakpointFactory(NxBreakpoints.BREAKPOINT_XLARGE);
// Create a stream of true & false values depending on the collapsed status.
// The involved subject can emit if a specific status is being forced,
// otherwise the stream will constantly invert any previous value to achieve the toggle mechanism.
this.collapseNavigationUser$ = this._collapseNavigationUser$.pipe(
scan((acc: boolean, value: boolean | undefined) => value ?? !acc, false)
);
}
toggleNavigation(force?: boolean) {
this._collapseNavigationUser$.next(force);
}
}
/**
* Create an observable that combines the information about the active channel and the
* available screen estate defined by a breaking point. With those information we can easily
* decide if we want to switch the layout to be stacked (one column) or keep the "holy grail layout"
* with the three columns in the center and footer/header above and below
*
* Combinations:
* SCREEN_TOO_SMALL + EXPERT = stacked
* SCREEN_TOO_SMALL + RETAIL = stacked
* SCREEN OKAY + RETAIL = stacked
* SCREEN OKAY + EXPERT = holy grail
*
*/
function createStackedLayoutObservable(breakpoint$: Observable<boolean>, channel: CHANNEL) {
return breakpoint$.pipe(
map((limitedScreenEstate) => {
return limitedScreenEstate || channel === CHANNEL.RETAIL;
})
);
}