From 5b6b95e5a59775a1bb34aed7cfc28a1a5c8870bf Mon Sep 17 00:00:00 2001 From: natuan9 Date: Sat, 14 Dec 2024 16:59:24 +0700 Subject: [PATCH] [MIG] web_datetime_picker_default_time: Migration to 18.0 --- web_datetime_picker_default_time/README.rst | 42 +++++-- .../__manifest__.py | 3 +- .../readme/CONTRIBUTORS.md | 2 + .../readme/CREDITS.md | 1 + .../readme/USAGE.md | 11 +- .../static/description/index.html | 34 ++++-- .../static/src/js/datepicker.esm.js | 109 ++++++++++------- .../static/src/js/datetime_field.esm.js | 113 ++++++++++++++++-- .../static/src/xml/datetime_field.xml | 8 -- 9 files changed, 238 insertions(+), 85 deletions(-) create mode 100644 web_datetime_picker_default_time/readme/CREDITS.md delete mode 100644 web_datetime_picker_default_time/static/src/xml/datetime_field.xml diff --git a/web_datetime_picker_default_time/README.rst b/web_datetime_picker_default_time/README.rst index c86cd7a52eaf..aa2f0a3c6566 100644 --- a/web_datetime_picker_default_time/README.rst +++ b/web_datetime_picker_default_time/README.rst @@ -17,13 +17,13 @@ Web Datetime Picker Default Time :target: http://www.gnu.org/licenses/agpl-3.0-standalone.html :alt: License: AGPL-3 .. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fweb-lightgray.png?logo=github - :target: https://github.com/OCA/web/tree/16.0/web_datetime_picker_default_time + :target: https://github.com/OCA/web/tree/18.0/web_datetime_picker_default_time :alt: OCA/web .. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png - :target: https://translation.odoo-community.org/projects/web-16-0/web-16-0-web_datetime_picker_default_time + :target: https://translation.odoo-community.org/projects/web-18-0/web-18-0-web_datetime_picker_default_time :alt: Translate me on Weblate .. |badge5| image:: https://img.shields.io/badge/runboat-Try%20me-875A7B.png - :target: https://runboat.odoo-community.org/builds?repo=OCA/web&target_branch=16.0 + :target: https://runboat.odoo-community.org/builds?repo=OCA/web&target_branch=18.0 :alt: Try me on Runboat |badge1| |badge2| |badge3| |badge4| |badge5| @@ -45,14 +45,22 @@ browser. Usage ===== -You can define the default time as follows for a static value: +**Static Default Time** You can define the default time as follows for a +static value For ``widget="datetime"``: .. code:: xml - + -Otherwise you can also use a JSON field to make it dynamic through a -compute function, and reference this field in the view: +For ``widget="daterange"``: + +.. code:: xml + + + +**Dynamic Default Time** Otherwise you can also use a JSON field to make +it dynamic through a compute function, and reference this field in the +view: .. code:: python @@ -70,7 +78,7 @@ compute function, and reference this field in the view: Known issues / Roadmap ====================== -- Handle Timezone related to the default time +- Handle Timezone related to the default time Bug Tracker =========== @@ -78,7 +86,7 @@ Bug Tracker Bugs are tracked on `GitHub Issues `_. In case of trouble, please check there if your issue has already been reported. If you spotted it first, help us to smash it by providing a detailed and welcomed -`feedback `_. +`feedback `_. Do not contact contributors directly about support or help with technical issues. @@ -93,8 +101,18 @@ Authors Contributors ------------ -- Akim Juillerat akim.juillerat@camptocamp.com -- Iván Todorovich ivan.todorovich@camptocamp.com +- Akim Juillerat akim.juillerat@camptocamp.com +- Iván Todorovich ivan.todorovich@camptocamp.com + +- `Trobz `__: + + - Tuan Nguyen + +Other credits +------------- + +The migration of this module from 16.0 to 18.0 was financially supported +by Camptocamp. Maintainers ----------- @@ -117,6 +135,6 @@ Current `maintainer `__: |maintainer-grindtildeath| -This module is part of the `OCA/web `_ project on GitHub. +This module is part of the `OCA/web `_ project on GitHub. You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute. diff --git a/web_datetime_picker_default_time/__manifest__.py b/web_datetime_picker_default_time/__manifest__.py index 98d289a2b32e..cfd3967b829e 100644 --- a/web_datetime_picker_default_time/__manifest__.py +++ b/web_datetime_picker_default_time/__manifest__.py @@ -3,7 +3,7 @@ { "name": "Web Datetime Picker Default Time", "summary": "Allows to define a default time on datetime picker", - "version": "16.0.1.0.0", + "version": "18.0.1.0.0", "category": "web", "website": "https://github.com/OCA/web", "author": "Camptocamp, Odoo Community Association (OCA)", @@ -15,7 +15,6 @@ "assets": { "web.assets_backend": [ "/web_datetime_picker_default_time/static/src/js/*.js", - "/web_datetime_picker_default_time/static/src/xml/*.xml", ], }, } diff --git a/web_datetime_picker_default_time/readme/CONTRIBUTORS.md b/web_datetime_picker_default_time/readme/CONTRIBUTORS.md index 6168e901d843..1dcb597d37d7 100644 --- a/web_datetime_picker_default_time/readme/CONTRIBUTORS.md +++ b/web_datetime_picker_default_time/readme/CONTRIBUTORS.md @@ -1,2 +1,4 @@ * Akim Juillerat * Iván Todorovich +- [Trobz](https://trobz.com): + - Tuan Nguyen \<\> \ No newline at end of file diff --git a/web_datetime_picker_default_time/readme/CREDITS.md b/web_datetime_picker_default_time/readme/CREDITS.md new file mode 100644 index 000000000000..57e03a9fe7a4 --- /dev/null +++ b/web_datetime_picker_default_time/readme/CREDITS.md @@ -0,0 +1 @@ +The migration of this module from 16.0 to 18.0 was financially supported by Camptocamp. diff --git a/web_datetime_picker_default_time/readme/USAGE.md b/web_datetime_picker_default_time/readme/USAGE.md index 03e2fc174e39..dfafdae45657 100644 --- a/web_datetime_picker_default_time/readme/USAGE.md +++ b/web_datetime_picker_default_time/readme/USAGE.md @@ -1,9 +1,16 @@ -You can define the default time as follows for a static value: +**Static Default Time** +You can define the default time as follows for a static value +For `widget="datetime"`: +```xml + +``` +For `widget="daterange"`: ```xml - + ``` +**Dynamic Default Time** Otherwise you can also use a JSON field to make it dynamic through a compute function, and reference this field in the view: diff --git a/web_datetime_picker_default_time/static/description/index.html b/web_datetime_picker_default_time/static/description/index.html index 8ff4371146e6..64191e63f8c0 100644 --- a/web_datetime_picker_default_time/static/description/index.html +++ b/web_datetime_picker_default_time/static/description/index.html @@ -369,7 +369,7 @@

Web Datetime Picker Default Time

!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! !! source digest: sha256:a5ffb697bdf4c26817212f783a9d4d617e91fcdc912a7750382d3eddaff05f7b !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! --> -

Beta License: AGPL-3 OCA/web Translate me on Weblate Try me on Runboat

+

Beta License: AGPL-3 OCA/web Translate me on Weblate Try me on Runboat

This module customizes the datetime picker widget and allows to define a default time to be applied in case the user selects only a Date.

For example, if a user wants to define a commitment date without having @@ -386,19 +386,26 @@

Web Datetime Picker Default Time

  • Credits
  • Usage

    -

    You can define the default time as follows for a static value:

    +

    Static Default Time You can define the default time as follows for a +static value For widget="datetime":

    -<field name="your_datetime_field" options="{'defaultTime': {'hour': 8, 'minute': 30, 'second': 15 }}"/>
    +<field name="your_datetime_field" widget="datetime" options="{'defaultTime': {'hour': 8, 'minute': 30, 'second': 15 }}"/>
     
    -

    Otherwise you can also use a JSON field to make it dynamic through a -compute function, and reference this field in the view:

    +

    For widget="daterange":

    +
    +<field name="your_start_datetime_field" widget="datetime" options="{'end_date_field': 'your_end_datetime_field', 'defaultStartTime': {'hour': 2, 'minute': 22, 'second': 22,}, 'defaultEndTime': {'hour': 3, 'minute': 33, 'second': 33,}}"/>
    +
    +

    Dynamic Default Time Otherwise you can also use a JSON field to make +it dynamic through a compute function, and reference this field in the +view:

     start_time = field.Json(compute="_compute_start_time")
     
    @@ -422,7 +429,7 @@ 

    Bug Tracker

    Bugs are tracked on GitHub Issues. In case of trouble, please check there if your issue has already been reported. If you spotted it first, help us to smash it by providing a detailed and welcomed -feedback.

    +feedback.

    Do not contact contributors directly about support or help with technical issues.

    @@ -438,10 +445,19 @@

    Contributors

    +
    +
    +

    Other credits

    +

    The migration of this module from 16.0 to 18.0 was financially supported +by Camptocamp.

    -

    Maintainers

    +

    Maintainers

    This module is maintained by the OCA.

    Odoo Community Association @@ -451,7 +467,7 @@

    Maintainers

    promote its widespread use.

    Current maintainer:

    grindtildeath

    -

    This module is part of the OCA/web project on GitHub.

    +

    This module is part of the OCA/web project on GitHub.

    You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.

    diff --git a/web_datetime_picker_default_time/static/src/js/datepicker.esm.js b/web_datetime_picker_default_time/static/src/js/datepicker.esm.js index f453cbf7cc5e..3872f6494b39 100644 --- a/web_datetime_picker_default_time/static/src/js/datepicker.esm.js +++ b/web_datetime_picker_default_time/static/src/js/datepicker.esm.js @@ -1,51 +1,58 @@ -/** @odoo-module **/ /* Copyright 2024 Camptocamp * License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl) */ - -import {DateTimePicker} from "@web/core/datepicker/datepicker"; +import {DateTimePicker} from "@web/core/datetime/datetime_picker"; +import {DateTimePickerPopover} from "@web/core/datetime/datetime_picker_popover"; import {patch} from "@web/core/utils/patch"; -import {localization} from "@web/core/l10n/localization"; - -patch(DateTimePicker.prototype, "DateTimePickerDefaultTime", { - onMounted() { - this._super.apply(this, arguments); - this.addPickerListener("change", ({date, oldDate}) => { - const default_time = this.props.defaultTime; - if (date && !oldDate && default_time) { - // FIXME: Consider TZ - date.set({ - hour: default_time.hour, - minute: default_time.minute, - second: default_time.second, - }); - window.$(this.rootRef.el).datetimepicker("date", date); - } - }); - }, - isStrDate(input_string) { - return input_string.trim().length == localization.dateFormat.length; - }, - customParseValue(input_value, options) { - const default_time = this.props.defaultTime; - let [res, error] = this.parseValueOriginal(input_value, options); - if (default_time && this.isStrDate(input_value)) { - const new_value = res.set({ - hour: default_time.hour, - minute: default_time.minute, - second: default_time.second, - }); - res = new_value; +const {DateTime} = luxon; + +/** + * @typedef {import("@web/core/datetime/datetime_picker").DateTimePickerProps & { + * defaultTime?: { hour: number, minute: number, second: number }, + * defaultStartTime?: { hour: number, minute: number, second: number }, + * defaultEndTime?: { hour: number, minute: number, second: number }, + * }} DateTimePickerProps + */ + +patch(DateTimePicker.prototype, { + /** + * @param {DateTimePickerProps} props + */ + onPropsUpdated(props) { + super.onPropsUpdated(props); + + const timeValues = this.values.map((val, index) => + this.getCustomTimeValues(val, index) + ); + + if (props.range) { + this.state.timeValues = timeValues; + } else { + this.state.timeValues = []; + this.state.timeValues[props.focusedDateIndex] = + timeValues[props.focusedDateIndex]; } - return [res, error]; + + this.adjustFocus(this.values, props.focusedDateIndex); + this.handle12HourSystem(); + this.state.timeValues = this.state.timeValues.map((timeValue) => + timeValue.map(String) + ); }, - initFormat() { - this._super.apply(this, arguments); - this.parseValueOriginal = this.parseValue; - this.parseValue = this.customParseValue; + + getCustomTimeValues(val, index) { + const defaultTime = + this.props.defaultTime || this.props.defaultStartTime || DateTime.local(); + const defaultEndTime = + this.props.defaultEndTime || DateTime.local().plus({hour: 1}); + + const timeSource = index === 1 ? val || defaultEndTime : val || defaultTime; + + return [timeSource.hour, timeSource.minute || 0, timeSource.second || 0]; }, }); -DateTimePicker.props = _.extend({}, DateTimePicker.props, { +DateTimePicker.props = { + ...DateTimePicker.props, defaultTime: { type: Object, shape: { @@ -55,4 +62,24 @@ DateTimePicker.props = _.extend({}, DateTimePicker.props, { }, optional: true, }, -}); + defaultStartTime: { + type: Object, + shape: { + hour: Number, + minute: Number, + second: Number, + }, + optional: true, + }, + defaultEndTime: { + type: Object, + shape: { + hour: Number, + minute: Number, + second: Number, + }, + optional: true, + }, +}; + +DateTimePickerPopover.props.pickerProps.shape = DateTimePicker.props; diff --git a/web_datetime_picker_default_time/static/src/js/datetime_field.esm.js b/web_datetime_picker_default_time/static/src/js/datetime_field.esm.js index 58f46609f94e..71c225bb02df 100644 --- a/web_datetime_picker_default_time/static/src/js/datetime_field.esm.js +++ b/web_datetime_picker_default_time/static/src/js/datetime_field.esm.js @@ -1,20 +1,64 @@ -/** @odoo-module **/ /* Copyright 2024 Camptocamp * License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl) */ -import {DateTimeField} from "@web/views/fields/datetime/datetime_field"; import {patch} from "@web/core/utils/patch"; +import { + DateTimeField, + dateRangeField, + dateTimeField, +} from "@web/views/fields/datetime/datetime_field"; +import { + listDateRangeField, + listDateTimeField, +} from "@web/views/fields/datetime/list_datetime_field"; -patch(DateTimeField.prototype, "DateTimeFieldDefaultTime", { +/** + * @typedef {import("./datepicker.esm").DateTimePickerProps} DateTimePickerProps + */ + +patch(DateTimeField.prototype, { + setup() { + super.setup(); + + this.state.defaultTime = this.defaultTime; + this.state.defaultStartTime = this.defaultStartTime; + this.state.defaultEndTime = this.defaultEndTime; + }, + + // Getter get defaultTime() { if (typeof this.props.defaultTime === "string") { return this.props.record.data[this.props.defaultTime]; } return this.props.defaultTime; }, + + get defaultStartTime() { + if (typeof this.props.defaultStartTime === "string") { + return this.props.record.data[this.props.defaultStartTime]; + } + return this.props.defaultStartTime; + }, + + get defaultEndTime() { + if (typeof this.props.defaultEndTime === "string") { + return this.props.record.data[this.props.defaultEndTime]; + } + return this.props.defaultEndTime; + }, + + // OVERRIDE:remove automatic date calculation + async addDate(valueIndex) { + this.state.focusedDateIndex = valueIndex; + this.state.value = this.values; + this.state.range = true; + + this.openPicker(valueIndex); + }, }); -DateTimeField.props = _.extend({}, DateTimeField.props, { +DateTimeField.props = { + ...DateTimeField.props, defaultTime: { type: [ String, @@ -30,13 +74,60 @@ DateTimeField.props = _.extend({}, DateTimeField.props, { ], optional: true, }, + defaultStartTime: { + type: [ + String, + { + type: Object, + shape: { + hour: Number, + minute: Number, + second: Number, + }, + optional: true, + }, + ], + optional: true, + }, + defaultEndTime: { + type: [ + String, + { + type: Object, + shape: { + hour: Number, + minute: Number, + second: Number, + }, + optional: true, + }, + ], + optional: true, + }, +}; + +const superDateTimeExtractProps = dateTimeField.extractProps; +dateTimeField.extractProps = ({attrs, options}, dynamicInfo) => ({ + ...superDateTimeExtractProps({attrs, options}, dynamicInfo), + defaultTime: options.defaultTime, }); -const super_extractProps = DateTimeField.extractProps; +const superDateRangeExtractProps = dateRangeField.extractProps; +dateRangeField.extractProps = ({attrs, options}, dynamicInfo) => ({ + ...superDateRangeExtractProps({attrs, options}, dynamicInfo), + defaultStartTime: options.defaultStartTime, + defaultEndTime: options.defaultEndTime, +}); -DateTimeField.extractProps = ({attrs}) => { - return { - ...super_extractProps({attrs}), - defaultTime: attrs.options.defaultTime, - }; -}; +const superListDateTimeExtractProps = listDateTimeField.extractProps; +listDateTimeField.extractProps = ({attrs, options}, dynamicInfo) => ({ + ...superListDateTimeExtractProps({attrs, options}, dynamicInfo), + defaultTime: options.defaultTime, +}); + +const superListDateRangeExtractProps = listDateRangeField.extractProps; +listDateRangeField.extractProps = ({attrs, options}, dynamicInfo) => ({ + ...superListDateRangeExtractProps({attrs, options}, dynamicInfo), + defaultStartTime: options.defaultStartTime, + defaultEndTime: options.defaultEndTime, +}); diff --git a/web_datetime_picker_default_time/static/src/xml/datetime_field.xml b/web_datetime_picker_default_time/static/src/xml/datetime_field.xml deleted file mode 100644 index df9affad0de1..000000000000 --- a/web_datetime_picker_default_time/static/src/xml/datetime_field.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - defaultTime - - -