Skip to content

Commit 6bdee49

Browse files
committed
[IMP] website: improve theme picker & theme preview
Previously, website's theme picker and theme preview pages suffered from a dense layout. With this update, we have transitioned to a more spacious and user-friendly 4-column layout. Additionally, various UI issues that were present on both the theme picker and theme preview pages have been addressed and resolved, further enhancing the overall usability and visual appeal. task-3648576 closes odoo#149989 Related: odoo/design-themes#758 Signed-off-by: Soukéina Bojabza (sobo) <[email protected]>
1 parent 993b96b commit 6bdee49

File tree

5 files changed

+96
-95
lines changed

5 files changed

+96
-95
lines changed
Loading
Lines changed: 46 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,54 +1,77 @@
11
<?xml version="1.0" encoding="utf-8"?>
22
<templates id="template" xml:space="preserve">
3+
<t t-name="website.ThemePreviewForm.ControlPanel.BreadCrumbs">
4+
<t t-set="breadcrumb" t-value="breadcrumbs.slice(-1)[0] || {}"/>
5+
<div class="o_breadcrumb d-flex gap-1">
6+
<div class="active d-flex flex-column">
7+
<h4 class="mb-0"><t t-call="web.Breadcrumb.Name"/></h4>
8+
</div>
9+
</div>
10+
</t>
11+
312
<t t-name="website.ThemePreviewForm.ControlPanel" t-inherit="web.ControlPanel" t-inherit-mode="primary">
13+
<xpath expr="//*[hasclass('o_control_panel')]" position="attributes">
14+
<attribute name="class" remove="pb-3" add="pb-2" separator=" "/>
15+
</xpath>
16+
<xpath expr="//*[hasclass('o_control_panel_main_buttons')]" position="inside">
17+
<button class="o_switch_theme btn btn-secondary d-none d-md-inline-block me-1" t-on-click.stop="this.back">
18+
<i class="oi oi-arrow-left" role="img" aria-label="Go Back"/>
19+
</button>
20+
</xpath>
21+
<xpath expr="//*[hasclass('o_control_panel_actions')]" position="attributes">
22+
<attribute name="class" remove="justify-content-lg-around" add="justify-content-sm-end flex-grow-1 flex-shrink-1 flex-basis-sm-0" separator=" "/>
23+
</xpath>
424
<xpath expr="//div[hasclass('o_control_panel_navigation')]" position="replace">
5-
<div class="d-none d-md-flex align-items-end justify-content-end order-2 order-lg-1 w-100 gap-1" role="group">
6-
<input class="btn-check" id="themeViewerDesktop" type="radio" name="viewer" data-mode='desktop' autocomplete="off" checked='checked'/>
7-
<label class="btn btn-secondary" for="themeViewerDesktop" t-on-click="this.onDesktopClick">Desktop</label>
8-
<input class="btn-check" id="themeViewerMobile" type="radio" name="viewer" data-mode='mobile' autocomplete="off"/>
9-
<label class="btn btn-secondary" for="themeViewerMobile" t-on-click="this.onMobileClick">Mobile</label>
25+
<div class="o_control_panel_switch_device d-none d-lg-flex" role="group">
26+
<div class="btn-group">
27+
<input class="btn-check" id="themeViewerDesktop" type="radio" name="viewer" data-mode='desktop' autocomplete="off" checked="checked"/>
28+
<label class="btn btn-secondary" for="themeViewerDesktop" t-on-click="this.onDesktopClick">
29+
<i class="fa fa-fw fa-desktop" role="img" aria-label="Desktop"/>
30+
</label>
31+
<input class="btn-check" id="themeViewerMobile" type="radio" name="viewer" data-mode='mobile' autocomplete="off"/>
32+
<label class="btn btn-secondary" for="themeViewerMobile" t-on-click="this.onMobileClick">
33+
<i class="fa fa-fw fa-mobile" role="img" aria-label="Mobile"/>
34+
</label>
35+
</div>
1036
</div>
1137
</xpath>
38+
<xpath expr="//t[@t-else]/Breadcrumbs" position="replace">
39+
<t t-call="website.ThemePreviewForm.ControlPanel.BreadCrumbs"/>
40+
</xpath>
1241
</t>
1342

1443
<t t-name="website.ThemePreviewFormController" t-inherit="web.FormView" t-inherit-mode="primary">
1544
<xpath expr="//Layout" position="inside">
1645
<t t-set-slot="layout-actions">
17-
<div>
18-
<div class="o_form_buttons_view" role="toolbar" aria-label="Main actions">
19-
<ViewButton className="'btn btn-primary o_use_theme'"
20-
clickParams="{type: 'object', name: 'button_choose_theme'}"
21-
record="this.model.root">
22-
<t t-set-slot="contents">Start Now</t>
23-
</ViewButton>
24-
<button class="btn btn-link o_switch_theme" t-on-click.stop="this.back">
25-
Choose another theme
26-
</button>
27-
</div>
28-
</div>
46+
<ViewButton className="'btn btn-primary o_use_theme'"
47+
clickParams="{type: 'object', name: 'button_choose_theme'}"
48+
record="this.model.root">
49+
<t t-set-slot="contents">Use this theme</t>
50+
</ViewButton>
2951
</t>
3052
</xpath>
3153
</t>
3254

3355
<t t-name="website.ThemePreviewKanban.ControlPanel.BreadCrumbs">
3456
<div class="o_breadcrumb d-flex gap-1">
3557
<div class="active d-flex flex-column">
36-
<div class="text-truncate">Pick a Theme</div>
58+
<div class="fw-bold text-truncate">Pick a Theme</div>
3759
<div class="text-muted small">Don't worry, you can switch later.</div>
3860
</div>
3961
</div>
4062
</t>
4163

4264
<t t-name="website.ThemePreviewKanban.ControlPanel" t-inherit="web.ControlPanel" t-inherit-mode="primary">
65+
<xpath expr="//*[hasclass('o_control_panel')]" position="attributes">
66+
<attribute name="class" remove="pb-3" add="pb-2" separator=" "/>
67+
</xpath>
4368
<xpath expr="//t[@t-else]/Breadcrumbs" position="replace">
4469
<t t-call="website.ThemePreviewKanban.ControlPanel.BreadCrumbs"/>
4570
</xpath>
4671
<xpath expr="//div[contains(@class,'o_control_panel_navigation')]" position="replace">
47-
<div>
48-
<a class="btn btn-secondary" t-on-click="this.close" aria-label="Close" data-tooltip="Close">
49-
<i class="fa fa-times" />
50-
</a>
51-
</div>
72+
<a class="btn btn-secondary align-self-center" t-on-click="this.close" aria-label="Close" data-tooltip="Close">
73+
<i class="fa fa-times" role="img" aria-label="close"/>
74+
</a>
5275
</xpath>
5376
</t>
5477
</templates>

addons/website/static/src/components/views/theme_preview_form.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,12 @@ class ThemePreviewFormControlPanel extends ControlPanel {
8989
onDesktopClick() {
9090
this.env.bus.trigger('THEME_PREVIEW:SWITCH_MODE', {mode: 'desktop'});
9191
}
92+
/**
93+
* Handler called when user click on Go Back button.
94+
*/
95+
back() {
96+
this.env.config.historyBack();
97+
}
9298
}
9399

94100
const ThemePreviewFormView = {

addons/website/static/src/scss/website.backend.scss

Lines changed: 23 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -88,42 +88,43 @@
8888

8989
.o_theme_preview_kanban_view .o_kanban_renderer {
9090
$o-theme-kanban-gray: #fcfcfc;
91+
--KanbanRecord-width: 100%;
9192

9293
/// Un-grouped Layout (default)
9394
&.o_kanban_ungrouped {
94-
justify-content: space-between;
95-
margin: 0 0 0 ($o-kanban-record-margin - 2 * $grid-gutter-width);
95+
display: grid !important;
96+
grid-template-columns: 1fr;
97+
grid-row-gap: map-get($spacers, 3);
98+
grid-column-gap: map-get($spacers, 3);
99+
justify-items: center;
100+
padding: map-get($spacers, 3);
101+
102+
@include media-breakpoint-up(sm) {
103+
grid-template-columns: repeat(2, 1fr);
104+
}
96105

97-
@include media-breakpoint-down(md) {
98-
padding-left: $o-horizontal-padding - $o-kanban-record-margin;
99-
padding-right: $o-horizontal-padding;
106+
@include media-breakpoint-up(md) {
107+
grid-template-columns: repeat(3, 1fr);
100108
}
101109

102-
.o_kanban_record {
103-
flex: 1 0 220px;
110+
@include media-breakpoint-up(xxl) {
111+
grid-template-columns: repeat(4, 1fr);
104112
}
105113
}
106114

107115
.o_kanban_record {
108-
margin-left: $grid-gutter-width * 2;
109-
margin-top: 16px;
110-
margin-bottom: 16px;
116+
117+
&:has(.o_theme_installed) {
118+
order: -1;
119+
}
111120

112121
.o_theme_preview {
113-
box-shadow: none;
114-
background: none;
115-
border: none;
116-
padding: 0;
117122
&.o_theme_installed .o_theme_preview_top {
118123
@include o-we-active-wrapper($top: 7px, $right: 7px);
119124
}
120125
}
121126

122127
.o_theme_preview_top {
123-
position: relative;
124-
border-radius: 2px;
125-
transform-origin: center bottom;
126-
transition: all .1s ease 0s;
127128

128129
.o_theme_cover, .o_theme_logo, .o_theme_screenshot {
129130
width: 100%;
@@ -142,41 +143,13 @@
142143
}
143144
}
144145

145-
.o_theme_preview_bottom {
146-
h5, h6 {
147-
line-height: 16px;
148-
}
149-
}
150-
151-
.o_button_area {
152-
@include o-position-absolute(0, 0, 0, 0);
153-
transition: opacity 100ms ease 0s;
154-
display: flex;
155-
flex-flow: column nowrap;
156-
justify-content: center;
157-
transform: translate3d(0,0,0);
158-
background-image: linear-gradient(0deg, rgba(black, 0.6), rgba(black, 0.3));
159-
padding: 10% 20%;
160-
opacity: 0;
161-
visibility: hidden;
162-
163-
> .btn {
164-
padding: $btn-padding-y-lg $btn-padding-x-lg;
165-
}
166-
167-
hr {
168-
width: 100%;
169-
}
170-
}
171-
172146
.o_theme_preview_top:hover {
173-
transition: all .3s ease 0s;
174-
transform: translateY(-10px);
175-
border-color: darken($o-theme-kanban-gray, 26%);
176-
box-shadow: 0 15px 12px -8px rgba(0, 0, 0, .4);
147+
transform: scale(1.01);
148+
transform-origin: center;
149+
box-shadow: $box-shadow;
177150

178151
.o_theme_screenshot {
179-
animation: o_theme_screenshot_scroll 4s linear .25s infinite alternate;
152+
animation: o_theme_screenshot_scroll 4s linear infinite alternate;
180153
}
181154
@keyframes o_theme_screenshot_scroll {
182155
25% {
@@ -187,11 +160,6 @@
187160
}
188161
}
189162

190-
.o_button_area {
191-
opacity: 1;
192-
visibility: visible;
193-
transition: opacity 0.2s ease 0.1s;
194-
}
195163
}
196164
}
197165

addons/website/views/website_views.xml

Lines changed: 21 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -245,31 +245,35 @@
245245
<field name="display_name"/>
246246
<field name="is_installed_on_current_website"/>
247247
<templates>
248-
<div t-name="kanban-box" t-attf-class="o_theme_preview #{record.is_installed_on_current_website.raw_value? 'o_theme_installed' : ''}">
248+
<div t-name="kanban-box" t-attf-class="o_theme_preview border-0 p-0 bg-transparent #{record.is_installed_on_current_website.raw_value? 'o_theme_installed' : ''}">
249249
<t t-set="has_image" t-value="record.image_ids.raw_value.length > 0"/>
250250
<t t-set="has_screenshot" t-value="record.image_ids.raw_value.length > 1"/>
251251
<t t-set="image_url" t-value="has_image ? '/web/image/' + record.image_ids.raw_value[0] : record.icon.value"/>
252252

253-
<div class="o_theme_preview_top bg-white mb4 border">
254-
<div t-attf-class="bg-gray-lighter #{has_screenshot? 'o_theme_screenshot' : (has_image ? 'o_theme_cover' : 'o_theme_logo')}" t-attf-style="background-image: url(#{image_url});"/>
255-
<div t-if="record.is_installed_on_current_website.raw_value" class="o_button_area">
256-
<button type="object" name="button_refresh_theme" class="btn btn-primary">Update theme</button>
257-
<hr />
258-
<button type="object" name="button_remove_theme" class="btn btn-secondary">Remove theme</button>
259-
</div>
260-
<div t-else="" class="o_button_area">
261-
<button type="object" name="button_choose_theme" class="btn btn-primary">Use this theme</button>
262-
<hr t-if="record.url.value"/>
263-
<button role="button" type="edit" t-if="record.url.value" class="btn btn-secondary">Live Preview</button>
253+
<div class="o_theme_preview_top position-relative border rounded-3 transition-base">
254+
<div t-attf-class="bg-gray-lighter #{has_screenshot? 'o_theme_screenshot' : (has_image ? 'o_theme_cover' : 'o_theme_logo')} rounded-3" t-attf-style="background-image: url(#{image_url});"/>
255+
<div t-if="record.is_installed_on_current_website.raw_value or !record.url.value" class="o_button_area position-absolute top-50 start-50 translate-middle d-flex align-items-center justify-content-center w-100 h-100 bg-dark bg-opacity-50 rounded opacity-0 opacity-100-hover transition-fade">
256+
<div class="d-flex flex-column gap-2 w-50">
257+
<t t-if="record.is_installed_on_current_website.raw_value">
258+
<button type="object" name="button_refresh_theme" class="btn btn-primary">Update theme</button>
259+
<button type="object" name="button_remove_theme" class="btn btn-secondary">Remove theme</button>
260+
</t>
261+
<t t-else="">
262+
<button type="object" name="button_choose_theme" class="btn btn-primary">Use default theme</button>
263+
</t>
264+
</div>
264265
</div>
266+
<t t-else="">
267+
<button class="position-absolute top-0 start-0 h-100 w-100 opacity-0" role="button" type="edit" t-if="record.url.value"/>
268+
</t>
265269
</div>
266-
<div class="o_theme_preview_bottom clearfix">
267-
<h5 t-if="record.summary.value" class="text-uppercase float-start">
270+
<div class="o_theme_preview_bottom mt-2 mb-3 px-2">
271+
<small t-if="record.summary.value" class="text-uppercase text-muted">
268272
<b><t t-esc="record.summary.value.split(',')[0]"/></b>
269-
</h5>
270-
<h6 t-if="record.display_name.value" class="text-muted float-end">
273+
</small>
274+
<h3 t-if="record.display_name.value">
271275
<b><t t-esc="record.display_name.value.replace('Theme', '').replace('theme', '')"/></b>
272-
</h6>
276+
</h3>
273277
</div>
274278
</div>
275279
</templates>

0 commit comments

Comments
 (0)