[REF] website: use formViewDialog OWL component

After [1], the frontend 'page properties' dialog was replaced by a 'form
view dialog' of the current 'website.page'.

The dialog structure in [1] was based on a 'PagePropertiesDialogWrapper'
component that handles a 'legacy formViewDialog' widget of the page.

Since 'FormViewDialog' is available as OWL component (starting from [2]),
we can now simplify the current code from:

A- 'PagePropertiesDialogWrapper': creates & opens a legacy FormViewDialog.

to:

B- 'PagePropertiesDialog' (the page formViewDialog): can simply be added
using 'dialog service'.

Remark: a wrapper ('PagePropertiesDialogManager' component) is used
temporarily by the legacy 'website.page' listView to add
'PagePropertiesDialog','DuplicatePageDialog' & 'DeletePageDialog'.
This component should be removed after the update of the listView to OWL
and components will be added using 'dialog service' as in the website
navbar menu code.

Follows the merge of the 'website in backend' task at [1].

[1]: https://github.com/odoo/odoo/commit/31cc10b91dc7762e23b4bde9b945be0c4ce3fe3b
[2]: https://github.com/odoo/odoo/commit/48ef812a635f70571b395f82ffdb2969ce99da9e

task-2687506

Part-of: odoo/odoo#97343
This commit is contained in:
xO-Tx
2022-08-16 16:28:04 +02:00
committed by qsm-odoo
parent e8949d9f79
commit bf34319005
7 changed files with 113 additions and 101 deletions
@@ -4,7 +4,6 @@ import { registry } from '@web/core/registry';
import { useService } from '@web/core/utils/hooks';
import core from 'web.core';
import { AceEditorAdapterComponent } from '../../components/ace_editor/ace_editor';
import { PagePropertiesDialogWrapper } from '../../components/dialog/page_properties';
import { WebsiteEditorComponent } from '../../components/editor/editor';
import { WebsiteTranslator } from '../../components/translator/translator';
import {OptimizeSEODialog} from '@website/components/dialog/seo';
@@ -307,7 +306,6 @@ WebsitePreview.components = {
BlockIframe,
WebsiteTranslator,
AceEditorAdapterComponent,
PagePropertiesDialogWrapper,
};
registry.category('actions').add('website_preview', WebsitePreview);
@@ -34,7 +34,6 @@
reloadIframe.bind="this.reloadIframe"
removeWelcomeMessage.bind="this.removeWelcomeMessage"/>
<AceEditorAdapterComponent t-if="websiteContext.showAceEditor"/>
<PagePropertiesDialogWrapper t-if="websiteContext.showPageProperties"/>
</div>
</t>
@@ -4,11 +4,10 @@ import {CheckBox} from '@web/core/checkbox/checkbox';
import {useService, useAutofocus} from "@web/core/utils/hooks";
import {useWowlService} from '@web/legacy/utils';
import {WebsiteDialog} from './dialog';
import {FormViewDialog} from 'web.view_dialogs';
import {standaloneAdapter} from 'web.OwlCompatibility';
import {qweb} from 'web.core';
import {FormViewDialog} from "@web/views/view_dialogs/form_view_dialog";
import {qweb, _t} from 'web.core';
const {Component, onWillStart, useState, xml, useRef, markup, onRendered} = owl;
const {Component, onWillStart, onRendered, useState, xml, useRef, markup} = owl;
export class PageDependencies extends Component {
setup() {
@@ -55,7 +54,7 @@ export class PageDependencies extends Component {
showDependencies() {
$(this.action.el).popover({
title: this.env._t('Dependencies'),
title: this.env._t("Dependencies"),
boundary: 'viewport',
placement: 'right',
trigger: 'focus',
@@ -101,9 +100,9 @@ export class DeletePageDialog extends Component {
await this.orm.unlink("website.page", [
this.props.pageId,
]);
this.website.goToWebsite();
this.website.goToWebsite({path: '/'});
this.props.close();
this.props.onClose();
this.props.onDelete();
}
}
DeletePageDialog.components = {
@@ -114,7 +113,7 @@ DeletePageDialog.components = {
DeletePageDialog.template = 'website.DeletePageDialog';
DeletePageDialog.props = {
pageId: Number,
onClose: Function,
onDelete: {type: Function, optional: true},
close: Function,
};
@@ -138,7 +137,7 @@ export class DuplicatePageDialog extends Component {
);
this.website.goToWebsite({path: res, edition: true});
}
this.props.onClose();
this.props.onDuplicate();
}
}
DuplicatePageDialog.components = {WebsiteDialog};
@@ -155,108 +154,108 @@ DuplicatePageDialog.template = xml`
</WebsiteDialog>
`;
DuplicatePageDialog.props = {
onClose: Function,
onDuplicate: {type: Function, optional: true},
close: Function,
pageId: Number,
};
export class PagePropertiesDialogWrapper extends Component {
export class PagePropertiesDialog extends FormViewDialog {
setup() {
try {
this.websiteService = useService('website');
this.dialogService = useService('dialog');
this.orm = useService('orm');
} catch {
// Use services in legacy environment.
this.websiteService = useWowlService('website');
this.dialogService = useWowlService('dialog');
this.orm = useWowlService('orm');
}
super.setup();
this.dialog = useService('dialog');
this.website = useService('website');
this.viewProps.resId = this.resId;
}
get resId() {
return this.props.resId || (this.website.currentWebsite && this.website.currentWebsite.metadata.mainObject.id);
}
clonePage() {
this.dialog.add(DuplicatePageDialog, {
pageId: this.resId,
onDuplicate: () => {
this.props.close();
this.props.onClose();
},
});
}
deletePage() {
this.dialog.add(DeletePageDialog, {
pageId: this.resId,
onDelete: () => {
this.props.close();
this.props.onClose();
},
});
}
}
PagePropertiesDialog.template = 'website.PagePropertiesDialog';
PagePropertiesDialog.props = {
...FormViewDialog.props,
onClose: {type: Function, optional: true},
resModel: {type: String, optional: true},
};
PagePropertiesDialog.defaultProps = {
...FormViewDialog.defaultProps,
resModel: 'website.page',
title: _t("Page Properties"),
context: {
form_view_ref: 'website.website_page_properties_view_form',
},
onClose: () => {},
};
// TODO remove this once the 'website.page' listView is adapted to OWL.
export class PagePropertiesDialogManager extends Component {
setup() {
this.dialog = useService('dialog');
onRendered(this.createDialog);
}
createDialog() {
if (this.props.mode === 'clone') {
this.dialogService.add(DuplicatePageDialog, {
pageId: this.pageId,
onClose: this.props.onClose,
});
} else if (this.props.mode === 'delete') {
this.dialogService.add(DeletePageDialog, {
pageId: this.pageId,
onClose: this.props.onClose,
});
} else {
const parent = standaloneAdapter({Component});
const formViewDialog = new FormViewDialog(parent, this.dialogOptions);
formViewDialog.buttons = [...formViewDialog.buttons, ...this.extraButtons];
formViewDialog.on('form_dialog_discarded', parent, () => this.websiteService.context.showPageProperties = false);
formViewDialog.open();
switch (this.props.mode) {
case 'clone':
this.dialog.add(DuplicatePageDialog, {
pageId: this.props.resId,
onDuplicate: this.props.onClose,
});
break;
case 'delete':
this.dialog.add(DeletePageDialog, {
pageId: this.props.resId,
onDelete: this.props.onClose,
});
break;
default:
this.dialog.add(PagePropertiesDialog, {
resId: this.props.resId,
onClose: this.props.onClose,
onRecordSaved: this.props.onRecordSaved,
});
break;
}
}
get pageId() {
return this.props.currentPage || (this.websiteService.currentWebsite && this.websiteService.currentWebsite.metadata.mainObject.id);
}
get dialogOptions() {
return {
res_model: "website.page",
res_id: this.pageId,
context: {
form_view_ref: 'website.website_page_properties_view_form'
},
title: this.env._t("Page Properties"),
size: 'medium',
on_saved: (record, changed) => {
if (changed) {
return this.orm.read("website.page", [this.pageId], ['url']).then(res => {
this.websiteService.goToWebsite({websiteId: record.data.website_id.res_id, path: res[0]['url']});
});
}
},
};
}
get extraButtons() {
const wrapper = this;
return [{
text: this.env._t("Duplicate Page"),
icon: 'fa-clone',
classes: 'btn-link ms-auto',
click: function () {
wrapper.dialogService.add(DuplicatePageDialog, {
pageId: wrapper.pageId,
onClose: this.close.bind(this),
});
},
},
{
text: this.env._t("Delete Page"),
icon: 'fa-trash',
classes: 'btn-link',
click: function () {
wrapper.dialogService.add(DeletePageDialog, {
pageId: wrapper.pageId,
onClose: this.close.bind(this),
});
},
}];
}
}
PagePropertiesDialogWrapper.template = xml``;
PagePropertiesDialogWrapper.props = {
PagePropertiesDialogManager.template = xml``;
PagePropertiesDialogManager.props = {
onClose: {
type: Function,
optional: true,
},
currentPage: {
type: Number,
optional: true,
},
mode: {
type: String,
optional: true,
},
resId: {
type: [Number, Boolean],
optional: true,
},
onRecordSaved: {
type: Function,
optional: true,
}
};
@@ -60,7 +60,7 @@
<p>Are you sure you want to delete this page ?</p>
<p class="text-warning">Don't forget to update all links referring to this page.</p>
<PageDependencies pageId="props.pageId" mode="'collapse'"/>
<CheckBox onChange.bind="onConfirmCheckboxChange">
<CheckBox value="state.confirm" onChange.bind="onConfirmCheckboxChange">
<p class="text-warning">I am sure about this.</p>
</CheckBox>
@@ -75,4 +75,11 @@
</WebsiteDialog>
</t>
<t t-name="website.PagePropertiesDialog" t-inherit="web.FormViewDialog" owl="1">
<xpath expr="//t[@t-set-slot='footer']" position="inside">
<button class="btn btn-link order-last ms-auto" t-on-click="clonePage"><i class="fa fa-fw fa-clone"/>Duplicate Page</button>
<button class="btn btn-link order-last" t-on-click="deletePage"><i class="fa fa-fw fa-trash"/>Delete Page</button>
</xpath>
</t>
</templates>
@@ -6,6 +6,7 @@ import { registry } from "@web/core/registry";
import { patch } from 'web.utils';
import { EditMenuDialog } from '@website/components/dialog/edit_menu';
import { OptimizeSEODialog } from '@website/components/dialog/seo';
import {PagePropertiesDialog} from '@website/components/dialog/page_properties';
const websiteSystrayRegistry = registry.category('website_systray');
const { useState } = owl;
@@ -13,6 +14,7 @@ const { useState } = owl;
patch(NavBar.prototype, 'website_navbar', {
setup() {
this._super();
this.orm = useService('orm');
this.websiteService = useService('website');
this.websiteContext = useState(this.websiteService.context);
@@ -41,8 +43,15 @@ patch(NavBar.prototype, 'website_navbar', {
isDisplayed: () => this.canShowAceEditor(),
},
'website.menu_page_properties': {
openWidget: () => this.websiteContext.showPageProperties = true,
Component: PagePropertiesDialog,
isDisplayed: () => this.canShowPageProperties(),
getProps: () => ({
onRecordSaved: (record) => {
return this.orm.read('website.page', [record.resId], ['url']).then(res => {
this.websiteService.goToWebsite({websiteId: record.data.website_id[0], path: res[0]['url']});
});
},
})
},
};
},
@@ -4,7 +4,7 @@ import ListController from 'web.ListController';
import viewRegistry from 'web.view_registry';
import ListView from 'web.ListView';
import {ComponentWrapper} from 'web.OwlCompatibility';
import {PagePropertiesDialogWrapper} from '@website/components/dialog/page_properties';
import {PagePropertiesDialogManager} from '@website/components/dialog/page_properties';
import {qweb} from 'web.core';
const WebsitePageListController = ListController.extend({
@@ -86,9 +86,10 @@ const WebsitePageListController = ListController.extend({
* @private
*/
async _addDialog(record, mode = '') {
this._pagePropertiesDialog = new ComponentWrapper(this, PagePropertiesDialogWrapper, {
currentPage: record.data.id,
this._pagePropertiesDialog = new ComponentWrapper(this, PagePropertiesDialogManager, {
resId: record.data.id,
onClose: this._onCloseDialog.bind(this),
onRecordSaved: this.reload.bind(this),
mode: mode,
});
await this._pagePropertiesDialog.mount(this.el);
@@ -46,7 +46,6 @@ export const websiteService = {
isPublicRootReady: false,
snippetsLoaded: false,
isMobile: false,
showPageProperties: false,
});
const bus = new EventBus();