nm-drawer-container
src/app/shared/widgets/container/drawer-container.component.ts
selector | nm-drawer-container |
styleUrls | drawer-container.component.scss |
templateUrl | drawer-container.component.html |
Widget inputs |
Widget outputs |
Properties |
|
Methods |
Inputs |
HostBindings |
constructor(appContext: AppContext, translateService: TranslateService, localStorageService: LocalStorageService, appService: AppService)
|
|||||||||||||||
Parameters :
|
configuration
|
Type: |
elementClass
|
Default value: |
id
|
Type: |
parent
|
Type: |
class |
class:
|
Default value : null
|
mouseleaveDrawer |
mouseleaveDrawer()
|
Returns :
void
|
mouseoverDrawer |
mouseoverDrawer()
|
Returns :
void
|
ngAfterViewInit |
ngAfterViewInit()
|
Returns :
void
|
ngOnDestroy |
ngOnDestroy()
|
Returns :
void
|
ngOnInit |
ngOnInit()
|
Returns :
void
|
Private _mouseEnterStream |
_mouseEnterStream:
|
Default value : new Subject<any>()
|
Private _mouseLeaveStream |
_mouseLeaveStream:
|
Default value : new Subject<any>()
|
Public dockMode |
dockMode:
|
Default value : new BehaviorSubject<boolean>(true)
|
Public dockModeStorage |
dockModeStorage:
|
Type : LocalStorageEntry
|
Public drawer |
drawer:
|
Type : MatDrawer
|
Decorators : ViewChild
|
Public drawerOpened |
drawerOpened:
|
Type : boolean
|
Public drawerTitle |
drawerTitle:
|
Type : string
|
Public drawerTitleDynamic |
drawerTitleDynamic:
|
Type : string
|
Private unsubscribe |
unsubscribe:
|
Default value : NgUnsubscribe.create()
|
Private widgetData |
widgetData:
|
Type : WidgetData
|
Private widgetId |
widgetId:
|
Type : string
|
import {
Component,
HostBinding,
Input,
OnDestroy,
OnInit,
Optional,
ViewChild,
} from "@angular/core";
import { AppService, WidgetData } from "../configuration/app.service";
import { WidgetConfig } from "../widget.configuration";
import { UtilService } from "../../components/util";
import { MatDrawer } from "@angular/material/sidenav";
import { AppContext } from "../../components/app-context";
import { delay, flatMap, map, takeUntil } from "rxjs/operators";
import { BehaviorSubject, of, Subject } from "rxjs";
import { NgUnsubscribe } from "../../ng-unsubscribe";
import { TranslateService } from "@ngx-translate/core";
import {
LocalStorageEntry,
LocalStorageService,
} from "../../components/local-storage/local-storage.service";
import {
DeletionMode,
Scope,
} from "../../components/local-storage/local-storage-constants";
import {
animate,
keyframes,
style,
transition,
trigger,
} from "@angular/animations";
@Component({
selector: "nm-drawer-container",
templateUrl: "drawer-container.component.html",
styleUrls: ["drawer-container.component.scss"],
animations: [
trigger("fadeTrigger", [
transition(":enter", [
style({ opacity: 0 }),
animate(
"200ms ease-out",
keyframes([
style({ opacity: 1, transform: "translate3d(0, -15%, 0)" }),
style({ opacity: 1, transform: "translate3d(0, 0, 0)" }),
])
),
]),
transition(":leave", [
style({ opacity: 1 }),
animate(
"200ms ease-out",
keyframes([
style({ opacity: 1, transform: "translate3d(0, 0, 0)" }),
style({ opacity: 0, transform: "translate3d(0, -15%, 0)" }),
])
),
]),
]),
],
})
export class NmDrawerContainerComponent implements OnInit, OnDestroy {
@HostBinding("class") hostClass = null;
@Input()
public elementClass = null;
@Input()
public configuration: WidgetConfig;
@Input()
public id: string;
public dockMode = new BehaviorSubject<boolean>(true);
public drawerTitle: string;
public drawerTitleDynamic: string;
public dockModeStorage: LocalStorageEntry;
public drawerOpened: boolean;
@ViewChild("drawer", { static: false }) public drawer: MatDrawer;
@Input()
private parent: string;
private widgetId: string;
private widgetData: WidgetData;
private unsubscribe = NgUnsubscribe.create();
private _mouseEnterStream = new Subject<any>();
private _mouseLeaveStream = new Subject<any>();
constructor(
private appContext: AppContext,
private translateService: TranslateService,
private localStorageService: LocalStorageService,
@Optional() private appService: AppService
) {}
ngOnInit() {
this.elementClass = UtilService.buildCssClass(
this.configuration.elementClass,
this.configuration.elementClassModifiers
);
this.hostClass = UtilService.buildCssClass(
this.configuration.hostClass,
this.configuration.hostClassModifiers
);
let searchWidgetConfig = this.appService.toWidgetConfig(
this.configuration.configuration.components[0]
);
if (searchWidgetConfig) {
this.drawerTitle = this.translateService.instant(
searchWidgetConfig.configuration.title
);
this.dockModeStorage = this.localStorageService.getLocalStorageEntry(
"dockMode-" + searchWidgetConfig.configuration.title,
Scope.USER_AND_CLIENT,
DeletionMode.NEVER
);
if (this.dockModeStorage.exists()) {
this.drawerOpened = JSON.parse(this.dockModeStorage.value);
this.dockMode.next(this.drawerOpened);
} else {
this.drawerOpened = true;
}
}
this.appContext.browserContext.replace(
{
target: ["widget-frame-header"],
action: "pinWidget",
},
{
type: "action",
icon: "pin",
name: "pinWidget",
conditions: [
(config, context) => {
const configuration = this.appService.toWidgetConfig(
this.configuration.configuration.components[0]
);
return (
context.widgetId ===
this.configuration.configuration.components[0] &&
context.configuration.configuration.title ===
configuration.configuration.title
);
},
],
onClick: () => {
this.dockMode.next(!this.dockMode.getValue());
this.dockModeStorage.value = JSON.stringify(this.dockMode.getValue());
},
onInit: () => {
return this.dockMode.pipe(
map((sideMode) => (sideMode ? "pin-off" : "pin")),
map((icon) => {
return {
icon: icon,
description: icon === "pin-off" ? "label.pin-off" : "label.pin",
};
})
);
},
}
);
this.appContext.browserContext
.subscribe({ target: ["toolbox-collapsed-drawer-content"] })
.pipe(takeUntil(this.unsubscribe))
.subscribe((content) => {
if (content && content.length > 0) {
this.drawerTitle = this.translateService.instant(this.drawerTitle);
this.drawerTitleDynamic = content[0].content;
}
});
this._mouseLeaveStream
.pipe(
flatMap((result) => {
return of(result).pipe(delay(300), takeUntil(this._mouseEnterStream));
})
)
.subscribe((e) => {
// TODO: Find better way to check if a overlay is open
let overlayBackdrop = document.getElementsByClassName(
"cdk-overlay-backdrop-showing"
);
if (!this.dockMode.getValue() && overlayBackdrop.length == 0) {
this.drawer.close();
}
});
}
ngAfterViewInit() {
this.mouseleaveDrawer();
}
ngOnDestroy() {}
mouseleaveDrawer() {
this._mouseLeaveStream.next();
}
mouseoverDrawer() {
this._mouseEnterStream.next();
}
}
<ng-container *ngIf="drawerOpened !== null">
<mat-card
*ngIf="!(dockMode | async)"
class="nm-drawerContainer__collapsedCard {{
drawer.opened ? '--drawerOpened' : ''
}}"
(click)="drawer.toggle()"
>
<mat-card-content>
<button
color="primary"
class="nm-drawerContainer__expandButton"
mat-icon-button
>
<mat-icon
*ngIf="!drawer.opened"
svgIcon="chevron-double-right"
></mat-icon>
<mat-icon
*ngIf="drawer.opened"
svgIcon="chevron-double-left"
></mat-icon>
</button>
<div
*ngIf="!drawer.opened"
[@fadeTrigger]
class="nm-drawerContainer__title"
>
{{ drawerTitle }}
{{ drawerTitleDynamic }}
</div>
</mat-card-content>
</mat-card>
<mat-drawer-container [hasBackdrop]="false">
<mat-drawer
#drawer
opened="drawerOpened"
[mode]="(dockMode | async) ? 'side' : 'over'"
(mouseleave)="mouseleaveDrawer()"
(mouseover)="mouseoverDrawer()"
[disableClose]="true"
>
<nm-container
[configuration]="
configuration.configuration.components[0] | widgetFor: configuration
"
[parent]="id"
[class]="elementClass"
[id]="configuration.configuration.components[0]"
>
</nm-container>
</mat-drawer>
<mat-drawer-content>
<nm-container
[configuration]="
configuration.configuration.components[1] | widgetFor: configuration
"
[parent]="id"
[class]="elementClass"
[id]="configuration.configuration.components[1]"
>
</nm-container>
</mat-drawer-content>
</mat-drawer-container>
</ng-container>