+
+
+ Start Now
+
+
-
-
-
-
Building your website...
-
-
- TIP: Once loaded, follow the
-
-
pointer to build the perfect page in 7 steps.
-
+
+
+
+
+
+
+
+
+
+
-
+
+
+
+
+
+
+
+ -
+ Pick a Theme
+ Don't worry, you can switch later.
+
+
+
+
+
+
+
+
+
diff --git a/addons/website/static/src/components/views/theme_preview_form.js b/addons/website/static/src/components/views/theme_preview_form.js
index 593c69a3e7e..169f4cd4621 100644
--- a/addons/website/static/src/components/views/theme_preview_form.js
+++ b/addons/website/static/src/components/views/theme_preview_form.js
@@ -1,157 +1,98 @@
-odoo.define('website.theme_preview_form', function (require) {
-"use strict";
+/** @odoo-module **/
-var FormController = require('web.FormController');
-var FormView = require('web.FormView');
-var viewRegistry = require('web.view_registry');
-var core = require('web.core');
-var qweb = core.qweb;
+import { ControlPanel } from "@web/search/control_panel/control_panel";
+import { FormController } from "@web/views/form/form_controller";
+import { formView } from "@web/views/form/form_view";
+import { registry } from "@web/core/registry";
+import { useService } from "@web/core/utils/hooks";
+import { ViewButton } from "@web/views/view_button/view_button";
+const { useSubEnv, useEnv } = owl;
/*
* Common code for theme installation/update handler.
+* It overrides the onClickViewButton function that's present in the env.
+* That way, we display our own Loader and make a silent call to the ORM.
*/
-const ThemePreviewControllerCommon = {
- /**
- * Called to add loading effect and install/pdate the selected theme depending on action.
- *
- * @private
- * @param {number} res_id
- * @param {String} action
- */
- _handleThemeAction(res_id, action) {
- this.$loader = $(qweb.render('website.ThemePreview.Loader', {
- 'showTips': action !== 'button_refresh_theme',
- }));
- let actionCallback = undefined;
- this._addLoader();
- switch (action) {
- case 'button_choose_theme':
- actionCallback = result => {
- this.do_action(result);
- this._removeLoader();
- };
- break;
- case 'button_refresh_theme':
- actionCallback = () => this._removeLoader();
- break;
+export function useLoaderOnClick() {
+ const website = useService('website');
+ const orm = useService('orm');
+ const action = useService('action');
+ const env = useEnv();
+ const previousOnClickViewButton = env.onClickViewButton;
+ useSubEnv({
+ async onClickViewButton(params) {
+ const name = params.clickParams.name;
+ if (['button_refresh_theme', 'button_choose_theme'].includes(name)) {
+ website.showLoader({ showTips: name !== 'button_refresh_theme' });
+ try {
+ const resParams = params.getResParams();
+ const callback = await orm.silent.call(resParams.resModel, name, [[resParams.resId]]);
+ if (callback) {
+ await action.doAction(callback);
+ }
+ website.hideLoader();
+ } catch (error) {
+ website.hideLoader();
+ throw error;
+ }
+ } else {
+ return previousOnClickViewButton(...arguments);
+ }
}
- const rpcData = {
- model: 'ir.module.module',
- method: action,
- args: [res_id],
- context: this.initialState.context,
- };
- const rpcOptions = {
- shadow: true,
- };
- this._rpc(rpcData, rpcOptions)
- .then(actionCallback)
- .guardedCatch(() => this._removeLoader());
- },
+ });
+}
+
+class ThemePreviewFormController extends FormController {
/**
- * Called to add loader element in DOM.
- *
- * @private
+ * @override
*/
- _addLoader() {
- $('body').append(this.$loader);
- },
- /**
- * @private
- */
- _removeLoader() {
- this.$loader.remove();
+ setup() {
+ super.setup();
+ useLoaderOnClick();
}
-};
-
-var ThemePreviewController = FormController.extend(ThemePreviewControllerCommon, {
- events: Object.assign({}, FormController.prototype.events, {
- 'click .o_use_theme': '_onStartNowClick',
- 'click .o_switch_theme': '_onSwitchThemeClick',
- 'change input[name="viewer"]': '_onSwitchButtonChange',
- }),
/**
* @override
*/
- start: function () {
- this.$el.addClass('o_view_form_theme_preview_controller');
- return this._super.apply(this, arguments);
- },
-
- // -------------------------------------------------------------------------
- // Public
- // -------------------------------------------------------------------------
-
- /**
- * @override
- */
- renderButtons: function ($node) {
- this.$buttons = $(qweb.render('website.ThemePreview.Buttons'));
- if ($node) {
- $node.html(this.$buttons);
- }
- },
- /**
- * Overriden to prevent the controller from hiding the buttons
- * @see FormController
- *
- * @override
- */
- updateButtons: function () { },
-
- // -------------------------------------------------------------------------
- // Private
- // -------------------------------------------------------------------------
- /**
- * Add Switcher View Mobile / Desktop near pager
- *
- * @private
- */
- _updateControlPanelProps: async function () {
- const props = this._super(...arguments);
- const $switchModeButton = $(qweb.render('website.ThemePreview.SwitchModeButton'));
- this.controlPanelProps.cp_content.$pager = $switchModeButton;
- return props;
- },
-
- // -------------------------------------------------------------------------
- // Handlers
- // -------------------------------------------------------------------------
- /**
- * Handler called when user click on 'Desktop/Mobile' switcher button.
- *
- * @private
- */
- _onSwitchButtonChange: function () {
- this.$('.o_preview_frame').toggleClass('is_mobile');
- },
+ get className() {
+ return {...super.className, 'o_view_form_theme_preview_controller': true};
+ }
/**
* Handler called when user click on 'Choose another theme' button.
- *
- * @private
*/
- _onSwitchThemeClick: function () {
- this.trigger_up('history_back');
- },
- /**
- * Handler called when user click on 'START NOW' button in form view.
- *
- * @private
- */
- _onStartNowClick: function () {
- this._handleThemeAction(this.getSelectedIds()[0], 'button_choose_theme');
- },
-});
-
-var ThemePreviewFormView = FormView.extend({
- config: _.extend({}, FormView.prototype.config, {
- Controller: ThemePreviewController
- }),
-});
-
-viewRegistry.add('theme_preview_form', ThemePreviewFormView);
-
-return {
- ThemePreviewControllerCommon: ThemePreviewControllerCommon
+ back() {
+ this.env.config.historyBack();
+ }
}
-});
+ThemePreviewFormController.components = { ...FormController.components, ViewButton };
+
+class ThemePreviewFormControlPanel extends ControlPanel {
+ /**
+ * Triggers an event on the main bus.
+ * @see {FieldIframePreview} for the event handler.
+ */
+ onMobileClick() {
+ this.env.bus.trigger('THEME_PREVIEW:SWITCH_MODE', {mode: 'mobile'});
+ }
+ /**
+ * @see {onMobileClick}
+ */
+ onDesktopClick() {
+ this.env.bus.trigger('THEME_PREVIEW:SWITCH_MODE', {mode: 'desktop'});
+ }
+}
+ThemePreviewFormControlPanel.template = 'website.ThemePreviewForm.ControlPanel';
+
+const ThemePreviewFormView = {
+ ...formView,
+ display: {
+ controlPanel: {
+ 'top-right': false,
+ 'bottom-right': true,
+ }
+ },
+ buttonTemplate: 'website.ThemePreview.Buttons',
+ Controller: ThemePreviewFormController,
+ ControlPanel: ThemePreviewFormControlPanel,
+};
+
+registry.category('views').add('theme_preview_form', ThemePreviewFormView);
diff --git a/addons/website/static/src/components/views/theme_preview_kanban.js b/addons/website/static/src/components/views/theme_preview_kanban.js
index f6019af10f3..03a2fcce111 100644
--- a/addons/website/static/src/components/views/theme_preview_kanban.js
+++ b/addons/website/static/src/components/views/theme_preview_kanban.js
@@ -1,63 +1,45 @@
-odoo.define('website.theme_preview_kanban', function (require) {
-"use strict";
+/** @odoo-module */
-var KanbanController = require('web.KanbanController');
-var KanbanView = require('web.KanbanView');
-var ViewRegistry = require('web.view_registry');
-const ThemePreviewControllerCommon = require('website.theme_preview_form').ThemePreviewControllerCommon;
-var core = require('web.core');
-var _lt = core._lt;
+import { ControlPanel } from "@web/search/control_panel/control_panel";
+import { kanbanView } from "@web/views/kanban/kanban_view";
+import { KanbanController } from "@web/views/kanban/kanban_controller";
+import { registry } from "@web/core/registry";
+import { useService } from "@web/core/utils/hooks";
+import { useLoaderOnClick } from './theme_preview_form';
-var ThemePreviewKanbanController = KanbanController.extend(ThemePreviewControllerCommon, {
+class ThemePreviewKanbanController extends KanbanController {
/**
* @override
*/
- start: async function () {
- await this._super(...arguments);
+ setup() {
+ super.setup();
+ useLoaderOnClick();
+ }
+}
- // hide pager
- this.el.classList.add('o_view_kanban_theme_preview_controller');
+class ThemePreviewControlPanel extends ControlPanel {
+ setup() {
+ super.setup();
+ this.website = useService('website');
+ }
+ close() {
+ this.website.goToWebsite();
+ }
+}
+ThemePreviewControlPanel.template = 'website.ThemePreviewKanban.ControlPanel';
- // update breacrumb
- const websiteLink = Object.assign(document.createElement('a'), {
- className: 'btn btn-secondary ms-3 text-black-75',
- href: '/web#action=website.website_preview',
- innerHTML: '
',
- });
- if (!this.initialState.context.module) { // not coming from res.config.settings
- const smallBreadcumb = Object.assign(document.createElement('small'), {
- className: 'mx-2 text-muted',
- innerHTML: _lt("Don't worry, you can switch later."),
- });
- this._controlPanelWrapper.el.querySelector('.o_cp_top li').appendChild(smallBreadcumb);
- this._controlPanelWrapper.el.querySelector('.o_cp_top').appendChild(websiteLink);
- }
- this._controlPanelWrapper.el.querySelector('.o_cp_top .breadcrumb li.active').classList.add('text-black-75');
+const ThemePreviewKanbanView = {
+ ...kanbanView,
+ Controller: ThemePreviewKanbanController,
+ ControlPanel: ThemePreviewControlPanel,
+ display: {
+ controlPanel: {
+ 'bottom-left': false,
+ 'bottom-right': false,
+ },
},
- /**
- * Called when user click on any button in kanban view.
- * Targeted buttons are selected using name attribute value.
- *
- * @override
- */
- _onButtonClicked: function (ev) {
- const attrName = ev.data.attrs.name;
- if (attrName === 'button_choose_theme' || attrName === 'button_refresh_theme') {
- this._handleThemeAction(ev.data.record.res_id, attrName);
- } else {
- this._super(...arguments);
- }
- },
-});
+};
-var ThemePreviewKanbanView = KanbanView.extend({
- withSearchBar: false, // hide searchBar
- config: _.extend({}, KanbanView.prototype.config, {
- Controller: ThemePreviewKanbanController,
- }),
-});
-ViewRegistry.add('theme_preview_kanban', ThemePreviewKanbanView);
-
-});
+registry.category('views').add('theme_preview_kanban', ThemePreviewKanbanView);
diff --git a/addons/website/static/src/scss/website.backend.scss b/addons/website/static/src/scss/website.backend.scss
index 9e3f41ba015..2c915113c47 100644
--- a/addons/website/static/src/scss/website.backend.scss
+++ b/addons/website/static/src/scss/website.backend.scss
@@ -166,7 +166,7 @@
display: contents;
}
-.o_legacy_kanban_view.o_theme_kanban {
+.o_kanban_renderer.o_theme_kanban {
$o-theme-kanban-gray: #fcfcfc;
background-color: $o-theme-kanban-gray;
@@ -187,10 +187,18 @@
.o_kanban_record {
margin-left: $grid-gutter-width * 2;
- padding: 0;
- box-shadow: none;
- background: none;
- border: none;
+ margin-top: 16px;
+ margin-bottom: 16px;
+
+ .o_theme_preview {
+ box-shadow: none;
+ background: none;
+ border: none;
+ padding: 0;
+ &.o_theme_installed .o_theme_preview_top {
+ @include o-we-active-wrapper($top: 7px, $right: 7px);
+ }
+ }
.o_theme_preview_top {
position: relative;
@@ -267,10 +275,6 @@
transition: opacity 0.2s ease 0.1s;
}
}
-
- &.o_theme_installed .o_theme_preview_top {
- @include o-we-active-wrapper($top: 7px, $right: 7px);
- }
}
/// Grouped Layout
@@ -327,40 +331,33 @@
}
.o_view_form_theme_preview_controller {
- .o_control_panel > div:first-of-type {
- display: none;
- }
div.o_form_nosheet {
padding: 0px;
height:100%;
width:100%;
}
- .is_mobile {
- @include media-breakpoint-up(md) {
- iframe {
+ .o_field_iframe{
+ width: 100%;
+ height: 100%;
+ div.is_mobile {
+ @include media-breakpoint-up(md) {
// mobile frame is rounded
- border-radius: 15px;
- height: 735px;
- }
- .img_mobile {
- pointer-events: none;
- display: block !important;
- position: absolute;
- top: 16px;
- left: calc(50% - 200px)
- }
- .o_field_iframe_preview {
margin: auto !important;
padding: 53px 11px 58px 28px;
width: 416px;
+ iframe {
+ height: 735px;
+ border-radius: 15px;
+ }
+ .img_mobile {
+ pointer-events: none;
+ display: block;
+ position: absolute;
+ top: 16px;
+ left: calc(50% - 200px)
+ }
}
}
}
-
-}
-.o_view_kanban_theme_preview_controller {
- .o_control_panel > div:nth-child(2) {
- display: none;
- }
}
diff --git a/addons/website/static/tests/tours/automatic_editor.js b/addons/website/static/tests/tours/automatic_editor.js
index e4b90421e37..aa8264d4fe3 100644
--- a/addons/website/static/tests/tours/automatic_editor.js
+++ b/addons/website/static/tests/tours/automatic_editor.js
@@ -78,7 +78,7 @@ wTourUtils.registerEditionTour('automatic_editor_on_new_website', {
},
{
content: "Install a theme",
- trigger: 'button[data-name="button_choose_theme"]'
+ trigger: 'button[name="button_choose_theme"]'
},
{
content: "Check that the editor is loaded",
diff --git a/addons/website/views/website_views.xml b/addons/website/views/website_views.xml
index 429b999efb3..c632c17303b 100644
--- a/addons/website/views/website_views.xml
+++ b/addons/website/views/website_views.xml
@@ -325,7 +325,7 @@
-