summaryrefslogtreecommitdiff
path: root/addons/web/static
diff options
context:
space:
mode:
authorNasreddin (bon) <bon@odoo.com>2021-03-08 12:57:03 +0000
committerLucas Perais (lpe) <lpe@odoo.com>2021-03-17 16:08:32 +0000
commite2c46bb80e1e312dd34ac554d79813ef35282e62 (patch)
tree186975fd56323a9426c682bf390180e81c4248ab /addons/web/static
parent629ce193e4725919c1aeede000517564f0e8adf1 (diff)
[FIX] web: compute default locale of Date(Time)Picker at the right time
Issue - Install "Accounting" - Change user language to arabic - Go to Customer Invoices list view - Try to filter on field "Created On" Traceback is raised from the DatePicker Component Cause The cause is two fold: There is an issue in moment that behaves abnormally when its internals are not able to extract the month in a locale, and, instead of returning an invalid moment, it returns a valid moment with the month set to January which just happens to be the first month of moment's default locale ref: https://github.com/moment/moment/issues/5600 Secondly, the defaultProps "locale" of the DatePicker was set to moment.locale() at the file's initial loading, that is, before any user locale parameters were loaded The bootstrap datepicker was then set with the wrong locale, and the case fell under moment's issue After this commit, the locale of the DatePicker is always the one of the user, and there is no traceback opw-2460156 closes odoo/odoo#67320 Signed-off-by: Aaron Bohy (aab) <aab@odoo.com> Co-authored-by: Lucas Perais <lpe@odoo.com>
Diffstat (limited to 'addons/web/static')
-rw-r--r--addons/web/static/src/js/components/datepicker.js4
-rw-r--r--addons/web/static/tests/components/datepicker_tests.js94
2 files changed, 96 insertions, 2 deletions
diff --git a/addons/web/static/src/js/components/datepicker.js b/addons/web/static/src/js/components/datepicker.js
index a11d51b5021..94ce7ece4fe 100644
--- a/addons/web/static/src/js/components/datepicker.js
+++ b/addons/web/static/src/js/components/datepicker.js
@@ -178,7 +178,7 @@ odoo.define('web.DatePickerOwl', function (require) {
today: 'fa fa-calendar-check-o',
up: 'fa fa-chevron-up',
},
- locale: moment.locale(),
+ get locale() {return moment.locale();},
maxDate: moment({ y: 9999, M: 11, d: 31 }),
minDate: moment({ y: 1000 }),
useCurrent: false,
@@ -248,7 +248,7 @@ odoo.define('web.DatePickerOwl', function (require) {
}
}
- DateTimePicker.defaultProps = Object.assign({}, DatePicker.defaultProps, {
+ DateTimePicker.defaultProps = Object.assign(Object.create(DatePicker.defaultProps), {
buttons: {
showClear: false,
showClose: true,
diff --git a/addons/web/static/tests/components/datepicker_tests.js b/addons/web/static/tests/components/datepicker_tests.js
index 7e59e9620d7..643bcdb5188 100644
--- a/addons/web/static/tests/components/datepicker_tests.js
+++ b/addons/web/static/tests/components/datepicker_tests.js
@@ -70,6 +70,47 @@ odoo.define('web.datepicker_tests', function (require) {
picker.destroy();
});
+ QUnit.test("pick a date with locale", async function (assert) {
+ assert.expect(4);
+
+ // weird shit of moment https://github.com/moment/moment/issues/5600
+ // When month regex returns undefined, january is taken (first month of the default "nameless" locale)
+ const originalLocale = moment.locale();
+ // Those parameters will make Moment's internal compute stuff that are relevant to the bug
+ const months = 'janvier_février_mars_avril_mai_juin_juillet_août_septembre_octobre_novembre_décembre'.split('_');
+ const monthsShort = 'janv._févr._mars_avr._mai_juin_juil._août_custSept._oct._nov._déc.'.split('_');
+ moment.defineLocale('frenchForTests', { months, monthsShort, code: 'frTest' , monthsParseExact: true});
+
+ const hasChanged = testUtils.makeTestPromise();
+ const picker = await createComponent(DatePicker, {
+ translateParameters: {
+ date_format: "%d %b, %Y", // Those are important too
+ time_format: "%H:%M:%S",
+ },
+ props: { date: moment('09/01/1997', 'MM/DD/YYYY') },
+ intercepts: {
+ 'datetime-changed': ev => {
+ assert.step('datetime-changed');
+ assert.strictEqual(ev.detail.date.format('MM/DD/YYYY'), '09/02/1997',
+ "Event should transmit the correct date");
+ hasChanged.resolve();
+ },
+ }
+ });
+ const input = picker.el.querySelector('.o_datepicker_input');
+ await testUtils.dom.click(input);
+
+ await testUtils.dom.click(document.querySelectorAll('.datepicker table td')[3]); // next day
+
+ assert.strictEqual(input.value, '02 custSept., 1997');
+ assert.verifySteps(['datetime-changed']);
+
+ moment.locale(originalLocale);
+ moment.updateLocale('englishForTest', null);
+
+ picker.destroy();
+ });
+
QUnit.test("enter a date value", async function (assert) {
assert.expect(5);
@@ -194,6 +235,59 @@ odoo.define('web.datepicker_tests', function (require) {
picker.destroy();
});
+ QUnit.test("pick a date and time with locale", async function (assert) {
+ assert.expect(5);
+
+ // weird shit of moment https://github.com/moment/moment/issues/5600
+ // When month regex returns undefined, january is taken (first month of the default "nameless" locale)
+ const originalLocale = moment.locale();
+ // Those parameters will make Moment's internal compute stuff that are relevant to the bug
+ const months = 'janvier_février_mars_avril_mai_juin_juillet_août_septembre_octobre_novembre_décembre'.split('_');
+ const monthsShort = 'janv._févr._mars_avr._mai_juin_juil._août_custSept._oct._nov._déc.'.split('_');
+ moment.defineLocale('frenchForTests', { months, monthsShort, code: 'frTest' , monthsParseExact: true});
+
+ const hasChanged = testUtils.makeTestPromise();
+ const picker = await createComponent(DateTimePicker, {
+ translateParameters: {
+ date_format: "%d %b, %Y", // Those are important too
+ time_format: "%H:%M:%S",
+ },
+ props: { date: moment('09/01/1997 12:30:01', 'MM/DD/YYYY HH:mm:ss') },
+ intercepts: {
+ 'datetime-changed': ev => {
+ assert.step('datetime-changed');
+ assert.strictEqual(ev.detail.date.format('MM/DD/YYYY HH:mm:ss'), '09/02/1997 15:45:05',
+ "Event should transmit the correct date");
+ hasChanged.resolve();
+ },
+ }
+ });
+
+ const input = picker.el.querySelector('input.o_input.o_datepicker_input');
+
+ await testUtils.dom.click(input);
+ await testUtils.dom.click(document.querySelectorAll('.datepicker table td')[3]); // next day
+ await testUtils.dom.click(document.querySelector('a[title="Select Time"]'));
+ await testUtils.dom.click(document.querySelector('.timepicker .timepicker-hour'));
+ await testUtils.dom.click(document.querySelectorAll('.timepicker .hour')[15]); // 15h
+ await testUtils.dom.click(document.querySelector('.timepicker .timepicker-minute'));
+ await testUtils.dom.click(document.querySelectorAll('.timepicker .minute')[9]); // 45m
+ await testUtils.dom.click(document.querySelector('.timepicker .timepicker-second'));
+
+ assert.verifySteps([]);
+ await testUtils.dom.click(document.querySelectorAll('.timepicker .second')[1]); // 05s
+
+ assert.strictEqual(input.value, '02 custSept., 1997 15:45:05');
+ assert.verifySteps(['datetime-changed']);
+
+ await hasChanged;
+
+ moment.locale(originalLocale);
+ moment.updateLocale('frenchForTests', null);
+
+ picker.destroy();
+ });
+
QUnit.test("enter a datetime value", async function (assert) {
assert.expect(9);