set own datepicker and change فاکتور to صورتحساب
This commit is contained in:
@@ -1,75 +1,170 @@
|
||||
import { Maybe } from '@/core';
|
||||
import { nowJalali } from '@/utils';
|
||||
import { CommonModule } from '@angular/common';
|
||||
import {
|
||||
AfterViewInit,
|
||||
Component,
|
||||
ElementRef,
|
||||
EventEmitter,
|
||||
Input,
|
||||
OnDestroy,
|
||||
Output,
|
||||
ViewChild,
|
||||
} from '@angular/core';
|
||||
import { FormControl, ReactiveFormsModule } from '@angular/forms';
|
||||
import { Component, EventEmitter, Input, Output, ViewChild, computed, signal } from '@angular/core';
|
||||
|
||||
import { FormControl } from '@angular/forms';
|
||||
|
||||
import dayjs from 'dayjs';
|
||||
import flatpickr from 'flatpickr-wrap';
|
||||
import { Persian } from 'flatpickr-wrap/dist/l10n/fa';
|
||||
import { BaseOptions, DateOption } from 'flatpickr-wrap/dist/types/options';
|
||||
import { InputTextModule } from 'primeng/inputtext';
|
||||
import jalaliday from 'jalaliday';
|
||||
|
||||
import { Maybe } from '@/core';
|
||||
import { formatJalali } from '@/utils';
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { InputText } from 'primeng/inputtext';
|
||||
import { Popover } from 'primeng/popover';
|
||||
import { UikitFieldComponent } from '../uikit-field.component';
|
||||
import {
|
||||
MonthInfo,
|
||||
MonthlyWeekDate,
|
||||
daysName,
|
||||
prepareMonthInfo,
|
||||
prepareWeekDayDates,
|
||||
} from './monthly-calendar.helper.util';
|
||||
|
||||
dayjs.extend(jalaliday);
|
||||
|
||||
@Component({
|
||||
selector: 'uikit-datepicker',
|
||||
selector: 'app-datepicker',
|
||||
standalone: true,
|
||||
imports: [CommonModule, ReactiveFormsModule, InputTextModule, UikitFieldComponent],
|
||||
templateUrl: './datepicker.component.html',
|
||||
imports: [Popover, UikitFieldComponent, InputText, CommonModule],
|
||||
})
|
||||
export class UikitFlatpickrJalaliComponent implements AfterViewInit, OnDestroy {
|
||||
@Input() control?: FormControl<Maybe<string>>;
|
||||
@Input() placeholder = 'انتخاب تاریخ';
|
||||
@Input() label = 'تاریخ';
|
||||
@Input() disabled = false;
|
||||
@Input() name: string = 'datepicker';
|
||||
@Input() options: Partial<BaseOptions> = {};
|
||||
@Input() showLabel: boolean = true;
|
||||
@Input() showErrors: boolean = true;
|
||||
@Input() hint?: string;
|
||||
@Input() minDate?: DateOption;
|
||||
@Input() maxDate?: DateOption;
|
||||
export class MiniMonthlyCalendarComponent {
|
||||
@Input() control!: FormControl<Maybe<string>>;
|
||||
@Input() alignment?: 'vertical' | 'horizontal' = 'vertical';
|
||||
@Input() name?: string = 'date';
|
||||
@Input() label?: string = 'تاریخ';
|
||||
@Input() closeOnSelect?: boolean = true;
|
||||
@Input() min?: string;
|
||||
@Input() max?: string;
|
||||
@Input() closedDays: number[] = [];
|
||||
|
||||
@Output() clickOnDayEvent = new EventEmitter<MonthlyWeekDate>();
|
||||
@Output() valueChange = new EventEmitter<string>();
|
||||
|
||||
@ViewChild('wrapper', { static: true }) wrapperRef!: ElementRef<HTMLElement>;
|
||||
@ViewChild('op') op!: Popover;
|
||||
|
||||
private fpInstance: any | null = null;
|
||||
readonly daysName = daysName;
|
||||
|
||||
ngAfterViewInit(): void {
|
||||
this.fpInstance = flatpickr(this.wrapperRef.nativeElement, {
|
||||
wrap: true,
|
||||
...this.options,
|
||||
locale: Persian,
|
||||
disableMobile: true,
|
||||
clickOpens: !this.disabled,
|
||||
minDate: this.minDate,
|
||||
maxDate: this.maxDate,
|
||||
now: nowJalali(),
|
||||
altInputClass: 'flatpicker-field w-full',
|
||||
altInput: true,
|
||||
dateFormat: 'Y-m-d',
|
||||
altFormat: 'Y/m/d',
|
||||
/**
|
||||
* Current displayed month
|
||||
* Gregorian YYYY-MM-DD
|
||||
*/
|
||||
private readonly activeDateSignal = signal(dayjs().format('YYYY-MM-DD'));
|
||||
|
||||
onChange: (selectedDates: Date[], dateStr: string) => {
|
||||
this.valueChange.emit(dateStr);
|
||||
if (this.control) this.control.setValue(dayjs(dateStr).toISOString());
|
||||
},
|
||||
});
|
||||
/**
|
||||
* Selected value
|
||||
* Gregorian YYYY-MM-DD
|
||||
*/
|
||||
private readonly selectedDateSignal = signal<Maybe<string>>(null);
|
||||
|
||||
disabled = false;
|
||||
|
||||
monthInfo = computed<MonthInfo>(() => prepareMonthInfo(this.activeDateSignal()));
|
||||
|
||||
weekDaysDates = computed(() => prepareWeekDayDates(this.monthInfo(), this.min, this.max));
|
||||
|
||||
// -----------------------
|
||||
// Getters
|
||||
// -----------------------
|
||||
|
||||
get value(): Maybe<string> {
|
||||
return this.selectedDateSignal();
|
||||
}
|
||||
|
||||
ngOnDestroy(): void {
|
||||
if (this.fpInstance?.destroy) {
|
||||
this.fpInstance.destroy();
|
||||
this.fpInstance = null;
|
||||
get valueToShow(): Maybe<string> {
|
||||
return this.selectedDateSignal() && formatJalali(this.selectedDateSignal()!);
|
||||
}
|
||||
|
||||
get activeDate(): string {
|
||||
return this.activeDateSignal();
|
||||
}
|
||||
|
||||
// -----------------------
|
||||
// Setters
|
||||
// -----------------------
|
||||
|
||||
set value(date: Maybe<string>) {
|
||||
this.selectedDateSignal.set(date);
|
||||
this.control.setValue(date);
|
||||
|
||||
if (date) {
|
||||
this.activeDateSignal.set(date);
|
||||
}
|
||||
}
|
||||
|
||||
set activeDate(date: string) {
|
||||
this.activeDateSignal.set(date);
|
||||
}
|
||||
|
||||
// -----------------------
|
||||
// Navigation
|
||||
// -----------------------
|
||||
|
||||
changeMonth(months: number): void {
|
||||
const newDate = dayjs(this.activeDateSignal()).add(months, 'month').format('YYYY-MM-DD');
|
||||
|
||||
this.activeDateSignal.set(newDate);
|
||||
}
|
||||
|
||||
// -----------------------
|
||||
// Selection
|
||||
// -----------------------
|
||||
|
||||
selectDate(day: MonthlyWeekDate): void {
|
||||
if (this.disabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (day.isDisabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.value = day.gregorianDate;
|
||||
|
||||
this.onChange(day.gregorianDate);
|
||||
|
||||
this.onTouched();
|
||||
|
||||
if (this.closeOnSelect) {
|
||||
this.op.toggle(false);
|
||||
}
|
||||
|
||||
this.clickOnDayEvent.emit(day);
|
||||
this.valueChange.emit(day.gregorianDate);
|
||||
}
|
||||
|
||||
isSelected(day: MonthlyWeekDate): boolean {
|
||||
return !!this.value && this.value === day.gregorianDate;
|
||||
}
|
||||
|
||||
// -----------------------
|
||||
// CVA
|
||||
// -----------------------
|
||||
|
||||
private onChange: (value: Maybe<string>) => void = () => {};
|
||||
|
||||
private onTouched: () => void = () => {};
|
||||
|
||||
writeValue(value: Maybe<string>): void {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
registerOnChange(fn: (value: Maybe<string>) => void): void {
|
||||
this.onChange = fn;
|
||||
}
|
||||
|
||||
registerOnTouched(fn: () => void): void {
|
||||
this.onTouched = fn;
|
||||
}
|
||||
|
||||
setDisabledState(isDisabled: boolean): void {
|
||||
this.disabled = isDisabled;
|
||||
}
|
||||
|
||||
// -----------------------
|
||||
// Helpers
|
||||
// -----------------------
|
||||
|
||||
trackByIndex(index: number): number {
|
||||
return index;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user