[FIX] web: fix datetime picker disabling incorrect periods
Previously, if you specified a min or max date for the datetime picker and zoomed out to the month/year/decade view, it would disable some months/year/decade incorrectly, this was caused by the code checking if the beginning of the period was in the min-max range instead of checking if the period had any overlap with the min-max range. This commit fixes that by checking for overlaps instead. closes odoo/odoo#133911 X-original-commit: 7cb61dca99be4b0a1c35f0ec762c1bda318ec043 Signed-off-by: Aaron Bohy (aab) <aab@odoo.com>
This commit is contained in:
@@ -180,11 +180,12 @@ const PRECISION_LEVELS = new Map()
|
||||
// Generate all days of the week
|
||||
for (let d = 0; d < 7; d++) {
|
||||
const day = startOfNextWeek.plus({ day: d });
|
||||
const range = [day, day.endOf("day")];
|
||||
const dayItem = toDateItem({
|
||||
isOutOfRange: !isInRange(day, monthRange),
|
||||
isInvalid: !isInRange(day, [minDate, maxDate]),
|
||||
isInvalid: !isInRange(range, [minDate, maxDate]),
|
||||
label: "day",
|
||||
range: [day, day.endOf("day")],
|
||||
range,
|
||||
});
|
||||
weekDayItems.push(dayItem);
|
||||
if (d === 6) {
|
||||
@@ -222,10 +223,11 @@ const PRECISION_LEVELS = new Map()
|
||||
const startOfYear = date.startOf("year");
|
||||
return numberRange(0, 12).map((i) => {
|
||||
const startOfMonth = startOfYear.plus({ month: i });
|
||||
const range = [startOfMonth, startOfMonth.endOf("month")];
|
||||
return toDateItem({
|
||||
isInvalid: !isInRange(startOfMonth, [minDate, maxDate]),
|
||||
isInvalid: !isInRange(range, [minDate, maxDate]),
|
||||
label: "monthShort",
|
||||
range: [startOfMonth, startOfMonth.endOf("month")],
|
||||
range,
|
||||
});
|
||||
});
|
||||
},
|
||||
@@ -240,11 +242,12 @@ const PRECISION_LEVELS = new Map()
|
||||
const startOfDecade = date.startOf("year").set({ year: getStartOfDecade(date) });
|
||||
return numberRange(-GRID_MARGIN, GRID_COUNT + GRID_MARGIN).map((i) => {
|
||||
const startOfYear = startOfDecade.plus({ year: i });
|
||||
const range = [startOfYear, startOfYear.endOf("year")];
|
||||
return toDateItem({
|
||||
isOutOfRange: i < 0 || i >= GRID_COUNT,
|
||||
isInvalid: !isInRange(startOfYear, [minDate, maxDate]),
|
||||
isInvalid: !isInRange(range, [minDate, maxDate]),
|
||||
label: "year",
|
||||
range: [startOfYear, startOfYear.endOf("year")],
|
||||
range,
|
||||
});
|
||||
});
|
||||
},
|
||||
@@ -259,11 +262,12 @@ const PRECISION_LEVELS = new Map()
|
||||
const startOfCentury = date.startOf("year").set({ year: getStartOfCentury(date) });
|
||||
return numberRange(-GRID_MARGIN, GRID_COUNT + GRID_MARGIN).map((i) => {
|
||||
const startOfDecade = startOfCentury.plus({ year: i * 10 });
|
||||
const range = [startOfDecade, startOfDecade.plus({ year: 10, millisecond: -1 })];
|
||||
return toDateItem({
|
||||
label: "year",
|
||||
isOutOfRange: i < 0 || i >= GRID_COUNT,
|
||||
isInvalid: !isInRange(startOfDecade, [minDate, maxDate]),
|
||||
range: [startOfDecade, startOfDecade.plus({ year: 10, millisecond: -1 })],
|
||||
isInvalid: !isInRange(range, [minDate, maxDate]),
|
||||
range,
|
||||
});
|
||||
});
|
||||
},
|
||||
@@ -403,6 +407,7 @@ export class DateTimePicker extends Component {
|
||||
|
||||
this.adjustFocus(this.values, props.focusedDateIndex);
|
||||
this.handle12HourSystem();
|
||||
this.state.timeValues = this.state.timeValues.map((timeValue) => timeValue.map(String));
|
||||
}
|
||||
|
||||
onWillRender() {
|
||||
|
||||
@@ -120,7 +120,7 @@
|
||||
class="text-center"
|
||||
t-att-value="unit[0]"
|
||||
t-esc="unit[1]"
|
||||
t-att-selected="timeValue[unitIndex] === unit[0]"
|
||||
t-att-selected="timeValue[unitIndex] === unit[0].toString()"
|
||||
/>
|
||||
</t>
|
||||
</select>
|
||||
|
||||
@@ -102,6 +102,331 @@ QUnit.module("Components", ({ beforeEach }) => {
|
||||
);
|
||||
});
|
||||
|
||||
QUnit.test("minDate: correct days/month/year/decades are disabled", async (assert) => {
|
||||
const fixture = getFixture();
|
||||
await mountPicker({
|
||||
minDate: DateTime.fromISO("2023-04-20T00:00:00.000"),
|
||||
});
|
||||
|
||||
assertDateTimePicker({
|
||||
title: "April 2023",
|
||||
date: [
|
||||
{
|
||||
cells: [
|
||||
[-26, -27, -28, -29, -30, -31, -1],
|
||||
[-2, -3, -4, -5, -6, -7, -8],
|
||||
[-9, -10, -11, -12, -13, -14, -15],
|
||||
[-16, -17, -18, -19, 20, 21, 22],
|
||||
[23, 24, "25", 26, 27, 28, 29],
|
||||
[30, -1, -2, -3, -4, -5, -6],
|
||||
],
|
||||
daysOfWeek: ["#", "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"],
|
||||
weekNumbers: [13, 14, 15, 16, 17, 18],
|
||||
},
|
||||
],
|
||||
time: [[13, 0]],
|
||||
});
|
||||
|
||||
const [hourSelect, minuteSelect] = getTimePickers().at(0);
|
||||
assert.deepEqual(getTexts(hourSelect, "option"), range(24, String));
|
||||
assert.deepEqual(
|
||||
getTexts(minuteSelect, "option"),
|
||||
range(12, (i) => pad2(i * 5))
|
||||
);
|
||||
|
||||
await click(fixture, ".o_zoom_out");
|
||||
assert.equal(fixture.querySelector(".o_datetime_picker_header").textContent, "2023");
|
||||
assert.deepEqual(
|
||||
getTexts(".o_date_item_cell[disabled]"),
|
||||
|
||||
["Jan", "Feb", "Mar"],
|
||||
"correct months are disabled"
|
||||
);
|
||||
assert.deepEqual(
|
||||
getTexts(".o_date_item_cell:not([disabled])"),
|
||||
["Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"],
|
||||
"correct months are enabled"
|
||||
);
|
||||
assert.equal($(fixture).find(".o_date_item_cell.o_today").text(), "Apr");
|
||||
|
||||
await click(fixture, ".o_zoom_out");
|
||||
assert.equal(fixture.querySelector(".o_datetime_picker_header").textContent, "2019 - 2030");
|
||||
assert.deepEqual(
|
||||
getTexts(".o_date_item_cell[disabled]"),
|
||||
|
||||
["2019", "2020", "2021", "2022"],
|
||||
"correct years are disabled"
|
||||
);
|
||||
assert.deepEqual(
|
||||
getTexts(".o_date_item_cell:not([disabled])"),
|
||||
["2023", "2024", "2025", "2026", "2027", "2028", "2029", "2030"],
|
||||
"correct years are enabled"
|
||||
);
|
||||
assert.equal($(fixture).find(".o_date_item_cell.o_today").text(), "2023");
|
||||
|
||||
await click(fixture, ".o_zoom_out");
|
||||
assert.equal(fixture.querySelector(".o_datetime_picker_header").textContent, "1990 - 2100");
|
||||
assert.deepEqual(
|
||||
getTexts(".o_date_item_cell[disabled]"),
|
||||
["1990", "2000", "2010"],
|
||||
"correct decades are disabled"
|
||||
);
|
||||
assert.deepEqual(
|
||||
getTexts(".o_date_item_cell:not([disabled])"),
|
||||
|
||||
["2020", "2030", "2040", "2050", "2060", "2070", "2080", "2090", "2100"],
|
||||
"correct decades are enabled"
|
||||
);
|
||||
assert.equal($(fixture).find(".o_date_item_cell.o_today").text(), "2020");
|
||||
|
||||
await click(fixture, ".o_today");
|
||||
await click(fixture, ".o_today");
|
||||
await click(fixture, ".o_today");
|
||||
|
||||
assertDateTimePicker({
|
||||
title: "April 2023",
|
||||
date: [
|
||||
{
|
||||
cells: [
|
||||
[-26, -27, -28, -29, -30, -31, -1],
|
||||
[-2, -3, -4, -5, -6, -7, -8],
|
||||
[-9, -10, -11, -12, -13, -14, -15],
|
||||
[-16, -17, -18, -19, 20, 21, 22],
|
||||
[23, 24, "25", 26, 27, 28, 29],
|
||||
[30, -1, -2, -3, -4, -5, -6],
|
||||
],
|
||||
daysOfWeek: ["#", "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"],
|
||||
weekNumbers: [13, 14, 15, 16, 17, 18],
|
||||
},
|
||||
],
|
||||
time: [[13, 0]],
|
||||
});
|
||||
});
|
||||
|
||||
QUnit.test("maxDate: correct days/month/year/decades are disabled", async (assert) => {
|
||||
const fixture = getFixture();
|
||||
await mountPicker({
|
||||
maxDate: DateTime.fromISO("2023-04-28T00:00:00.000"),
|
||||
});
|
||||
|
||||
assertDateTimePicker({
|
||||
title: "April 2023",
|
||||
date: [
|
||||
{
|
||||
cells: [
|
||||
[-26, -27, -28, -29, -30, -31, 1],
|
||||
[2, 3, 4, 5, 6, 7, 8],
|
||||
[9, 10, 11, 12, 13, 14, 15],
|
||||
[16, 17, 18, 19, 20, 21, 22],
|
||||
[23, 24, "25", 26, 27, 28, -29],
|
||||
[-30, -1, -2, -3, -4, -5, -6],
|
||||
],
|
||||
daysOfWeek: ["#", "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"],
|
||||
weekNumbers: [13, 14, 15, 16, 17, 18],
|
||||
},
|
||||
],
|
||||
time: [[13, 0]],
|
||||
});
|
||||
|
||||
const [hourSelect, minuteSelect] = getTimePickers().at(0);
|
||||
assert.deepEqual(getTexts(hourSelect, "option"), range(24, String));
|
||||
assert.deepEqual(
|
||||
getTexts(minuteSelect, "option"),
|
||||
range(12, (i) => pad2(i * 5))
|
||||
);
|
||||
|
||||
await click(fixture, ".o_zoom_out");
|
||||
assert.equal(fixture.querySelector(".o_datetime_picker_header").textContent, "2023");
|
||||
assert.deepEqual(
|
||||
getTexts(".o_date_item_cell[disabled]"),
|
||||
["May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"],
|
||||
"correct months are disabled"
|
||||
);
|
||||
assert.deepEqual(
|
||||
getTexts(".o_date_item_cell:not([disabled])"),
|
||||
["Jan", "Feb", "Mar", "Apr"],
|
||||
"correct months are enabled"
|
||||
);
|
||||
assert.equal($(fixture).find(".o_date_item_cell.o_today").text(), "Apr");
|
||||
|
||||
await click(fixture, ".o_zoom_out");
|
||||
assert.equal(fixture.querySelector(".o_datetime_picker_header").textContent, "2019 - 2030");
|
||||
assert.deepEqual(
|
||||
getTexts(".o_date_item_cell[disabled]"),
|
||||
|
||||
["2024", "2025", "2026", "2027", "2028", "2029", "2030"],
|
||||
"correct years are disabled"
|
||||
);
|
||||
assert.deepEqual(
|
||||
getTexts(".o_date_item_cell:not([disabled])"),
|
||||
["2019", "2020", "2021", "2022", "2023"],
|
||||
"correct years are enabled"
|
||||
);
|
||||
assert.equal($(fixture).find(".o_date_item_cell.o_today").text(), "2023");
|
||||
|
||||
await click(fixture, ".o_zoom_out");
|
||||
assert.equal(fixture.querySelector(".o_datetime_picker_header").textContent, "1990 - 2100");
|
||||
assert.deepEqual(
|
||||
getTexts(".o_date_item_cell[disabled]"),
|
||||
["2030", "2040", "2050", "2060", "2070", "2080", "2090", "2100"],
|
||||
"correct decades are disabled"
|
||||
);
|
||||
assert.deepEqual(
|
||||
getTexts(".o_date_item_cell:not([disabled])"),
|
||||
|
||||
["1990", "2000", "2010", "2020"],
|
||||
"correct decades are enabled"
|
||||
);
|
||||
assert.equal($(fixture).find(".o_date_item_cell.o_today").text(), "2020");
|
||||
|
||||
await click(fixture, ".o_today");
|
||||
await click(fixture, ".o_today");
|
||||
await click(fixture, ".o_today");
|
||||
|
||||
assertDateTimePicker({
|
||||
title: "April 2023",
|
||||
date: [
|
||||
{
|
||||
cells: [
|
||||
[-26, -27, -28, -29, -30, -31, 1],
|
||||
[2, 3, 4, 5, 6, 7, 8],
|
||||
[9, 10, 11, 12, 13, 14, 15],
|
||||
[16, 17, 18, 19, 20, 21, 22],
|
||||
[23, 24, "25", 26, 27, 28, -29],
|
||||
[-30, -1, -2, -3, -4, -5, -6],
|
||||
],
|
||||
daysOfWeek: ["#", "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"],
|
||||
weekNumbers: [13, 14, 15, 16, 17, 18],
|
||||
},
|
||||
],
|
||||
time: [[13, 0]],
|
||||
});
|
||||
});
|
||||
|
||||
QUnit.test("min+max date: correct days/month/year/decades are disabled", async (assert) => {
|
||||
const fixture = getFixture();
|
||||
await mountPicker({
|
||||
minDate: DateTime.fromISO("2023-04-20T00:00:00.000"),
|
||||
maxDate: DateTime.fromISO("2023-04-28T00:00:00.000"),
|
||||
});
|
||||
|
||||
assertDateTimePicker({
|
||||
title: "April 2023",
|
||||
date: [
|
||||
{
|
||||
cells: [
|
||||
[-26, -27, -28, -29, -30, -31, -1],
|
||||
[-2, -3, -4, -5, -6, -7, -8],
|
||||
[-9, -10, -11, -12, -13, -14, -15],
|
||||
[-16, -17, -18, -19, 20, 21, 22],
|
||||
[23, 24, "25", 26, 27, 28, -29],
|
||||
[-30, -1, -2, -3, -4, -5, -6],
|
||||
],
|
||||
daysOfWeek: ["#", "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"],
|
||||
weekNumbers: [13, 14, 15, 16, 17, 18],
|
||||
},
|
||||
],
|
||||
time: [[13, 0]],
|
||||
});
|
||||
|
||||
const [hourSelect, minuteSelect] = getTimePickers().at(0);
|
||||
assert.deepEqual(getTexts(hourSelect, "option"), range(24, String));
|
||||
assert.deepEqual(
|
||||
getTexts(minuteSelect, "option"),
|
||||
range(12, (i) => pad2(i * 5))
|
||||
);
|
||||
|
||||
await click(fixture, ".o_zoom_out");
|
||||
assert.equal(fixture.querySelector(".o_datetime_picker_header").textContent, "2023");
|
||||
assert.deepEqual(
|
||||
getTexts(".o_date_item_cell[disabled]"),
|
||||
["Jan", "Feb", "Mar", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"],
|
||||
"correct months are disabled"
|
||||
);
|
||||
assert.deepEqual(
|
||||
getTexts(".o_date_item_cell:not([disabled])"),
|
||||
["Apr"],
|
||||
"correct months are enabled"
|
||||
);
|
||||
assert.equal($(fixture).find(".o_date_item_cell.o_today").text(), "Apr");
|
||||
|
||||
await click(fixture, ".o_zoom_out");
|
||||
assert.equal(fixture.querySelector(".o_datetime_picker_header").textContent, "2019 - 2030");
|
||||
assert.deepEqual(
|
||||
getTexts(".o_date_item_cell[disabled]"),
|
||||
[
|
||||
"2019",
|
||||
"2020",
|
||||
"2021",
|
||||
"2022",
|
||||
"2024",
|
||||
"2025",
|
||||
"2026",
|
||||
"2027",
|
||||
"2028",
|
||||
"2029",
|
||||
"2030",
|
||||
],
|
||||
"correct years are disabled"
|
||||
);
|
||||
assert.deepEqual(
|
||||
getTexts(".o_date_item_cell:not([disabled])"),
|
||||
["2023"],
|
||||
"correct years are enabled"
|
||||
);
|
||||
assert.equal($(fixture).find(".o_date_item_cell.o_today").text(), "2023");
|
||||
|
||||
await click(fixture, ".o_zoom_out");
|
||||
assert.equal(fixture.querySelector(".o_datetime_picker_header").textContent, "1990 - 2100");
|
||||
assert.deepEqual(
|
||||
getTexts(".o_date_item_cell[disabled]"),
|
||||
[
|
||||
"1990",
|
||||
"2000",
|
||||
"2010",
|
||||
"2030",
|
||||
"2040",
|
||||
"2050",
|
||||
"2060",
|
||||
"2070",
|
||||
"2080",
|
||||
"2090",
|
||||
"2100",
|
||||
],
|
||||
"correct decades are disabled"
|
||||
);
|
||||
assert.deepEqual(
|
||||
getTexts(".o_date_item_cell:not([disabled])"),
|
||||
|
||||
["2020"],
|
||||
"correct decades are enabled"
|
||||
);
|
||||
assert.equal($(fixture).find(".o_date_item_cell.o_today").text(), "2020");
|
||||
|
||||
await click(fixture, ".o_today");
|
||||
await click(fixture, ".o_today");
|
||||
await click(fixture, ".o_today");
|
||||
|
||||
assertDateTimePicker({
|
||||
title: "April 2023",
|
||||
date: [
|
||||
{
|
||||
cells: [
|
||||
[-26, -27, -28, -29, -30, -31, -1],
|
||||
[-2, -3, -4, -5, -6, -7, -8],
|
||||
[-9, -10, -11, -12, -13, -14, -15],
|
||||
[-16, -17, -18, -19, 20, 21, 22],
|
||||
[23, 24, "25", 26, 27, 28, -29],
|
||||
[-30, -1, -2, -3, -4, -5, -6],
|
||||
],
|
||||
daysOfWeek: ["#", "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"],
|
||||
weekNumbers: [13, 14, 15, 16, 17, 18],
|
||||
},
|
||||
],
|
||||
time: [[13, 0]],
|
||||
});
|
||||
});
|
||||
|
||||
QUnit.test("twelve-hour clock", async (assert) => {
|
||||
useTwelveHourClockFormat();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user