diff --git a/addons/website/static/src/components/fields/widget_iframe.js b/addons/website/static/src/components/fields/widget_iframe.js index 8829ffa8684..3850d857f99 100644 --- a/addons/website/static/src/components/fields/widget_iframe.js +++ b/addons/website/static/src/components/fields/widget_iframe.js @@ -1,28 +1,19 @@ -odoo.define('website.iframe_widget', function (require) { -"use strict"; +/** @odoo-module **/ +import { registry } from '@web/core/registry'; +import { useBus } from "@web/core/utils/hooks"; -var AbstractField = require('web.AbstractField'); -var core = require('web.core'); -var fieldRegistry = require('web.field_registry'); +const { Component, useState } = owl; -var QWeb = core.qweb; +class FieldIframePreview extends Component { + setup() { + this.state = useState({isMobile: false}); -/** - * Display iframe - */ -var FieldIframePreview = AbstractField.extend({ - className: 'd-block o_field_iframe_preview m-0 h-100', + useBus(this.env.bus, 'THEME_PREVIEW:SWITCH_MODE', (ev) => { + this.state.isMobile = ev.detail.mode === 'mobile'; + }); + } +} +FieldIframePreview.template = 'website.iframeWidget'; - _render: function () { - this.$el.html(QWeb.render('website.iframeWidget', { - url: this.value, - })); - }, -}); - -fieldRegistry.add('iframe', FieldIframePreview); - -return FieldIframePreview; - -}); +registry.category('fields').add('iframe', FieldIframePreview); diff --git a/addons/website/static/src/components/fields/widget_iframe.xml b/addons/website/static/src/components/fields/widget_iframe.xml index 48a6d7c5503..439b0e392ca 100644 --- a/addons/website/static/src/components/fields/widget_iframe.xml +++ b/addons/website/static/src/components/fields/widget_iframe.xml @@ -2,16 +2,20 @@ - + +
-
No Url
- + t-att-src="props.value"/> + phone +
+
No Url
+
diff --git a/addons/website/static/src/components/views/theme_preview.xml b/addons/website/static/src/components/views/theme_preview.xml index 8786d99b5aa..545b9aa3675 100644 --- a/addons/website/static/src/components/views/theme_preview.xml +++ b/addons/website/static/src/components/views/theme_preview.xml @@ -1,38 +1,50 @@ - -
- -
-
- -
- - + +
+ - - -
- Building your website... -
-

- TIP: Once loaded, follow the - -
pointer to build the perfect page in 7 steps. -

+
+
+ + + +
+ + + +
-
+ + + + + +
+ +
+
+ +
+ + + +
+
+
+ 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 @@ -
+
@@ -385,10 +385,8 @@
- - +
-