Skip to content

Commit 109f155

Browse files
committed
feat(common)!: migrate from Flatpickr to Vanilla-Calendar
1 parent 8054ca7 commit 109f155

19 files changed

+87
-88
lines changed

angular.json

-2
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@
2121
"allowedCommonJsDependencies": [
2222
"@fnando/sparkline",
2323
"fetch-jsonp",
24-
"flatpickr",
2524
"isomorphic-dompurify",
2625
"moment-mini",
2726
"stream"
@@ -52,7 +51,6 @@
5251
],
5352
"styles": [
5453
"node_modules/bootstrap/dist/css/bootstrap.min.css",
55-
"node_modules/flatpickr/dist/flatpickr.min.css",
5654
"node_modules/font-awesome/css/font-awesome.min.css",
5755
"node_modules/@ng-select/ng-select/themes/default.theme.css",
5856
"src/app/slickgrid-custom-variables.scss",

package.json

+2-2
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,8 @@
6060
"dequal": "^2.0.3",
6161
"isomorphic-dompurify": "^2.7.0",
6262
"rxjs": "^7.8.1",
63-
"sortablejs": "^1.15.2"
63+
"sortablejs": "^1.15.2",
64+
"vanilla-calendar-picker": "^2.10.2"
6465
},
6566
"devDependencies": {
6667
"@4tw/cypress-drag-drop": "^2.2.5",
@@ -94,7 +95,6 @@
9495
"@slickgrid-universal/odata": "~4.7.0",
9596
"@slickgrid-universal/text-export": "~4.7.0",
9697
"@types/dompurify": "^3.0.5",
97-
"@types/flatpickr": "^3.1.2",
9898
"@types/fnando__sparkline": "^0.3.7",
9999
"@types/jest": "^29.5.12",
100100
"@types/node": "^20.12.7",

src/app/app.module.ts

-3
Original file line numberDiff line numberDiff line change
@@ -61,9 +61,6 @@ import { SwtCommonGridComponent } from './examples/swt-common-grid.component';
6161
import { AngularSlickgridModule } from './modules/angular-slickgrid/modules/angular-slickgrid.module';
6262
// import { AngularSlickgridModule } from 'angular-slickgrid';
6363

64-
// load necessary Flatpickr Locale(s), but make sure it's imported AFTER the SlickgridModule import
65-
import 'flatpickr/dist/l10n/fr';
66-
6764
// AoT requires an exported function for factories
6865
export function createTranslateLoader(http: HttpClient) {
6966
return new TranslateHttpLoader(http, './assets/i18n/', '.json');

src/app/examples/grid-clientside.component.ts

+3-3
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,12 @@ import {
88
Column,
99
FieldType,
1010
Filters,
11-
FlatpickrOption,
1211
Formatters,
1312
GridOption,
1413
GridStateChange,
1514
Metrics,
1615
OperatorType,
16+
VanillaCalendarOption,
1717
} from './../modules/angular-slickgrid';
1818
import { CustomInputFilter } from './custom-inputFilter';
1919

@@ -135,9 +135,9 @@ export class GridClientSideComponent implements OnInit {
135135
type: FieldType.dateUtc, exportWithFormatter: true, outputType: FieldType.dateTimeIsoAmPm, filterable: true,
136136
filter: {
137137
model: Filters.compoundDate,
138-
// override any of the Flatpickr options through "filterOptions"
138+
// override any of the calendar picker options through "filterOptions"
139139
// please note that there's no TSlint on this property since it's generic for any filter, so make sure you entered the correct filter option(s)
140-
filterOptions: { minDate: 'today' } as FlatpickrOption
140+
filterOptions: { range: { min: 'today' } } as VanillaCalendarOption
141141
}
142142
},
143143
{

src/app/examples/grid-composite-editor.component.ts

+10-9
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@ import {
1313
Editors,
1414
FieldType,
1515
Filters,
16-
FlatpickrOption,
1716
formatNumber,
1817
Formatter,
1918
Formatters,
@@ -24,6 +23,7 @@ import {
2423
SlickGlobalEditorLock,
2524
SlickGrid,
2625
SortComparers,
26+
VanillaCalendarOption,
2727
} from '../modules/angular-slickgrid';
2828

2929
const NB_ITEMS = 500;
@@ -249,16 +249,17 @@ export class GridCompositeEditorComponent implements OnDestroy, OnInit {
249249
editor: {
250250
model: Editors.date,
251251
editorOptions: {
252-
minDate: 'today',
252+
range: { min: 'today' },
253253

254254
// if we want to preload the date picker with a different date,
255-
// we could toggle the `closeOnSelect: false`, set the date in the picker and re-toggle `closeOnSelect: true`
256-
// closeOnSelect: false,
257-
// onOpen: (selectedDates: Date[] | Date, dateStr: string, instance: FlatpickrInstance) => {
258-
// instance.setDate('2021-06-04', true);
259-
// instance.set('closeOnSelect', true);
260-
// },
261-
} as FlatpickrOption,
255+
// we could do it by assigning settings.seleted.dates
256+
// NOTE: vanilla-calendar doesn't automatically focus the picker to the year/month and you need to do it yourself
257+
// selected: {
258+
// dates: ['2021-06-04'],
259+
// month: 6 - 1, // Note: JS Date month (only) is zero index based, so June is 6-1 => 5
260+
// year: 2021
261+
// }
262+
} as VanillaCalendarOption,
262263
massUpdate: true,
263264
validator: (value, args) => {
264265
const dataContext = args && args.item;

src/app/examples/grid-custom-tooltip.component.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -187,7 +187,7 @@ export class GridCustomTooltipComponent implements OnInit {
187187
},
188188
{
189189
id: 'finish', name: 'Finish', field: 'finish', sortable: true,
190-
editor: { model: Editors.date, editorOptions: { minDate: 'today' }, },
190+
editor: { model: Editors.date, editorOptions: { range: { min: 'today' } }, },
191191
// formatter: Formatters.dateIso,
192192
type: FieldType.date, outputType: FieldType.dateIso,
193193
formatter: Formatters.dateIso,

src/app/examples/grid-editor.component.ts

+16-12
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
import { Component, OnInit } from '@angular/core';
22
import { HttpClient } from '@angular/common/http';
33
import { TranslateService } from '@ngx-translate/core';
4-
import { Instance as FlatpickrInstance } from 'flatpickr/dist/types/instance';
54
import fetchJsonp from 'fetch-jsonp';
65

76
import {
@@ -13,7 +12,6 @@ import {
1312
EditorValidator,
1413
FieldType,
1514
Filters,
16-
FlatpickrOption,
1715
Formatter,
1816
Formatters,
1917
GridOption,
@@ -22,6 +20,7 @@ import {
2220
OperatorType,
2321
SortComparers,
2422
SlickGlobalEditorLock,
23+
VanillaCalendarOption,
2524
} from './../modules/angular-slickgrid';
2625
import { CustomInputEditor } from './custom-inputEditor';
2726
import { CustomInputFilter } from './custom-inputFilter';
@@ -304,19 +303,20 @@ export class GridEditorComponent implements OnInit {
304303
saveOutputType: FieldType.dateUtc, // save output date formattype: FieldType.date,
305304
editor: {
306305
model: Editors.date,
307-
// override any of the Flatpickr options through "editorOptions"
306+
// override any of the calendar picker options through "editorOptions"
308307
// please note that there's no TSlint on this property since it's generic for any filter, so make sure you entered the correct filter option(s)
309308
editorOptions: {
310-
minDate: 'today',
309+
range: { min: 'today' },
311310

312311
// if we want to preload the date picker with a different date,
313-
// we could toggle the `closeOnSelect: false`, set the date in the picker and re-toggle `closeOnSelect: true`
314-
// closeOnSelect: false,
315-
// onOpen: (selectedDates: Date[] | Date, dateStr: string, instance: FlatpickrInstance) => {
316-
// instance.setDate('2021-12-31', true);
317-
// instance.set('closeOnSelect', true);
318-
// },
319-
} as FlatpickrOption
312+
// we could do it by assigning settings.seleted.dates
313+
// NOTE: vanilla-calendar doesn't automatically focus the picker to the year/month and you need to do it yourself
314+
// selected: {
315+
// dates: ['2021-06-04'],
316+
// month: 6 - 1, // Note: JS Date month (only) is zero index based, so June is 6-1 => 5
317+
// year: 2021
318+
// }
319+
} as VanillaCalendarOption
320320
},
321321
}, {
322322
id: 'cityOfOrigin', name: 'City of Origin', field: 'cityOfOrigin',
@@ -562,7 +562,7 @@ export class GridEditorComponent implements OnInit {
562562
// mock a dataset
563563
const tempDataset = [];
564564
for (let i = startingIndex; i < (startingIndex + itemCount); i++) {
565-
const randomYear = 2000 + Math.floor(Math.random() * 10);
565+
const randomYear = 2000 + this.randomBetween(4, 15);
566566
const randomFinishYear = (new Date().getFullYear() - 3) + Math.floor(Math.random() * 10); // use only years not lower than 3 years ago
567567
const randomMonth = Math.floor(Math.random() * 11);
568568
const randomDay = Math.floor((Math.random() * 29));
@@ -587,6 +587,10 @@ export class GridEditorComponent implements OnInit {
587587
return tempDataset;
588588
}
589589

590+
randomBetween(min: number, max: number): number {
591+
return Math.floor(Math.random() * (max - min + 1) + min);
592+
}
593+
590594
onCellChanged(e: Event, args: any) {
591595
this.updatedObject = args.item;
592596
}

src/app/examples/grid-range.component.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ export class GridRangeComponent implements OnInit, OnDestroy {
5555
<li>by default the range is inclusive which would be the same as defining the filter options to "operator: 'RangeInclusive'" or "operator: OperatoryType.rangeInclusive"</li>
5656
<li>you can also set the inverse (exclusive) by defining the filter options to "operator: 'RangeExclusive'" or "operator: OperatoryType.rangeExclusive"</li>
5757
</ul>
58-
<li>Date Range with Flatpickr Date Picker, they will also use the locale, choose a start date then drag or click on the end date</li>
58+
<li>Date Range with Vanilla Calendar Date Picker, they will also use the locale, choose a start date then drag or click on the end date</li>
5959
</ul>
6060
`;
6161
private subscriptions: Subscription[] = [];

src/app/examples/grid-resize-by-content.component.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import { Component, OnInit, ViewEncapsulation } from '@angular/core';
22
import { HttpClient } from '@angular/common/http';
33
import { ExcelExportService } from '@slickgrid-universal/excel-export';
44

5-
import { AngularGridInstance, Column, GridOption, Filters, Formatter, LongTextEditorOption, FieldType, Editors, Formatters, AutocompleterOption, EditCommand, formatNumber, SortComparers, SlickGrid, SlickGlobalEditorLock } from '../modules/angular-slickgrid';
5+
import { AngularGridInstance, Column, GridOption, Filters, Formatter, LongTextEditorOption, FieldType, Editors, Formatters, AutocompleterOption, EditCommand, formatNumber, SortComparers, SlickGrid, SlickGlobalEditorLock, VanillaCalendarOption } from '../modules/angular-slickgrid';
66

77
const URL_COUNTRIES_COLLECTION = 'assets/data/countries.json';
88

@@ -181,7 +181,7 @@ export class GridResizeByContentComponent implements OnInit {
181181
exportCustomFormatter: Formatters.dateUs,
182182
editor: {
183183
model: Editors.date,
184-
editorOptions: { minDate: 'today' },
184+
editorOptions: { range: { min: 'today' } } as VanillaCalendarOption,
185185
validator: (value, args) => {
186186
const dataContext = args && args.item;
187187
if (dataContext && (dataContext.completed && !value)) {

src/app/modules/angular-slickgrid/components/__tests__/angular-slickgrid.component.spec.ts

-2
Original file line numberDiff line numberDiff line change
@@ -57,8 +57,6 @@ import { GridOption } from '../../models';
5757
import { MockSlickEvent, MockSlickEventHandler } from '../../../../../../test/mockSlickEvent';
5858
import { RxJsResourceStub } from '../../../../../../test/rxjsResourceStub';
5959

60-
jest.mock('flatpickr', () => { });
61-
6260
const mockSlickRowDetailView = {
6361
create: jest.fn(),
6462
init: jest.fn(),

src/app/modules/angular-slickgrid/services/__tests__/angularUtilService.spec.ts

-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ import { AngularUtilService } from '..';
44

55
const DOM_ELEMENT_ID = 'row-detail123';
66
const DOM_PARENT_ID = 'parent-detail';
7-
jest.mock('flatpickr', () => { });
87

98
const viewContainerRefStub = {
109
createComponent: jest.fn(),

test/cypress/e2e/example03.cy.ts

+11-9
Original file line numberDiff line numberDiff line change
@@ -67,10 +67,11 @@ describe('Example 3 - Grid with Editors', () => {
6767

6868
// change Finish date
6969
cy.get(`[style="top: ${GRID_ROW_HEIGHT * 2}px;"] > .slick-cell:nth(6)`).click();
70-
cy.get('.flatpickr-monthDropdown-months:visible')
71-
.select('January', { force: true });
72-
cy.get('.numInput.cur-year:visible').type('2009');
73-
cy.get('.flatpickr-day:visible:nth(25)').click('bottom', { force: true });
70+
cy.get('.vanilla-calendar-month:visible').click();
71+
cy.get('.vanilla-calendar-months__month').contains('Jan').click();
72+
cy.get('.vanilla-calendar-year').click();
73+
cy.get('.vanilla-calendar-years__year').contains('2009').click();
74+
cy.get('.vanilla-calendar-day__btn').contains('22').click();
7475
cy.get(`[style="top: ${GRID_ROW_HEIGHT * 2}px;"] > .slick-cell:nth(6)`).should('contain', '2009-01-22');
7576

7677
// change City of Origin
@@ -140,10 +141,11 @@ describe('Example 3 - Grid with Editors', () => {
140141

141142
// change Finish date
142143
cy.get(`[style="top: ${GRID_ROW_HEIGHT * 0}px;"] > .slick-cell:nth(6)`).click();
143-
cy.get('.flatpickr-monthDropdown-months:visible')
144-
.select('January', { force: true });
145-
cy.get('.numInput.cur-year:visible').type('2009');
146-
cy.get('.flatpickr-day:visible:nth(25)').click('bottom', { force: true });
144+
cy.get('.vanilla-calendar-month:visible').click();
145+
cy.get('.vanilla-calendar-months__month').contains('Jan').click();
146+
cy.get('.vanilla-calendar-year').click();
147+
cy.get('.vanilla-calendar-years__year').contains('2009').click();
148+
cy.get('.vanilla-calendar-day__btn').contains('22').click();
147149
cy.get(`[style="top: ${GRID_ROW_HEIGHT * 0}px;"] > .slick-cell:nth(6)`).should('contain', '2009-01-22');
148150

149151
// change Effort Driven
@@ -217,7 +219,7 @@ describe('Example 3 - Grid with Editors', () => {
217219

218220
// change Finish date
219221
cy.get(`[style="top: ${GRID_ROW_HEIGHT * 0}px;"] > .slick-cell:nth(6)`).click();
220-
cy.get('.flatpickr-day:visible:nth(24)').click('bottom', { force: true });
222+
cy.get('.vanilla-calendar-day__btn').contains('21').click();
221223
cy.get(`[style="top: ${GRID_ROW_HEIGHT * 0}px;"] > .slick-cell:nth(6)`).should('contain', '2009-01-21');
222224

223225
// // change Effort Driven

test/cypress/e2e/example04.cy.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ describe('Example 4 - Client Side Sort/Filter Grid', () => {
99

1010
describe('Load Grid with Presets', () => {
1111
const presetDurationValues = [98, 10];
12-
const presetUsDateShort = '04/20/25';
12+
const presetUsDateShort = '4/20/25';
1313

1414
it('should have "Duration" fields within the inclusive range of the preset filters and be displayed in the Filter itself', () => {
1515
cy.get('.ms-filter.search-filter.filter-duration.filled')

test/cypress/e2e/example06.cy.ts

+3-9
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,6 @@ describe('Example 6 - GraphQL Grid', { retries: 0 }, () => {
2121
it('should have English Text inside some of the Filters', () => {
2222
cy.get('.search-filter.filter-gender .ms-choice > span')
2323
.contains('Male');
24-
25-
cy.get('.flatpickr-input')
26-
.should('contain.value', 'to'); // date range will contains (y to z) or in French (y au z)
2724
});
2825

2926
it('should have GraphQL query with defined Grid Presets', () => {
@@ -44,7 +41,7 @@ describe('Example 6 - GraphQL Grid', { retries: 0 }, () => {
4441
cy.get('.search-filter.filter-finish')
4542
.find('input')
4643
.invoke('val')
47-
.then(text => expect(text).to.eq(`${presetLowestDay} to ${presetHighestDay}`));
44+
.then(text => expect(text).to.eq(`${presetLowestDay} ${presetHighestDay}`));
4845

4946
cy.get('[data-test=alert-graphql-query]').should('exist');
5047
cy.get('[data-test=alert-graphql-query]').should('contain', 'GraphQL Query');
@@ -326,7 +323,7 @@ describe('Example 6 - GraphQL Grid', { retries: 0 }, () => {
326323
cy.get('.search-filter.filter-finish')
327324
.find('input')
328325
.invoke('val')
329-
.then(text => expect(text).to.eq(`${presetLowestDay} to ${presetHighestDay}`));
326+
.then(text => expect(text).to.eq(`${presetLowestDay} ${presetHighestDay}`));
330327

331328
// wait for the query to finish
332329
cy.get('[data-test=status]').should('contain', 'finished');
@@ -644,7 +641,7 @@ describe('Example 6 - GraphQL Grid', { retries: 0 }, () => {
644641
cy.get('.search-filter.filter-finish')
645642
.find('input')
646643
.invoke('val')
647-
.then(text => expect(text).to.eq(`${presetLowestDay} au ${presetHighestDay}`));
644+
.then(text => expect(text).to.eq(`${presetLowestDay} ${presetHighestDay}`));
648645

649646
// wait for the query to finish
650647
cy.get('[data-test=status]').should('contain', 'finished');
@@ -670,9 +667,6 @@ describe('Example 6 - GraphQL Grid', { retries: 0 }, () => {
670667

671668
cy.get('.search-filter.filter-gender .ms-choice > span')
672669
.contains('Masculin');
673-
674-
cy.get('.flatpickr-input')
675-
.should('contain.value', 'au'); // date range will contains (y to z) or in French (y au z)
676670
});
677671

678672
it('should switch locale to English', () => {

test/cypress/e2e/example25.cy.ts

+10-6
Original file line numberDiff line numberDiff line change
@@ -112,14 +112,18 @@ describe('Example 25 - Range Filters', () => {
112112
});
113113

114114
it('should change the "Finish" date in the picker and expect all rows to be within new dates range', () => {
115-
cy.get('.flatpickr.search-filter.filter-finish')
115+
cy.get('.date-picker.search-filter.filter-finish')
116116
.click();
117117

118-
cy.get('.flatpickr-day.inRange')
118+
cy.get('.vanilla-calendar-day_selected-first')
119+
.should('exist');
120+
121+
cy.get('.vanilla-calendar-day_selected-intermediate')
119122
.should('have.length.gte', 2);
120123

121-
// cy.get('.flatpickr-day.selected.endRange')
122-
// .should('contain', moment().add(25, 'days').day() - 1);
124+
cy.get('.vanilla-calendar-day_selected-last')
125+
.should('exist');
126+
// .should('contain', moment().add(28, 'days').day() - 1);
123127
});
124128

125129
it('should change the "Duration" input filter and expect all rows to be within new range', () => {
@@ -201,7 +205,7 @@ describe('Example 25 - Range Filters', () => {
201205
cy.get('.search-filter.filter-finish')
202206
.find('input')
203207
.invoke('val')
204-
.then(text => expect(text).to.eq(`${dynamicLowestDay} to ${dynamicHighestDay}`));
208+
.then(text => expect(text).to.eq(`${dynamicLowestDay} ${dynamicHighestDay}`));
205209

206210
cy.get('#grid25')
207211
.find('.slick-row')
@@ -222,7 +226,7 @@ describe('Example 25 - Range Filters', () => {
222226
cy.get('.search-filter.filter-finish')
223227
.find('input')
224228
.invoke('val')
225-
.then(text => expect(text).to.eq(`${currentYear}-01-01 to ${currentYear}-12-31`));
229+
.then(text => expect(text).to.eq(`${currentYear}-01-01 ${currentYear}-12-31`));
226230

227231
cy.get('.ms-parent.search-filter.filter-completed > button > span')
228232
.should('contain', 'True');

0 commit comments

Comments
 (0)