gp-crm-ui
Version:
Модуль компонентов UI Имя модуля: `gp-crm-ui`
117 lines (99 loc) • 3.39 kB
text/typescript
import { OverlayRef } from '@angular/cdk/overlay';
import {
Component,
ElementRef,
Inject,
OnDestroy,
Renderer2
} from '@angular/core';
// Токены
import {
CONTEXT_MENU_CONFIG,
CONTEXT_MENU_DATA
} from '../../tokens';
// Интерфейсы
import { IContextMenuConfig } from '../../interfaces';
// Сервисы
import { CrmHelperService } from '../../services/crm-helper.service';
// Контекстное меню
export class CrmContextMenuComponent implements OnDestroy {
constructor(
private readonly renderer: Renderer2,
private readonly el: ElementRef,
private readonly overlayRef: OverlayRef,
public readonly config: IContextMenuConfig,
public readonly data: any
) {
this.setArrowParams();
this.addListener();
}
// Функция для отключения прослушивания события
private clickListen: () => void;
// Оси для overlay
private readonly OVERLAY_X: string = 'overlay-x';
private readonly OVERLAY_Y: string = 'overlay-y';
// Оси для origin
private readonly ORIGIN_X: string = 'origin-x';
private readonly ORIGIN_Y: string = 'origin-y';
// Переменные css для стрелки
private readonly ARROW_SIZE: string = '--arrow-size';
private readonly ARROW_OFFSET: string = '--arrow-offset';
// Закрыть всплывающее окно
public close(): void {
this.overlayRef.dispose();
}
// Установка параметров для стрелки
private setArrowParams(): void {
const el = this.el && this.el.nativeElement;
if (el) {
el.style.setProperty(this.ARROW_SIZE, `${this.config.arrowSize}px`);
el.style.setProperty(this.ARROW_OFFSET, `${this.config.arrowOffset}px`);
el.setAttribute(this.OVERLAY_X, this.config.overlay.overlayX);
el.setAttribute(this.OVERLAY_Y, this.config.overlay.overlayY);
el.setAttribute(this.ORIGIN_X, this.config.origin.originX);
el.setAttribute(this.ORIGIN_Y, this.config.origin.originY);
}
}
// Добавить слушателя
private addListener(): void {
// Игнорируем нажатие которое вызвало всплывающее окно
setTimeout(() => {
this.clickListen = this.renderer.listen(
document,
'click',
this.onClick.bind(this)
);
});
}
// Удалить слушателя
private removeListener(): void {
if (this.clickListen) { this.clickListen(); }
}
// Обработчик клика
private onClick(event: MouseEvent): void {
const overlayEl = this.el && this.el.nativeElement;
const originEl = this.config.elementRef && this.config.elementRef.nativeElement;
const path = CrmHelperService.eventPath(event);
const isOverlayEl = path.some((node: Node) => node === overlayEl);
const isOriginEl = path.some((node: Node) => node === originEl);
if (!isOverlayEl && !isOriginEl) {
this.close();
}
}
// Обработчик выбора
public onSelect(item: any): void {
this.data.select.emit(item);
this.close();
}
// --------------------------------------------------------------------------
// HOOKS
// Уничтожение
public ngOnDestroy(): void {
this.removeListener();
}
}