Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixed min and max for KolInputDate #6892

Merged
Merged
Show file tree
Hide file tree
Changes from 27 commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
ac07ea4
max no longer use always default
AlexanderSchmidtCE Sep 27, 2024
a38ef70
Added Sample for MinMax
AlexanderSchmidtCE Sep 27, 2024
84343c3
added e2e Tests
AlexanderSchmidtCE Sep 27, 2024
26229e0
updated unitTest
AlexanderSchmidtCE Sep 27, 2024
c639d3c
Merge branch 'develop' into 6849-_min-und-_max-werden-beim-inputdate-…
AlexanderSchmidtCE Sep 27, 2024
5b52a18
updated unitTest
AlexanderSchmidtCE Sep 27, 2024
d621b82
Merge remote-tracking branch 'origin/6849-_min-und-_max-werden-beim-i…
AlexanderSchmidtCE Sep 27, 2024
83a03ea
updated unitTest
AlexanderSchmidtCE Sep 27, 2024
75011fc
Merge branch 'feature/revert-deps-update' into 6849-_min-und-_max-wer…
laske185 Sep 30, 2024
c9ffc4d
Merge branch 'develop' into 6849-_min-und-_max-werden-beim-inputdate-…
AlexanderSchmidtCE Oct 7, 2024
f2bee0a
lint fix
AlexanderSchmidtCE Oct 8, 2024
94e09a7
Merge branch 'develop' into 6849-_min-und-_max-werden-beim-inputdate-…
AlexanderSchmidtCE Oct 8, 2024
b95e1e2
lint fix
AlexanderSchmidtCE Oct 8, 2024
803f7b8
Merge remote-tracking branch 'origin/6849-_min-und-_max-werden-beim-i…
AlexanderSchmidtCE Oct 8, 2024
3bfda36
lint fix
AlexanderSchmidtCE Oct 8, 2024
be6b095
Fixed getWeekNumberOfDate()
AlexanderSchmidtCE Oct 8, 2024
1618059
lint fix
AlexanderSchmidtCE Oct 8, 2024
7356931
Update all snapshots$
AlexanderSchmidtCE Oct 8, 2024
3a5d060
added unit test for getWeekNumberOfDate
AlexanderSchmidtCE Oct 9, 2024
e4f8114
added e2e test for InputDate
AlexanderSchmidtCE Oct 9, 2024
bebabc6
lint fixes
AlexanderSchmidtCE Oct 9, 2024
1e12ae4
Merge branch 'develop' into 6849-_min-und-_max-werden-beim-inputdate-…
AlexanderSchmidtCE Oct 9, 2024
183fe9e
removed samples e2e test for inputDate
AlexanderSchmidtCE Oct 9, 2024
a4992d6
update Date to UTC
AlexanderSchmidtCE Oct 9, 2024
d1b3d55
Merge branch 'develop' into 6849-_min-und-_max-werden-beim-inputdate-…
AlexanderSchmidtCE Oct 9, 2024
53fc0d9
Update all snapshots$
AlexanderSchmidtCE Oct 9, 2024
c1cdb00
Merge branch 'develop' into 6849-_min-und-_max-werden-beim-inputdate-…
AlexanderSchmidtCE Oct 11, 2024
3ea2551
Added Tests for Year Change
AlexanderSchmidtCE Oct 11, 2024
a853315
e2e update
AlexanderSchmidtCE Oct 11, 2024
298a5b9
Merge branch 'develop' into 6849-_min-und-_max-werden-beim-inputdate-…
AlexanderSchmidtCE Oct 11, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 8 additions & 2 deletions packages/components/src/components/input-date/controller.spec.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { InputDateController } from './controller';
import { describe, it, expect } from '@jest/globals';

const TEST_DATE = new Date('2020-03-03T03:02:01.099');

Expand Down Expand Up @@ -41,9 +42,14 @@ describe('InputDateController', () => {
expect(InputDateController.tryParseToString(TEST_DATE, 'time', 10)).toBe('03:02:01');
});

it('throws an Error for type week', () => {
expect(() => InputDateController.tryParseToString(TEST_DATE, 'week')).toThrowError('Auto convert to week is not supported!');
it('returns a ISO8601 week string for type week', () => {
expect(InputDateController.tryParseToString(TEST_DATE, 'week')).toBe('2020-W10');
});
});
});
describe('method getWeekNumberOfDate', () => {
it('should return correct WeekOfYear', () => {
expect(InputDateController.getWeekNumberOfDate(TEST_DATE)).toBe('10');
});
});
});
53 changes: 35 additions & 18 deletions packages/components/src/components/input-date/controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import { inputDateTypeOptions, setState, validateReadOnly, validateSuggestions,
import { InputIconController } from '../@deprecated/input/controller-icon';

import type { Generic } from 'adopted-style-sheets';

export class InputDateController extends InputIconController implements InputDateWatches {
// test: https://regex101.com/r/NTVh4L/1
private static readonly isoDateRegex = /^\d{4}-([0]\d|1[0-2])-([0-2]\d|3[01])/;
Expand Down Expand Up @@ -75,11 +76,40 @@ export class InputDateController extends InputIconController implements InputDat
return formattedTimeWithSeconds;
}
case 'week':
throw new Error('Auto convert to week is not supported!');
return `${formattedYear}-W${this.getWeekNumberOfDate(value)}`;
}
}
}

static getWeekNumberOfDate(date: Date): string {
AlexanderSchmidtCE marked this conversation as resolved.
Show resolved Hide resolved
const copiedDate = new Date(date);

// ISO week date weeks start on Monday, so correct the day number
const nDay = (copiedDate.getDay() + 6) % 7;

// ISO 8601 states that week 1 is the week with the first Thursday of that year
// Set the target date to the Thursday in the target week
copiedDate.setDate(copiedDate.getDate() - nDay + 3);

// Store the millisecond value of the target date
const n1stThursday = copiedDate.valueOf();

// Set the target to the first Thursday of the year
// First, set the target to January 1st
copiedDate.setMonth(0, 1);

// Not a Thursday? Correct the date to the next Thursday
if (copiedDate.getDay() !== 4) {
copiedDate.setMonth(0, 1 + ((4 - copiedDate.getDay() + 7) % 7));
}

// The week number is the number of weeks between the first Thursday of the year
// and the Thursday in the target week (604800000 = 7 * 24 * 3600 * 1000)
const dayOfYear = 1 + Math.ceil((n1stThursday - copiedDate.valueOf()) / 604800000);

return dayOfYear.toString().padStart(2, '0');
}

private validateDateString(value: string): boolean {
switch (this.component._type) {
case 'date':
Expand Down Expand Up @@ -127,29 +157,16 @@ export class InputDateController extends InputIconController implements InputDat

public validateMax(value?: Iso8601 | Date): void {
const ensuredValue =
((value === undefined || value === null) && this.component._type === 'date') ||
this.component._type === 'month' ||
this.component._type === 'datetime-local'
(value === undefined || value === null) &&
(this.component._type === 'date' || this.component._type === 'month' || this.component._type === 'datetime-local')
? InputDateController.DEFAULT_MAX_DATE
: value;

watchValidator(
this.component,
'_max',
(value): boolean => value === undefined || (value !== null && this.validateDateString(value)),
new Set(['Iso8601', 'Date']),
InputDateController.tryParseToString(ensuredValue, this.component._type, this.component._step),
);
this.validateIso8601('_max', ensuredValue);
}

public validateMin(value?: Iso8601 | Date): void {
watchValidator(
this.component,
'_min',
(value): boolean => value === undefined || (value !== null && this.validateDateString(value)),
new Set(['Iso8601', 'Date']),
InputDateController.tryParseToString(value, this.component._type, this.component._step),
);
this.validateIso8601('_min', value);
}

public validateOn(value?: InputTypeOnDefault) {
Expand Down
138 changes: 138 additions & 0 deletions packages/components/src/components/input-date/input-date.e2e.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,4 +59,142 @@ test.describe('kol-input-date', () => {
await expect(page.locator('input')).toHaveValue('04:02');
});
});

test.describe('when min and max is set', () => {
test.describe('for Iso8601-Format', () => {
test('should set correct min and max for type date', async ({ page }) => {
const minDate = '2024-09-26';
const maxDate = '2024-09-27';
await page.setContent(`<kol-input-date _label="Date input" _type="date" _min="${minDate}" _max="${maxDate}"></kol-input-date>`);

await expect(page.locator('input')).toHaveAttribute('min', minDate);
await expect(page.locator('input')).toHaveAttribute('max', maxDate);
});

test('should set correct min and max for type time', async ({ page }) => {
const minTime = '12:00';
const maxTime = '15:00';
await page.setContent(`<kol-input-date _label="Date input" _type="time" _min="${minTime}" _max="${maxTime}"></kol-input-date>`);

await expect(page.locator('input')).toHaveAttribute('min', minTime);
await expect(page.locator('input')).toHaveAttribute('max', maxTime);
});

test('should set correct min and max for type datetime_locale', async ({ page }) => {
const minDayTime = '2024-09-26T12:00';
const maxDaytime = '2024-09-27T15:00';
await page.setContent(`<kol-input-date _label="Date input" _type="datetime-local" _min="${minDayTime}" _max="${maxDaytime}"></kol-input-date>`);

await expect(page.locator('input')).toHaveAttribute('min', minDayTime);
await expect(page.locator('input')).toHaveAttribute('max', maxDaytime);
});

test('should set correct min and max for type week', async ({ page }) => {
const minWeek = '2024-W10';
const maxWeek = '2024-W50';
await page.setContent(`<kol-input-date _label="Date input" _type="week" _min="${minWeek}" _max="${maxWeek}"></kol-input-date>`);

await expect(page.locator('input')).toHaveAttribute('min', minWeek);
await expect(page.locator('input')).toHaveAttribute('max', maxWeek);
});

test('should set correct min and max for type month', async ({ page }) => {
const minMonth = '2024-02';
const maxMonth = '2024-10';
await page.setContent(`<kol-input-date _label="Date input" _type="month" _min="${minMonth}" _max="${maxMonth}"></kol-input-date>`);

await expect(page.locator('input')).toHaveAttribute('min', minMonth);
await expect(page.locator('input')).toHaveAttribute('max', maxMonth);
});
});
test.describe('for Date-Format', () => {
let minDateFormat: Date;
let maxDateFormat: Date;

test.beforeEach(() => {
minDateFormat = new Date('2024-01-10T12:00:00Z');
maxDateFormat = new Date('2024-10-20T15:00:00Z');
});
test('should set correct min and max for type date', async ({ page }) => {
const minDate = '2024-01-10';
const maxDate = '2024-10-20';
await page.setContent(`<kol-input-date _label="Date input" _type="date"></kol-input-date>`);

await page.locator('kol-input-date').evaluate((element: HTMLKolInputDateElement, date) => {
element._min = date;
}, minDateFormat);
await page.locator('kol-input-date').evaluate((element: HTMLKolInputDateElement, date) => {
AlexanderSchmidtCE marked this conversation as resolved.
Show resolved Hide resolved
element._max = date;
}, maxDateFormat);
await page.waitForChanges();

await expect(page.locator('input')).toHaveAttribute('min', minDate);
await expect(page.locator('input')).toHaveAttribute('max', maxDate);
});

test('should set correct min and max for type time', async ({ page }) => {
const minTime = '13:00';
const maxTime = '17:00';
await page.setContent(`<kol-input-date _label="Date input" _type="time"></kol-input-date>`);

await page.locator('kol-input-date').evaluate((element: HTMLKolInputDateElement, date) => {
element._min = date;
}, minDateFormat);
await page.locator('kol-input-date').evaluate((element: HTMLKolInputDateElement, date) => {
element._max = date;
}, maxDateFormat);

await expect(page.locator('input')).toHaveAttribute('min', minTime);
await expect(page.locator('input')).toHaveAttribute('max', maxTime);
});

test('should set correct min and max for type datetime_locale', async ({ page }) => {
const minDayTime = '2024-01-10T13:00:00';
const maxDaytime = '2024-10-20T17:00:00';
await page.setContent(`<kol-input-date _label="Date input" _type="datetime-local"></kol-input-date>`);

await page.locator('kol-input-date').evaluate((element: HTMLKolInputDateElement, date) => {
element._min = date;
}, minDateFormat);
await page.locator('kol-input-date').evaluate((element: HTMLKolInputDateElement, date) => {
element._max = date;
}, maxDateFormat);

await expect(page.locator('input')).toHaveAttribute('min', minDayTime);
await expect(page.locator('input')).toHaveAttribute('max', maxDaytime);
});

test('should set correct min and max for type week', async ({ page }) => {
const minWeek = '2024-W02';
const maxWeek = '2024-W42';
await page.setContent(`<kol-input-date _label="Date input" _type="week"></kol-input-date>`);

await page.locator('kol-input-date').evaluate((element: HTMLKolInputDateElement, date) => {
element._min = date;
}, minDateFormat);
await page.locator('kol-input-date').evaluate((element: HTMLKolInputDateElement, date) => {
element._max = date;
}, maxDateFormat);

await expect(page.locator('input')).toHaveAttribute('min', minWeek);
await expect(page.locator('input')).toHaveAttribute('max', maxWeek);
});

test('should set correct min and max for type month', async ({ page }) => {
const minMonth = '2024-01';
const maxMonth = '2024-10';
await page.setContent(`<kol-input-date _label="Date input" _type="month"></kol-input-date>`);

await page.locator('kol-input-date').evaluate((element: HTMLKolInputDateElement, date) => {
element._min = date;
}, minDateFormat);
await page.locator('kol-input-date').evaluate((element: HTMLKolInputDateElement, date) => {
element._max = date;
}, maxDateFormat);

await expect(page.locator('input')).toHaveAttribute('min', minMonth);
await expect(page.locator('input')).toHaveAttribute('max', maxMonth);
});
});
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import React, { forwardRef } from 'react';
import { KolInputDate } from '@public-ui/react';
import type { Components } from '@public-ui/components';

export const InputDateMinMaxCases = forwardRef<HTMLKolInputDateElement, Components.KolInputDate>(function InputDateCases(props) {
const minDateIso = '2024-09-26';
const maxDateIso = '2024-09-27';

const minTimeIso = '12:00';
const maxTimeIso = '15:00';

const minDayTimeIso = '2024-09-26T12:00';
const maxDaytimeIso = '2024-09-27T15:00';

const minWeekIso = '2024-W10';
const maxWeekIso = '2024-W50';

const minMonthIso = '2024-02';
const maxMonthIso = '2024-10';

const minDate = new Date('January 10, 2024, 12:00');
const maxDate = new Date('October 20, 2024, 15:00');
return (
<div className="grid gap-4">
<KolInputDate {...props} _type="date" _label="Date with Iso" _min={minDateIso} _max={maxDateIso} />
<KolInputDate {...props} _type="date" _label="Date with Date" _min={minDate} _max={maxDate} />

<KolInputDate {...props} _type="time" _label="Time with Iso" _min={minTimeIso} _max={maxTimeIso} />
<KolInputDate {...props} _type="time" _label="Time with Date" _min={minDate} _max={maxDate} />

<KolInputDate {...props} _type="datetime-local" _label="DayTime with Iso" _min={minDayTimeIso} _max={maxDaytimeIso} />
<KolInputDate {...props} _type="datetime-local" _label="DayTime with Date" _min={minDate} _max={maxDate} />

<KolInputDate {...props} _type="week" _label="Week with Iso" _min={minWeekIso} _max={maxWeekIso} />
<KolInputDate {...props} _type="week" _label="Week with Date" _min={minDate} _max={maxDate} />

<KolInputDate {...props} _type="month" _label="Month with Iso" _min={minMonthIso} _max={maxMonthIso} />
<KolInputDate {...props} _type="month" _label="Month with Date" _min={minDate} _max={maxDate} />
</div>
);
});
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import React, { forwardRef } from 'react';
import { InputDateCases } from './cases';

import type { Components } from '@public-ui/components';
import { InputDateMinMaxCases } from './minMax';
export const InputDateVariants = forwardRef<HTMLKolInputDateElement, Components.KolInputDate>(function InputDateVariant(props, ref) {
return (
<div className="grid md:grid-cols-2 gap-4">
Expand All @@ -14,6 +15,10 @@ export const InputDateVariants = forwardRef<HTMLKolInputDateElement, Components.
<legend>Date (hideLabel)</legend>
<InputDateCases ref={ref} {...props} _hideLabel />
</fieldset>
<fieldset>
<legend>Date (with min/max)</legend>
<InputDateMinMaxCases ref={ref} {...props} />
</fieldset>
</div>
);
});
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading