From 2eef2b5430ce889baa7b898fb251e7b4cac6a2b7 Mon Sep 17 00:00:00 2001 From: Younn Olivier Date: Fri, 11 Mar 2022 11:14:52 +0100 Subject: [PATCH] [FIX] website: return to the correct url after editing in backend Before this commit, clicking on the breadcrumb item "Website Editor" after an "Edit in backend" systray item click would not redirect to the edited object path. It would redo the website_editor action with the initial params (most often path is undefined, and the component will by default redirect to '/'). Now, when clicking on the "Edit in backend" systray, the frontend path of the edited object is saved in the service. The client action component takes it as the default path for the iframe if there is one. See merge commit for more information. task-2687506 --- .../website_preview/website_preview.js | 39 +++++++++++-------- .../static/src/services/website_service.js | 14 +++++++ .../src/systray_items/edit_in_backend.js | 7 +++- 3 files changed, 42 insertions(+), 18 deletions(-) diff --git a/addons/website/static/src/client_actions/website_preview/website_preview.js b/addons/website/static/src/client_actions/website_preview/website_preview.js index c65c708e9f7..22df3a6b97f 100644 --- a/addons/website/static/src/client_actions/website_preview/website_preview.js +++ b/addons/website/static/src/client_actions/website_preview/website_preview.js @@ -27,6 +27,7 @@ export class WebsitePreview extends Component { return () => { this.websiteService.currentWebsiteId = null; this.websiteService.pageDocument = null; + this.websiteService.contentWindow = null; }; }, () => [this.props.action.context.params]); } @@ -46,25 +47,28 @@ export class WebsitePreview extends Component { } get path() { - let path = this.props.action.context.params && this.props.action.context.params.path; - if (path) { - const url = new URL(path, window.location.origin); - if (this._isTopWindowURL(url)) { - // If the client action is initialized with a path that - // should not be opened inside the iframe (= something we - // would want to open on the top window), we consider that - // this is not a valid flow. Instead of trying to open it on - // the top window, we initialize the iframe with the - // website homepage... - path = '/'; + let path = this.websiteService.editedObjectPath; + if (!path) { + path = this.props.action.context.params && this.props.action.context.params.path; + if (path) { + const url = new URL(path, window.location.origin); + if (this._isTopWindowURL(url)) { + // If the client action is initialized with a path that + // should not be opened inside the iframe (= something we + // would want to open on the top window), we consider that + // this is not a valid flow. Instead of trying to open it on + // the top window, we initialize the iframe with the + // website homepage... + path = '/'; + } else { + // ... otherwise, the path still needs to be normalized (as + // it would be if the given path was used as an href of a + // element). + path = url.pathname + url.search + url.hash; + } } else { - // ... otherwise, the path still needs to be normalized (as - // it would be if the given path was used as an href of a - // element). - path = url.pathname + url.search + url.hash; + path = '/'; } - } else { - path = '/'; } return path; } @@ -91,6 +95,7 @@ export class WebsitePreview extends Component { this.title.setParts({ action: this.currentTitle }); this.websiteService.pageDocument = this.iframe.el.contentDocument; + this.websiteService.contentWindow = this.iframe.el.contentWindow; // Before leaving the iframe, its content is replicated on an // underlying iframe, to avoid for white flashes (visible on diff --git a/addons/website/static/src/services/website_service.js b/addons/website/static/src/services/website_service.js index 89a043118c2..1ec9b4fbda2 100644 --- a/addons/website/static/src/services/website_service.js +++ b/addons/website/static/src/services/website_service.js @@ -27,6 +27,8 @@ export const websiteService = { let currentMetadata = {}; let fullscreen; let pageDocument; + let contentWindow; + let editedObjectPath; const context = reactive({ showNewContentModal: false, }); @@ -85,6 +87,18 @@ export const websiteService = { get pageDocument() { return pageDocument; }, + set contentWindow(window) { + contentWindow = window; + }, + get contentWindow() { + return contentWindow; + }, + set editedObjectPath(path) { + editedObjectPath = path; + }, + get editedObjectPath() { + return editedObjectPath; + }, goToWebsite({ websiteId = currentWebsiteId || websites[0].id, path = '/' } = {}) { action.doAction('website.website_preview', { clearBreadcrumbs: true, 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 1402230b250..d12586092ea 100644 --- a/addons/website/static/src/systray_items/edit_in_backend.js +++ b/addons/website/static/src/systray_items/edit_in_backend.js @@ -5,12 +5,16 @@ import { useService } from "@web/core/utils/hooks"; import { Dropdown } from "@web/core/dropdown/dropdown"; import { DropdownItem } from "@web/core/dropdown/dropdown_item"; -const { Component } = owl; +const { Component, onMounted } = owl; export class EditInBackendSystray extends Component { setup() { this.websiteService = useService('website'); this.actionService = useService('action'); + + onMounted(() => { + this.websiteService.editedObjectPath = null; + }); } getElements() { @@ -22,6 +26,7 @@ export class EditInBackendSystray extends Component { editInBackend() { const { metadata: { mainObject } } = this.websiteService.currentWebsite; + this.websiteService.editedObjectPath = this.websiteService.contentWindow.location.pathname; this.actionService.doAction({ res_model: mainObject.model, res_id: mainObject.id,