[IMP] website: adapt ThemePreview to OWL
This commit will adapt ThemePreview views to OWL. Those views use custom components to achieve the desired layout and functionality. Part-of: odoo/odoo#99150 Co-authored-by: Younn Olivier <yol@odoo.com>
This commit is contained in:
co-authored by
Younn Olivier
parent
ed7794839b
commit
b9fef88c47
@@ -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);
|
||||
|
||||
@@ -2,16 +2,20 @@
|
||||
|
||||
<templates xml:space="preserve">
|
||||
|
||||
<t t-name="website.iframeWidget">
|
||||
<t t-name="website.iframeWidget" owl="1">
|
||||
<div t-if="props.value" class="h-100" t-att-class="this.state.isMobile and 'is_mobile'">
|
||||
<iframe
|
||||
t-if="url"
|
||||
frameBorder="0"
|
||||
class="d-block"
|
||||
height="100%"
|
||||
width="100%"
|
||||
frameBorder="0"
|
||||
t-att-src="url"
|
||||
class='d-block'
|
||||
></iframe>
|
||||
<div t-else="">No Url</div>
|
||||
</t>
|
||||
t-att-src="props.value"/>
|
||||
<img t-if="this.state.isMobile"
|
||||
alt="phone"
|
||||
class="img_mobile"
|
||||
src="/website/static/src/img/phone.png"/>
|
||||
</div>
|
||||
<div t-else="">No Url</div>
|
||||
</t>
|
||||
|
||||
</templates>
|
||||
|
||||
@@ -1,38 +1,50 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<templates id="template" xml:space="preserve">
|
||||
<t t-name="website.ThemePreview.Buttons">
|
||||
<div>
|
||||
<div class="o_form_buttons_view" role="toolbar" aria-label="Main actions">
|
||||
<button type="object" name="button_choose_theme" class="btn btn-primary o_use_theme">
|
||||
Start Now
|
||||
</button>
|
||||
<button class="btn btn-link o_switch_theme">
|
||||
Choose another theme
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</t>
|
||||
|
||||
<t t-name="website.ThemePreview.SwitchModeButton">
|
||||
<div class="btn-group btn-group-toggle ms-1" data-bs-toggle="buttons">
|
||||
<label class="btn btn-secondary active">
|
||||
<input type="radio" name="viewer" data-mode='desktop' autocomplete="off" checked='checked'/> Desktop
|
||||
</label>
|
||||
<label class="btn btn-secondary">
|
||||
<input type="radio" name="viewer" data-mode='mobile' autocomplete="off"/> Mobile
|
||||
</label>
|
||||
<t t-name="website.ThemePreview.Buttons" owl="1">
|
||||
<div>
|
||||
<div class="o_form_buttons_view" role="toolbar" aria-label="Main actions">
|
||||
<ViewButton className="'btn btn-primary o_use_theme'"
|
||||
clickParams="{type: 'object', name: 'button_choose_theme'}"
|
||||
record="this.model.root">
|
||||
<t t-set-slot="contents">Start Now</t>
|
||||
</ViewButton>
|
||||
<button class="btn btn-link o_switch_theme" t-on-click.stop="this.back">
|
||||
Choose another theme
|
||||
</button>
|
||||
</div>
|
||||
</t>
|
||||
<t t-name="website.ThemePreview.Loader">
|
||||
<div class="o_theme_install_loader_container position-fixed fixed-top fixed-left
|
||||
h-100 w-100 d-flex flex-column align-items-center text-white fw-bold text-center">
|
||||
<t t-if="showTips">Building your website...</t>
|
||||
<div class="o_theme_install_loader"></div>
|
||||
<p t-if="showTips" class="o_theme_install_loader_tip w-25">
|
||||
TIP: Once loaded, follow the
|
||||
<span class="o_tooltip o_tooltip_visible bottom o_animated position-relative"></span>
|
||||
<br/>pointer to build the perfect page in 7 steps.
|
||||
</p>
|
||||
</div>
|
||||
</t>
|
||||
|
||||
<t t-name="website.ThemePreviewForm.ControlPanel" t-inherit="web.ControlPanel" t-inherit-mode="primary" owl="1">
|
||||
<xpath expr="//div[hasclass('o_cp_bottom_right')]" position="replace">
|
||||
<div class="o_cp_bottom_right" role="group">
|
||||
<input class="btn-check" id="themeViewerDesktop" type="radio" name="viewer" data-mode='desktop' autocomplete="off" checked='checked'/>
|
||||
<label class="btn btn-secondary" for="themeViewerDesktop" t-on-click="this.onDesktopClick">Desktop</label>
|
||||
<input class="btn-check" id="themeViewerMobile" type="radio" name="viewer" data-mode='mobile' autocomplete="off"/>
|
||||
<label class="btn btn-secondary" for="themeViewerMobile" t-on-click="this.onMobileClick">Mobile</label>
|
||||
</div>
|
||||
</t>
|
||||
</xpath>
|
||||
</t>
|
||||
|
||||
<t t-name="website.ThemePreviewKanban.ControlPanel" t-inherit="web.ControlPanel" t-inherit-mode="primary" owl="1">
|
||||
<xpath expr="//div[hasclass('o_cp_top_left')]" position="replace">
|
||||
<div class="o_cp_top_left">
|
||||
<ol class="breadcrumb" role="navigation">
|
||||
<li class="breadcrumb-item active text-black-75">
|
||||
<span class="text-900">Pick a Theme</span>
|
||||
<small class="mx-2 text-muted">Don't worry, you can switch later.</small>
|
||||
</li>
|
||||
</ol>
|
||||
</div>
|
||||
</xpath>
|
||||
<xpath expr="//div[hasclass('o_cp_top_right')]" position="replace">
|
||||
<div class="o_cp_top_right d-flex flex-row-reverse">
|
||||
<a class="btn btn-secondary" t-on-click="this.close">
|
||||
<i class="fa fa-times" />
|
||||
</a>
|
||||
</div>
|
||||
</xpath>
|
||||
</t>
|
||||
|
||||
</templates>
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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: '<i class="fa fa-close"></i>',
|
||||
});
|
||||
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);
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -325,7 +325,7 @@
|
||||
<field name="display_name"/>
|
||||
<field name="is_installed_on_current_website"/>
|
||||
<templates>
|
||||
<div t-name="kanban-box" t-attf-class="o_theme_preview mb16 mt16 #{record.is_installed_on_current_website.raw_value? 'o_theme_installed' : ''}">
|
||||
<div t-name="kanban-box" t-attf-class="o_theme_preview #{record.is_installed_on_current_website.raw_value? 'o_theme_installed' : ''}">
|
||||
<t t-set="has_image" t-value="record.image_ids.raw_value.length > 0"/>
|
||||
<t t-set="has_screenshot" t-value="record.image_ids.raw_value.length > 1"/>
|
||||
<t t-set="image_url" t-value="has_image ? '/web/image/' + record.image_ids.raw_value[0] : record.icon.value"/>
|
||||
@@ -385,10 +385,8 @@
|
||||
<field name="arch" type="xml">
|
||||
<form create="false" edit="false" delete="0" js_class="theme_preview_form">
|
||||
<div class="o_preview_frame h-100">
|
||||
<field name='url' widget='iframe'/>
|
||||
<img alt='phone' class='img_mobile' style='display:none' src="/website/static/src/img/phone.png"/>
|
||||
<field name="url" widget='iframe' class="d-block m-0 h-100"/>
|
||||
</div>
|
||||
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
Reference in New Issue
Block a user