@tapsellorg/angular-material-library
Version:
Angular library for Tapsell
682 lines (669 loc) • 45.4 kB
JavaScript
import { CommonModule } from '@angular/common';
import * as i0 from '@angular/core';
import { InjectionToken, Inject, Injectable, signal, HostBinding, ViewEncapsulation, Component, input, Directive, inject, output, ChangeDetectionStrategy, NgModule } from '@angular/core';
import * as i4$1 from '@angular/forms';
import { UntypedFormControl, ReactiveFormsModule } from '@angular/forms';
import * as i4 from '@angular/material/button';
import { MatButtonModule } from '@angular/material/button';
import * as i2 from '@angular/material/core';
import { DateAdapter, MAT_DATE_FORMATS, MAT_DATE_LOCALE } from '@angular/material/core';
import * as i3 from '@angular/material/datepicker';
import { DateRange, MAT_DATE_RANGE_SELECTION_STRATEGY, MatDatepickerModule } from '@angular/material/datepicker';
import { MatFormFieldModule } from '@angular/material/form-field';
import * as i5 from '@angular/material/icon';
import { MatIconModule } from '@angular/material/icon';
import { MatInputModule } from '@angular/material/input';
import * as i1 from '@tapsellorg/angular-material-library/src/lib/jalali-date-adapter';
import { GregorianJalaliHelper, JalaliDate, DateUtils, MaterialJalaliDateAdapter } from '@tapsellorg/angular-material-library/src/lib/jalali-date-adapter';
import { takeUntil, distinctUntilChanged } from 'rxjs/operators';
import { withDestroy } from '@tapsellorg/angular-material-library/src/lib/common';
import { BehaviorSubject, Subject } from 'rxjs';
import * as i6 from '@tapsellorg/angular-material-library/src/lib/translate';
import { TranslateModule } from '@tapsellorg/angular-material-library/src/lib/translate';
import * as i2$1 from '@tapsellorg/angular-material-library/notif';
import * as i5$1 from '@angular/material/chips';
import { MatChipsModule } from '@angular/material/chips';
const PghPredefinedDateRanges = {
last7Days: {
id: 'last 7 days',
type: 'relative',
start: -6,
end: 0,
title: 'DATE_RANGE_PICKER_LAST_SEVEN_DAYS',
},
};
const PGH_DEFAULT_PREDEFINED_DATE_RANGES = [
{ id: 'today', type: 'relative', start: 0, end: 0, title: 'DATE_RANGE_PICKER_TODAY' },
{ id: 'yesterday', type: 'relative', start: -1, end: -1, title: 'DATE_RANGE_PICKER_YESTERDAY' },
PghPredefinedDateRanges.last7Days,
{
id: 'last 30 days',
type: 'relative',
start: -29,
end: 0,
title: 'DATE_RANGE_PICKER_LAST_THIRTY_DAYS',
},
{
id: 'last 60 days',
type: 'relative',
start: -59,
end: 0,
title: 'DATE_RANGE_PICKER_LAST_SIXTY_DAYS',
},
{ id: 'this month', type: 'month', from: 0, title: 'DATE_RANGE_PICKER_CURRENT_MONTH' },
// { id: 'this year', type: 'year', from: 0, title: 'امسال' },
// { id: 'last year', type: 'year', from: -1, title: 'سال گذشته' },
{
id: 'clear date',
type: 'clearDate',
title: 'DATE_RANGE_PICKER_DELETE_BUTTON',
},
];
const PGH_DEFAULT_PREDEFINED_EXPANDED_DATE_RANGES = [
{ id: 'today', type: 'relative', start: 0, end: 0, title: 'DATE_RANGE_PICKER_TODAY' },
PghPredefinedDateRanges.last7Days,
{
id: 'last 30 days',
type: 'relative',
start: -29,
end: 0,
title: 'DATE_RANGE_PICKER_LAST_THIRTY_DAYS',
},
{ id: 'this month', type: 'month', from: 0, title: 'DATE_RANGE_PICKER_CURRENT_MONTH' },
];
const DEFAULT_SELECTED_DATE_RANGE = [
'today',
'this month',
'clear date',
'last 7 days',
'yesterday',
'last 30 days',
'last 60 days',
];
const PGH_PREDEFINED_DATE_RANGES = new InjectionToken('pghPredefinedDateRanges', {
providedIn: 'root',
factory: () => PGH_DEFAULT_PREDEFINED_DATE_RANGES,
});
const PGH_PREDEFINED_EXPANDED_DATE_RANGES = new InjectionToken('pghPredefinedDateRanges', {
providedIn: 'root',
factory: () => PGH_DEFAULT_PREDEFINED_EXPANDED_DATE_RANGES,
});
const PGH_FALLBACK_PREDEFINED_DATE_RANGE = new InjectionToken('pghPredefinedDateRanges', {
providedIn: 'root',
factory: () => PghPredefinedDateRanges.last7Days,
});
const PGH_DEFAULT_SELECTED_DATE_RANGE = new InjectionToken('pghDefaultSelectedDateRange', {
providedIn: 'root',
factory: () => 'last 7 days',
});
class PghPredefinedRangeCalculator {
constructor(dateAdapter) {
this.dateAdapter = dateAdapter;
}
static getEnrichedDateRange(range, predefined) {
if (predefined && (!range?.start || !range.end)) {
return;
}
const startGregorian = GregorianJalaliHelper.toGregorian(range.start);
const endGregorian = GregorianJalaliHelper.toGregorian(range.end);
endGregorian.setHours(23, 59, 59, 999);
startGregorian.setHours(0, 0, 0, 0);
return {
start: range.start,
end: range.end,
startGregorian,
endGregorian,
startTimestamp: startGregorian?.getTime(),
endTimestamp: endGregorian?.getTime(),
predefined,
};
}
extractRangeFromSavedItem(savedDateRange) {
if (savedDateRange.type === 'clearDate') {
return;
}
else if (savedDateRange.type === 'predefined') {
const predefinedDate = savedDateRange.range;
const dateRange = predefinedDate && this.calculateDateRange(predefinedDate);
if (!dateRange)
return;
return dateRange;
}
else {
const range = savedDateRange.range;
if (!range)
return;
const start = new JalaliDate(range.start.year, range.start.month, range.start.day);
const end = new JalaliDate(range.end.year, range.end.month, range.end.day);
return { start, end };
}
}
calculateDateRange(range) {
if (!range)
return;
const today = this.dateAdapter.today();
const year = this.dateAdapter.getYear(today);
switch (range.type) {
case 'relative':
const start = this.dateAdapter.addCalendarDays(today, range.start);
const end = this.dateAdapter.addCalendarDays(today, range.end);
return { start, end };
case 'week':
const thisDayAtWantedWeek = this.dateAdapter.addCalendarDays(today, 7 * range.from);
return this.calculateWeek(thisDayAtWantedWeek);
case 'month':
const thisDayAtWantedMonth = this.dateAdapter.addCalendarMonths(today, range.from);
return this.calculateMonth(thisDayAtWantedMonth);
case 'year':
const startOfYear = this.dateAdapter.createDate(year + range.from, 0, 1);
const lastDayOfYear = this.dateAdapter.isLeapYear(year + range.from) ? 30 : 29;
const endOfYear = this.dateAdapter.createDate(year + range.from, 11, lastDayOfYear);
return { start: startOfYear, end: endOfYear };
case 'clearDate':
default:
return;
}
}
calculateMonth(forDay) {
const year = this.dateAdapter.getYear(forDay);
const month = this.dateAdapter.getMonth(forDay);
const start = this.dateAdapter.createDate(year, month, 1);
const end = this.dateAdapter.addCalendarDays(start, this.dateAdapter.getNumDaysInMonth(forDay) - 1);
return { start, end };
}
calculateWeek(forDay) {
// Just works for JalaliDates
const deltaStart = ((this.dateAdapter.getFirstDayOfWeek() + 1) % 7) -
((this.dateAdapter.getDayOfWeek(forDay) + 1) % 7);
const start = this.dateAdapter.addCalendarDays(forDay, deltaStart);
const end = this.dateAdapter.addCalendarDays(start, 6);
return { start, end };
}
}
class PghDatePickerService {
constructor(dateAdapter, fallBackPredefinedDate) {
this.dateAdapter = dateAdapter;
this.fallBackPredefinedDate = fallBackPredefinedDate;
this.predefinedRangeCalculator = new PghPredefinedRangeCalculator(this.dateAdapter);
this.DATE_KEY = 'pgh_datepicker_state';
this.dateChange$ = new BehaviorSubject(this.extractLocalStorageValue());
this.localStorageListener = (_event) => {
const savedItem = this.getSavedDateFromLocalStorage();
if (!savedItem)
return;
this.dateChange$.next(this.extractLocalStorageValue(savedItem));
};
window.addEventListener('storage', this.localStorageListener);
}
ngOnDestroy() {
window.removeEventListener('storage', this.localStorageListener);
}
setDateRange(range) {
if (!range?.start || !range.end)
return;
this.saveDateInLocalStorage({ type: 'range', range });
this.dateChange$.next(PghPredefinedRangeCalculator.getEnrichedDateRange(range));
}
setPredefinedDate(predefinedDate) {
const range = this.predefinedRangeCalculator.calculateDateRange(predefinedDate);
this.saveDateInLocalStorage({ type: 'predefined', range: predefinedDate });
this.dateChange$.next(PghPredefinedRangeCalculator.getEnrichedDateRange(range, predefinedDate));
}
saveDateInLocalStorage(dateInfo) {
const datePickerSavedItem = {
...dateInfo,
lastChange: Date.now(),
};
const value = JSON.stringify(datePickerSavedItem);
localStorage.setItem(this.DATE_KEY, value);
}
isDateExpired(date) {
if (!this.EXPIRATION_PERIOD)
return false;
const today = new Date();
return DateUtils.daysBetween(today, new Date(date)) > this.EXPIRATION_PERIOD;
}
getSavedDateFromLocalStorage() {
try {
const savedRangeItem = localStorage.getItem(this.DATE_KEY);
if (!savedRangeItem)
return;
const savedDateRange = JSON.parse(savedRangeItem);
if (this.isDateExpired(savedDateRange.lastChange))
return;
return savedDateRange;
}
catch (_e) {
return;
}
}
extractLocalStorageValue(savedDate = this.getSavedDateFromLocalStorage()) {
const fallBackRange = {
type: 'predefined',
lastChange: Date.now(),
range: this.fallBackPredefinedDate,
};
let predefined = savedDate?.type === 'predefined' ? savedDate?.range : undefined;
let range = this.predefinedRangeCalculator.extractRangeFromSavedItem(savedDate ?? fallBackRange);
if (!range && !predefined) {
range = this.predefinedRangeCalculator.extractRangeFromSavedItem(fallBackRange);
predefined = fallBackRange.range;
}
return PghPredefinedRangeCalculator.getEnrichedDateRange(range, predefined);
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.15", ngImport: i0, type: PghDatePickerService, deps: [{ token: DateAdapter }, { token: PGH_FALLBACK_PREDEFINED_DATE_RANGE }], target: i0.ɵɵFactoryTarget.Injectable }); }
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.15", ngImport: i0, type: PghDatePickerService, providedIn: 'root' }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.15", ngImport: i0, type: PghDatePickerService, decorators: [{
type: Injectable,
args: [{
providedIn: 'root',
}]
}], ctorParameters: () => [{ type: i1.MaterialJalaliDateAdapter, decorators: [{
type: Inject,
args: [DateAdapter]
}] }, { type: undefined, decorators: [{
type: Inject,
args: [PGH_FALLBACK_PREDEFINED_DATE_RANGE]
}] }] });
class PghDateRangePickerControllerService extends withDestroy() {
emitDateRange(dateRange) {
this.dateRange$.next(dateRange);
}
constructor(dateAdapter, injectedDateRanges, injectedExpandedDateRanges, synchronizationService) {
super();
this.dateAdapter = dateAdapter;
this.synchronizationService = synchronizationService;
this.predefinedRangeCalculator = new PghPredefinedRangeCalculator(this.dateAdapter);
this.isSynced = true;
this.dateRange$ = new BehaviorSubject(this.synchronizationService.dateChange$.value);
this.predefinedDates = injectedDateRanges ?? PGH_DEFAULT_PREDEFINED_DATE_RANGES;
}
ngOnDestroy() {
this.dateRange$.complete();
}
setSync(isSynced) {
this.isSynced = isSynced;
this.handleSynchronization();
}
setDateRange(range) {
this.predefinedDate = undefined;
if (!range?.start || !range.end)
return;
this.emitDateRange(PghPredefinedRangeCalculator.getEnrichedDateRange(range));
if (this.isSynced) {
this.synchronizationService.setDateRange(range);
}
}
setPredefinedDate(predefinedDate) {
this.predefinedDate = predefinedDate;
const range = this.predefinedRangeCalculator.calculateDateRange(predefinedDate);
if (!predefinedDate)
return;
this.emitDateRange(PghPredefinedRangeCalculator.getEnrichedDateRange(range, predefinedDate));
if (this.isSynced) {
this.synchronizationService.setPredefinedDate(predefinedDate);
}
}
handleSynchronization() {
if (this.syncServiceSubscription) {
this.syncServiceSubscription.unsubscribe();
}
if (!this.isSynced)
return;
this.syncServiceSubscription = this.synchronizationService.dateChange$
.pipe(takeUntil(this._destroyed$))
.subscribe(savedItem => {
if (!savedItem)
return;
if (savedItem.predefined) {
this.predefinedDate = savedItem.predefined;
}
this.emitDateRange(savedItem);
});
}
setPredefinedDateById(id) {
const predefinedDate = this.predefinedDates.find(item => item.id === id);
this.setPredefinedDate(predefinedDate);
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.15", ngImport: i0, type: PghDateRangePickerControllerService, deps: [{ token: DateAdapter }, { token: PGH_PREDEFINED_DATE_RANGES }, { token: PGH_PREDEFINED_EXPANDED_DATE_RANGES }, { token: PghDatePickerService }], target: i0.ɵɵFactoryTarget.Injectable }); }
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.15", ngImport: i0, type: PghDateRangePickerControllerService }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.15", ngImport: i0, type: PghDateRangePickerControllerService, decorators: [{
type: Injectable
}], ctorParameters: () => [{ type: i1.MaterialJalaliDateAdapter, decorators: [{
type: Inject,
args: [DateAdapter]
}] }, { type: undefined, decorators: [{
type: Inject,
args: [PGH_PREDEFINED_DATE_RANGES]
}] }, { type: undefined, decorators: [{
type: Inject,
args: [PGH_PREDEFINED_EXPANDED_DATE_RANGES]
}] }, { type: PghDatePickerService }] });
class PghDatePickerHeaderComponent extends withDestroy() {
constructor(calendar, dateAdapter, picker, datePickerController, dateFormats, cdr) {
super();
this.calendar = calendar;
this.dateAdapter = dateAdapter;
this.picker = picker;
this.datePickerController = datePickerController;
this.dateFormats = dateFormats;
this.currentPredefinedDate = signal(undefined);
this.predefinedDateRanges = signal(this.datePickerController.predefinedDates);
this.isTouchUi = this.picker.touchUi;
calendar.stateChanges.pipe(takeUntil(this._destroyed$)).subscribe(() => {
cdr.markForCheck();
});
this.datePickerController.dateRange$.pipe(takeUntil(this._destroyed$)).subscribe(data => {
this.currentPredefinedDate.set(data?.predefined);
});
calendar.selectedChange.pipe(takeUntil(this._destroyed$)).subscribe(() => {
this.currentPredefinedDate.set(undefined);
});
}
get periodLabel() {
return this.dateAdapter
.format(this.calendar.activeDate, this.dateFormats.display.monthYearLabel)
.toLocaleUpperCase();
}
selectRange(predefinedDate) {
this.picker.close();
this.datePickerController.setPredefinedDate(predefinedDate);
}
changeDate(mode, amount) {
this.calendar.activeDate =
mode === 'month'
? this.dateAdapter.addCalendarMonths(this.calendar.activeDate, amount)
: this.dateAdapter.addCalendarYears(this.calendar.activeDate, amount);
if (!this.dateAdapter.isValid(this.calendar.activeDate)) {
const diffDaysNumber = this.dateAdapter.getNumDaysInMonth(this.calendar.activeDate) - this.calendar.activeDate.day;
this.calendar.activeDate = this.dateAdapter.addCalendarDays(this.calendar.activeDate, diffDaysNumber);
}
this.calendar.focusActiveCell();
}
previousClicked(mode) {
this.changeDate(mode, -1);
}
nextClicked(mode) {
this.changeDate(mode, 1);
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.15", ngImport: i0, type: PghDatePickerHeaderComponent, deps: [{ token: i3.MatCalendar }, { token: i2.DateAdapter }, { token: i3.MatDateRangePicker }, { token: PghDateRangePickerControllerService }, { token: MAT_DATE_FORMATS }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component }); }
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.15", type: PghDatePickerHeaderComponent, isStandalone: false, selector: "pgh-date-picker-header", host: { properties: { "class.touch-ui": "this.isTouchUi" } }, usesInheritance: true, ngImport: i0, template: "<div class=\"pgh-date-picker-predefined-dates\">\n @for (item of predefinedDateRanges(); track item) {\n <div\n class=\"pgh-predefined-date\"\n [class.pgh-active]=\"currentPredefinedDate()?.id === item.id\"\n [class.pgh-clear-date]=\"item.type === 'clearDate'\"\n (click)=\"selectRange(item)\"\n >\n {{ item.title | translate }}\n </div>\n }\n</div>\n\n<div class=\"pgh-date-picker-header\">\n <button mat-icon-button (click)=\"previousClicked('year')\">\n <mat-icon svgIcon=\"chevron_right\" style=\"filter: drop-shadow(-6px 0px 0px)\"></mat-icon>\n </button>\n\n <button mat-icon-button (click)=\"previousClicked('month')\">\n <mat-icon svgIcon=\"chevron_right\"></mat-icon>\n </button>\n\n <span class=\"pgh-date-picker-header-label\">{{ periodLabel }}</span>\n\n <button mat-icon-button (click)=\"nextClicked('month')\">\n <mat-icon svgIcon=\"chevron_left\"></mat-icon>\n </button>\n\n <button mat-icon-button (click)=\"nextClicked('year')\">\n <mat-icon svgIcon=\"chevron_left\" style=\"filter: drop-shadow(6px 0px 0px)\"></mat-icon>\n </button>\n</div>\n", styles: [".pgh-date-picker-predefined-dates{position:absolute;height:100%;right:0;border-inline-end:1px solid var(--light-border-color);padding-block:.5rem;padding-inline:0;font-size:.875rem;width:130px}.pgh-date-picker-predefined-dates.touch-ui{position:relative;left:0;display:flex;width:100%}[dir=ltr] .pgh-date-picker-predefined-dates{left:0}.pgh-predefined-date{text-align:start;padding-block:.5rem;padding-inline:1rem;margin-bottom:.5rem;cursor:pointer}.pgh-predefined-date:last-child{margin-bottom:0}.pgh-predefined-date:hover,.pgh-predefined-date:focus{background:var(--primary-50)}.pgh-predefined-date.pgh-active{background:var(--primary-50);border-inline-end:2px solid var(--primary)}.pgh-predefined-date.pgh-clear-date{color:var(--primary-300)}.pgh-predefined-date.pgh-clear-date:hover{background:transparent}.pgh-date-picker-header{display:flex;align-items:center;padding:.5rem}.pgh-date-picker-header .pgh-date-picker-header-label{flex:1;text-align:center}.pgh-date-picker-header>button{color:var(--999)}.pgh-date-range-picker-panel{margin-inline-start:130px}\n"], dependencies: [{ kind: "component", type: i4.MatIconButton, selector: "button[mat-icon-button]", exportAs: ["matButton"] }, { kind: "component", type: i5.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "pipe", type: i6.TranslatePipe, name: "translate" }], encapsulation: i0.ViewEncapsulation.None }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.15", ngImport: i0, type: PghDatePickerHeaderComponent, decorators: [{
type: Component,
args: [{ selector: 'pgh-date-picker-header', encapsulation: ViewEncapsulation.None, standalone: false, template: "<div class=\"pgh-date-picker-predefined-dates\">\n @for (item of predefinedDateRanges(); track item) {\n <div\n class=\"pgh-predefined-date\"\n [class.pgh-active]=\"currentPredefinedDate()?.id === item.id\"\n [class.pgh-clear-date]=\"item.type === 'clearDate'\"\n (click)=\"selectRange(item)\"\n >\n {{ item.title | translate }}\n </div>\n }\n</div>\n\n<div class=\"pgh-date-picker-header\">\n <button mat-icon-button (click)=\"previousClicked('year')\">\n <mat-icon svgIcon=\"chevron_right\" style=\"filter: drop-shadow(-6px 0px 0px)\"></mat-icon>\n </button>\n\n <button mat-icon-button (click)=\"previousClicked('month')\">\n <mat-icon svgIcon=\"chevron_right\"></mat-icon>\n </button>\n\n <span class=\"pgh-date-picker-header-label\">{{ periodLabel }}</span>\n\n <button mat-icon-button (click)=\"nextClicked('month')\">\n <mat-icon svgIcon=\"chevron_left\"></mat-icon>\n </button>\n\n <button mat-icon-button (click)=\"nextClicked('year')\">\n <mat-icon svgIcon=\"chevron_left\" style=\"filter: drop-shadow(6px 0px 0px)\"></mat-icon>\n </button>\n</div>\n", styles: [".pgh-date-picker-predefined-dates{position:absolute;height:100%;right:0;border-inline-end:1px solid var(--light-border-color);padding-block:.5rem;padding-inline:0;font-size:.875rem;width:130px}.pgh-date-picker-predefined-dates.touch-ui{position:relative;left:0;display:flex;width:100%}[dir=ltr] .pgh-date-picker-predefined-dates{left:0}.pgh-predefined-date{text-align:start;padding-block:.5rem;padding-inline:1rem;margin-bottom:.5rem;cursor:pointer}.pgh-predefined-date:last-child{margin-bottom:0}.pgh-predefined-date:hover,.pgh-predefined-date:focus{background:var(--primary-50)}.pgh-predefined-date.pgh-active{background:var(--primary-50);border-inline-end:2px solid var(--primary)}.pgh-predefined-date.pgh-clear-date{color:var(--primary-300)}.pgh-predefined-date.pgh-clear-date:hover{background:transparent}.pgh-date-picker-header{display:flex;align-items:center;padding:.5rem}.pgh-date-picker-header .pgh-date-picker-header-label{flex:1;text-align:center}.pgh-date-picker-header>button{color:var(--999)}.pgh-date-range-picker-panel{margin-inline-start:130px}\n"] }]
}], ctorParameters: () => [{ type: i3.MatCalendar }, { type: i2.DateAdapter }, { type: i3.MatDateRangePicker }, { type: PghDateRangePickerControllerService }, { type: undefined, decorators: [{
type: Inject,
args: [MAT_DATE_FORMATS]
}] }, { type: i0.ChangeDetectorRef }], propDecorators: { isTouchUi: [{
type: HostBinding,
args: ['class.touch-ui']
}] } });
// https://github.com/angular/components/blob/master/src/material/datepicker/date-range-selection-strategy.ts
class PghDateRangePickerSelectionStrategy {
constructor(_dateAdapter) {
this._dateAdapter = _dateAdapter;
}
selectionFinished(date, currentRange) {
let { start, end } = currentRange;
if (start == null) {
start = date;
}
else if (!this.delta &&
end == null &&
date &&
this._dateAdapter.compareDate(date, start) >= 0) {
end = date;
}
else if (this.delta &&
end == null &&
date &&
this._dateAdapter.compareDate(date, start) >= 0) {
const maxDate = this._dateAdapter.addCalendarDays(start, this.delta);
end = this._dateAdapter.compareDate(date, maxDate) >= 0 ? maxDate : date;
}
else {
start = date;
end = null;
}
return new DateRange(start, end);
}
createPreview(activeDate, currentRange) {
let start = null;
let end = null;
if (!this.delta && currentRange.start && !currentRange.end && activeDate) {
start = currentRange.start;
end = activeDate;
}
else if (this.delta && currentRange.start && !currentRange.end && activeDate) {
const maxDate = this._dateAdapter.addCalendarDays(currentRange.start, this.delta);
start = currentRange.start;
end = this._dateAdapter.compareDate(activeDate, maxDate) >= 0 ? maxDate : activeDate;
}
return new DateRange(start, end);
}
setMaxRange(maxRange) {
this.delta = maxRange - 1;
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.15", ngImport: i0, type: PghDateRangePickerSelectionStrategy, deps: [{ token: i2.DateAdapter }], target: i0.ɵɵFactoryTarget.Injectable }); }
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.15", ngImport: i0, type: PghDateRangePickerSelectionStrategy }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.15", ngImport: i0, type: PghDateRangePickerSelectionStrategy, decorators: [{
type: Injectable
}], ctorParameters: () => [{ type: i2.DateAdapter }] });
class PghMaxRangeDirective {
constructor(maxRangeStrategy) {
this.maxRangeStrategy = maxRangeStrategy;
this.maxRange = input(undefined, {
alias: 'pghMaxRange',
});
}
ngOnChanges(changes) {
if (!this.maxRange())
return;
if (changes.maxRange) {
this.maxRangeStrategy.setMaxRange(this.maxRange());
}
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.15", ngImport: i0, type: PghMaxRangeDirective, deps: [{ token: MAT_DATE_RANGE_SELECTION_STRATEGY }], target: i0.ɵɵFactoryTarget.Directive }); }
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "19.2.15", type: PghMaxRangeDirective, isStandalone: false, selector: "[pghMaxRange]", inputs: { maxRange: { classPropertyName: "maxRange", publicName: "pghMaxRange", isSignal: true, isRequired: false, transformFunction: null } }, providers: [
{
provide: MAT_DATE_RANGE_SELECTION_STRATEGY,
useClass: PghDateRangePickerSelectionStrategy,
},
], usesOnChanges: true, ngImport: i0 }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.15", ngImport: i0, type: PghMaxRangeDirective, decorators: [{
type: Directive,
args: [{
selector: '[pghMaxRange]',
providers: [
{
provide: MAT_DATE_RANGE_SELECTION_STRATEGY,
useClass: PghDateRangePickerSelectionStrategy,
},
],
standalone: false,
}]
}], ctorParameters: () => [{ type: PghDateRangePickerSelectionStrategy, decorators: [{
type: Inject,
args: [MAT_DATE_RANGE_SELECTION_STRATEGY]
}] }] });
class PghDateRangePickerComponent {
constructor(dateRangePickerController, pghNotifService, injectedExpandedDateRanges) {
this.dateRangePickerController = dateRangePickerController;
this.pghNotifService = pghNotifService;
this.injectedDefault = inject(PGH_DEFAULT_SELECTED_DATE_RANGE);
this.headerComponent = PghDatePickerHeaderComponent;
this.start = input(new UntypedFormControl());
this.end = input(new UntypedFormControl());
this.maxRange = input();
this.isSynced = input(true);
this.expanded = input(false);
this.disableClickOnInputs = input(true);
this.defaultSelectedDateRangeId = input();
this.disabledDates = input();
this.rangeChange = output();
this.destroy$ = new Subject();
this.selectedChip = signal(undefined);
this.chipDateRanges = signal([]);
this.dateClass = (date) => {
const isoDate = this.jalaliDateToISOString(date);
return this.isDateDisabled(isoDate) ? 'disabled-day' : '';
};
this.chipDateRanges.set(injectedExpandedDateRanges);
}
ngOnInit() {
this.dateRangePickerController.setSync(this.isSynced());
this.setDefaultDateRange();
this.dateRangePickerController.dateRange$
.pipe(takeUntil(this.destroy$), distinctUntilChanged((a, b) => JSON.stringify(a) === JSON.stringify(b)))
.subscribe(dateRange => {
this.start().setValue(dateRange?.start);
this.end().setValue(dateRange?.end);
this.emitRange(dateRange);
});
}
changeSelection(id) {
if (this.selectedChip() !== id) {
this.selectedChip.set(id);
this.dateRangePickerController.setPredefinedDateById(this.selectedChip());
}
else {
this.selectedChip.set(undefined);
this.dateRangePickerController.setPredefinedDateById('clear date');
}
}
jalaliDateToISOString(jalaliDate) {
const { year, month, day } = jalaliDate;
return `${year}${month.toString().padStart(2, '0')}${day.toString().padStart(2, '0')}`;
}
isDateDisabled(date) {
return this.disabledDates()?.includes(date) ?? false;
}
getDatesBetween(startDate, endDate) {
const dates = [];
let currentDate = startDate;
while (currentDate <= endDate) {
dates.push(currentDate);
currentDate = this.incrementDate(currentDate);
}
return dates;
}
isDateRangeValid(startDate, endDate) {
const startDateISO = this.jalaliDateToISOString(startDate);
const endDateISO = this.jalaliDateToISOString(endDate);
const dateRange = this.getDatesBetween(startDateISO, endDateISO);
return !dateRange.some(date => this.isDateDisabled(date));
}
incrementDate(date) {
const parsedDate = new Date(parseInt(date.slice(0, 4), 10), parseInt(date.slice(4, 6), 10) - 1, parseInt(date.slice(6, 8), 10));
parsedDate.setDate(parsedDate.getDate() + 1);
return this.jalaliDateToISOString({
year: parsedDate.getFullYear(),
month: parsedDate.getMonth() + 1,
day: parsedDate.getDate(),
});
}
datePickerDateChange() {
const selectedStartDate = this.start().value;
const selectedEndDate = this.end().value;
if (!selectedStartDate || !selectedEndDate)
return;
if (this.isDateRangeValid(selectedStartDate, selectedEndDate)) {
this.dateRangePickerController.setDateRange({
start: selectedStartDate,
end: selectedEndDate,
});
}
else {
this.start().setValue(null);
this.end().setValue(null);
this.pghNotifService.error('محدوده انتخابی نمیتواند شامل تاریخهای رزرو شده باشد.');
}
}
setDefaultDateRange() {
if (this.isSynced())
return;
const effectiveDefault = this.defaultSelectedDateRangeId() ?? this.injectedDefault;
this.dateRangePickerController.setPredefinedDateById(effectiveDefault);
}
ngOnChanges(changes) {
if (changes.isSynced) {
this.dateRangePickerController.setSync(this.isSynced());
}
}
ngOnDestroy() {
this.destroy$.next();
}
emitRange(range) {
if (range?.predefined) {
this.selectedChip.set(range.predefined.id);
}
this.selectedDateRange = range;
this.rangeChange.emit(range);
}
getSelectedDateRange() {
return this.selectedDateRange;
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.15", ngImport: i0, type: PghDateRangePickerComponent, deps: [{ token: PghDateRangePickerControllerService }, { token: i2$1.PghNotifService }, { token: PGH_PREDEFINED_EXPANDED_DATE_RANGES }], target: i0.ɵɵFactoryTarget.Component }); }
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.15", type: PghDateRangePickerComponent, isStandalone: false, selector: "pgh-date-range-picker", inputs: { start: { classPropertyName: "start", publicName: "start", isSignal: true, isRequired: false, transformFunction: null }, end: { classPropertyName: "end", publicName: "end", isSignal: true, isRequired: false, transformFunction: null }, maxRange: { classPropertyName: "maxRange", publicName: "maxRange", isSignal: true, isRequired: false, transformFunction: null }, isSynced: { classPropertyName: "isSynced", publicName: "isSynced", isSignal: true, isRequired: false, transformFunction: null }, expanded: { classPropertyName: "expanded", publicName: "expanded", isSignal: true, isRequired: false, transformFunction: null }, disableClickOnInputs: { classPropertyName: "disableClickOnInputs", publicName: "disableClickOnInputs", isSignal: true, isRequired: false, transformFunction: null }, defaultSelectedDateRangeId: { classPropertyName: "defaultSelectedDateRangeId", publicName: "defaultSelectedDateRangeId", isSignal: true, isRequired: false, transformFunction: null }, disabledDates: { classPropertyName: "disabledDates", publicName: "disabledDates", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { rangeChange: "rangeChange" }, providers: [PghDateRangePickerControllerService], usesOnChanges: true, ngImport: i0, template: "<mat-chip-listbox>\n @if (expanded()) { @for (chip of chipDateRanges(); track chip) {\n <mat-chip-option [selected]=\"chip.id === selectedChip()\" (click)=\"changeSelection(chip.id)\">\n {{ chip.title | translate }}\n </mat-chip-option>\n } }\n <div class=\"pgh-date-range-picker\" (click)=\"disableClickOnInputs() && picker.open()\">\n <mat-datepicker-toggle [for]=\"picker\"></mat-datepicker-toggle>\n\n <span class=\"pgh-range-from\">{{ 'DATE_RANGE_PICKER_FROM' | translate }}</span>\n <mat-date-range-input [rangePicker]=\"picker\" [separator]=\"'DATE_RANGE_PICKER_TO' | translate\">\n <input\n [readOnly]=\"disableClickOnInputs()\"\n matStartDate\n [formControl]=\"start()\"\n [placeholder]=\"'DATE_RANGE_PICKER_START_DATE' | translate\"\n (change)=\"!disableClickOnInputs() && datePickerDateChange()\"\n />\n <input\n [readOnly]=\"disableClickOnInputs()\"\n matEndDate\n [formControl]=\"end()\"\n [placeholder]=\"'DATE_RANGE_PICKER_END_DATE' | translate\"\n (dateChange)=\"datePickerDateChange()\"\n />\n </mat-date-range-input>\n\n <!-- TODO: v17 [dateClass]=\"dateClass\" removed from this element -->\n <mat-date-range-picker\n [dateClass]=\"dateClass\"\n [panelClass]=\"'pgh-date-range-picker-panel'\"\n #picker\n [pghMaxRange]=\"maxRange()\"\n [calendarHeaderComponent]=\"headerComponent\"\n ></mat-date-range-picker>\n </div>\n</mat-chip-listbox>\n", styles: [".font-monospaced-numbers{font-feature-settings:\"ss03\"!important}.font-english-numbers{font-feature-settings:normal!important}.font-weight-light{font-weight:300}.font-weight-normal{font-weight:400}.font-weight-bold{font-weight:600}.black-50{background-color:hsl(var(--_body-hue),var(--_body-saturation),var(--lightness-0),50%)!important}.white-50{background-color:hsl(var(--_body-hue),var(--_body-saturation),var(--lightness-1000),50%)!important}.pgh-date-range-picker{display:inline-flex;align-items:center;font-size:.875rem}.pgh-date-range-picker .pgh-range-from{margin-inline-end:.375rem}.pgh-date-range-picker .mat-date-range-input-separator,.pgh-date-range-picker .pgh-range-from{color:var(--777)}.pgh-date-range-picker .mat-date-range-input-wrapper,.pgh-date-range-picker .mat-date-range-input-start-wrapper,.pgh-date-range-picker .mat-date-range-input-end-wrapper{font-weight:600}.disabled-day{pointer-events:none;background:var(--disabled-day-background)!important;border-radius:50%;border:2px solid var(--fff)!important}.disabled-day span{color:var(--gray-700)!important}\n"], dependencies: [{ kind: "component", type: i3.MatDatepickerToggle, selector: "mat-datepicker-toggle", inputs: ["for", "tabIndex", "aria-label", "disabled", "disableRipple"], exportAs: ["matDatepickerToggle"] }, { kind: "component", type: i3.MatDateRangeInput, selector: "mat-date-range-input", inputs: ["rangePicker", "required", "dateFilter", "min", "max", "disabled", "separator", "comparisonStart", "comparisonEnd"], exportAs: ["matDateRangeInput"] }, { kind: "directive", type: i3.MatStartDate, selector: "input[matStartDate]", outputs: ["dateChange", "dateInput"] }, { kind: "directive", type: i3.MatEndDate, selector: "input[matEndDate]", outputs: ["dateChange", "dateInput"] }, { kind: "component", type: i3.MatDateRangePicker, selector: "mat-date-range-picker", exportAs: ["matDateRangePicker"] }, { kind: "directive", type: i4$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i4$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i4$1.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "component", type: i5$1.MatChipListbox, selector: "mat-chip-listbox", inputs: ["multiple", "aria-orientation", "selectable", "compareWith", "required", "hideSingleSelectionIndicator", "value"], outputs: ["change"] }, { kind: "component", type: i5$1.MatChipOption, selector: "mat-basic-chip-option, [mat-basic-chip-option], mat-chip-option, [mat-chip-option]", inputs: ["selectable", "selected"], outputs: ["selectionChange"] }, { kind: "directive", type: PghMaxRangeDirective, selector: "[pghMaxRange]", inputs: ["pghMaxRange"] }, { kind: "pipe", type: i6.TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.15", ngImport: i0, type: PghDateRangePickerComponent, decorators: [{
type: Component,
args: [{ selector: 'pgh-date-range-picker', providers: [PghDateRangePickerControllerService], encapsulation: ViewEncapsulation.None, changeDetection: ChangeDetectionStrategy.OnPush, standalone: false, template: "<mat-chip-listbox>\n @if (expanded()) { @for (chip of chipDateRanges(); track chip) {\n <mat-chip-option [selected]=\"chip.id === selectedChip()\" (click)=\"changeSelection(chip.id)\">\n {{ chip.title | translate }}\n </mat-chip-option>\n } }\n <div class=\"pgh-date-range-picker\" (click)=\"disableClickOnInputs() && picker.open()\">\n <mat-datepicker-toggle [for]=\"picker\"></mat-datepicker-toggle>\n\n <span class=\"pgh-range-from\">{{ 'DATE_RANGE_PICKER_FROM' | translate }}</span>\n <mat-date-range-input [rangePicker]=\"picker\" [separator]=\"'DATE_RANGE_PICKER_TO' | translate\">\n <input\n [readOnly]=\"disableClickOnInputs()\"\n matStartDate\n [formControl]=\"start()\"\n [placeholder]=\"'DATE_RANGE_PICKER_START_DATE' | translate\"\n (change)=\"!disableClickOnInputs() && datePickerDateChange()\"\n />\n <input\n [readOnly]=\"disableClickOnInputs()\"\n matEndDate\n [formControl]=\"end()\"\n [placeholder]=\"'DATE_RANGE_PICKER_END_DATE' | translate\"\n (dateChange)=\"datePickerDateChange()\"\n />\n </mat-date-range-input>\n\n <!-- TODO: v17 [dateClass]=\"dateClass\" removed from this element -->\n <mat-date-range-picker\n [dateClass]=\"dateClass\"\n [panelClass]=\"'pgh-date-range-picker-panel'\"\n #picker\n [pghMaxRange]=\"maxRange()\"\n [calendarHeaderComponent]=\"headerComponent\"\n ></mat-date-range-picker>\n </div>\n</mat-chip-listbox>\n", styles: [".font-monospaced-numbers{font-feature-settings:\"ss03\"!important}.font-english-numbers{font-feature-settings:normal!important}.font-weight-light{font-weight:300}.font-weight-normal{font-weight:400}.font-weight-bold{font-weight:600}.black-50{background-color:hsl(var(--_body-hue),var(--_body-saturation),var(--lightness-0),50%)!important}.white-50{background-color:hsl(var(--_body-hue),var(--_body-saturation),var(--lightness-1000),50%)!important}.pgh-date-range-picker{display:inline-flex;align-items:center;font-size:.875rem}.pgh-date-range-picker .pgh-range-from{margin-inline-end:.375rem}.pgh-date-range-picker .mat-date-range-input-separator,.pgh-date-range-picker .pgh-range-from{color:var(--777)}.pgh-date-range-picker .mat-date-range-input-wrapper,.pgh-date-range-picker .mat-date-range-input-start-wrapper,.pgh-date-range-picker .mat-date-range-input-end-wrapper{font-weight:600}.disabled-day{pointer-events:none;background:var(--disabled-day-background)!important;border-radius:50%;border:2px solid var(--fff)!important}.disabled-day span{color:var(--gray-700)!important}\n"] }]
}], ctorParameters: () => [{ type: PghDateRangePickerControllerService }, { type: i2$1.PghNotifService }, { type: undefined, decorators: [{
type: Inject,
args: [PGH_PREDEFINED_EXPANDED_DATE_RANGES]
}] }] });
class PghDateRangePickerModule {
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.15", ngImport: i0, type: PghDateRangePickerModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "19.2.15", ngImport: i0, type: PghDateRangePickerModule, declarations: [PghDateRangePickerComponent, PghMaxRangeDirective, PghDatePickerHeaderComponent], imports: [CommonModule,
MatDatepickerModule,
MatFormFieldModule,
MatInputModule,
MatButtonModule,
MatIconModule,
ReactiveFormsModule,
TranslateModule,
MatChipsModule], exports: [PghDateRangePickerComponent, PghMaxRangeDirective, PghDatePickerHeaderComponent] }); }
static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "19.2.15", ngImport: i0, type: PghDateRangePickerModule, providers: [
{ provide: DateAdapter, useClass: MaterialJalaliDateAdapter, deps: [MAT_DATE_LOCALE] },
], imports: [CommonModule,
MatDatepickerModule,
MatFormFieldModule,
MatInputModule,
MatButtonModule,
MatIconModule,
ReactiveFormsModule,
TranslateModule,
MatChipsModule] }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.15", ngImport: i0, type: PghDateRangePickerModule, decorators: [{
type: NgModule,
args: [{
declarations: [PghDateRangePickerComponent, PghMaxRangeDirective, PghDatePickerHeaderComponent],
imports: [
CommonModule,
MatDatepickerModule,
MatFormFieldModule,
MatInputModule,
MatButtonModule,
MatIconModule,
ReactiveFormsModule,
TranslateModule,
MatChipsModule,
],
exports: [PghDateRangePickerComponent, PghMaxRangeDirective, PghDatePickerHeaderComponent],
providers: [
{ provide: DateAdapter, useClass: MaterialJalaliDateAdapter, deps: [MAT_DATE_LOCALE] },
],
}]
}] });
/**
* Generated bundle index. Do not edit.
*/
export { PGH_DEFAULT_PREDEFINED_DATE_RANGES, PGH_DEFAULT_SELECTED_DATE_RANGE, PGH_FALLBACK_PREDEFINED_DATE_RANGE, PGH_PREDEFINED_DATE_RANGES, PGH_PREDEFINED_EXPANDED_DATE_RANGES, PghDatePickerHeaderComponent, PghDatePickerService, PghDateRangePickerComponent, PghDateRangePickerControllerService, PghDateRangePickerModule, PghDateRangePickerSelectionStrategy, PghMaxRangeDirective, PghPredefinedRangeCalculator };
//# sourceMappingURL=tapsellorg-angular-material-library-src-lib-date-range-picker.mjs.map