diff --git a/src-ui/src/app/utils/ngb-input-date-picker-config.spec.ts b/src-ui/src/app/utils/ngb-input-date-picker-config.spec.ts new file mode 100644 index 000000000..0eb477441 --- /dev/null +++ b/src-ui/src/app/utils/ngb-input-date-picker-config.spec.ts @@ -0,0 +1,84 @@ +import { LOCALE_ID } from '@angular/core' +import { TestBed } from '@angular/core/testing' +import { NgbInputDatepickerConfig } from '@ng-bootstrap/ng-bootstrap' +import { PngxDatePickerConfig } from './ngb-input-date-picker-config' + +describe('PngxDatePickerConfig', () => { + const configureLocale = (locale: string) => { + TestBed.configureTestingModule({ + providers: [ + { provide: LOCALE_ID, useValue: locale }, + { + provide: NgbInputDatepickerConfig, + useClass: PngxDatePickerConfig, + }, + ], + }) + } + + it('uses Sunday as the first day of the week for en-US', () => { + configureLocale('en-US') + + const config = TestBed.inject(NgbInputDatepickerConfig) + + expect(config).toBeInstanceOf(PngxDatePickerConfig) + expect(config.firstDayOfWeek).toEqual(7) + }) + + it('uses Monday as the first day of the week for de-DE', () => { + configureLocale('de-DE') + + const config = TestBed.inject(NgbInputDatepickerConfig) + + expect(config.firstDayOfWeek).toEqual(1) + }) + + it('supports browsers that provide getWeekInfo() and weekInfo', () => { + const getWeekInfo = jest.fn().mockReturnValue({ firstDay: 6 }) + const originalDescriptor = Object.getOwnPropertyDescriptor( + Intl.Locale.prototype, + 'getWeekInfo' + ) + Object.defineProperty(Intl.Locale.prototype, 'getWeekInfo', { + configurable: true, + value: getWeekInfo, + }) + let config: NgbInputDatepickerConfig + try { + configureLocale('ar-EG') + config = TestBed.inject(NgbInputDatepickerConfig) + } finally { + if (originalDescriptor) { + Object.defineProperty( + Intl.Locale.prototype, + 'getWeekInfo', + originalDescriptor + ) + } else { + delete Intl.Locale.prototype['getWeekInfo'] + } + } + + expect(getWeekInfo).toHaveBeenCalledTimes(1) + expect(config.firstDayOfWeek).toEqual(6) + + Object.defineProperty(Intl.Locale.prototype, 'weekInfo', { + configurable: true, + value: { firstDay: 5 }, + }) + Object.defineProperty(Intl.Locale.prototype, 'getWeekInfo', { + configurable: true, + value: undefined, + }) + try { + TestBed.resetTestingModule() + configureLocale('ar-EG') + config = TestBed.inject(NgbInputDatepickerConfig) + } finally { + delete Intl.Locale.prototype['weekInfo'] + delete Intl.Locale.prototype['getWeekInfo'] + } + + expect(config.firstDayOfWeek).toEqual(5) + }) +}) diff --git a/src-ui/src/app/utils/ngb-input-date-picker-config.ts b/src-ui/src/app/utils/ngb-input-date-picker-config.ts new file mode 100644 index 000000000..37af80384 --- /dev/null +++ b/src-ui/src/app/utils/ngb-input-date-picker-config.ts @@ -0,0 +1,20 @@ +import { inject, Injectable, LOCALE_ID } from '@angular/core' +import { NgbInputDatepickerConfig } from '@ng-bootstrap/ng-bootstrap' + +@Injectable() +export class PngxDatePickerConfig extends NgbInputDatepickerConfig { + currentLocale = inject(LOCALE_ID) + + constructor() { + super() + const localeInfo = new Intl.Locale(this.currentLocale) as any + let firstDay + if (localeInfo?.getWeekInfo) firstDay = localeInfo.getWeekInfo?.().firstDay + else if (localeInfo?.weekInfo?.firstDay) + firstDay = localeInfo.weekInfo.firstDay + + if (firstDay !== undefined) { + this.firstDayOfWeek = firstDay + } + } +} diff --git a/src-ui/src/main.ts b/src-ui/src/main.ts index 174d0f5e0..dc8d8d3f5 100644 --- a/src-ui/src/main.ts +++ b/src-ui/src/main.ts @@ -18,6 +18,7 @@ import { BrowserModule, bootstrapApplication } from '@angular/platform-browser' import { NgbDateAdapter, NgbDateParserFormatter, + NgbInputDatepickerConfig, NgbModule, } from '@ng-bootstrap/ng-bootstrap' import { NgSelectModule } from '@ng-select/ng-select' @@ -227,6 +228,7 @@ import { provideUiTour } from 'ngx-ui-tour-ng-bootstrap' import { CorrespondentNamePipe } from './app/pipes/correspondent-name.pipe' import { DocumentTypeNamePipe } from './app/pipes/document-type-name.pipe' import { StoragePathNamePipe } from './app/pipes/storage-path-name.pipe' +import { PngxDatePickerConfig } from './app/utils/ngb-input-date-picker-config' registerLocaleData(localeAf) registerLocaleData(localeAr) @@ -439,6 +441,7 @@ bootstrapApplication(AppComponent, { CookieService, FilterPipe, DocumentTitlePipe, + { provide: NgbInputDatepickerConfig, useClass: PngxDatePickerConfig }, { provide: NgbDateAdapter, useClass: ISODateAdapter }, { provide: NgbDateParserFormatter, useClass: LocalizedDateParserFormatter }, PermissionsGuard,