[IMP] website(_sale): Improve UX for the website dashboard

Purpose
=======

There are some usability issues in the website dashboard

Specification
=============

1/ Move button 'Go to Website' in the header
2/ Hide the action button bar if there's nothing in it
3/ Align the labels in the graph's legend
4/ Make the legend labels and display more obvious
5/ Modify the graph colors to be more readable
6/ Remove margins around todo buttons
This commit is contained in:
Dhawal Limbuwala
2017-12-05 13:13:23 +01:00
committed by Yannick Tivisse
parent 595a7b9c1b
commit 4764cae315
7 changed files with 141 additions and 90 deletions
@@ -36,7 +36,7 @@ var Dashboard = Widget.extend(ControlPanelMixin, {
this.date_from = moment().subtract(1, 'week');
this.date_to = moment();
this.dashboards_templates = ['website.dashboard_visits'];
this.dashboards_templates = ['website.dashboard_header', 'website.dashboard_content'];
this.graphs = [];
},
@@ -51,7 +51,6 @@ var Dashboard = Widget.extend(ControlPanelMixin, {
var self = this;
return this._super().then(function() {
self.update_cp();
self.render_dashboards();
self.render_graphs();
self.$el.parent().addClass('oe_background_grey');
});
@@ -126,7 +125,7 @@ var Dashboard = Widget.extend(ControlPanelMixin, {
render_dashboards: function() {
var self = this;
_.each(this.dashboards_templates, function(template) {
self.$('.o_website_dashboard_content').append(QWeb.render(template, {widget: self}));
self.$('.o_website_dashboard').append(QWeb.render(template, {widget: self}));
});
},
@@ -152,6 +151,14 @@ var Dashboard = Widget.extend(ControlPanelMixin, {
.tickValues(_.map(tick_values, function(d) { return self.getDate(d); }))
.rotateLabels(-45);
chart.interactiveLayer.tooltip.contentGenerator(function(data) {
return QWeb.render('website.SalesChartTooltip', {
format: field_utils.format,
chartData: data,
dateRange: self.date_range
});
});
chart.yAxis
.tickFormat(d3.format('.02f'));
@@ -172,7 +179,7 @@ var Dashboard = Widget.extend(ControlPanelMixin, {
var self = this;
_.each(this.graphs, function(e) {
if (self.groups[e.group]) {
self.render_graph('#o_graph_' + e.name, self.dashboards_data[e.name].graph);
self.render_graph('.o_graph_' + e.name, self.dashboards_data[e.name].graph);
}
});
this.render_graph_analytics(this.dashboards_data.visits.ga_client_id);
@@ -230,7 +237,7 @@ var Dashboard = Widget.extend(ControlPanelMixin, {
var self = this;
$.when(this.fetch_data()).then(function() {
self.$('.o_website_dashboard_content').empty();
self.$('.o_website_dashboard').empty();
self.render_dashboards();
self.render_graphs();
});
@@ -294,6 +301,7 @@ var Dashboard = Widget.extend(ControlPanelMixin, {
this.update_control_panel({
cp_content: {
$searchview: this.$searchview,
$buttons: QWeb.render("website.GoToButtons"),
},
breadcrumbs: this.getParent().get_breadcrumbs(),
});
@@ -8,7 +8,7 @@
color: @odoo-main-color-muted;
background-color: @odoo-view-background-color;
background-size: cover;
margin-bottom: @odoo-horizontal-padding;
margin-top: @odoo-horizontal-padding;
position: static;
box-shadow: 0 1px 2px 0 rgba(0, 0, 0, 0.3);
@@ -20,7 +20,7 @@
h4 { margin: 0 0 0 8px; }
.col-md-6, .col-md-12 {
.col-md-7, .col-xs-12 {
padding: 15px;
.js_field_selection {
@@ -36,7 +36,11 @@
table {
tr:nth-child(even) {
tr:first-child {
background: white;
}
tr:nth-child(even):not(:hover) {
background: #f5f6f7;
}
@@ -53,6 +57,9 @@
text-align: left;
}
}
.o_tooltip_key {
text-align: left;
}
}
/*------------------------------------------*/
@@ -75,23 +82,26 @@
opacity: 0 !important;
}
[class*="nv-series-"] {
stroke-width: 3 !important;
fill: @odoo-main-color-muted !important;
}
.nv-groups .nv-point, g circle {
fill: @odoo-brand-optional;
}
.nv-groups .nv-point {
fill-opacity: 1 !important;
stroke-opacity: 1 !important;
stroke: @odoo-brand-optional;
}
.nv-groups .nv-point.hover, .nv-group.nv-noninteractive .nv-point.hover {
stroke: darken(@odoo-brand-optional, 10%);
.nv-groups {
.nv-series-0 {
stroke-width: 3 !important;
.nv-point {
stroke: @odoo-brand-optional;
stroke-opacity: 1 !important;
&.hover {
stroke: darken(@odoo-brand-optional, 10%);
}
}
}
.nv-series-1 {
.nv-point {
stroke: @odoo-main-color-muted !important;
stroke-opacity: 1 !important;
&.hover {
stroke: darken(@odoo-main-color-muted, 10%);
}
}
}
}
}
@@ -118,7 +128,7 @@
display: flex;
flex-flow: row wrap;
justify-content: flex-start;
> .o_box_item {
> .o_inner_box {
@media (max-width: @screen-sm-min) {
flex: 1 1 200px;
display: block !important;
@@ -136,15 +146,12 @@
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
&.o_main {
background-color: @odoo-brand-optional;
cursor: pointer;
color: white;
background-color: @odoo-brand-optional;
&:hover {
background-color: darken(@odoo-brand-optional, 10%);
}
a {
color: white;
}
}
&.o_primary {
background-color: @odoo-brand-primary;
color: white;
@@ -158,6 +165,15 @@
}
}
.o_graph_sales {
.o_legend0 {
background-color: @odoo-brand-optional;
}
.o_legend1 {
background-color: @odoo-main-color-muted;
}
}
.o_dashboard_visits {
h2 {
@@ -9,7 +9,7 @@
<div class="o_dashboards">
<div class="container-fluid o_website_dashboard">
<t t-call="website.dashboard_header"/>
<div class="o_website_dashboard_content"/>
<t t-call="website.dashboard_content"/>
</div>
</div>
</t>
@@ -18,21 +18,23 @@
<div class="row o_dashboard_common"/>
</t>
<t t-name="website.dashboard_visits">
<div class="row o_dashboard_visits" t-if="widget.groups.website_designer">
<div class="col-xs-12 o_box">
<h2>Visits</h2>
<div t-if="widget.dashboards_data.visits &amp;&amp; widget.dashboards_data.visits.ga_client_id">
<div class="row js_analytics_components"/>
<a href="#" class="js_link_analytics_settings">Edit my Analytics Client ID</a>
</div>
<div t-if="!(widget.dashboards_data.visits &amp;&amp; widget.dashboards_data.visits.ga_client_id)" class="col-md-12">
<div class="o_demo_background">
<div class="o_layer">
</div>
<div class="o_buttons text-center">
<h3>There is no data currently available.</h3>
<button class="btn btn-sm btn-primary js_link_analytics_settings center-block mb8">Link my Analytics Account</button>
<t t-name="website.dashboard_content">
<div class="o_website_dashboard_content">
<div class="row o_dashboard_visits" t-if="widget.groups.website_designer">
<div class="col-xs-12 o_box">
<h2>Visits</h2>
<div t-if="widget.dashboards_data.visits &amp;&amp; widget.dashboards_data.visits.ga_client_id">
<div class="row js_analytics_components"/>
<a href="#" class="js_link_analytics_settings">Edit my Analytics Client ID</a>
</div>
<div t-if="!(widget.dashboards_data.visits &amp;&amp; widget.dashboards_data.visits.ga_client_id)" class="col-md-12">
<div class="o_demo_background">
<div class="o_layer">
</div>
<div class="o_buttons text-center">
<h3>There is no data currently available.</h3>
<button class="btn btn-sm btn-primary js_link_analytics_settings center-block mb8">Link my Analytics Account</button>
</div>
</div>
</div>
</div>
@@ -66,4 +68,30 @@
</div>
</t>
<t t-name="website.SalesChartTooltip">
<table>
<thead>
<tr><td colspan="3"><strong><t t-esc="chartData.series[0].key"/></strong></td></tr>
</thead>
<tbody>
<tr>
<td class="legend-color-guide"><div class="o_legend0"/></td>
<td class="key o_tooltip_key"><t t-esc="format.date(moment(chartData.value))"/></td>
<td class="value"><t t-esc="format.float(chartData.series[0].data[1])"/></td>
</tr>
<tr>
<td class="legend-color-guide"><div class="o_legend1"/></td>
<td class="key o_tooltip_key"><t t-esc="format.date(moment(chartData.value).subtract(1, dateRange))"/></td>
<td class="value"><t t-esc="format.float(chartData.series[1].data[1])"/></td>
</tr>
</tbody>
</table>
</t>
<t t-name="website.GoToButtons">
<a href="/" class="btn btn-primary" title="Go to Website">
Go to Website
</a>
</t>
</templates>
@@ -11,7 +11,6 @@ WebsiteBackend.include({
init: function (parent, context) {
this._super(parent, context);
this.dashboards_templates.unshift('website_sale.dashboard_sales');
this.graphs.push({'name': 'sales', 'group': 'sale_salesman'});
},
@@ -1,4 +1,8 @@
.o_dashboard_sales {
h2 {
padding: 15px;
}
h4 { margin: 3px 0 4px 0 !important; }
.o_demo_background {
margin-top: 16px;
@@ -1,61 +1,60 @@
<?xml version="1.0" encoding="UTF-8"?>
<templates>
<t t-extend="website.dashboard_header">
<t t-jquery="t[t-foreach='apps']" t-operation="before">
<div t-if="widget.dashboards_data.sales.summary.order_unpaid_count" class="o_inner_box o_main o_box_item" title="Confirm orders when you get paid." t-name='unpaid_orders_box'>
<a href="#" class="o_dashboard_action" name="website_sale.action_unpaid_orders_ecommerce">
<t t-jquery="div.o_dashboard_common" t-operation="append">
<div class="o_box" t-if="widget.dashboards_data.sales.summary.order_unpaid_count || widget.dashboards_data.sales.summary.order_to_invoice_count || widget.dashboards_data.sales.summary.payment_to_capture_count || widget.dashboards_data.sales.summary.order_carts_abandoned_count">
<div t-if="widget.dashboards_data.sales.summary.order_unpaid_count" class="o_inner_box o_dashboard_action" title="Confirm orders when you get paid." name="website_sale.action_unpaid_orders_ecommerce">
<div class="o_highlight"><t t-esc="widget.dashboards_data.sales.summary.order_unpaid_count"/></div>
Unpaid Orders
</a>
<t t-set="vignette_nbr" t-value="vignette_nbr + 1"/>
</div>
<div t-if="widget.dashboards_data.sales.summary.payment_to_capture_count" class="o_inner_box o_main o_box_item" title="Capture order payments when the delivery is completed.">
<a href="#" class="o_dashboard_action" name="website_sale.payment_transaction_action_payments_to_capture">
</div>
<div t-if="widget.dashboards_data.sales.summary.order_to_invoice_count" class="o_inner_box o_dashboard_action" title="Generate an invoice from orders ready for invoicing." name="website_sale.sale_order_action_to_invoice">
<div class="o_highlight"><t t-esc="widget.dashboards_data.sales.summary.order_to_invoice_count"/></div>
Orders to Invoice
</div>
<div t-if="widget.dashboards_data.sales.summary.payment_to_capture_count" class="o_inner_box o_dashboard_action" title="Capture order payments when the delivery is completed." name="website_sale.payment_transaction_action_payments_to_capture">
<div class="o_highlight"><t t-esc="widget.dashboards_data.sales.summary.payment_to_capture_count"/></div>
Payments to Capture
</a>
<t t-set="vignette_nbr" t-value="vignette_nbr + 1"/>
</div>
<div t-if="widget.dashboards_data.sales.summary.order_carts_abandoned_count" class="o_inner_box o_main o_box_item" title="Send a recovery email to visitors who haven't completed their order.">
<a href="#" class="o_dashboard_action" name="website_sale.action_abandoned_orders_ecommerce">
</div>
<div t-if="widget.dashboards_data.sales.summary.order_carts_abandoned_count" class="o_inner_box o_dashboard_action" title="Send a recovery email to visitors who haven't completed their order." name="website_sale.action_abandoned_orders_ecommerce">
<div class="o_highlight"><t t-esc="widget.dashboards_data.sales.summary.order_carts_abandoned_count"/></div>
Abandoned Carts to Recover
</a>
<t t-set="vignette_nbr" t-value="vignette_nbr + 1"/>
Abandoned Carts
</div>
</div>
</t>
</t>
<t t-name="website_sale.dashboard_sales">
<div t-if="widget.groups.sale_salesman" class="row o_dashboard_sales">
<div class="col-xs-12 o_box">
<div t-if="widget.dashboards_data.sales.summary.order_count">
<div class="col-md-6 col-xs-12">
<t t-extend="website.dashboard_content">
<t t-jquery="div.o_website_dashboard_content" t-operation="prepend">
<div t-if="widget.groups.sale_salesman" class="row o_dashboard_sales">
<div class="col-xs-12 o_box">
<t t-if="widget.dashboards_data.sales.summary.order_count">
<t t-if="widget.date_range">
<h2>Sales Since Last <t t-esc="widget.date_range"></t></h2>
</t>
<t t-else=""><h2>Sales</h2></t>
<div id="o_graph_sales" class="o_graph" data-type="sales"/>
</div>
<div class="col-md-6 col-xs-12">
<t t-call="website_sale.products_table"/>
</div>
</div>
<div t-if="! widget.dashboards_data.sales.summary.order_count">
<div class="col-md-12 col-xs-12">
<div class="col-md-7 col-xs-12">
<div class="o_graph_sales" data-type="sales"/>
</div>
<div class="col-md-5 col-xs-12">
<t t-call="website_sale.products_table"/>
</div>
</t>
<t t-if="! widget.dashboards_data.sales.summary.order_count">
<t t-if="widget.date_range">
<h2>Sales Since Last <t t-esc="widget.date_range"></t></h2>
</t>
<t t-else=""><h2>Sales</h2></t>
<div class="o_demo_background">
<div class="col-md-12 col-xs-12">
<div class="o_demo_background">
</div>
<div class="o_demo_message">
<h3>There is no recent confirmed order.</h3>
</div>
</div>
<div class="o_demo_message">
<h3>There is no recent confirmed order.</h3>
</div>
</div>
</t>
</div>
</div>
</div>
</t>
</t>
<t t-name="website_sale.products_table">
@@ -2,12 +2,9 @@
<templates>
<t t-extend="website.dashboard_header">
<t t-jquery=".o_dashboard_common a.o_dashboard_action .o_primary" t-operation="after">
<div t-if="widget.dashboards_data.sales.summary.order_to_invoice_count" class="o_inner_box o_main o_box_item" title="Generate an invoice from orders ready for invoicing.">
<a href="#" class="o_dashboard_action" name="website_sale.sale_order_action_to_invoice">
<div class="o_highlight"><t t-esc="widget.dashboards_data.sales.summary.order_to_invoice_count"/></div>
Orders to Invoice
</a>
<t t-set="vignette_nbr" t-value="vignette_nbr + 1"/>
<div t-if="widget.dashboards_data.sales.summary.order_to_invoice_count" class="o_inner_box o_dashboard_action" title="Generate an invoice from orders ready for invoicing." name="website_sale.sale_order_action_to_invoice">
<div class="o_highlight"><t t-esc="widget.dashboards_data.sales.summary.order_to_invoice_count"/></div>
Orders to Invoice
</div>
</t>
</t>