UNPKG

gp-crm-ui

Version:

Модуль компонентов UI Имя модуля: `gp-crm-ui`

183 lines (155 loc) 4.44 kB
import { OverlayOrigin, OverlayRef } from '@angular/cdk/overlay'; import { Component, EventEmitter, forwardRef, HostBinding, HostListener, Input, OnDestroy, OnInit, ViewChild } from '@angular/core'; import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms'; import { format, parse } from 'date-fns'; import * as ru from 'date-fns/locale/ru'; // Компоненты import { CrmDatepickerPopupComponent } from '../../components/crm-datepicker-popup/crm-datepicker-popup.component'; // Сервисы import { CrmContextMenuOverlayService } from '../../services'; // Выбор даты @Component({ selector: 'crm-datepicker', templateUrl: './crm-datepicker.component.html', styleUrls: ['./crm-datepicker.component.scss'], providers: [{ provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => CrmDatepickerComponent), multi: true }] }) export class CrmDatepickerComponent implements OnInit, OnDestroy, ControlValueAccessor { constructor(private readonly contextMenuOverlay: CrmContextMenuOverlayService) { this.DATA.select.subscribe((date: Date) => { this.date = date; }); } // Флаг наличия ошибки @HostBinding('attr.has-error') @Input() public hasError: boolean; // Заглушка поля @Input() public placeholder: string; // Ссылка на поле ввода @ViewChild('popupOrigin') private readonly popupOrigin: OverlayOrigin; // Конфигурация всплывающего окна private readonly CONFIG = { elementRef: null, overlayComponent: CrmDatepickerPopupComponent, origin: { originX: 'start', originY: 'bottom' }, overlay: { overlayX: 'start', overlayY: 'top' } }; // Данные календаря private readonly DATA = { selected: null, select: new EventEmitter<Date>() }; // Вызовем когда значение изменится private onChange: (value: Date) => void; // Вызовем при любом дествии пользователя с контроллом private onTouched: () => void; // Дата public _date: Date; public get date(): Date { return this._date; } public set date(value: Date) { this._date = value; this.DATA.selected = value; this.text = value && format(value, 'DD.MM.YYYY', { locale: ru }); if (this.onChange) { this.onChange(value); } } // Поле ввода public text: string; // Флаг, отключено public disabled: boolean = false; // Ссылка на календарь private overlayRef: OverlayRef; // Открыть окно private open(): void { if ( !(this.overlayRef && this.overlayRef.hasAttached()) && !this.disabled ) { this.overlayRef = this.contextMenuOverlay.open(this.CONFIG, this.DATA); } } // Закрыть окно private close(): void { if (this.overlayRef) { this.overlayRef.dispose(); } this.overlayRef = null; } // Реакция на клик хост-элемента @HostListener('click') public onClick(): void { if (this.onTouched) { this.onTouched(); } } // Открыть/скрыть календаь public onToggle(): void { if (this.overlayRef && this.overlayRef.hasAttached()) { this.close(); } else { this.open(); } } // Обработчик заполнености маски public onCompleteMask(isCompleted: boolean): void { this.date = isCompleted ? parse( this.text .split('.') .reverse() .join('-') ) : null; } // -------------------------------------------------------------------------- // Вызовет форма, если значение изменилось извне public writeValue(date: Date): void { this.date = date; } // Сохраняем обратный вызов для изменений public registerOnChange(fn: any): void { this.onChange = fn; } // Сохраняем обратный вызов для "касаний" public registerOnTouched(fn: any): void { this.onTouched = fn; } // Установка состояния disabled public setDisabledState(isDisabled: boolean): void { this.disabled = isDisabled; } // -------------------------------------------------------------------------- // HOOKS // Инициализация public ngOnInit(): void { this.CONFIG.elementRef = this.popupOrigin.elementRef; } // Уничтожение public ngOnDestroy(): void { this.close(); } }