From e782707a7a13dc7f24701dc955e6c5a156774ce8 Mon Sep 17 00:00:00 2001 From: ghiscoding Date: Mon, 4 Jan 2021 23:28:03 -0500 Subject: [PATCH 1/3] fix(build): import Flatpickr Locale on demand via regular imports - we shouldn't use require(locale) because they all end up being part of the final bundle, it's better to let the user import whichever Flatpickr Locale he wants to use and that will end up being a much smaller bundle with only the locale we really need --- .../webpack-demo-vanilla-bundle/src/main.ts | 3 +++ .../src/editors/__tests__/dateEditor.spec.ts | 19 +++++++++++--- packages/common/src/editors/dateEditor.ts | 21 +++++---------- .../__tests__/compoundDateFilter.spec.ts | 20 +++++++++----- .../filters/__tests__/dateRangeFilter.spec.ts | 20 +++++++++----- .../common/src/filters/compoundDateFilter.ts | 26 +++++-------------- .../common/src/filters/dateRangeFilter.ts | 26 +++++-------------- .../components/slick-vanilla-grid-bundle.ts | 1 + test/cypress/screenshots/README.md | 1 - 9 files changed, 66 insertions(+), 71 deletions(-) delete mode 100644 test/cypress/screenshots/README.md 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..375565b15 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 it 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..4b4505cf1 100644 --- a/packages/common/src/editors/dateEditor.ts +++ b/packages/common/src/editors/dateEditor.ts @@ -119,10 +119,13 @@ 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';`); + } } }; @@ -404,16 +407,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..c267b2493 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 it 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..00c0e4c37 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 it 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 From a2a1c73268577565e602d7d35acba6d18a0d6ac4 Mon Sep 17 00:00:00 2001 From: ghiscoding Date: Mon, 4 Jan 2021 23:38:00 -0500 Subject: [PATCH 2/3] refactor: add comment for any other Flatpickr error thrown --- packages/common/src/editors/dateEditor.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/packages/common/src/editors/dateEditor.ts b/packages/common/src/editors/dateEditor.ts index 4b4505cf1..4227167c7 100644 --- a/packages/common/src/editors/dateEditor.ts +++ b/packages/common/src/editors/dateEditor.ts @@ -126,6 +126,8 @@ export class DateEditor implements Editor { 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 } }; From 193e1e4e2fbbbba8f006bc8cd53a7da8552aa540 Mon Sep 17 00:00:00 2001 From: ghiscoding Date: Tue, 5 Jan 2021 08:07:20 -0500 Subject: [PATCH 3/3] tests: fix typo --- packages/common/src/editors/__tests__/dateEditor.spec.ts | 2 +- .../common/src/filters/__tests__/compoundDateFilter.spec.ts | 2 +- packages/common/src/filters/__tests__/dateRangeFilter.spec.ts | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/common/src/editors/__tests__/dateEditor.spec.ts b/packages/common/src/editors/__tests__/dateEditor.spec.ts index 375565b15..a75836dd0 100644 --- a/packages/common/src/editors/__tests__/dateEditor.spec.ts +++ b/packages/common/src/editors/__tests__/dateEditor.spec.ts @@ -434,7 +434,7 @@ describe('DateEditor', () => { }); describe('with different locale', () => { - it('should display a console warning when locale it not previously imported', (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; diff --git a/packages/common/src/filters/__tests__/compoundDateFilter.spec.ts b/packages/common/src/filters/__tests__/compoundDateFilter.spec.ts index c267b2493..6e718d9d6 100644 --- a/packages/common/src/filters/__tests__/compoundDateFilter.spec.ts +++ b/packages/common/src/filters/__tests__/compoundDateFilter.spec.ts @@ -236,7 +236,7 @@ describe('CompoundDateFilter', () => { expect(selectonOptionElms[0].textContent).toBe('janvier'); }); - it('should display a console warning when locale it not previously imported', (done) => { + 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" diff --git a/packages/common/src/filters/__tests__/dateRangeFilter.spec.ts b/packages/common/src/filters/__tests__/dateRangeFilter.spec.ts index 00c0e4c37..67783bea1 100644 --- a/packages/common/src/filters/__tests__/dateRangeFilter.spec.ts +++ b/packages/common/src/filters/__tests__/dateRangeFilter.spec.ts @@ -221,7 +221,7 @@ describe('DateRangeFilter', () => { expect(selectonOptionElms[0].textContent).toBe('janvier'); }); - it('should display a console warning when locale it not previously imported', (done) => { + 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"