diff --git a/README.md b/README.md index 904376a92a4a..a9536f9203ce 100644 --- a/README.md +++ b/README.md @@ -23,11 +23,13 @@ addon | version | maintainers | summary --- | --- | --- | --- [web_calendar_slot_duration](web_calendar_slot_duration/) | 18.0.1.0.0 | Yajo | Customizable calendar slot durations [web_chatter_position](web_chatter_position/) | 18.0.1.0.0 | trisdoan | Add an option to change the chatter position -[web_company_color](web_company_color/) | 18.0.1.0.3 | | Web Company Color +[web_company_color](web_company_color/) | 18.0.1.0.4 | | Web Company Color [web_copy_confirm](web_copy_confirm/) | 18.0.1.0.0 | | Show confirmation dialogue before copying records -[web_dialog_size](web_dialog_size/) | 18.0.1.0.0 | | A module that lets the user expand a dialog box to the full screen width. +[web_datetime_picker_default_time](web_datetime_picker_default_time/) | 18.0.1.0.0 | grindtildeath | Allows to define a default time on datetime picker +[web_dialog_size](web_dialog_size/) | 18.0.1.0.1 | | A module that lets the user expand a dialog box to the full screen width. [web_disable_export_group](web_disable_export_group/) | 18.0.1.0.0 | | Web Disable Export Group [web_editor_class_selector](web_editor_class_selector/) | 18.0.1.0.0 | carlos-lopez-tecnativa | Web editor class selector +[web_editor_disable_chatgpt](web_editor_disable_chatgpt/) | 18.0.1.0.0 | | Web Disable ChatGPT [web_environment_ribbon](web_environment_ribbon/) | 18.0.1.0.3 | | Web Environment Ribbon [web_excel_export_dynamic_expand](web_excel_export_dynamic_expand/) | 18.0.1.0.0 | | Export collapsed groups or the full tree, based on its view. [web_favicon](web_favicon/) | 18.0.1.0.0 | | Allows to set a custom shortcut icon (aka favicon) diff --git a/checklog-odoo.cfg b/checklog-odoo.cfg index 0b55b7bf6638..5054bacdd3d2 100644 --- a/checklog-odoo.cfg +++ b/checklog-odoo.cfg @@ -1,3 +1,4 @@ [checklog-odoo] ignore= WARNING.* 0 failed, 0 error\(s\).* + Missing widget: res_partner_many2one for field of type many2one diff --git a/setup/_metapackage/pyproject.toml b/setup/_metapackage/pyproject.toml index 44d990e66fdd..483741d3482f 100644 --- a/setup/_metapackage/pyproject.toml +++ b/setup/_metapackage/pyproject.toml @@ -1,14 +1,16 @@ [project] name = "odoo-addons-oca-web" -version = "18.0.20251007.0" +version = "18.0.20251015.0" dependencies = [ "odoo-addon-web_calendar_slot_duration==18.0.*", "odoo-addon-web_chatter_position==18.0.*", "odoo-addon-web_company_color==18.0.*", "odoo-addon-web_copy_confirm==18.0.*", + "odoo-addon-web_datetime_picker_default_time==18.0.*", "odoo-addon-web_dialog_size==18.0.*", "odoo-addon-web_disable_export_group==18.0.*", "odoo-addon-web_editor_class_selector==18.0.*", + "odoo-addon-web_editor_disable_chatgpt==18.0.*", "odoo-addon-web_environment_ribbon==18.0.*", "odoo-addon-web_excel_export_dynamic_expand==18.0.*", "odoo-addon-web_favicon==18.0.*", diff --git a/web_company_color/README.rst b/web_company_color/README.rst index 38d79d4f2f0c..13215077c780 100644 --- a/web_company_color/README.rst +++ b/web_company_color/README.rst @@ -11,7 +11,7 @@ Web Company Color !! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - !! source digest: sha256:622d249810675797d351ceaaa800f9df89d92067ce131c14087b0b92fbf78283 + !! source digest: sha256:75f2396aade33370837fa8dc343dfb818e4b777b8115331fed547449727181f5 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! .. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png diff --git a/web_company_color/__manifest__.py b/web_company_color/__manifest__.py index 6bd35b046e8c..be2582397a45 100644 --- a/web_company_color/__manifest__.py +++ b/web_company_color/__manifest__.py @@ -5,7 +5,7 @@ { "name": "Web Company Color", "category": "web", - "version": "18.0.1.0.3", + "version": "18.0.1.0.4", "author": "Alexandre Díaz, Odoo Community Association (OCA)", "website": "https://github.com/OCA/web", "depends": ["web", "base_sparse_field"], diff --git a/web_company_color/models/res_company.py b/web_company_color/models/res_company.py index 0dc6d2147192..f4c296b0fba6 100644 --- a/web_company_color/models/res_company.py +++ b/web_company_color/models/res_company.py @@ -115,7 +115,10 @@ class ResCompany(models.Model): background-color: %(color_navbar_bg_hover)s !important; } } - .o_menu_systray button{ + .o_menu_systray button, + .o_navbar_breadcrumbs, + .o_main_navbar button, + .o_menu_toggle { color: %(color_navbar_text)s !important; &:hover, &:focus, &:active, &:focus:active { background-color: %(color_navbar_bg_hover)s !important; diff --git a/web_company_color/static/description/index.html b/web_company_color/static/description/index.html index 36e812031a5a..8545f0ec29b1 100644 --- a/web_company_color/static/description/index.html +++ b/web_company_color/static/description/index.html @@ -372,7 +372,7 @@

Web Company Color

!! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -!! source digest: sha256:622d249810675797d351ceaaa800f9df89d92067ce131c14087b0b92fbf78283 +!! source digest: sha256:75f2396aade33370837fa8dc343dfb818e4b777b8115331fed547449727181f5 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->

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

This module change navbar colors based in the company logo colors.

diff --git a/web_datetime_picker_default_time/README.rst b/web_datetime_picker_default_time/README.rst new file mode 100644 index 000000000000..67c38940828d --- /dev/null +++ b/web_datetime_picker_default_time/README.rst @@ -0,0 +1,144 @@ +.. image:: https://odoo-community.org/readme-banner-image + :target: https://odoo-community.org/get-involved?utm_source=readme + :alt: Odoo Community Association + +================================ +Web Datetime Picker Default Time +================================ + +.. + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! This file is generated by oca-gen-addon-readme !! + !! changes will be overwritten. !! + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! source digest: sha256:57ed080d68dcc33c99d25c23549366d7703114c6c61f803e30e21f2c01fd0141 + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +.. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png + :target: https://odoo-community.org/page/development-status + :alt: Beta +.. |badge2| image:: https://img.shields.io/badge/license-AGPL--3-blue.png + :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/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-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=18.0 + :alt: Try me on Runboat + +|badge1| |badge2| |badge3| |badge4| |badge5| + +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 +to specify the time on that date, setting the default time value on the +field in the Form view allows to ensure the commitment date will be set +to this time instead of the time when the page was loaded by the +browser. + +**Table of contents** + +.. contents:: + :local: + +Usage +===== + +**Static Default Time** You can define the default time as follows for a +static value For ``widget="datetime"``: + +.. code:: xml + + + +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 + + start_time = field.Json(compute="_compute_start_time") + + def _compute_start_time(self): + for rec in self: + rec.start_time = {'hour': 8, 'minute': 30, 'second': 15 } + +.. code:: xml + + + + +Known issues / Roadmap +====================== + +- Handle Timezone related to the default time + +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 `_. + +Do not contact contributors directly about support or help with technical issues. + +Credits +======= + +Authors +------- + +* Camptocamp + +Contributors +------------ + +- 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 +----------- + +This module is maintained by the OCA. + +.. image:: https://odoo-community.org/logo.png + :alt: Odoo Community Association + :target: https://odoo-community.org + +OCA, or the Odoo Community Association, is a nonprofit organization whose +mission is to support the collaborative development of Odoo features and +promote its widespread use. + +.. |maintainer-grindtildeath| image:: https://github.com/grindtildeath.png?size=40px + :target: https://github.com/grindtildeath + :alt: grindtildeath + +Current `maintainer `__: + +|maintainer-grindtildeath| + +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/__init__.py b/web_datetime_picker_default_time/__init__.py new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/web_datetime_picker_default_time/__manifest__.py b/web_datetime_picker_default_time/__manifest__.py new file mode 100644 index 000000000000..26fb657eac0d --- /dev/null +++ b/web_datetime_picker_default_time/__manifest__.py @@ -0,0 +1,23 @@ +# Copyright 2024 Camptocamp SA +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl) +{ + "name": "Web Datetime Picker Default Time", + "summary": "Allows to define a default time on datetime picker", + "version": "18.0.1.0.0", + "category": "web", + "website": "https://github.com/OCA/web", + "author": "Camptocamp, Odoo Community Association (OCA)", + "maintainers": ["grindtildeath"], + "license": "AGPL-3", + "depends": [ + "web", + ], + "assets": { + "web.assets_backend": [ + "/web_datetime_picker_default_time/static/src/js/*.js", + ], + "web.assets_unit_tests": [ + "web_datetime_picker_default_time/static/tests/web_datetime_picker_default_time.test.js", + ], + }, +} diff --git a/web_datetime_picker_default_time/i18n/it.po b/web_datetime_picker_default_time/i18n/it.po new file mode 100644 index 000000000000..73388557f6d5 --- /dev/null +++ b/web_datetime_picker_default_time/i18n/it.po @@ -0,0 +1,14 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 16.0\n" +"Report-Msgid-Bugs-To: \n" +"Last-Translator: Automatically generated\n" +"Language-Team: none\n" +"Language: it\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" diff --git a/web_datetime_picker_default_time/i18n/web_datetime_picker_default_time.pot b/web_datetime_picker_default_time/i18n/web_datetime_picker_default_time.pot new file mode 100644 index 000000000000..aadee09bfeda --- /dev/null +++ b/web_datetime_picker_default_time/i18n/web_datetime_picker_default_time.pot @@ -0,0 +1,13 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 18.0\n" +"Report-Msgid-Bugs-To: \n" +"Last-Translator: \n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: \n" diff --git a/web_datetime_picker_default_time/pyproject.toml b/web_datetime_picker_default_time/pyproject.toml new file mode 100644 index 000000000000..4231d0cccb3d --- /dev/null +++ b/web_datetime_picker_default_time/pyproject.toml @@ -0,0 +1,3 @@ +[build-system] +requires = ["whool"] +build-backend = "whool.buildapi" diff --git a/web_datetime_picker_default_time/readme/CONTRIBUTORS.md b/web_datetime_picker_default_time/readme/CONTRIBUTORS.md new file mode 100644 index 000000000000..1dcb597d37d7 --- /dev/null +++ b/web_datetime_picker_default_time/readme/CONTRIBUTORS.md @@ -0,0 +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/DESCRIPTION.md b/web_datetime_picker_default_time/readme/DESCRIPTION.md new file mode 100644 index 000000000000..4e15c7e1324a --- /dev/null +++ b/web_datetime_picker_default_time/readme/DESCRIPTION.md @@ -0,0 +1,7 @@ +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 to specify +the time on that date, setting the default time value on the field in the Form view +allows to ensure the commitment date will be set to this time instead of the time +when the page was loaded by the browser. diff --git a/web_datetime_picker_default_time/readme/ROADMAP.md b/web_datetime_picker_default_time/readme/ROADMAP.md new file mode 100644 index 000000000000..53bc263629f1 --- /dev/null +++ b/web_datetime_picker_default_time/readme/ROADMAP.md @@ -0,0 +1 @@ +* Handle Timezone related to the default time diff --git a/web_datetime_picker_default_time/readme/USAGE.md b/web_datetime_picker_default_time/readme/USAGE.md new file mode 100644 index 000000000000..dfafdae45657 --- /dev/null +++ b/web_datetime_picker_default_time/readme/USAGE.md @@ -0,0 +1,28 @@ +**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: + +```python + start_time = field.Json(compute="_compute_start_time") + + def _compute_start_time(self): + for rec in self: + rec.start_time = {'hour': 8, 'minute': 30, 'second': 15 } +``` + +```xml + + +``` diff --git a/web_datetime_picker_default_time/static/description/icon.png b/web_datetime_picker_default_time/static/description/icon.png new file mode 100644 index 000000000000..3a0328b516c4 Binary files /dev/null and b/web_datetime_picker_default_time/static/description/icon.png differ diff --git a/web_datetime_picker_default_time/static/description/index.html b/web_datetime_picker_default_time/static/description/index.html new file mode 100644 index 000000000000..08002cf3a7b4 --- /dev/null +++ b/web_datetime_picker_default_time/static/description/index.html @@ -0,0 +1,482 @@ + + + + + +README.rst + + + +
+ + + +Odoo Community Association + +
+

Web Datetime Picker Default Time

+ +

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 +to specify the time on that date, setting the default time value on the +field in the Form view allows to ensure the commitment date will be set +to this time instead of the time when the page was loaded by the +browser.

+

Table of contents

+ +
+

Usage

+

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

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

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")
+
+def _compute_start_time(self):
+    for rec in self:
+        rec.start_time = {'hour': 8, 'minute': 30, 'second': 15 }
+
+
+<field name="start_time" invisible="1" />
+<field name="your_datetime_field" options="{'defaultTime': 'start_time'}"/>
+
+
+
+

Known issues / Roadmap

+
    +
  • Handle Timezone related to the default time
  • +
+
+
+

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.

+

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

+
+
+

Credits

+
+

Authors

+
    +
  • Camptocamp
  • +
+
+
+

Contributors

+ +
+
+

Other credits

+

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

+
+
+

Maintainers

+

This module is maintained by the OCA.

+ +Odoo Community Association + +

OCA, or the Odoo Community Association, is a nonprofit organization whose +mission is to support the collaborative development of Odoo features and +promote its widespread use.

+

Current maintainer:

+

grindtildeath

+

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 new file mode 100644 index 000000000000..3872f6494b39 --- /dev/null +++ b/web_datetime_picker_default_time/static/src/js/datepicker.esm.js @@ -0,0 +1,85 @@ +/* Copyright 2024 Camptocamp + * License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl) */ +import {DateTimePicker} from "@web/core/datetime/datetime_picker"; +import {DateTimePickerPopover} from "@web/core/datetime/datetime_picker_popover"; +import {patch} from "@web/core/utils/patch"; +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]; + } + + this.adjustFocus(this.values, props.focusedDateIndex); + this.handle12HourSystem(); + this.state.timeValues = this.state.timeValues.map((timeValue) => + timeValue.map(String) + ); + }, + + 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 = { + ...DateTimePicker.props, + defaultTime: { + type: Object, + shape: { + hour: Number, + minute: Number, + second: Number, + }, + 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 new file mode 100644 index 000000000000..3165d9080492 --- /dev/null +++ b/web_datetime_picker_default_time/static/src/js/datetime_field.esm.js @@ -0,0 +1,247 @@ +/* Copyright 2024 Camptocamp + * License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl) */ + +import {useRef} from "@odoo/owl"; +import {localization} from "@web/core/l10n/localization"; +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"; +const {DateTime} = luxon; +/** + * @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; + this.userInputValue = ""; + this.endDateRef = useRef("end-date"); + + // UserInputIndex is used to determine which input the user is typing in + // 0 = start date, 1 = end date + this.userInputIndex = 1; + }, + + // Getter + get defaultTime() { + if (typeof this.props.defaultTime === "string") { + if (!this.props.record.data[this.props.defaultTime]) { + return ""; + } + if (typeof this.props.record.data[this.props.defaultTime] === "string") { + return JSON.parse(this.props.record.data[this.props.defaultTime]); + } + return this.props.record.data[this.props.defaultTime]; + } + return this.props.defaultTime; + }, + + get defaultStartTime() { + if (typeof this.props.defaultStartTime === "string") { + if (!this.props.record.data[this.props.defaultStartTime]) { + return ""; + } + if ( + typeof this.props.record.data[this.props.defaultStartTime] === "string" + ) { + return JSON.parse(this.props.record.data[this.props.defaultStartTime]); + } + return this.props.record.data[this.props.defaultStartTime]; + } + return this.props.defaultStartTime; + }, + + get defaultEndTime() { + if (typeof this.props.defaultEndTime === "string") { + if (!this.props.record.data[this.props.defaultEndTime]) { + return ""; + } + if (typeof this.props.record.data[this.props.defaultEndTime] === "string") { + return JSON.parse(this.props.record.data[this.props.defaultEndTime]); + } + 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); + }, + onInput(ev) { + super.onInput(...arguments); + this.userInputValue = arguments[0].target.value; + if (this.state.range) { + this.userInputIndex = ev.target == this.endDateRef.el ? 1 : 0; + } + }, + getRecordValue() { + let values = super.getRecordValue(...arguments); + if (this.userInputValue) { + if (Array.isArray(values)) { + values[this.userInputIndex] = this.setRangeTimeValue( + values[this.userInputIndex] + ); + } else { + values = this.setTimeValue(values); + } + } + return values; + }, + isStrDate(input_string) { + if (!input_string) { + return false; + } + return input_string.trim().length == localization.dateFormat.length; + }, + setRangeTimeValue(dateValue) { + const default_start_time = this.defaultStartTime; + const default_end_time = this.defaultEndTime; + if ( + !default_start_time || + !default_end_time || + !dateValue || + !DateTime.isDateTime(dateValue) + ) { + return dateValue; + } + if (!this.isStrDate(this.userInputValue)) { + return dateValue; + } + + if (this.userInputIndex) { + // End date + const endDateValue = dateValue.set({ + hour: default_end_time.hour, + minute: default_end_time.minute, + second: default_end_time.second, + }); + this.props.record.update({ + [this.endDateField]: endDateValue, + }); + this.userInputValue = ""; + return endDateValue; + } + + // Start date + const startDateValue = dateValue.set({ + hour: default_start_time.hour, + minute: default_start_time.minute, + second: default_start_time.second, + }); + this.props.record.update({ + [this.startDateField]: startDateValue, + }); + this.userInputValue = ""; + return startDateValue; + }, + setTimeValue(dateValue) { + const default_time = this.defaultTime; + if (!default_time || !dateValue || !DateTime.isDateTime(dateValue)) { + return dateValue; + } + if (!this.isStrDate(this.userInputValue)) { + return dateValue; + } + const newDateValue = dateValue.set({ + hour: default_time.hour, + minute: default_time.minute, + second: default_time.second, + }); + this.props.record.update({ + [this.props.name]: newDateValue, + }); + this.userInputValue = ""; + return newDateValue; + }, +}); + +DateTimeField.props = { + ...DateTimeField.props, + defaultTime: { + type: [ + String, + { + type: Object, + shape: { + hour: Number, + minute: Number, + second: Number, + }, + optional: true, + }, + ], + 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 superDateRangeExtractProps = dateRangeField.extractProps; +dateRangeField.extractProps = ({attrs, options}, dynamicInfo) => ({ + ...superDateRangeExtractProps({attrs, options}, dynamicInfo), + defaultStartTime: options.defaultStartTime, + defaultEndTime: options.defaultEndTime, +}); + +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/tests/web_datetime_picker_default_time.test.js b/web_datetime_picker_default_time/static/tests/web_datetime_picker_default_time.test.js new file mode 100644 index 000000000000..f11696a9f206 --- /dev/null +++ b/web_datetime_picker_default_time/static/tests/web_datetime_picker_default_time.test.js @@ -0,0 +1,166 @@ +import {expect, test} from "@odoo/hoot"; +import {click, hover, queryOne, waitFor} from "@odoo/hoot-dom"; + +import { + contains, + defineModels, + fields, + models, + mountView, + onRpc, +} from "@web/../tests/web_test_helpers"; + +class ProductPricelistItem extends models.Model { + _name = "product.pricelist.item"; + _inherit = []; + + default_date = fields.Json(); + date_start = fields.Datetime(); + date_end = fields.Datetime(); + datetime_field = fields.Datetime({string: "Datetime Field"}); + + _records = [{id: 1, default_date: '{"hour": 8, "minute": 30, "second": 15}'}]; +} + +defineModels([ProductPricelistItem]); + +test("Default time is applied correctly for datetime field", async () => { + await mountView({ + type: "form", + resModel: "product.pricelist.item", + arch: ` +
+ + `, + }); + + const dateTimeFieldSelector = "input[data-field='datetime_field']"; + await click(dateTimeFieldSelector); + await contains(".o_date_picker .o_datetime_button:first").click(); + const dateTimeFieldElement = queryOne(dateTimeFieldSelector); + const date = new Date(dateTimeFieldElement.value); + + expect(date.getHours()).toBe(5); + expect(date.getMinutes()).toBe(5); + expect(date.getSeconds()).toBe(5); +}); + +test("Default time is applied correctly for daterange field", async () => { + await mountView({ + type: "form", + resModel: "product.pricelist.item", + arch: ` +
+ + `, + }); + + // Test defaultStartTime + const dateStartFieldSelector = "input[data-field='date_start']"; + await click(dateStartFieldSelector); + await contains(".o_date_picker .o_datetime_button:first").click(); + const dateStartFieldElement = queryOne(dateStartFieldSelector); + const dateStart = new Date(dateStartFieldElement.value); + + expect(dateStart.getHours()).toBe(2); + expect(dateStart.getMinutes()).toBe(22); + expect(dateStart.getSeconds()).toBe(22); + + // Test defaultEndTime + await hover("div[name='date_start']"); + await contains(".o_add_end_date").click(); + await contains(".o_date_picker:nth-of-type(2) .o_datetime_button:last").click(); + await waitFor("input[data-field='date_end']"); + const dateEndFieldElement = queryOne("input[data-field='date_end']"); + const dateEnd = new Date(dateEndFieldElement.value); + + expect(dateEnd.getHours()).toBe(3); + expect(dateEnd.getMinutes()).toBe(33); + expect(dateEnd.getSeconds()).toBe(33); +}); + +onRpc("has_group", () => true); +test("Default time is applied correctly for list.datetime field", async () => { + await mountView({ + type: "list", + resModel: "product.pricelist.item", + arch: ` + + + `, + }); + + await contains(".o_control_panel_main_buttons .o_list_button_add").click(); + const dateTimeFieldSelector = "input[data-field='datetime_field']"; + await contains(dateTimeFieldSelector).click(); + await contains(".o_date_picker .o_datetime_button:first").click(); + const dateTimeFieldElement = queryOne(dateTimeFieldSelector); + const date = new Date(dateTimeFieldElement.value); + + expect(date.getHours()).toBe(5); + expect(date.getMinutes()).toBe(5); + expect(date.getSeconds()).toBe(5); +}); + +test("Default time is applied correctly for list.daterange field", async () => { + await mountView({ + type: "list", + resModel: "product.pricelist.item", + arch: ` + + + `, + }); + + await contains(".o_control_panel_main_buttons .o_list_button_add").click(); + + // Test defaultStartTime + const dateStartFieldSelector = "input[data-field='date_start']"; + await contains(dateStartFieldSelector).click(); + await contains(".o_date_picker .o_datetime_button:first").click(); + const dateStartFieldElement = queryOne(dateStartFieldSelector); + const dateStart = new Date(dateStartFieldElement.value); + + expect(dateStart.getHours()).toBe(2); + expect(dateStart.getMinutes()).toBe(22); + expect(dateStart.getSeconds()).toBe(22); + + // Test defaultEndTime + await contains(".o_add_end_date").click(); + await contains(".o_date_picker .o_datetime_button:first").click(); + await contains(".o_date_picker .o_datetime_button:last").click(); + await contains(".o_date_picker .o_datetime_button:last").click(); + await contains("button.o_apply").click(); + await waitFor("input[data-field='date_end']", {timeout: 1500}); + + const dateEndFieldElement = queryOne("input[data-field='date_end']"); + const dateEnd = new Date(dateEndFieldElement.value); + + expect(dateEnd.getHours()).toBe(3); + expect(dateEnd.getMinutes()).toBe(33); + expect(dateEnd.getSeconds()).toBe(33); +}); + +test("Dynamic default time is applied correctly", async () => { + await mountView({ + type: "form", + resId: 1, + resModel: "product.pricelist.item", + arch: ` +
+ + + `, + }); + + const dateTimeFieldSelector = "input[data-field='datetime_field']"; + await click(dateTimeFieldSelector); + await waitFor(".o_date_picker .o_datetime_button"); + await click(".o_date_picker .o_datetime_button:first"); + const dateTimeFieldElement = queryOne(dateTimeFieldSelector); + const date = new Date(dateTimeFieldElement.value); + + expect(date.getHours()).toBe(8); + expect(date.getMinutes()).toBe(30); + expect(date.getSeconds()).toBe(15); +}); diff --git a/web_dialog_size/README.rst b/web_dialog_size/README.rst index 9e7bb197c4f1..7089baf74f36 100644 --- a/web_dialog_size/README.rst +++ b/web_dialog_size/README.rst @@ -1,3 +1,7 @@ +.. image:: https://odoo-community.org/readme-banner-image + :target: https://odoo-community.org/get-involved?utm_source=readme + :alt: Odoo Community Association + =============== Web Dialog Size =============== @@ -7,13 +11,13 @@ Web Dialog Size !! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - !! source digest: sha256:6e8cbde132eca54a0b756ffe2922edfe7b701ea5400063603cba71aa0e4de87d + !! source digest: sha256:f6929a4ea631421f13754b691bc3d9a480c45862d49c52fa84f55488d247c1ff !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! .. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png :target: https://odoo-community.org/page/development-status :alt: Beta -.. |badge2| image:: https://img.shields.io/badge/licence-AGPL--3-blue.png +.. |badge2| image:: https://img.shields.io/badge/license-AGPL--3-blue.png :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 diff --git a/web_dialog_size/__manifest__.py b/web_dialog_size/__manifest__.py index baac404f3c98..331b9174f8bc 100644 --- a/web_dialog_size/__manifest__.py +++ b/web_dialog_size/__manifest__.py @@ -15,7 +15,7 @@ "Odoo Community Association (OCA)", "website": "https://github.com/OCA/web", "category": "web", - "version": "18.0.1.0.0", + "version": "18.0.1.0.1", "license": "AGPL-3", "depends": ["web"], "installable": True, diff --git a/web_dialog_size/static/description/index.html b/web_dialog_size/static/description/index.html index e0d9251f239d..42441517a38f 100644 --- a/web_dialog_size/static/description/index.html +++ b/web_dialog_size/static/description/index.html @@ -3,7 +3,7 @@ -Web Dialog Size +README.rst -
-

Web Dialog Size

+
+ + +Odoo Community Association + +
+

Web Dialog Size

-

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

A module that lets the user expand/restore the dialog box size through a button in the upper right corner (imitating most windows managers). It also adds draggable support to the dialogs.

@@ -388,7 +393,7 @@

Web Dialog Size

-

Configuration

+

Configuration

By default, the module respects the caller’s dialog_size option. If you want to set dialog boxes maximized by default, you need to:

    @@ -403,13 +408,13 @@

    Configuration

-

Known issues / Roadmap

+

Known issues / Roadmap

  • Allow setting default dialog size per user.
-

Bug Tracker

+

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 @@ -417,9 +422,9 @@

Bug Tracker

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

-

Credits

+

Credits

-

Authors

+

Authors

  • ACSONE SA/NV
  • Therp BV
  • @@ -429,7 +434,7 @@

    Authors

-

Contributors

+

Contributors

-

Maintainers

+

Maintainers

This module is maintained by the OCA.

Odoo Community Association @@ -464,5 +469,6 @@

Maintainers

+
diff --git a/web_dialog_size/static/src/js/web_dialog_size.esm.js b/web_dialog_size/static/src/js/web_dialog_size.esm.js index 068bc3abd619..18b5b0c9736a 100644 --- a/web_dialog_size/static/src/js/web_dialog_size.esm.js +++ b/web_dialog_size/static/src/js/web_dialog_size.esm.js @@ -1,4 +1,4 @@ -import {Component, onMounted} from "@odoo/owl"; +import {Component, onMounted, onWillRender} from "@odoo/owl"; import {ActionDialog} from "@web/webclient/actions/action_dialog"; import {Dialog} from "@web/core/dialog/dialog"; import {SelectCreateDialog} from "@web/views/view_dialogs/select_create_dialog"; @@ -42,9 +42,15 @@ patch(Dialog.prototype, { super.setup(); this.setSize = this.setSize.bind(this); this.getSize = this.getSize.bind(this); + onWillRender(() => { + if (this._forcedSize && this.props.size !== this._forcedSize) { + this.props.size = this._forcedSize; + } + }); }, setSize(size) { + this._forcedSize = size; this.props.size = size; this.render(); }, diff --git a/web_editor_disable_chatgpt/README.rst b/web_editor_disable_chatgpt/README.rst new file mode 100644 index 000000000000..b570aec908b5 --- /dev/null +++ b/web_editor_disable_chatgpt/README.rst @@ -0,0 +1,88 @@ +.. image:: https://odoo-community.org/readme-banner-image + :target: https://odoo-community.org/get-involved?utm_source=readme + :alt: Odoo Community Association + +=================== +Web Disable ChatGPT +=================== + +.. + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! This file is generated by oca-gen-addon-readme !! + !! changes will be overwritten. !! + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! source digest: sha256:dcefeae4ee9fa287f9f5b19298c4aab7673d0829f175764c7a0adb336e92c14c + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +.. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png + :target: https://odoo-community.org/page/development-status + :alt: Beta +.. |badge2| image:: https://img.shields.io/badge/license-AGPL--3-blue.png + :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/18.0/web_editor_disable_chatgpt + :alt: OCA/web +.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png + :target: https://translation.odoo-community.org/projects/web-18-0/web-18-0-web_editor_disable_chatgpt + :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=18.0 + :alt: Try me on Runboat + +|badge1| |badge2| |badge3| |badge4| |badge5| + +Installing this module removes ChatGPT capabilities from the HTML +editor. + +**Table of contents** + +.. contents:: + :local: + +Known issues / Roadmap +====================== + +- Remove ChatGPT capabilities from WYSIWYG editor. + +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 `_. + +Do not contact contributors directly about support or help with technical issues. + +Credits +======= + +Authors +------- + +* MetricWise + +Contributors +------------ + +- `MetricWise `__: + + - Adam Heinz + +Maintainers +----------- + +This module is maintained by the OCA. + +.. image:: https://odoo-community.org/logo.png + :alt: Odoo Community Association + :target: https://odoo-community.org + +OCA, or the Odoo Community Association, is a nonprofit organization whose +mission is to support the collaborative development of Odoo features and +promote its widespread use. + +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_editor_disable_chatgpt/__init__.py b/web_editor_disable_chatgpt/__init__.py new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/web_editor_disable_chatgpt/__manifest__.py b/web_editor_disable_chatgpt/__manifest__.py new file mode 100644 index 000000000000..f5e3c0653e66 --- /dev/null +++ b/web_editor_disable_chatgpt/__manifest__.py @@ -0,0 +1,17 @@ +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). +{ + "name": "Web Disable ChatGPT", + "version": "18.0.1.0.0", + "license": "AGPL-3", + "author": "MetricWise, Odoo Community Association (OCA)", + "website": "https://github.com/OCA/web", + "category": "Web", + "depends": ["web_editor"], + "installable": True, + "assets": { + "web.assets_backend": [ + "web_editor_disable_chatgpt/static/src/**", + ], + "web.assets_tests": ["web_editor_disable_chatgpt/static/tests/**"], + }, +} diff --git a/web_editor_disable_chatgpt/i18n/it.po b/web_editor_disable_chatgpt/i18n/it.po new file mode 100644 index 000000000000..c0d5085374bd --- /dev/null +++ b/web_editor_disable_chatgpt/i18n/it.po @@ -0,0 +1,14 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 18.0\n" +"Report-Msgid-Bugs-To: \n" +"Last-Translator: Automatically generated\n" +"Language-Team: none\n" +"Language: it\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" diff --git a/web_editor_disable_chatgpt/i18n/web_editor_disable_chatgpt.pot b/web_editor_disable_chatgpt/i18n/web_editor_disable_chatgpt.pot new file mode 100644 index 000000000000..aadee09bfeda --- /dev/null +++ b/web_editor_disable_chatgpt/i18n/web_editor_disable_chatgpt.pot @@ -0,0 +1,13 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 18.0\n" +"Report-Msgid-Bugs-To: \n" +"Last-Translator: \n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: \n" diff --git a/web_editor_disable_chatgpt/pyproject.toml b/web_editor_disable_chatgpt/pyproject.toml new file mode 100644 index 000000000000..4231d0cccb3d --- /dev/null +++ b/web_editor_disable_chatgpt/pyproject.toml @@ -0,0 +1,3 @@ +[build-system] +requires = ["whool"] +build-backend = "whool.buildapi" diff --git a/web_editor_disable_chatgpt/readme/CONTRIBUTORS.md b/web_editor_disable_chatgpt/readme/CONTRIBUTORS.md new file mode 100644 index 000000000000..193e395918f3 --- /dev/null +++ b/web_editor_disable_chatgpt/readme/CONTRIBUTORS.md @@ -0,0 +1,2 @@ +- [MetricWise](https://metricwise.com): + - Adam Heinz \<\> diff --git a/web_editor_disable_chatgpt/readme/DESCRIPTION.md b/web_editor_disable_chatgpt/readme/DESCRIPTION.md new file mode 100644 index 000000000000..2da266127490 --- /dev/null +++ b/web_editor_disable_chatgpt/readme/DESCRIPTION.md @@ -0,0 +1 @@ +Installing this module removes ChatGPT capabilities from the HTML editor. diff --git a/web_editor_disable_chatgpt/readme/ROADMAP.md b/web_editor_disable_chatgpt/readme/ROADMAP.md new file mode 100644 index 000000000000..5ab45c174a50 --- /dev/null +++ b/web_editor_disable_chatgpt/readme/ROADMAP.md @@ -0,0 +1 @@ +* Remove ChatGPT capabilities from WYSIWYG editor. diff --git a/web_editor_disable_chatgpt/static/description/icon.png b/web_editor_disable_chatgpt/static/description/icon.png new file mode 100644 index 000000000000..3a0328b516c4 Binary files /dev/null and b/web_editor_disable_chatgpt/static/description/icon.png differ diff --git a/web_editor_disable_chatgpt/static/description/index.html b/web_editor_disable_chatgpt/static/description/index.html new file mode 100644 index 000000000000..beae50425fea --- /dev/null +++ b/web_editor_disable_chatgpt/static/description/index.html @@ -0,0 +1,440 @@ + + + + + +README.rst + + + +
+ + + +Odoo Community Association + +
+

Web Disable ChatGPT

+ +

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

+

Installing this module removes ChatGPT capabilities from the HTML +editor.

+

Table of contents

+ +
+

Known issues / Roadmap

+
    +
  • Remove ChatGPT capabilities from WYSIWYG editor.
  • +
+
+
+

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.

+

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

+
+
+

Credits

+
+

Authors

+
    +
  • MetricWise
  • +
+
+ +
+

Maintainers

+

This module is maintained by the OCA.

+ +Odoo Community Association + +

OCA, or the Odoo Community Association, is a nonprofit organization whose +mission is to support the collaborative development of Odoo features and +promote its widespread use.

+

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_editor_disable_chatgpt/static/src/main/chatgpt/chatgpt_plugin_patch.esm.js b/web_editor_disable_chatgpt/static/src/main/chatgpt/chatgpt_plugin_patch.esm.js new file mode 100644 index 000000000000..e1ffa2556a26 --- /dev/null +++ b/web_editor_disable_chatgpt/static/src/main/chatgpt/chatgpt_plugin_patch.esm.js @@ -0,0 +1,6 @@ +/* License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). */ + +import {ChatGPTPlugin} from "@html_editor/main/chatgpt/chatgpt_plugin"; +import {MAIN_PLUGINS} from "@html_editor/plugin_sets"; + +MAIN_PLUGINS.splice(MAIN_PLUGINS.indexOf(ChatGPTPlugin), 1); diff --git a/web_editor_disable_chatgpt/static/tests/tours/html_editor_disable_chatgpt_tour.esm.js b/web_editor_disable_chatgpt/static/tests/tours/html_editor_disable_chatgpt_tour.esm.js new file mode 100644 index 000000000000..e1409c4ab969 --- /dev/null +++ b/web_editor_disable_chatgpt/static/tests/tours/html_editor_disable_chatgpt_tour.esm.js @@ -0,0 +1,78 @@ +/* License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). */ + +import {registry} from "@web/core/registry"; +import {scroll} from "@web/../tests/utils"; + +registry.category("web_tour.tours").add("html_editor_disable_chatgpt_tour", { + url: "/odoo/res.partner/3", + steps: () => [ + { + content: "Click on Internal Notes tab", + trigger: ".o_notebook_headers a[name='internal_notes']", + run: "click", + }, + { + trigger: ".note-editable.odoo-editor-editable", + run: "click", + }, + { + content: "Enter text", + trigger: ".note-editable.odoo-editor-editable .o-paragraph", + run: "editor text", + }, + { + content: "Highlight text", + trigger: ".note-editable.odoo-editor-editable .o-paragraph", + run: "dblclick", + }, + { + content: "Ensure toolbar buttons are absent", + trigger: ".o-we-toolbar", + async run() { + if (document.querySelector(".o-we-toolbar .btn[name='chatgpt']")) { + throw new Error("ChatGPT button should be absent"); + } + if (document.querySelector(".o-we-toolbar .btn[name='translate']")) { + throw new Error("Translate with AI button should be absent"); + } + }, + }, + { + content: "Clear text", + trigger: ".note-editable.odoo-editor-editable", + run: "editor", + }, + { + content: "Open Powerbox", + trigger: ".note-editable.odoo-editor-editable", + async run(actions) { + await actions.editor("/"); + document.querySelector(".note-editable").dispatchEvent( + new InputEvent("input", { + inputType: "insertText", + data: "/", + }) + ); + }, + }, + { + content: "Ensure command is absent", + trigger: "div.o-we-powerbox", + async run() { + await scroll(".o-we-powerbox", "bottom"); + for (const node of document.querySelectorAll( + ".o-we-powerbox .o-we-command-name" + )) { + if (node.textContent && node.textContent.includes("ChatGPT")) { + throw new Error("ChatGPT command should be absent"); + } + } + }, + }, + { + content: "Discard changes", + trigger: ".o_form_button_cancel", + run: "click", + }, + ], +}); diff --git a/web_editor_disable_chatgpt/tests/__init__.py b/web_editor_disable_chatgpt/tests/__init__.py new file mode 100644 index 000000000000..2294f718b9e2 --- /dev/null +++ b/web_editor_disable_chatgpt/tests/__init__.py @@ -0,0 +1 @@ +from . import test_tours diff --git a/web_editor_disable_chatgpt/tests/test_tours.py b/web_editor_disable_chatgpt/tests/test_tours.py new file mode 100644 index 000000000000..c13f27051d6f --- /dev/null +++ b/web_editor_disable_chatgpt/tests/test_tours.py @@ -0,0 +1,10 @@ +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). +import odoo.tests + + +@odoo.tests.tagged("post_install", "-at_install") +class TestTours(odoo.tests.HttpCase): + def test_disable_chatgpt(self): + self.start_tour( + "/odoo/res.partner/3", "html_editor_disable_chatgpt_tour", login="admin" + )