diff --git a/examples/webpack-demo-vanilla-bundle/src/main.ts b/examples/webpack-demo-vanilla-bundle/src/main.ts index 3304bbb3e..48db5a591 100644 --- a/examples/webpack-demo-vanilla-bundle/src/main.ts +++ b/examples/webpack-demo-vanilla-bundle/src/main.ts @@ -14,6 +14,9 @@ import * as SlickerModule from '@slickgrid-universal/vanilla-bundle'; import { App } from './app'; import { TranslateService } from 'translate.service'; +// load necessary Flatpickr Locale(s), but make sure it's imported AFTER the SlickerModule import +import 'flatpickr/dist/l10n/fr'; + class Main { app: App; constructor(private renderer: Renderer) { } diff --git a/packages/common/src/editors/__tests__/dateEditor.spec.ts b/packages/common/src/editors/__tests__/dateEditor.spec.ts index 8c59a5072..a75836dd0 100644 --- a/packages/common/src/editors/__tests__/dateEditor.spec.ts +++ b/packages/common/src/editors/__tests__/dateEditor.spec.ts @@ -434,10 +434,24 @@ describe('DateEditor', () => { }); describe('with different locale', () => { - it('should display text in new locale', (done) => { + it('should display a console warning when locale is not previously imported', (done) => { + const consoleSpy = jest.spyOn(global.console, 'warn').mockReturnValue(); + gridOptionMock.translater = translateService; - translateService.use('fr-CA'); // will be trimmed to "fr" + translateService.use('zz-yy'); // will be trimmed to 2 chars "zz" + editor = new DateEditor(editorArguments); + setTimeout(() => { + expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining(`[Slickgrid-Universal] Flatpickr missing locale imports (zz), will revert to English as the default locale.`)); + done(); + }); + }); + + it('should display text in new locale', async () => { + await (await import('flatpickr/dist/l10n/fr')).French; + gridOptionMock.translater = translateService; + + translateService.use('fr'); editor = new DateEditor(editorArguments); const spy = jest.spyOn(editor.flatInstance, 'open'); @@ -450,7 +464,6 @@ describe('DateEditor', () => { expect(selectonOptionElms.length).toBe(12); expect(selectonOptionElms[0].textContent).toBe('janvier'); expect(spy).toHaveBeenCalled(); - done(); }); }); }); diff --git a/packages/common/src/editors/dateEditor.ts b/packages/common/src/editors/dateEditor.ts index bbb296c05..4227167c7 100644 --- a/packages/common/src/editors/dateEditor.ts +++ b/packages/common/src/editors/dateEditor.ts @@ -119,10 +119,15 @@ export class DateEditor implements Editor { dateFormat: inputFormat, closeOnSelect: true, wrap: true, - locale: (currentLocale !== 'en') ? this.loadFlatpickrLocale(currentLocale) : 'en', + locale: currentLocale, onChange: () => this.handleOnDateChange(), - errorHandler: () => { - // do nothing, Flatpickr is a little too sensitive and will throw an error when provided date is lower than minDate so just disregard the error completely + errorHandler: (error: Error) => { + if (error.toString().includes('invalid locale')) { + console.warn(`[Slickgrid-Universal] Flatpickr missing locale imports (${currentLocale}), will revert to English as the default locale. + See Flatpickr Localization for more info, for example if we want to use French, then we can import it with: import 'flatpickr/dist/l10n/fr';`); + } + // for any other error do nothing + // Flatpickr is a little too sensitive and will throw an error when provided date is lower than minDate so just disregard the error completely } }; @@ -404,16 +409,4 @@ export class DateEditor implements Editor { } grid.onCompositeEditorChange.notify({ ...activeCell, item, grid, column, formValues: compositeEditorOptions.formValues, editors: compositeEditorOptions.editors }, new Slick.EventData()); } - - /** Load a different set of locales for Flatpickr to be localized */ - private loadFlatpickrLocale(language: string) { - let locales = 'en'; - - if (language !== 'en') { - // change locale if needed, Flatpickr reference: https://chmln.github.io/flatpickr/localization/ - const localeDefault: any = require(`flatpickr/dist/l10n/${language}.js`).default; - locales = (localeDefault && localeDefault[language]) ? localeDefault[language] : 'en'; - } - return locales; - } } diff --git a/packages/common/src/filters/__tests__/compoundDateFilter.spec.ts b/packages/common/src/filters/__tests__/compoundDateFilter.spec.ts index fe6063230..6e718d9d6 100644 --- a/packages/common/src/filters/__tests__/compoundDateFilter.spec.ts +++ b/packages/common/src/filters/__tests__/compoundDateFilter.spec.ts @@ -110,6 +110,7 @@ describe('CompoundDateFilter', () => { closeOnSelect: true, dateFormat: 'Y-m-d', defaultDate: '', + errorHandler: expect.toBeFunction(), locale: 'en', onChange: expect.anything(), wrap: true, @@ -207,8 +208,10 @@ describe('CompoundDateFilter', () => { expect(spyCallback).toHaveBeenCalledWith(expect.anything(), { columnDef: mockColumn, operator: '<=', searchTerms: ['2000-01-01T05:00:00.000Z'], shouldTriggerQuery: true }); }); - it('should work with different locale when locale is changed', () => { - translateService.use('fr-CA'); // will be trimmed to "fr" + it('should work with different locale when locale is changed', async () => { + await (await import('flatpickr/dist/l10n/fr')).French; + + translateService.use('fr'); filterArguments.searchTerms = ['2000-01-01T05:00:00.000Z']; mockColumn.filter!.operator = '<='; const spyCallback = jest.spyOn(filterArguments, 'callback'); @@ -233,10 +236,10 @@ describe('CompoundDateFilter', () => { expect(selectonOptionElms[0].textContent).toBe('janvier'); }); - it('should throw an error and use English locale when user tries to load an unsupported Flatpickr locale', () => { - translateService.use('zx'); + it('should display a console warning when locale is not previously imported', (done) => { const consoleSpy = jest.spyOn(global.console, 'warn').mockReturnValue(); + translateService.use('zz-yy'); // will be trimmed to 2 chars "zz" filterArguments.searchTerms = ['2000-01-01T05:00:00.000Z']; mockColumn.filter!.operator = '<='; @@ -250,9 +253,12 @@ describe('CompoundDateFilter', () => { filterInputElm.focus(); filterInputElm.dispatchEvent(new (window.window as any).KeyboardEvent('keyup', { keyCode: 97, bubbles: true, cancelable: true })); - expect(consoleSpy).toHaveBeenCalledWith(expect.toInclude('[Slickgrid-Universal - CompoundDate Filter] It seems that "zx" is not a locale supported by Flatpickr')); - expect(selectonOptionElms.length).toBe(12); - expect(selectonOptionElms[0].textContent).toBe('January'); + setTimeout(() => { + expect(selectonOptionElms.length).toBe(12); + expect(selectonOptionElms[0].textContent).toBe('January'); + expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining(`[Slickgrid-Universal] Flatpickr missing locale imports (zz), will revert to English as the default locale.`)); + done(); + }); }); it('should trigger a callback with the clear filter set when calling the "clear" method', () => { diff --git a/packages/common/src/filters/__tests__/dateRangeFilter.spec.ts b/packages/common/src/filters/__tests__/dateRangeFilter.spec.ts index 696fd9941..67783bea1 100644 --- a/packages/common/src/filters/__tests__/dateRangeFilter.spec.ts +++ b/packages/common/src/filters/__tests__/dateRangeFilter.spec.ts @@ -106,6 +106,7 @@ describe('DateRangeFilter', () => { dateFormat: 'Y-m-d', defaultDate: [], enableTime: true, + errorHandler: expect.toBeFunction(), locale: 'en', mode: 'range', onChange: expect.anything(), @@ -193,8 +194,10 @@ describe('DateRangeFilter', () => { expect(spyCallback).toHaveBeenCalledWith(expect.anything(), { columnDef: mockColumn, operator: 'RangeInclusive', searchTerms: ['2000-01-01', '2000-01-31'], shouldTriggerQuery: true }); }); - it('should work with different locale when locale is changed', () => { - translateService.use('fr-CA'); // will be trimmed to "fr" + it('should work with different locale when locale is changed', async () => { + await (await import('flatpickr/dist/l10n/fr')).French; + + translateService.use('fr'); filterArguments.searchTerms = ['2000-01-01T05:00:00.000Z', '2000-01-31T05:00:00.000Z']; mockColumn.filter!.operator = 'RangeInclusive'; const spyCallback = jest.spyOn(filterArguments, 'callback'); @@ -218,10 +221,10 @@ describe('DateRangeFilter', () => { expect(selectonOptionElms[0].textContent).toBe('janvier'); }); - it('should throw an error and use English locale when user tries to load an unsupported Flatpickr locale', () => { - translateService.use('zx'); + it('should display a console warning when locale is not previously imported', (done) => { const consoleSpy = jest.spyOn(global.console, 'warn').mockReturnValue(); + translateService.use('zz-yy'); // will be trimmed to 2 chars "zz" filterArguments.searchTerms = ['2000-01-01T05:00:00.000Z', '2000-01-31T05:00:00.000Z']; mockColumn.filter!.operator = 'RangeInclusive'; @@ -235,9 +238,12 @@ describe('DateRangeFilter', () => { filterInputElm.focus(); filterInputElm.dispatchEvent(new (window.window as any).KeyboardEvent('keyup', { keyCode: 97, bubbles: true, cancelable: true })); - expect(consoleSpy).toHaveBeenCalledWith(expect.toInclude('[Slickgrid-Universal - DateRange Filter] It seems that "zx" is not a locale supported by Flatpickr')); - expect(selectonOptionElms.length).toBe(12); - expect(selectonOptionElms[0].textContent).toBe('January'); + setTimeout(() => { + expect(selectonOptionElms.length).toBe(12); + expect(selectonOptionElms[0].textContent).toBe('January'); + expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining(`[Slickgrid-Universal] Flatpickr missing locale imports (zz), will revert to English as the default locale.`)); + done(); + }); }); it('should trigger a callback with the clear filter set when calling the "clear" method', () => { diff --git a/packages/common/src/filters/compoundDateFilter.ts b/packages/common/src/filters/compoundDateFilter.ts index b02101eb2..25e22dd52 100644 --- a/packages/common/src/filters/compoundDateFilter.ts +++ b/packages/common/src/filters/compoundDateFilter.ts @@ -191,7 +191,7 @@ export class CompoundDateFilter implements Filter { dateFormat: inputFormat, wrap: true, closeOnSelect: true, - locale: (currentLocale !== 'en') ? this.loadFlatpickrLocale(currentLocale) : 'en', + locale: currentLocale, onChange: (selectedDates: Date[] | Date, dateStr: string) => { this._currentValue = dateStr; this._currentDate = Array.isArray(selectedDates) && selectedDates[0] || undefined; @@ -203,6 +203,12 @@ export class CompoundDateFilter implements Filter { customEvent = new CustomEvent('keyup'); } this.onTriggerEvent(customEvent); + }, + errorHandler: (error) => { + if (error.toString().includes('invalid locale')) { + console.warn(`[Slickgrid-Universal] Flatpickr missing locale imports (${currentLocale}), will revert to English as the default locale. + See Flatpickr Localization for more info, for example if we want to use French, then we can import it with: import 'flatpickr/dist/l10n/fr';`); + } } }; @@ -298,24 +304,6 @@ export class CompoundDateFilter implements Filter { return $filterContainerElm; } - /** Load a different set of locales for Flatpickr to be localized */ - private loadFlatpickrLocale(language: string) { - let locales = 'en'; - - try { - if (language !== 'en') { - // change locale if needed, Flatpickr reference: https://chmln.github.io/flatpickr/localization/ - const localeDefault: any = require(`flatpickr/dist/l10n/${language}.js`).default; - locales = (localeDefault && localeDefault[language]) ? localeDefault[language] : 'en'; - } - } catch (e) { - console.warn(`[Slickgrid-Universal - CompoundDate Filter] It seems that "${language}" is not a locale supported by Flatpickr, we will use "en" instead. ` - + `To avoid seeing this message, you can specifically set "filter: { filterOptions: { locale: 'en' } }" in your column definition.`); - return 'en'; - } - return locales; - } - private onTriggerEvent(e: Event | undefined) { if (this._clearFilterTriggered) { this.callback(e, { columnDef: this.columnDef, clearFilterTriggered: this._clearFilterTriggered, shouldTriggerQuery: this._shouldTriggerQuery }); diff --git a/packages/common/src/filters/dateRangeFilter.ts b/packages/common/src/filters/dateRangeFilter.ts index 33a4aa8b3..4494b039c 100644 --- a/packages/common/src/filters/dateRangeFilter.ts +++ b/packages/common/src/filters/dateRangeFilter.ts @@ -200,7 +200,7 @@ export class DateRangeFilter implements Filter { mode: 'range', wrap: true, closeOnSelect: true, - locale: (currentLocale !== 'en') ? this.loadFlatpickrLocale(currentLocale) : 'en', + locale: currentLocale, onChange: (selectedDates: Date[] | Date, _dateStr: string, _instance: any) => { if (Array.isArray(selectedDates)) { this._currentDates = selectedDates; @@ -213,6 +213,12 @@ export class DateRangeFilter implements Filter { // since backend request are only executed after user start typing, changing the time should be treated the same way const newEvent = pickerOptions.enableTime ? new CustomEvent('keyup') : undefined; this.onTriggerEvent(newEvent); + }, + errorHandler: (error) => { + if (error.toString().includes('invalid locale')) { + console.warn(`[Slickgrid-Universal] Flatpickr missing locale imports (${currentLocale}), will revert to English as the default locale. + See Flatpickr Localization for more info, for example if we want to use French, then we can import it with: import 'flatpickr/dist/l10n/fr';`); + } } }; @@ -269,24 +275,6 @@ export class DateRangeFilter implements Filter { return this.$filterInputElm; } - /** Load a different set of locales for Flatpickr to be localized */ - private loadFlatpickrLocale(language: string) { - let locales = 'en'; - - try { - if (language !== 'en') { - // change locale if needed, Flatpickr reference: https://chmln.github.io/flatpickr/localization/ - const localeDefault: any = require(`flatpickr/dist/l10n/${language}.js`).default; - locales = (localeDefault && localeDefault[language]) ? localeDefault[language] : 'en'; - } - } catch (e) { - console.warn(`[Slickgrid-Universal - DateRange Filter] It seems that "${language}" is not a locale supported by Flatpickr, we will use "en" instead. ` - + `To avoid seeing this message, you can specifically set "filter: { filterOptions: { locale: 'en' } }" in your column definition.`); - return 'en'; - } - return locales; - } - private onTriggerEvent(e: Event | undefined) { if (this._clearFilterTriggered) { this.callback(e, { columnDef: this.columnDef, clearFilterTriggered: this._clearFilterTriggered, shouldTriggerQuery: this._shouldTriggerQuery }); diff --git a/packages/vanilla-bundle/src/components/slick-vanilla-grid-bundle.ts b/packages/vanilla-bundle/src/components/slick-vanilla-grid-bundle.ts index c7586e4e8..3c06a66e8 100644 --- a/packages/vanilla-bundle/src/components/slick-vanilla-grid-bundle.ts +++ b/packages/vanilla-bundle/src/components/slick-vanilla-grid-bundle.ts @@ -1,3 +1,4 @@ +import 'flatpickr/dist/l10n/fr'; import 'slickgrid/lib/jquery.event.drag-2.3.0'; import 'slickgrid/lib/jquery.mousewheel'; import 'slickgrid/slick.core'; diff --git a/test/cypress/screenshots/README.md b/test/cypress/screenshots/README.md deleted file mode 100644 index d9236514a..000000000 --- a/test/cypress/screenshots/README.md +++ /dev/null @@ -1 +0,0 @@ -screenshots of Cypress errors