@ohayojp.com/components
Version:
Common business components of ohayojp.
585 lines (579 loc) • 21.1 kB
JavaScript
import { __decorate, __metadata } from 'tslib';
import { DOCUMENT, CommonModule } from '@angular/common';
import { EventEmitter, Component, ChangeDetectionStrategy, ViewEncapsulation, Renderer2, ChangeDetectorRef, NgZone, Inject, Input, Output, NgModule } from '@angular/core';
import { DomSanitizer } from '@angular/platform-browser';
import { NavigationEnd, Router, RouterModule } from '@angular/router';
import { MenuService, SettingsService, WINDOW } from '@ohayojp.com/theme';
import { InputBoolean, InputNumber, OhayoUtilModule } from '@ohayojp.com/util';
import { Subject } from 'rxjs';
import { takeUntil, filter } from 'rxjs/operators';
import { NzIconModule } from 'ng-zorro-antd/icon';
import { NzToolTipModule } from 'ng-zorro-antd/tooltip';
/**
* @fileoverview added by tsickle
* Generated from: sidebar-nav.component.ts
* @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingRequire,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
/** @type {?} */
const SHOWCLS = 'sidebar-nav__floating-show';
/** @type {?} */
const FLOATINGCLS = 'sidebar-nav__floating';
class SidebarNavComponent {
/**
* @param {?} menuSrv
* @param {?} settings
* @param {?} router
* @param {?} render
* @param {?} cdr
* @param {?} ngZone
* @param {?} sanitizer
* @param {?} doc
* @param {?} win
*/
constructor(menuSrv, settings, router, render, cdr, ngZone, sanitizer, doc, win) {
this.menuSrv = menuSrv;
this.settings = settings;
this.router = router;
this.render = render;
this.cdr = cdr;
this.ngZone = ngZone;
this.sanitizer = sanitizer;
this.doc = doc;
this.win = win;
this.unsubscribe$ = new Subject();
this.list = [];
this.disabledAcl = false;
this.autoCloseUnderPad = true;
this.recursivePath = true;
this.openStrictly = false;
this.maxLevelIcon = 3;
// tslint:disable-next-line:no-output-native
this.select = new EventEmitter();
}
/**
* @return {?}
*/
get collapsed() {
return this.settings.layout.collapsed;
}
/**
* @private
* @param {?} node
* @return {?}
*/
getLinkNode(node) {
node = node.nodeName === 'A' ? node : ((/** @type {?} */ (node.parentNode)));
return node.nodeName !== 'A' ? null : node;
}
/**
* @private
* @param {?} e
* @return {?}
*/
floatingClickHandle(e) {
e.stopPropagation();
/** @type {?} */
const linkNode = this.getLinkNode((/** @type {?} */ (e.target)));
if (linkNode == null) {
return false;
}
/** @type {?} */
const id = +(/** @type {?} */ ((/** @type {?} */ (linkNode.dataset)).id));
// Should be ingore children title trigger event
if (isNaN(id)) {
return false;
}
/** @type {?} */
let item;
this.menuSrv.visit(this.list, (/**
* @param {?} i
* @return {?}
*/
(i) => {
if (!item && i._id === id) {
item = i;
}
}));
this.to((/** @type {?} */ (item)));
this.hideAll();
e.preventDefault();
return false;
}
/**
* @private
* @return {?}
*/
clearFloating() {
if (!this.floatingEl)
return;
this.floatingEl.removeEventListener('click', this.floatingClickHandle.bind(this));
// fix ie: https://github.com/ohayojp/ohayo/issues/52
if (this.floatingEl.hasOwnProperty('remove')) {
this.floatingEl.remove();
}
else if (this.floatingEl.parentNode) {
this.floatingEl.parentNode.removeChild(this.floatingEl);
}
}
/**
* @private
* @return {?}
*/
genFloating() {
this.clearFloating();
this.floatingEl = this.render.createElement('div');
this.floatingEl.classList.add(FLOATINGCLS + '-container');
this.floatingEl.addEventListener('click', this.floatingClickHandle.bind(this), false);
this.bodyEl.appendChild(this.floatingEl);
}
/**
* @private
* @param {?} linkNode
* @param {?} item
* @return {?}
*/
genSubNode(linkNode, item) {
/** @type {?} */
const id = `_sidebar-nav-${item._id}`;
/** @type {?} */
const childNode = item.badge ? (/** @type {?} */ ((/** @type {?} */ (linkNode.nextElementSibling)).nextElementSibling)) : (/** @type {?} */ (linkNode.nextElementSibling));
/** @type {?} */
const node = (/** @type {?} */ (childNode.cloneNode(true)));
node.id = id;
node.classList.add(FLOATINGCLS);
node.addEventListener('mouseleave', (/**
* @return {?}
*/
() => {
node.classList.remove(SHOWCLS);
}), false);
this.floatingEl.appendChild(node);
return node;
}
/**
* @private
* @return {?}
*/
hideAll() {
/** @type {?} */
const allNode = this.floatingEl.querySelectorAll('.' + FLOATINGCLS);
// tslint:disable-next-line:prefer-for-of
for (let i = 0; i < allNode.length; i++) {
allNode[i].classList.remove(SHOWCLS);
}
}
// calculate the node position values.
/**
* @private
* @param {?} linkNode
* @param {?} node
* @return {?}
*/
calPos(linkNode, node) {
/** @type {?} */
const rect = linkNode.getBoundingClientRect();
// bug: https://developer.microsoft.com/en-us/microsoft-edge/platform/issues/14721015/
/** @type {?} */
const scrollTop = Math.max(this.doc.documentElement.scrollTop, this.bodyEl.scrollTop);
/** @type {?} */
const docHeight = Math.max(this.doc.documentElement.clientHeight, this.bodyEl.clientHeight);
/** @type {?} */
const spacing = 5;
/** @type {?} */
let offsetHeight = -spacing;
if (docHeight < rect.top + node.clientHeight) {
offsetHeight = rect.top + node.clientHeight - docHeight + spacing;
}
node.style.top = `${rect.top + scrollTop - offsetHeight}px`;
node.style.left = `${rect.right + spacing}px`;
}
/**
* @param {?} e
* @param {?} item
* @return {?}
*/
showSubMenu(e, item) {
if (this.collapsed !== true) {
return;
}
this.ngZone.runOutsideAngular((/**
* @return {?}
*/
() => {
e.preventDefault();
/** @type {?} */
const linkNode = (/** @type {?} */ (e.target));
this.genFloating();
/** @type {?} */
const subNode = this.genSubNode((/** @type {?} */ (linkNode)), item);
this.hideAll();
subNode.classList.add(SHOWCLS);
this.calPos((/** @type {?} */ (linkNode)), subNode);
}));
}
/**
* @param {?} item
* @return {?}
*/
to(item) {
this.select.emit(item);
if (item.disabled)
return;
if (item.externalLink) {
if (item.target === '_blank') {
this.win.open(item.externalLink);
}
else {
this.win.location.href = item.externalLink;
}
return;
}
this.ngZone.run((/**
* @return {?}
*/
() => this.router.navigateByUrl((/** @type {?} */ (item.link)))));
}
/**
* @param {?} item
* @return {?}
*/
toggleOpen(item) {
if (!this.openStrictly) {
this.menuSrv.visit(this.list, (/**
* @param {?} i
* @return {?}
*/
(i) => {
if (i !== item)
i._open = false;
}));
/** @type {?} */
let pItem = (/** @type {?} */ (item._parent));
while (pItem) {
pItem._open = true;
pItem = (/** @type {?} */ (pItem._parent));
}
}
item._open = !item._open;
this.cdr.markForCheck();
}
/**
* @return {?}
*/
_click() {
if (this.isPad && this.collapsed) {
this.openAside(false);
this.hideAll();
}
}
/**
* @return {?}
*/
_docClick() {
if (this.collapsed) {
this.hideAll();
}
}
/**
* @private
* @param {?} url
* @return {?}
*/
openedByUrl(url) {
const { menuSrv, recursivePath, openStrictly } = this;
/** @type {?} */
let findItem = menuSrv.getHit(this.menuSrv.menus, (/** @type {?} */ (url)), recursivePath, (/**
* @param {?} i
* @return {?}
*/
(i) => {
i._selected = false;
if (!openStrictly) {
i._open = false;
}
}));
if (findItem == null)
return;
do {
findItem._selected = true;
if (!openStrictly) {
findItem._open = true;
}
findItem = (/** @type {?} */ (findItem._parent));
} while (findItem);
}
/**
* @return {?}
*/
ngOnInit() {
const { doc, router, unsubscribe$, menuSrv, settings, cdr } = this;
this.bodyEl = doc.querySelector('body');
this.openedByUrl(router.url);
this.ngZone.runOutsideAngular((/**
* @return {?}
*/
() => this.genFloating()));
menuSrv.change.pipe(takeUntil(unsubscribe$)).subscribe((/**
* @param {?} data
* @return {?}
*/
data => {
menuSrv.visit(data, (/**
* @param {?} i
* @param {?} _p
* @param {?} depth
* @return {?}
*/
(i, _p, depth) => {
i._text = this.sanitizer.bypassSecurityTrustHtml((/** @type {?} */ (i.text)));
i._needIcon = (/** @type {?} */ (depth)) <= this.maxLevelIcon && !!i.icon;
if (!i._aclResult) {
if (this.disabledAcl) {
i.disabled = true;
}
else {
i._hidden = true;
}
}
if (this.openStrictly) {
i._open = i.open != null ? i.open : false;
}
}));
this.list = menuSrv.menus.filter((/**
* @param {?} w
* @return {?}
*/
(w) => w._hidden !== true));
cdr.detectChanges();
}));
router.events.pipe(takeUntil(unsubscribe$)).subscribe((/**
* @param {?} e
* @return {?}
*/
e => {
if (e instanceof NavigationEnd) {
this.openedByUrl(e.urlAfterRedirects);
this.underPad();
this.cdr.detectChanges();
}
}));
settings.notify
.pipe(takeUntil(unsubscribe$), filter((/**
* @param {?} t
* @return {?}
*/
t => t.type === 'layout' && t.name === 'collapsed')))
.subscribe((/**
* @return {?}
*/
() => this.clearFloating()));
this.underPad();
}
/**
* @return {?}
*/
ngOnDestroy() {
const { unsubscribe$ } = this;
unsubscribe$.next();
unsubscribe$.complete();
this.clearFloating();
}
// #region Under pad
/**
* @private
* @return {?}
*/
get isPad() {
return window.innerWidth < 768;
}
/**
* @private
* @return {?}
*/
underPad() {
if (this.autoCloseUnderPad && this.isPad && !this.collapsed) {
setTimeout((/**
* @return {?}
*/
() => this.openAside(true)));
}
}
/**
* @private
* @param {?} status
* @return {?}
*/
openAside(status) {
this.settings.setLayout('collapsed', status);
}
}
SidebarNavComponent.decorators = [
{
type: Component, args: [{
selector: 'sidebar-nav',
exportAs: 'sidebarNav',
template: "<ng-template #icon let-i>\n <ng-container *ngIf=\"i\" [ngSwitch]=\"i.type\">\n <i\n *ngSwitchCase=\"'icon'\"\n class=\"sidebar-nav__item-icon\"\n nz-icon\n [nzType]=\"i.value\"\n [nzTheme]=\"i.theme\"\n [nzSpin]=\"i.spin\"\n [nzTwotoneColor]=\"i.twoToneColor\"\n [nzIconfont]=\"i.iconfont\"\n [nzRotate]=\"i.rotate\"\n ></i>\n <i *ngSwitchCase=\"'iconfont'\" class=\"sidebar-nav__item-icon\" nz-icon [nzIconfont]=\"i.iconfont\"></i>\n <img *ngSwitchCase=\"'img'\" [src]=\"i.value\" class=\"sidebar-nav__item-icon sidebar-nav__item-img\" />\n <i *ngSwitchDefault class=\"sidebar-nav__item-icon {{ i.value }}\"></i>\n </ng-container>\n</ng-template>\n<ng-template #tree let-ls>\n <ng-container *ngFor=\"let i of ls\">\n <li *ngIf=\"i._hidden !== true\" class=\"sidebar-nav__item\" [class.sidebar-nav__selected]=\"i._selected\" [class.sidebar-nav__open]=\"i._open\">\n <!-- link -->\n <a\n *ngIf=\"i.children.length === 0\"\n (click)=\"to(i)\"\n [attr.data-id]=\"i._id\"\n class=\"sidebar-nav__item-link\"\n [ngClass]=\"{ 'sidebar-nav__item-disabled': i.disabled }\"\n >\n <ng-container *ngIf=\"i._needIcon\">\n <ng-container *ngIf=\"!collapsed\">\n <ng-template [ngTemplateOutlet]=\"icon\" [ngTemplateOutletContext]=\"{ $implicit: i.icon }\"></ng-template>\n </ng-container>\n <span *ngIf=\"collapsed\" nz-tooltip nzTooltipPlacement=\"right\" [nzTooltipTitle]=\"i.text\">\n <ng-template [ngTemplateOutlet]=\"icon\" [ngTemplateOutletContext]=\"{ $implicit: i.icon }\"></ng-template>\n </span>\n </ng-container>\n <span class=\"sidebar-nav__item-text\" [innerHTML]=\"i._text\" [attr.title]=\"i.text\"></span>\n </a>\n <!-- has children link -->\n <a *ngIf=\"i.children.length > 0\" (click)=\"toggleOpen(i)\" (mouseenter)=\"showSubMenu($event, i)\" class=\"sidebar-nav__item-link\">\n <ng-template [ngTemplateOutlet]=\"icon\" [ngTemplateOutletContext]=\"{ $implicit: i.icon }\"></ng-template>\n <span class=\"sidebar-nav__item-text\" [innerHTML]=\"i._text\" [attr.title]=\"i.text\"></span>\n <i class=\"sidebar-nav__sub-arrow\"></i>\n </a>\n <!-- badge -->\n <div *ngIf=\"i.badge\" [attr.title]=\"i.badge\" class=\"badge badge-{{ i.badgeStatus }}\" [class.badge-dot]=\"i.badgeDot\">\n <em>{{ i.badge }}</em>\n </div>\n <ul *ngIf=\"i.children.length > 0\" class=\"sidebar-nav sidebar-nav__sub sidebar-nav__depth{{ i._depth }}\">\n <ng-template [ngTemplateOutlet]=\"tree\" [ngTemplateOutletContext]=\"{ $implicit: i.children }\"></ng-template>\n </ul>\n </li>\n </ng-container>\n</ng-template>\n<ul class=\"sidebar-nav\">\n <ng-container *ngFor=\"let group of list\">\n <li class=\"sidebar-nav__item sidebar-nav__group-title\" *ngIf=\"group.group\">\n <span [innerHTML]=\"group._text\"></span>\n </li>\n <ng-template [ngTemplateOutlet]=\"tree\" [ngTemplateOutletContext]=\"{ $implicit: group.children }\"></ng-template>\n </ng-container>\n</ul>\n",
host: {
'(click)': '_click()',
'(document:click)': '_docClick()',
},
preserveWhitespaces: false,
changeDetection: ChangeDetectionStrategy.OnPush,
encapsulation: ViewEncapsulation.None
}]
}
];
/** @nocollapse */
SidebarNavComponent.ctorParameters = () => [
{ type: MenuService },
{ type: SettingsService },
{ type: Router },
{ type: Renderer2 },
{ type: ChangeDetectorRef },
{ type: NgZone },
{ type: DomSanitizer },
{ type: undefined, decorators: [{ type: Inject, args: [DOCUMENT,] }] },
{ type: Window, decorators: [{ type: Inject, args: [WINDOW,] }] }
];
SidebarNavComponent.propDecorators = {
disabledAcl: [{ type: Input }],
autoCloseUnderPad: [{ type: Input }],
recursivePath: [{ type: Input }],
openStrictly: [{ type: Input }],
maxLevelIcon: [{ type: Input }],
select: [{ type: Output }]
};
__decorate([
InputBoolean(),
__metadata("design:type", Object)
], SidebarNavComponent.prototype, "disabledAcl", void 0);
__decorate([
InputBoolean(),
__metadata("design:type", Object)
], SidebarNavComponent.prototype, "autoCloseUnderPad", void 0);
__decorate([
InputBoolean(),
__metadata("design:type", Object)
], SidebarNavComponent.prototype, "recursivePath", void 0);
__decorate([
InputBoolean(),
__metadata("design:type", Object)
], SidebarNavComponent.prototype, "openStrictly", void 0);
__decorate([
InputNumber(),
__metadata("design:type", Object)
], SidebarNavComponent.prototype, "maxLevelIcon", void 0);
if (false) {
/** @type {?} */
SidebarNavComponent.ngAcceptInputType_disabledAcl;
/** @type {?} */
SidebarNavComponent.ngAcceptInputType_autoCloseUnderPad;
/** @type {?} */
SidebarNavComponent.ngAcceptInputType_recursivePath;
/** @type {?} */
SidebarNavComponent.ngAcceptInputType_openStrictly;
/** @type {?} */
SidebarNavComponent.ngAcceptInputType_maxLevelIcon;
/**
* @type {?}
* @private
*/
SidebarNavComponent.prototype.bodyEl;
/**
* @type {?}
* @private
*/
SidebarNavComponent.prototype.unsubscribe$;
/**
* @type {?}
* @private
*/
SidebarNavComponent.prototype.floatingEl;
/** @type {?} */
SidebarNavComponent.prototype.list;
/** @type {?} */
SidebarNavComponent.prototype.disabledAcl;
/** @type {?} */
SidebarNavComponent.prototype.autoCloseUnderPad;
/** @type {?} */
SidebarNavComponent.prototype.recursivePath;
/** @type {?} */
SidebarNavComponent.prototype.openStrictly;
/** @type {?} */
SidebarNavComponent.prototype.maxLevelIcon;
/** @type {?} */
SidebarNavComponent.prototype.select;
/**
* @type {?}
* @private
*/
SidebarNavComponent.prototype.menuSrv;
/**
* @type {?}
* @private
*/
SidebarNavComponent.prototype.settings;
/**
* @type {?}
* @private
*/
SidebarNavComponent.prototype.router;
/**
* @type {?}
* @private
*/
SidebarNavComponent.prototype.render;
/**
* @type {?}
* @private
*/
SidebarNavComponent.prototype.cdr;
/**
* @type {?}
* @private
*/
SidebarNavComponent.prototype.ngZone;
/**
* @type {?}
* @private
*/
SidebarNavComponent.prototype.sanitizer;
/**
* @type {?}
* @private
*/
SidebarNavComponent.prototype.doc;
/**
* @type {?}
* @private
*/
SidebarNavComponent.prototype.win;
}
/**
* @fileoverview added by tsickle
* Generated from: sidebar-nav.module.ts
* @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingRequire,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
class SidebarNavModule {
}
SidebarNavModule.decorators = [
{
type: NgModule, args: [{
imports: [CommonModule, RouterModule, NzIconModule, NzToolTipModule, OhayoUtilModule],
declarations: [SidebarNavComponent],
exports: [SidebarNavComponent],
},]
}
];
/**
* @fileoverview added by tsickle
* Generated from: public_api.ts
* @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingRequire,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
/**
* @fileoverview added by tsickle
* Generated from: sidebarNav.ts
* @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingRequire,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
export { SidebarNavComponent, SidebarNavModule };
//# sourceMappingURL=sidebarNav.js.map