Skip to content

Commit

Permalink
fix(datepicker): performance issues when huge min/max dates (#3357)
Browse files Browse the repository at this point in the history
Fixes #3338
  • Loading branch information
maxokorokov committed Oct 4, 2019
1 parent 22a1cb6 commit 22b4ca8
Show file tree
Hide file tree
Showing 3 changed files with 18 additions and 10 deletions.
10 changes: 6 additions & 4 deletions src/datepicker/datepicker-service.spec.ts
Expand Up @@ -552,28 +552,30 @@ describe('ngb-datepicker-service', () => {
expect(model.selectBoxes.years).toEqual(range(2010, 2030));
});

it(`should generate [min, +10] 'years' when max date is missing`, () => {
it(`should generate [min/-500, +10] 'years' when max date is missing`, () => {
service.minDate = new NgbDate(2010, 1, 1);
service.open(new NgbDate(2011, 1, 1));
expect(model.selectBoxes.years).toEqual(range(2010, 2021));

service.minDate = new NgbDate(2015, 1, 1);
expect(model.selectBoxes.years).toEqual(range(2015, 2025));

// -500
service.minDate = new NgbDate(1000, 1, 1);
expect(model.selectBoxes.years).toEqual(range(1000, 2025));
expect(model.selectBoxes.years).toEqual(range(1515, 2025));
});

it(`should generate [min, +10] 'years' when min date is missing`, () => {
it(`should generate [-10, +500/max] 'years' when min date is missing`, () => {
service.maxDate = new NgbDate(2010, 1, 1);
service.open(new NgbDate(2009, 1, 1));
expect(model.selectBoxes.years).toEqual(range(1999, 2010));

service.maxDate = new NgbDate(2005, 1, 1);
expect(model.selectBoxes.years).toEqual(range(1995, 2005));

// +500
service.maxDate = new NgbDate(3000, 1, 1);
expect(model.selectBoxes.years).toEqual(range(1995, 3000));
expect(model.selectBoxes.years).toEqual(range(1995, 2505));
});

it(`should generate 'months' when min/max dates are missing`, () => {
Expand Down
6 changes: 3 additions & 3 deletions src/datepicker/datepicker-tools.spec.ts
Expand Up @@ -566,17 +566,17 @@ describe(`datepicker-tools`, () => {
it(`should generate years correctly`, () => {
// both 'min' and 'max' are set
test(new NgbDate(2017, 1, 1), new NgbDate(2018, 1, 1), new NgbDate(2019, 1, 1), range(2017, 2019));
test(new NgbDate(2000, 1, 1), new NgbDate(2018, 1, 1), new NgbDate(3000, 1, 1), range(2000, 3000));
test(new NgbDate(1000, 1, 1), new NgbDate(2018, 1, 1), new NgbDate(3000, 1, 1), range(1518, 2518));
test(new NgbDate(2018, 1, 1), new NgbDate(2018, 1, 1), new NgbDate(2018, 1, 1), [2018]);

// 'min' is not set
test(null, new NgbDate(2018, 1, 1), new NgbDate(2019, 1, 1), range(2008, 2019));
test(null, new NgbDate(2018, 1, 1), new NgbDate(3000, 1, 1), range(2008, 3000));
test(null, new NgbDate(2018, 1, 1), new NgbDate(3000, 1, 1), range(2008, 2518));
test(null, new NgbDate(2018, 1, 1), new NgbDate(2018, 1, 1), range(2008, 2018));

// 'max' is not set
test(new NgbDate(2017, 1, 1), new NgbDate(2018, 1, 1), null, range(2017, 2028));
test(new NgbDate(2000, 1, 1), new NgbDate(2018, 1, 1), null, range(2000, 2028));
test(new NgbDate(1000, 1, 1), new NgbDate(2018, 1, 1), null, range(1518, 2028));
test(new NgbDate(2018, 1, 1), new NgbDate(2018, 1, 1), null, range(2018, 2028));

// both are not set
Expand Down
12 changes: 9 additions & 3 deletions src/datepicker/datepicker-tools.ts
Expand Up @@ -71,10 +71,16 @@ export function generateSelectBoxYears(date: NgbDate, minDate: NgbDate, maxDate:
return [];
}

const start = minDate && minDate.year || date.year - 10;
const end = maxDate && maxDate.year || date.year + 10;
const start = minDate ? Math.max(minDate.year, date.year - 500) : date.year - 10;
const end = maxDate ? Math.min(maxDate.year, date.year + 500) : date.year + 10;

return Array.from({length: end - start + 1}, (e, i) => start + i);
const length = end - start + 1;
const numbers = Array(length);
for (let i = 0; i < length; i++) {
numbers[i] = start + i;
}

return numbers;
}

export function nextMonthDisabled(calendar: NgbCalendar, date: NgbDate, maxDate: NgbDate) {
Expand Down

0 comments on commit 22b4ca8

Please sign in to comment.