File
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 { Injectable, inject } from '@angular/core';
import { NxBreakpoints } from '@allianz/ng-aquila/utils';
import { Observable, Subject } from 'rxjs';
import { distinctUntilChanged, map, scan } from 'rxjs/operators';
import { ContainerViewService } from './container-view.service';
import { TALY_FRAME_ELEMENT } from '../core/tokens';
const createBreakpointFactory =
(container: Element, service: ContainerViewService) => (breakpoint: NxBreakpoints) =>
service.max(container, breakpoint).pipe(distinctUntilChanged());
@Injectable()
export class TalyFrameLayoutService {
private _containerViewService = inject(ContainerViewService);
private _channel = inject<CHANNEL>(CHANNEL_TOKEN);
private _container = inject(TALY_FRAME_ELEMENT);
isStackedLayoutObservable!: Observable<boolean>;
compactNavigationBreakpoint$!: Observable<boolean>;
private _collapseNavigationUser$ = new Subject<boolean | undefined>();
collapseNavigationUser$!: Observable<boolean>;
hideSidebarBreakpoint$!: Observable<boolean>;
constructor() {
this.init();
}
init() {
const breakpointFactory = createBreakpointFactory(this._container, this._containerViewService);
/**
* 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 observables 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 will take care of showing the sidebar or not, and is consumed in the frame component itself
*/
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 state 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;
})
);
}