From c2f394253ef329c62497b8d9986b36183354e474 Mon Sep 17 00:00:00 2001 From: "Guillaume (gdi)" Date: Tue, 23 Aug 2022 12:22:04 +0000 Subject: [PATCH] [IMP] website, *: improve the "edit in backend" button *: base, mrp_account, product, mail, website_blog, website_event, website_forum This commit improves the button that allows to go to the backend view of an object when you are on its corresponding page on the website. The button is more visible and the user can see which object he is going to edit. Note that this commit also: - Changes the access key to translate a website page to ALT + T. - Adds a new access key to edit an object in backend with ALT + E. - Removes the possibility to duplicate a blog post (but this feature will be reintroduced later for all models, generically) **. **: Note that the duplication of blog posts actually had a mistake: The controller to create a new blog post has been added with [1] where it has been decided to not be a follower of the blog posts at their creation. A new controller has been added by [2] to be able to duplicate a blog post, to be consistent with [1], here also the user does not become a follower of the new blog post (the copy). So far, so good. Finally, [3] has changed the blog post creation controller so that the user who creates the blog post is a follower of the new blog post. Unfortunately the same change was not made for the duplicate controller, which is a mistake. There is no reason to be a follower of the newly created blog posts when you go through the add blog post controller but not when you go through the duplication controller. The behaviors should be consistent and there is no reason for there to be a difference. [1]: https://github.com/odoo/odoo/commit/4c3b516a7b988d758a67ff19242e8ed0837d756c [2]: https://github.com/odoo/odoo/commit/fe40538aff2b65f7719840c8e2d6e51e858f560f [3]: https://github.com/odoo/odoo/commit/4bf9dc4078a5ca413539a6fd16400fd5aad46907 task-2889929 closes odoo/odoo#97353 Related: odoo/enterprise#30075 Signed-off-by: Quentin Smetz (qsm) Co-authored-by: qsm-odoo --- addons/mail/models/res_users.py | 1 - addons/mrp_account/models/product.py | 1 - addons/product/models/product_product.py | 2 +- addons/product/models/product_template.py | 2 +- .../static/src/services/website_service.js | 31 +++++++++++++++++++ .../src/systray_items/edit_in_backend.js | 28 +++++++---------- .../src/systray_items/edit_in_backend.xml | 15 ++++----- .../static/src/systray_items/edit_website.js | 2 +- .../static/src/systray_items/new_content.js | 2 +- .../src/systray_items/translate_website.js | 2 +- .../src/systray_items/translate_website.xml | 2 +- addons/website_blog/controllers/main.py | 13 -------- .../src/js/systray_items/edit_in_backend.js | 27 ---------------- .../static/src/js/tours/event_tour.js | 6 +--- .../static/tests/tours/website_event.js | 2 +- addons/website_forum/controllers/main.py | 3 +- odoo/addons/base/models/res_users.py | 2 +- 17 files changed, 60 insertions(+), 81 deletions(-) delete mode 100644 addons/website_blog/static/src/js/systray_items/edit_in_backend.js diff --git a/addons/mail/models/res_users.py b/addons/mail/models/res_users.py index c31df5c5020..5c0a3baec40 100644 --- a/addons/mail/models/res_users.py +++ b/addons/mail/models/res_users.py @@ -16,7 +16,6 @@ class Users(models.Model): """ _name = 'res.users' _inherit = ['res.users'] - _description = 'Users' notification_type = fields.Selection([ ('email', 'Handle by Emails'), diff --git a/addons/mrp_account/models/product.py b/addons/mrp_account/models/product.py index 8aa27a0fae4..ab44b72b50c 100644 --- a/addons/mrp_account/models/product.py +++ b/addons/mrp_account/models/product.py @@ -23,7 +23,6 @@ class ProductTemplate(models.Model): class ProductProduct(models.Model): _name = 'product.product' _inherit = 'product.product' - _description = 'Product' def button_bom_cost(self): self.ensure_one() diff --git a/addons/product/models/product_product.py b/addons/product/models/product_product.py index 9a3d24562ec..0da0554d3f9 100644 --- a/addons/product/models/product_product.py +++ b/addons/product/models/product_product.py @@ -12,7 +12,7 @@ from odoo.tools import float_compare class ProductProduct(models.Model): _name = "product.product" - _description = "Product" + _description = "Product Variant" _inherits = {'product.template': 'product_tmpl_id'} _inherit = ['mail.thread', 'mail.activity.mixin'] _order = 'priority desc, default_code, name, id' diff --git a/addons/product/models/product_template.py b/addons/product/models/product_template.py index 547011f56ef..789750e749d 100644 --- a/addons/product/models/product_template.py +++ b/addons/product/models/product_template.py @@ -15,7 +15,7 @@ _logger = logging.getLogger(__name__) class ProductTemplate(models.Model): _name = "product.template" _inherit = ['mail.thread', 'mail.activity.mixin', 'image.mixin'] - _description = "Product Template" + _description = "Product" _order = "priority desc, name" @tools.ormcache() diff --git a/addons/website/static/src/services/website_service.js b/addons/website/static/src/services/website_service.js index e66c8c895bc..5f84c1c32d1 100644 --- a/addons/website/static/src/services/website_service.js +++ b/addons/website/static/src/services/website_service.js @@ -42,6 +42,9 @@ export const websiteService = { let hasMultiWebsites; let actionJsId; let blockingProcesses = []; + let modelNamesProm = null; + const modelNames = {}; + const context = reactive({ showNewContentModal: false, showAceEditor: false, @@ -222,6 +225,34 @@ export const websiteService = { hideLoader() { bus.trigger('HIDE-WEBSITE-LOADER'); }, + /** + * Returns the (translated) "functional" name of a model + * (_description) given its "technical" name (_name). + * + * @param {string} [model] + * @returns {string} + */ + async getUserModelName(model = this.currentWebsite.metadata.mainObject.model) { + if (!modelNamesProm) { + // FIXME the `get_available_models` is to be removed/changed + // in a near future. This code is to be adapted, probably + // with another helper to map a model functional name from + // its technical map without the need of the right access + // rights (which is why I cannot use search_read here). + modelNamesProm = orm.call("ir.model", "get_available_models") + .then(modelsData => { + for (const modelData of modelsData) { + modelNames[modelData['model']] = modelData['display_name']; + } + }) + // Precaution in case the util is simply removed without + // adapting this method: not critical, we can restore + // later and use the fallback until the fix is made. + .catch(() => {}); + } + await modelNamesProm; + return modelNames[model] || env._t("Data"); + }, }; }, }; diff --git a/addons/website/static/src/systray_items/edit_in_backend.js b/addons/website/static/src/systray_items/edit_in_backend.js index d12586092ea..fd64d3aa3ff 100644 --- a/addons/website/static/src/systray_items/edit_in_backend.js +++ b/addons/website/static/src/systray_items/edit_in_backend.js @@ -1,29 +1,25 @@ /** @odoo-module **/ import { registry } from "@web/core/registry"; -import { useService } from "@web/core/utils/hooks"; -import { Dropdown } from "@web/core/dropdown/dropdown"; -import { DropdownItem } from "@web/core/dropdown/dropdown_item"; +import { useService, useBus } from "@web/core/utils/hooks"; -const { Component, onMounted } = owl; +const { Component, onWillStart, onMounted } = owl; + +const websiteSystrayRegistry = registry.category('website_systray'); export class EditInBackendSystray extends Component { setup() { this.websiteService = useService('website'); this.actionService = useService('action'); + onWillStart(this._updateMainObjectName); + useBus(websiteSystrayRegistry, 'CONTENT-UPDATED', this._updateMainObjectName); + onMounted(() => { this.websiteService.editedObjectPath = null; }); } - getElements() { - return [{ - title: this.env._t("Settings"), - callback: () => this.editInBackend(), - }]; - } - editInBackend() { const { metadata: { mainObject } } = this.websiteService.currentWebsite; this.websiteService.editedObjectPath = this.websiteService.contentWindow.location.pathname; @@ -35,16 +31,16 @@ export class EditInBackendSystray extends Component { view_mode: "form", }); } + + async _updateMainObjectName() { + this.mainObjectName = await this.websiteService.getUserModelName(); + } } EditInBackendSystray.template = "website.EditInBackendSystray"; -EditInBackendSystray.components = { - Dropdown, - DropdownItem -}; export const systrayItem = { Component: EditInBackendSystray, isDisplayed: env => env.services.website.currentWebsite && env.services.website.currentWebsite.metadata.editableInBackend, }; -registry.category("website_systray").add("EditInBackend", systrayItem, { sequence: 7 }); +registry.category("website_systray").add("EditInBackend", systrayItem, { sequence: 9 }); diff --git a/addons/website/static/src/systray_items/edit_in_backend.xml b/addons/website/static/src/systray_items/edit_in_backend.xml index b94cd337a56..e2d68b6549c 100644 --- a/addons/website/static/src/systray_items/edit_in_backend.xml +++ b/addons/website/static/src/systray_items/edit_in_backend.xml @@ -1,14 +1,11 @@ - - - - - - + diff --git a/addons/website/static/src/systray_items/edit_website.js b/addons/website/static/src/systray_items/edit_website.js index b34b6faf5ed..8f44b72728d 100644 --- a/addons/website/static/src/systray_items/edit_website.js +++ b/addons/website/static/src/systray_items/edit_website.js @@ -62,4 +62,4 @@ export const systrayItem = { isDisplayed: (env) => env.services.website.currentWebsite.metadata.editable, }; -registry.category("website_systray").add("EditWebsite", systrayItem, { sequence: 8 }); +registry.category("website_systray").add("EditWebsite", systrayItem, { sequence: 7 }); diff --git a/addons/website/static/src/systray_items/new_content.js b/addons/website/static/src/systray_items/new_content.js index deca6bd67ff..bbc627c926e 100644 --- a/addons/website/static/src/systray_items/new_content.js +++ b/addons/website/static/src/systray_items/new_content.js @@ -96,7 +96,7 @@ export class NewContentModal extends Component { moduleXmlId: 'base.module_website_hr_recruitment', status: MODULE_STATUS.NOT_INSTALLED, icon: xml``, - title: this.env._t('Job Offer'), + title: this.env._t('Job Position'), }, { moduleXmlId: 'base.module_website_sale', diff --git a/addons/website/static/src/systray_items/translate_website.js b/addons/website/static/src/systray_items/translate_website.js index 630f447b54e..c1c7881bf5a 100644 --- a/addons/website/static/src/systray_items/translate_website.js +++ b/addons/website/static/src/systray_items/translate_website.js @@ -32,4 +32,4 @@ export const systrayItem = { isDisplayed: env => env.services.website.currentWebsite && env.services.website.currentWebsite.metadata.translatable, }; -registry.category("website_systray").add("TranslateWebsiteSystray", systrayItem, { sequence: 9 }); +registry.category("website_systray").add("TranslateWebsiteSystray", systrayItem, { sequence: 8 }); diff --git a/addons/website/static/src/systray_items/translate_website.xml b/addons/website/static/src/systray_items/translate_website.xml index 940b51c3339..5e1a0602574 100644 --- a/addons/website/static/src/systray_items/translate_website.xml +++ b/addons/website/static/src/systray_items/translate_website.xml @@ -3,7 +3,7 @@
- + TRANSLATE diff --git a/addons/website_blog/controllers/main.py b/addons/website_blog/controllers/main.py index e197fa5403d..4d3668a0c0d 100644 --- a/addons/website_blog/controllers/main.py +++ b/addons/website_blog/controllers/main.py @@ -205,7 +205,6 @@ class WebsiteBlog(http.Controller): if blog: values['main_object'] = blog - values['edit_in_backend'] = True values['blog_url'] = QueryURL('', ['blog', 'tag'], blog=blog, tag=tag, date_begin=date_begin, date_end=date_end, search=search) else: values['blog_url'] = QueryURL('/blog', ['tag'], date_begin=date_begin, date_end=date_end, search=search) @@ -301,15 +300,3 @@ class WebsiteBlog(http.Controller): request.session['posts_viewed'].append(blog_post.id) request.session.modified = True return response - - @http.route('/blog/post_duplicate', type='http', auth="user", website=True, methods=['POST']) - def blog_post_copy(self, blog_post_id, **post): - """ Duplicate a blog. - - :param blog_post_id: id of the blog post currently browsed. - - :return redirect to the new blog created - """ - new_blog_post = request.env['blog.post'].with_context(mail_create_nosubscribe=True).browse(int(blog_post_id)).copy() - client_action_url = request.env["website"].get_client_action_url(f"/blog/{slug(new_blog_post.blog_id)}/{slug(new_blog_post)}", True) - return request.redirect(client_action_url) diff --git a/addons/website_blog/static/src/js/systray_items/edit_in_backend.js b/addons/website_blog/static/src/js/systray_items/edit_in_backend.js deleted file mode 100644 index f1ad5a5d6a1..00000000000 --- a/addons/website_blog/static/src/js/systray_items/edit_in_backend.js +++ /dev/null @@ -1,27 +0,0 @@ -/** @odoo-module **/ - -import { EditInBackendSystray } from '@website/systray_items/edit_in_backend'; -import { patch } from 'web.utils'; -import wUtils from 'website.utils'; - -patch(EditInBackendSystray.prototype, 'website_blog_edit_in_backend', { - /** - * @override - */ - getElements() { - const elements = this._super(); - const { metadata: { mainObject } } = this.websiteService.currentWebsite; - if (mainObject.model === 'blog.post') { - return [...elements, { - title: this.env._t("Duplicate"), - callback: () => this.duplicate(), - }]; - } - return elements; - }, - - async duplicate() { - const { metadata: { mainObject } } = this.websiteService.currentWebsite; - wUtils.sendRequest('/blog/post_duplicate', { blog_post_id: mainObject.id }); - } -}); diff --git a/addons/website_event/static/src/js/tours/event_tour.js b/addons/website_event/static/src/js/tours/event_tour.js index 8229e01048d..4f629ed59aa 100644 --- a/addons/website_event/static/src/js/tours/event_tour.js +++ b/addons/website_event/static/src/js/tours/event_tour.js @@ -40,11 +40,7 @@ EventAdditionalTourSteps.include({ content: Markup(_t("Looking great! Let's now publish this page so that it becomes visible on your website!")), position: 'bottom', }, { - trigger: '.o_menu_systray_item.o_website_edit_in_backend .dropdown-toggle', - content: _t("Want to change your event configuration? Let's go back to the event form."), - position: 'bottom', - }, { - trigger: '.o_menu_systray_item.o_website_edit_in_backend .dropdown-menu .dropdown-item', + trigger: '.o_website_edit_in_backend > a', extra_trigger: 'iframe .o_wevent_event', content: _t("This shortcut will bring you right back to the event form."), position: 'bottom' diff --git a/addons/website_event/static/tests/tours/website_event.js b/addons/website_event/static/tests/tours/website_event.js index 3e6364518e6..30d958d061b 100644 --- a/addons/website_event/static/tests/tours/website_event.js +++ b/addons/website_event/static/tests/tours/website_event.js @@ -62,7 +62,7 @@ odoo.define("website_event.tour", function (require) { content: _t("Click to publish your event."), position: "top", }, { - trigger: ".o_menu_systray_item.o_website_edit_in_backend", + trigger: ".o_website_edit_in_backend > a", content: _t("Click here to customize your event further."), position: "bottom", }]); diff --git a/addons/website_forum/controllers/main.py b/addons/website_forum/controllers/main.py index d8f3339cd9c..f0e01a317b8 100644 --- a/addons/website_forum/controllers/main.py +++ b/addons/website_forum/controllers/main.py @@ -155,7 +155,7 @@ class WebsiteForum(WebsiteProfile): values = self._prepare_user_values(forum=forum, searches=post, header={'ask_hide': not forum.active}) values.update({ 'main_object': tag or forum, - 'edit_in_backend': not tag, + 'edit_in_backend': True, 'question_ids': question_ids, 'question_count': question_count, 'search_count': question_count, @@ -258,6 +258,7 @@ class WebsiteForum(WebsiteProfile): values = self._prepare_user_values(forum=forum, searches=post) values.update({ 'main_object': question, + 'edit_in_backend': True, 'question': question, 'can_bump': (question.forum_id.allow_bump and not question.child_count and (datetime.today() - question.write_date).days > 9), 'header': {'question_data': True}, diff --git a/odoo/addons/base/models/res_users.py b/odoo/addons/base/models/res_users.py index 35d12e23322..403f16d5af3 100644 --- a/odoo/addons/base/models/res_users.py +++ b/odoo/addons/base/models/res_users.py @@ -244,7 +244,7 @@ class Users(models.Model): avatar, ... The user model is now dedicated to technical data. """ _name = "res.users" - _description = 'Users' + _description = 'User' _inherits = {'res.partner': 'partner_id'} _order = 'name, login'