UNPKG

@tapsellorg/angular-material-library

Version:

Angular library for Tapsell

682 lines (669 loc) 45.4 kB
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