[FIX] mail: no crash on edit message in mobile

Before this commit, editing a message in message in a conversation
and then pressing on the paper plane icon was throwing the following
error:

```
TypeError: null is not an object (evaluating 'thread.model')
@_sendMessage
```

This happens because this button was in "send" message mode rather
than in edit mode. Since we cannot post a message while editing a
message, the crash happens because composer is not related to thread
but the message.

This button is not visible in desktop mode, and user should use
suggested keyboard shortcuts or click on links to either save edit or
discard it. In mobile, these interactions are not intuitive.

This commit fixes the issue by keeping the paper-plane button while
editing in mobile but it acts as "save". The labels to save/discard
was not appropriate in mobile, so it has been turned to a simple
button to discard editing.

opw-3670482

closes odoo/odoo#148918

Signed-off-by: Alexandre Kühn (aku) <aku@odoo.com>
This commit is contained in:
Alexandre Kühn
2024-01-20 02:42:54 +00:00
parent 6f4dad6f28
commit 9b3a0b4aa0
3 changed files with 124 additions and 252 deletions
+39 -239
View File
@@ -105,6 +105,37 @@ msgid ""
"%(bold_start)s/command%(bold_end)s to execute a command."
msgstr ""
#. module: mail
#. odoo-javascript
#: code:addons/mail/static/src/core/common/composer.js:0
#, python-format
msgid ""
"%(open_button)s%(icon)s%(open_em)sDiscard "
"editing%(close_em)s%(close_button)s"
msgstr ""
#. module: mail
#. odoo-javascript
#: code:addons/mail/static/src/core/common/composer.js:0
#, python-format
msgid ""
"%(open_samp)sEscape%(close_samp)s %(open_em)sto "
"%(open_cancel)scancel%(close_cancel)s%(close_em)s, %(open_samp)sCTRL-"
"Enter%(close_samp)s %(open_em)sto "
"%(open_save)ssave%(close_save)s%(close_em)s"
msgstr ""
#. module: mail
#. odoo-javascript
#: code:addons/mail/static/src/core/common/composer.js:0
#, python-format
msgid ""
"%(open_samp)sEscape%(close_samp)s %(open_em)sto "
"%(open_cancel)scancel%(close_cancel)s%(close_em)s, "
"%(open_samp)sEnter%(close_samp)s %(open_em)sto "
"%(open_save)ssave%(close_save)s%(close_em)s"
msgstr ""
#. module: mail
#. odoo-javascript
#: code:addons/mail/static/src/discuss/core/web/discuss_core_web_service.js:0
@@ -337,16 +368,6 @@ msgstr ""
msgid "<i class=\"fa fa-globe\" aria-label=\"Document url\"/>"
msgstr ""
#. module: mail
#. odoo-javascript
#: code:addons/mail/static/src/core/common/composer.js:0
#, python-format
msgid ""
"<samp>%(cancel_keybind)s</samp><i> to <a href='#' data-"
"type='%(cancel_type)s'>cancel</a></i>, <samp>%(save_keybind)s</samp><i> to "
"<a href='#' data-type='%(save_type)s'>save</a></i>"
msgstr ""
#. module: mail
#. odoo-javascript
#: code:addons/mail/static/src/core/common/composer.js:0
@@ -880,53 +901,9 @@ msgid "Advanced Options"
msgstr ""
#. module: mail
#: model:ir.model.fields.selection,name:mail.selection__account_journal__activity_exception_decoration__warning
#: model:ir.model.fields.selection,name:mail.selection__account_move__activity_exception_decoration__warning
#: model:ir.model.fields.selection,name:mail.selection__account_payment__activity_exception_decoration__warning
#: model:ir.model.fields.selection,name:mail.selection__crm_lead__activity_exception_decoration__warning
#: model:ir.model.fields.selection,name:mail.selection__event_booth__activity_exception_decoration__warning
#: model:ir.model.fields.selection,name:mail.selection__event_event__activity_exception_decoration__warning
#: model:ir.model.fields.selection,name:mail.selection__event_registration__activity_exception_decoration__warning
#: model:ir.model.fields.selection,name:mail.selection__event_sponsor__activity_exception_decoration__warning
#: model:ir.model.fields.selection,name:mail.selection__event_track__activity_exception_decoration__warning
#: model:ir.model.fields.selection,name:mail.selection__fleet_vehicle__activity_exception_decoration__warning
#: model:ir.model.fields.selection,name:mail.selection__fleet_vehicle_log_contract__activity_exception_decoration__warning
#: model:ir.model.fields.selection,name:mail.selection__fleet_vehicle_log_services__activity_exception_decoration__warning
#: model:ir.model.fields.selection,name:mail.selection__hr_applicant__activity_exception_decoration__warning
#: model:ir.model.fields.selection,name:mail.selection__hr_contract__activity_exception_decoration__warning
#: model:ir.model.fields.selection,name:mail.selection__hr_employee__activity_exception_decoration__warning
#: model:ir.model.fields.selection,name:mail.selection__hr_expense__activity_exception_decoration__warning
#: model:ir.model.fields.selection,name:mail.selection__hr_expense_sheet__activity_exception_decoration__warning
#: model:ir.model.fields.selection,name:mail.selection__hr_leave__activity_exception_decoration__warning
#: model:ir.model.fields.selection,name:mail.selection__hr_leave_allocation__activity_exception_decoration__warning
#: model:ir.model.fields.selection,name:mail.selection__lunch_supplier__activity_exception_decoration__warning
#: model:ir.model.fields.selection,name:mail.selection__mail_activity_mixin__activity_exception_decoration__warning
#: model:ir.model.fields.selection,name:mail.selection__mail_activity_type__decoration_type__warning
#: model:ir.model.fields.selection,name:mail.selection__mailing_mailing__activity_exception_decoration__warning
#: model:ir.model.fields.selection,name:mail.selection__maintenance_equipment__activity_exception_decoration__warning
#: model:ir.model.fields.selection,name:mail.selection__maintenance_request__activity_exception_decoration__warning
#: model:ir.model.fields.selection,name:mail.selection__mrp_production__activity_exception_decoration__warning
#: model:ir.model.fields.selection,name:mail.selection__mrp_unbuild__activity_exception_decoration__warning
#: model:ir.model.fields.selection,name:mail.selection__pos_session__activity_exception_decoration__warning
#: model:ir.model.fields.selection,name:mail.selection__product_pricelist__activity_exception_decoration__warning
#: model:ir.model.fields.selection,name:mail.selection__product_product__activity_exception_decoration__warning
#: model:ir.model.fields.selection,name:mail.selection__product_template__activity_exception_decoration__warning
#: model:ir.model.fields.selection,name:mail.selection__project_project__activity_exception_decoration__warning
#: model:ir.model.fields.selection,name:mail.selection__project_task__activity_exception_decoration__warning
#: model:ir.model.fields.selection,name:mail.selection__project_update__activity_exception_decoration__warning
#: model:ir.model.fields.selection,name:mail.selection__purchase_order__activity_exception_decoration__warning
#: model:ir.model.fields.selection,name:mail.selection__purchase_requisition__activity_exception_decoration__warning
#: model:ir.model.fields.selection,name:mail.selection__repair_order__activity_exception_decoration__warning
#: model:ir.model.fields.selection,name:mail.selection__res_partner__activity_exception_decoration__warning
#: model:ir.model.fields.selection,name:mail.selection__res_partner_bank__activity_exception_decoration__warning
#: model:ir.model.fields.selection,name:mail.selection__sale_order__activity_exception_decoration__warning
#: model:ir.model.fields.selection,name:mail.selection__slide_channel__activity_exception_decoration__warning
#: model:ir.model.fields.selection,name:mail.selection__stock_landed_cost__activity_exception_decoration__warning
#: model:ir.model.fields.selection,name:mail.selection__stock_lot__activity_exception_decoration__warning
#: model:ir.model.fields.selection,name:mail.selection__stock_picking__activity_exception_decoration__warning
#: model:ir.model.fields.selection,name:mail.selection__stock_picking_batch__activity_exception_decoration__warning
#: model:ir.model.fields.selection,name:mail.selection__survey_survey__activity_exception_decoration__warning
#: model:ir.model.fields.selection,name:mail.selection__survey_user_input__activity_exception_decoration__warning
msgid "Alert"
msgstr ""
@@ -2807,7 +2784,6 @@ msgstr ""
msgid "Dismiss"
msgstr ""
#. module: mail
#: model:ir.model.fields,field_description:mail.field_discuss_channel__display_name
#: model:ir.model.fields,field_description:mail.field_discuss_channel_member__display_name
@@ -3354,53 +3330,9 @@ msgstr ""
#. odoo-javascript
#: code:addons/mail/static/src/core/common/notification_model.js:0
#: model:ir.model.fields,field_description:mail.field_mail_activity_schedule__error
#: model:ir.model.fields.selection,name:mail.selection__account_journal__activity_exception_decoration__danger
#: model:ir.model.fields.selection,name:mail.selection__account_move__activity_exception_decoration__danger
#: model:ir.model.fields.selection,name:mail.selection__account_payment__activity_exception_decoration__danger
#: model:ir.model.fields.selection,name:mail.selection__crm_lead__activity_exception_decoration__danger
#: model:ir.model.fields.selection,name:mail.selection__event_booth__activity_exception_decoration__danger
#: model:ir.model.fields.selection,name:mail.selection__event_event__activity_exception_decoration__danger
#: model:ir.model.fields.selection,name:mail.selection__event_registration__activity_exception_decoration__danger
#: model:ir.model.fields.selection,name:mail.selection__event_sponsor__activity_exception_decoration__danger
#: model:ir.model.fields.selection,name:mail.selection__event_track__activity_exception_decoration__danger
#: model:ir.model.fields.selection,name:mail.selection__fleet_vehicle__activity_exception_decoration__danger
#: model:ir.model.fields.selection,name:mail.selection__fleet_vehicle_log_contract__activity_exception_decoration__danger
#: model:ir.model.fields.selection,name:mail.selection__fleet_vehicle_log_services__activity_exception_decoration__danger
#: model:ir.model.fields.selection,name:mail.selection__hr_applicant__activity_exception_decoration__danger
#: model:ir.model.fields.selection,name:mail.selection__hr_contract__activity_exception_decoration__danger
#: model:ir.model.fields.selection,name:mail.selection__hr_employee__activity_exception_decoration__danger
#: model:ir.model.fields.selection,name:mail.selection__hr_expense__activity_exception_decoration__danger
#: model:ir.model.fields.selection,name:mail.selection__hr_expense_sheet__activity_exception_decoration__danger
#: model:ir.model.fields.selection,name:mail.selection__hr_leave__activity_exception_decoration__danger
#: model:ir.model.fields.selection,name:mail.selection__hr_leave_allocation__activity_exception_decoration__danger
#: model:ir.model.fields.selection,name:mail.selection__lunch_supplier__activity_exception_decoration__danger
#: model:ir.model.fields.selection,name:mail.selection__mail_activity_mixin__activity_exception_decoration__danger
#: model:ir.model.fields.selection,name:mail.selection__mail_activity_type__decoration_type__danger
#: model:ir.model.fields.selection,name:mail.selection__mailing_mailing__activity_exception_decoration__danger
#: model:ir.model.fields.selection,name:mail.selection__maintenance_equipment__activity_exception_decoration__danger
#: model:ir.model.fields.selection,name:mail.selection__maintenance_request__activity_exception_decoration__danger
#: model:ir.model.fields.selection,name:mail.selection__mrp_production__activity_exception_decoration__danger
#: model:ir.model.fields.selection,name:mail.selection__mrp_unbuild__activity_exception_decoration__danger
#: model:ir.model.fields.selection,name:mail.selection__pos_session__activity_exception_decoration__danger
#: model:ir.model.fields.selection,name:mail.selection__product_pricelist__activity_exception_decoration__danger
#: model:ir.model.fields.selection,name:mail.selection__product_product__activity_exception_decoration__danger
#: model:ir.model.fields.selection,name:mail.selection__product_template__activity_exception_decoration__danger
#: model:ir.model.fields.selection,name:mail.selection__project_project__activity_exception_decoration__danger
#: model:ir.model.fields.selection,name:mail.selection__project_task__activity_exception_decoration__danger
#: model:ir.model.fields.selection,name:mail.selection__project_update__activity_exception_decoration__danger
#: model:ir.model.fields.selection,name:mail.selection__purchase_order__activity_exception_decoration__danger
#: model:ir.model.fields.selection,name:mail.selection__purchase_requisition__activity_exception_decoration__danger
#: model:ir.model.fields.selection,name:mail.selection__repair_order__activity_exception_decoration__danger
#: model:ir.model.fields.selection,name:mail.selection__res_partner__activity_exception_decoration__danger
#: model:ir.model.fields.selection,name:mail.selection__res_partner_bank__activity_exception_decoration__danger
#: model:ir.model.fields.selection,name:mail.selection__sale_order__activity_exception_decoration__danger
#: model:ir.model.fields.selection,name:mail.selection__slide_channel__activity_exception_decoration__danger
#: model:ir.model.fields.selection,name:mail.selection__stock_landed_cost__activity_exception_decoration__danger
#: model:ir.model.fields.selection,name:mail.selection__stock_lot__activity_exception_decoration__danger
#: model:ir.model.fields.selection,name:mail.selection__stock_picking__activity_exception_decoration__danger
#: model:ir.model.fields.selection,name:mail.selection__stock_picking_batch__activity_exception_decoration__danger
#: model:ir.model.fields.selection,name:mail.selection__survey_survey__activity_exception_decoration__danger
#: model:ir.model.fields.selection,name:mail.selection__survey_user_input__activity_exception_decoration__danger
#, python-format
msgid "Error"
msgstr ""
@@ -5246,7 +5178,7 @@ msgstr ""
#. odoo-javascript
#: code:addons/mail/static/src/discuss/core/public/welcome_page.js:0
#, python-format
msgid "Logged in as"
msgid "Logged in as %s"
msgstr ""
#. module: mail
@@ -6128,6 +6060,13 @@ msgstr ""
msgid "No messages found"
msgstr ""
#. module: mail
#. odoo-javascript
#: code:addons/mail/static/src/core/web/chatter.js:0
#, python-format
msgid "No recipient"
msgstr ""
#. module: mail
#. odoo-python
#: code:addons/mail/wizard/mail_compose_message.py:0
@@ -6685,53 +6624,9 @@ msgstr ""
#. module: mail
#. odoo-javascript
#: code:addons/mail/static/src/core/web/activity_list_popover.xml:0
#: model:ir.model.fields.selection,name:mail.selection__account_journal__activity_state__overdue
#: model:ir.model.fields.selection,name:mail.selection__account_move__activity_state__overdue
#: model:ir.model.fields.selection,name:mail.selection__account_payment__activity_state__overdue
#: model:ir.model.fields.selection,name:mail.selection__crm_lead__activity_state__overdue
#: model:ir.model.fields.selection,name:mail.selection__event_booth__activity_state__overdue
#: model:ir.model.fields.selection,name:mail.selection__event_event__activity_state__overdue
#: model:ir.model.fields.selection,name:mail.selection__event_registration__activity_state__overdue
#: model:ir.model.fields.selection,name:mail.selection__event_sponsor__activity_state__overdue
#: model:ir.model.fields.selection,name:mail.selection__event_track__activity_state__overdue
#: model:ir.model.fields.selection,name:mail.selection__fleet_vehicle__activity_state__overdue
#: model:ir.model.fields.selection,name:mail.selection__fleet_vehicle_log_contract__activity_state__overdue
#: model:ir.model.fields.selection,name:mail.selection__fleet_vehicle_log_services__activity_state__overdue
#: model:ir.model.fields.selection,name:mail.selection__hr_applicant__activity_state__overdue
#: model:ir.model.fields.selection,name:mail.selection__hr_contract__activity_state__overdue
#: model:ir.model.fields.selection,name:mail.selection__hr_employee__activity_state__overdue
#: model:ir.model.fields.selection,name:mail.selection__hr_expense__activity_state__overdue
#: model:ir.model.fields.selection,name:mail.selection__hr_expense_sheet__activity_state__overdue
#: model:ir.model.fields.selection,name:mail.selection__hr_leave__activity_state__overdue
#: model:ir.model.fields.selection,name:mail.selection__hr_leave_allocation__activity_state__overdue
#: model:ir.model.fields.selection,name:mail.selection__lunch_supplier__activity_state__overdue
#: model:ir.model.fields.selection,name:mail.selection__mail_activity__state__overdue
#: model:ir.model.fields.selection,name:mail.selection__mail_activity_mixin__activity_state__overdue
#: model:ir.model.fields.selection,name:mail.selection__mailing_mailing__activity_state__overdue
#: model:ir.model.fields.selection,name:mail.selection__maintenance_equipment__activity_state__overdue
#: model:ir.model.fields.selection,name:mail.selection__maintenance_request__activity_state__overdue
#: model:ir.model.fields.selection,name:mail.selection__mrp_production__activity_state__overdue
#: model:ir.model.fields.selection,name:mail.selection__mrp_unbuild__activity_state__overdue
#: model:ir.model.fields.selection,name:mail.selection__pos_session__activity_state__overdue
#: model:ir.model.fields.selection,name:mail.selection__product_pricelist__activity_state__overdue
#: model:ir.model.fields.selection,name:mail.selection__product_product__activity_state__overdue
#: model:ir.model.fields.selection,name:mail.selection__product_template__activity_state__overdue
#: model:ir.model.fields.selection,name:mail.selection__project_project__activity_state__overdue
#: model:ir.model.fields.selection,name:mail.selection__project_task__activity_state__overdue
#: model:ir.model.fields.selection,name:mail.selection__project_update__activity_state__overdue
#: model:ir.model.fields.selection,name:mail.selection__purchase_order__activity_state__overdue
#: model:ir.model.fields.selection,name:mail.selection__purchase_requisition__activity_state__overdue
#: model:ir.model.fields.selection,name:mail.selection__repair_order__activity_state__overdue
#: model:ir.model.fields.selection,name:mail.selection__res_partner__activity_state__overdue
#: model:ir.model.fields.selection,name:mail.selection__res_partner_bank__activity_state__overdue
#: model:ir.model.fields.selection,name:mail.selection__sale_order__activity_state__overdue
#: model:ir.model.fields.selection,name:mail.selection__slide_channel__activity_state__overdue
#: model:ir.model.fields.selection,name:mail.selection__stock_landed_cost__activity_state__overdue
#: model:ir.model.fields.selection,name:mail.selection__stock_lot__activity_state__overdue
#: model:ir.model.fields.selection,name:mail.selection__stock_picking__activity_state__overdue
#: model:ir.model.fields.selection,name:mail.selection__stock_picking_batch__activity_state__overdue
#: model:ir.model.fields.selection,name:mail.selection__survey_survey__activity_state__overdue
#: model:ir.model.fields.selection,name:mail.selection__survey_user_input__activity_state__overdue
#, python-format
msgid "Overdue"
msgstr ""
@@ -6959,53 +6854,9 @@ msgstr ""
#. module: mail
#. odoo-javascript
#: code:addons/mail/static/src/core/web/activity_list_popover.xml:0
#: model:ir.model.fields.selection,name:mail.selection__account_journal__activity_state__planned
#: model:ir.model.fields.selection,name:mail.selection__account_move__activity_state__planned
#: model:ir.model.fields.selection,name:mail.selection__account_payment__activity_state__planned
#: model:ir.model.fields.selection,name:mail.selection__crm_lead__activity_state__planned
#: model:ir.model.fields.selection,name:mail.selection__event_booth__activity_state__planned
#: model:ir.model.fields.selection,name:mail.selection__event_event__activity_state__planned
#: model:ir.model.fields.selection,name:mail.selection__event_registration__activity_state__planned
#: model:ir.model.fields.selection,name:mail.selection__event_sponsor__activity_state__planned
#: model:ir.model.fields.selection,name:mail.selection__event_track__activity_state__planned
#: model:ir.model.fields.selection,name:mail.selection__fleet_vehicle__activity_state__planned
#: model:ir.model.fields.selection,name:mail.selection__fleet_vehicle_log_contract__activity_state__planned
#: model:ir.model.fields.selection,name:mail.selection__fleet_vehicle_log_services__activity_state__planned
#: model:ir.model.fields.selection,name:mail.selection__hr_applicant__activity_state__planned
#: model:ir.model.fields.selection,name:mail.selection__hr_contract__activity_state__planned
#: model:ir.model.fields.selection,name:mail.selection__hr_employee__activity_state__planned
#: model:ir.model.fields.selection,name:mail.selection__hr_expense__activity_state__planned
#: model:ir.model.fields.selection,name:mail.selection__hr_expense_sheet__activity_state__planned
#: model:ir.model.fields.selection,name:mail.selection__hr_leave__activity_state__planned
#: model:ir.model.fields.selection,name:mail.selection__hr_leave_allocation__activity_state__planned
#: model:ir.model.fields.selection,name:mail.selection__lunch_supplier__activity_state__planned
#: model:ir.model.fields.selection,name:mail.selection__mail_activity__state__planned
#: model:ir.model.fields.selection,name:mail.selection__mail_activity_mixin__activity_state__planned
#: model:ir.model.fields.selection,name:mail.selection__mailing_mailing__activity_state__planned
#: model:ir.model.fields.selection,name:mail.selection__maintenance_equipment__activity_state__planned
#: model:ir.model.fields.selection,name:mail.selection__maintenance_request__activity_state__planned
#: model:ir.model.fields.selection,name:mail.selection__mrp_production__activity_state__planned
#: model:ir.model.fields.selection,name:mail.selection__mrp_unbuild__activity_state__planned
#: model:ir.model.fields.selection,name:mail.selection__pos_session__activity_state__planned
#: model:ir.model.fields.selection,name:mail.selection__product_pricelist__activity_state__planned
#: model:ir.model.fields.selection,name:mail.selection__product_product__activity_state__planned
#: model:ir.model.fields.selection,name:mail.selection__product_template__activity_state__planned
#: model:ir.model.fields.selection,name:mail.selection__project_project__activity_state__planned
#: model:ir.model.fields.selection,name:mail.selection__project_task__activity_state__planned
#: model:ir.model.fields.selection,name:mail.selection__project_update__activity_state__planned
#: model:ir.model.fields.selection,name:mail.selection__purchase_order__activity_state__planned
#: model:ir.model.fields.selection,name:mail.selection__purchase_requisition__activity_state__planned
#: model:ir.model.fields.selection,name:mail.selection__repair_order__activity_state__planned
#: model:ir.model.fields.selection,name:mail.selection__res_partner__activity_state__planned
#: model:ir.model.fields.selection,name:mail.selection__res_partner_bank__activity_state__planned
#: model:ir.model.fields.selection,name:mail.selection__sale_order__activity_state__planned
#: model:ir.model.fields.selection,name:mail.selection__slide_channel__activity_state__planned
#: model:ir.model.fields.selection,name:mail.selection__stock_landed_cost__activity_state__planned
#: model:ir.model.fields.selection,name:mail.selection__stock_lot__activity_state__planned
#: model:ir.model.fields.selection,name:mail.selection__stock_picking__activity_state__planned
#: model:ir.model.fields.selection,name:mail.selection__stock_picking_batch__activity_state__planned
#: model:ir.model.fields.selection,name:mail.selection__survey_survey__activity_state__planned
#: model:ir.model.fields.selection,name:mail.selection__survey_user_input__activity_state__planned
#, python-format
msgid "Planned"
msgstr ""
@@ -9247,53 +9098,9 @@ msgstr ""
#: code:addons/mail/static/src/core/web/activity_list_popover.xml:0
#: code:addons/mail/static/src/core/web/activity_list_popover_item.js:0
#: code:addons/mail/static/src/core/web/activity_menu.xml:0
#: model:ir.model.fields.selection,name:mail.selection__account_journal__activity_state__today
#: model:ir.model.fields.selection,name:mail.selection__account_move__activity_state__today
#: model:ir.model.fields.selection,name:mail.selection__account_payment__activity_state__today
#: model:ir.model.fields.selection,name:mail.selection__crm_lead__activity_state__today
#: model:ir.model.fields.selection,name:mail.selection__event_booth__activity_state__today
#: model:ir.model.fields.selection,name:mail.selection__event_event__activity_state__today
#: model:ir.model.fields.selection,name:mail.selection__event_registration__activity_state__today
#: model:ir.model.fields.selection,name:mail.selection__event_sponsor__activity_state__today
#: model:ir.model.fields.selection,name:mail.selection__event_track__activity_state__today
#: model:ir.model.fields.selection,name:mail.selection__fleet_vehicle__activity_state__today
#: model:ir.model.fields.selection,name:mail.selection__fleet_vehicle_log_contract__activity_state__today
#: model:ir.model.fields.selection,name:mail.selection__fleet_vehicle_log_services__activity_state__today
#: model:ir.model.fields.selection,name:mail.selection__hr_applicant__activity_state__today
#: model:ir.model.fields.selection,name:mail.selection__hr_contract__activity_state__today
#: model:ir.model.fields.selection,name:mail.selection__hr_employee__activity_state__today
#: model:ir.model.fields.selection,name:mail.selection__hr_expense__activity_state__today
#: model:ir.model.fields.selection,name:mail.selection__hr_expense_sheet__activity_state__today
#: model:ir.model.fields.selection,name:mail.selection__hr_leave__activity_state__today
#: model:ir.model.fields.selection,name:mail.selection__hr_leave_allocation__activity_state__today
#: model:ir.model.fields.selection,name:mail.selection__lunch_supplier__activity_state__today
#: model:ir.model.fields.selection,name:mail.selection__mail_activity__state__today
#: model:ir.model.fields.selection,name:mail.selection__mail_activity_mixin__activity_state__today
#: model:ir.model.fields.selection,name:mail.selection__mailing_mailing__activity_state__today
#: model:ir.model.fields.selection,name:mail.selection__maintenance_equipment__activity_state__today
#: model:ir.model.fields.selection,name:mail.selection__maintenance_request__activity_state__today
#: model:ir.model.fields.selection,name:mail.selection__mrp_production__activity_state__today
#: model:ir.model.fields.selection,name:mail.selection__mrp_unbuild__activity_state__today
#: model:ir.model.fields.selection,name:mail.selection__pos_session__activity_state__today
#: model:ir.model.fields.selection,name:mail.selection__product_pricelist__activity_state__today
#: model:ir.model.fields.selection,name:mail.selection__product_product__activity_state__today
#: model:ir.model.fields.selection,name:mail.selection__product_template__activity_state__today
#: model:ir.model.fields.selection,name:mail.selection__project_project__activity_state__today
#: model:ir.model.fields.selection,name:mail.selection__project_task__activity_state__today
#: model:ir.model.fields.selection,name:mail.selection__project_update__activity_state__today
#: model:ir.model.fields.selection,name:mail.selection__purchase_order__activity_state__today
#: model:ir.model.fields.selection,name:mail.selection__purchase_requisition__activity_state__today
#: model:ir.model.fields.selection,name:mail.selection__repair_order__activity_state__today
#: model:ir.model.fields.selection,name:mail.selection__res_partner__activity_state__today
#: model:ir.model.fields.selection,name:mail.selection__res_partner_bank__activity_state__today
#: model:ir.model.fields.selection,name:mail.selection__sale_order__activity_state__today
#: model:ir.model.fields.selection,name:mail.selection__slide_channel__activity_state__today
#: model:ir.model.fields.selection,name:mail.selection__stock_landed_cost__activity_state__today
#: model:ir.model.fields.selection,name:mail.selection__stock_lot__activity_state__today
#: model:ir.model.fields.selection,name:mail.selection__stock_picking__activity_state__today
#: model:ir.model.fields.selection,name:mail.selection__stock_picking_batch__activity_state__today
#: model:ir.model.fields.selection,name:mail.selection__survey_survey__activity_state__today
#: model:ir.model.fields.selection,name:mail.selection__survey_user_input__activity_state__today
#, python-format
msgid "Today"
msgstr ""
@@ -11056,10 +10863,3 @@ msgstr ""
#, python-format
msgid "“%(member_name)s” in “%(channel_name)s”"
msgstr ""
#. module: mail
#. odoo-javascript
#: code:addons/mail/static/src/core/web/chatter.js:0
#, python-format
msgid "No recipient"
msgstr ""
+52 -13
View File
@@ -25,6 +25,7 @@ import {
import { _t } from "@web/core/l10n/translation";
import { useService } from "@web/core/utils/hooks";
import { FileUploader } from "@web/views/fields/file_handler";
import { escape, sprintf } from "@web/core/utils/strings";
const EDIT_CLICK_TYPE = {
CANCEL: "cancel",
@@ -59,7 +60,7 @@ export class Composer extends Component {
className: "",
sidebar: true,
showFullComposer: true,
allowUpload: true
allowUpload: true,
};
static props = [
"composer",
@@ -76,7 +77,7 @@ export class Composer extends Component {
"sidebar?",
"type?",
"showFullComposer?",
"allowUpload?"
"allowUpload?",
];
static template = "mail.Composer";
@@ -209,17 +210,51 @@ export class Composer extends Component {
}
get CANCEL_OR_SAVE_EDIT_TEXT() {
return markup(
_t(
"<samp>%(cancel_keybind)s</samp><i> to <a href='#' data-type='%(cancel_type)s'>cancel</a></i>, <samp>%(save_keybind)s</samp><i> to <a href='#' data-type='%(save_type)s'>save</a></i>",
{
cancel_keybind: _t("Escape"),
cancel_type: EDIT_CLICK_TYPE.CANCEL,
save_keybind: this.sendKeybind,
save_type: EDIT_CLICK_TYPE.SAVE,
}
)
);
if (this.ui.isSmall) {
return markup(
sprintf(
escape(
_t(
"%(open_button)s%(icon)s%(open_em)sDiscard editing%(close_em)s%(close_button)s"
)
),
{
open_button: `<button class='btn px-1 py-0' data-type="${escape(
EDIT_CLICK_TYPE.CANCEL
)}">`,
close_button: "</button>",
icon: `<i class='fa fa-times-circle pe-1' data-type="${escape(
EDIT_CLICK_TYPE.CANCEL
)}"></i>`,
open_em: `<em data-type="${escape(EDIT_CLICK_TYPE.CANCEL)}">`,
close_em: "</em>",
}
)
);
} else {
const translation1 = _t(
"%(open_samp)sEscape%(close_samp)s %(open_em)sto %(open_cancel)scancel%(close_cancel)s%(close_em)s, %(open_samp)sCTRL-Enter%(close_samp)s %(open_em)sto %(open_save)ssave%(close_save)s%(close_em)s"
);
const translation2 = _t(
"%(open_samp)sEscape%(close_samp)s %(open_em)sto %(open_cancel)scancel%(close_cancel)s%(close_em)s, %(open_samp)sEnter%(close_samp)s %(open_em)sto %(open_save)ssave%(close_save)s%(close_em)s"
);
return markup(
sprintf(escape(this.props.mode === "extended" ? translation1 : translation2), {
open_samp: "<samp>",
close_samp: "</samp>",
open_em: "<em>",
close_em: "</em>",
open_cancel: `<a role="button" href="#" data-type="${escape(
EDIT_CLICK_TYPE.CANCEL
)}">`,
close_cancel: "</a>",
open_save: `<a role="button" href="#" data-type="${escape(
EDIT_CLICK_TYPE.SAVE
)}">`,
close_save: "</a>",
})
);
}
}
get SEND_TEXT() {
@@ -518,6 +553,10 @@ export class Composer extends Component {
}
async sendMessage() {
if (this.props.composer.message) {
this.editMessage();
return;
}
await this.processMessage(async (value) => {
const postData = {
attachments: this.props.composer.attachments,
@@ -9,6 +9,7 @@ import { deserializeDateTime } from "@web/core/l10n/dates";
import { getOrigin } from "@web/core/utils/urls";
import { makeDeferred, patchWithCleanup, triggerHotkey } from "@web/../tests/helpers/utils";
import { click, contains, insertText } from "@web/../tests/utils";
import { SIZES, patchUiSize } from "../helpers/patch_ui_size";
const { DateTime } = luxon;
@@ -34,6 +35,38 @@ QUnit.test("Start edition on click edit", async () => {
await contains(".o-mail-Message-editable .o-mail-Composer-input", { value: "Hello world" });
});
QUnit.test("Edit message (mobile)", async () => {
patchUiSize({ size: SIZES.SM });
const pyEnv = await startServer();
const channelId = pyEnv["discuss.channel"].create({
name: "general",
channel_type: "channel",
});
pyEnv["mail.message"].create({
author_id: pyEnv.currentPartnerId,
body: "Hello world",
model: "discuss.channel",
res_id: channelId,
message_type: "comment",
});
const { openDiscuss } = await start();
await openDiscuss();
await click("button", { text: "Channel" });
await click("button", { text: "general" });
await contains(".o-mail-Message");
await click(".o-mail-Message [title='Expand']");
await click(".o-mail-Message [title='Edit']");
await contains(".o-mail-Message-editable .o-mail-Composer-input", { value: "Hello world" });
await click("button", { text: "Discard editing" });
await contains(".o-mail-Message-editable .o-mail-Composer", { count: 0 });
await contains(".o-mail-Message-content", { text: "Hello world" });
await click(".o-mail-Message [title='Expand']");
await click(".o-mail-Message [title='Edit']");
await insertText(".o-mail-Message .o-mail-Composer-input", "edited message", { replace: true });
await click(".o-mail-Message .fa-paper-plane-o");
await contains(".o-mail-Message-content", { text: "edited message" });
});
QUnit.test("Can edit message comment in chatter", async () => {
const pyEnv = await startServer();
const partnerId = pyEnv["res.partner"].create({ name: "TestPartner" });