import {Component, forwardRef, HostListener, Input, OnChanges, SimpleChanges} from '@angular/core'; import {ControlValueAccessor, NG_VALUE_ACCESSOR} from '@angular/forms'; import moment, {Moment} from 'moment'; import {DataCardService} from '../api/data-card.service'; export const APP_DATE_PICKER_CONTROL_VALUE_ACCESSOR: any = { provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => DatePickerComponent), multi: true }; @Component({ selector: 'app-date-picker', templateUrl: './date-picker.component.html', styleUrls: ['./date-picker.component.scss'], providers: [APP_DATE_PICKER_CONTROL_VALUE_ACCESSOR] }) export class DatePickerComponent implements OnChanges, ControlValueAccessor { @Input() label = ''; @Input() name = ''; @Input() notRelevant: boolean|undefined; public innerModel: Moment | undefined; public disabled = false; public hover = false; // When notRelevant is toggled on, we store the old value, so we can re-fill it it gets turned off again private oldValue: Moment | undefined; private dirtyAble = false; private onChangeCallback: (newValue: Date|undefined) => any = () => {}; private onTouchedCallback: () => any = () => {}; constructor(private dataCardService: DataCardService) { this.dataCardService.isDataCardClosed.subscribe(isClosed => this.setDisabledState(isClosed)); } get value(): Moment|undefined { return this.innerModel; } set value(value: Moment|undefined) { if (this.innerModel?.toDate?.()?.getTime?.() !== value?.toDate?.()?.getTime?.()) { this.innerModel = value; if (this.dirtyAble) { this.onChangeCallback(this.innerModel?.toDate()); } } } @HostListener('(mouseenter)') onMouseEnter(): void { this.hover = !(this.disabled || this.notRelevant); } @HostListener('(mouseleave)') onMouseLeave(): void { this.hover = false; } @HostListener('(blur)') onBlur(): void { this.onTouchedCallback(); } ngOnChanges(changes: SimpleChanges): void { if (changes.notRelevant) { if (this.notRelevant) { this.oldValue = this.innerModel; this.writeValue(undefined); } else { this.writeValue(this.oldValue?.toDate()); } } } registerOnChange(fn: any): void { this.onChangeCallback = fn; } registerOnTouched(fn: any): void { this.onTouchedCallback = fn; } setDisabledState(isDisabled: boolean): void { this.disabled = isDisabled; } writeValue(newValue: Date|undefined): void { if (newValue) { this.value = moment(newValue.toISOString(), 'YYYY-MM-DD\'t\'hh:mm:ss.SS').add(1, 'hour'); } else { this.value = undefined; } } makeDirtyable(): void { // on user input we're naturally dirty-able this.dirtyAble = true; } }