[IMP] pos_*: Ticket/Order kanban screens on mobile

Using a list view isn't the best way to display data on small screen.
We had to change this behavior to display a kanban view of orders.

We also merge design of "Ticket" screen and "Order Management" screen.

Task ID: 2453679

X-original-commit: d0e53721a97c14419a2f81ef8aa8be317cc5644a
Part-of: odoo/odoo#79448
Co-authored-by: Adrien Dieudonné <adr@odoo.com>
This commit is contained in:
Romain Estievenart
2021-11-05 19:44:47 +00:00
committed by Adrien Dieudonne
co-authored by Adrien Dieudonné
parent a4b617dd95
commit a2ddef022f
8 changed files with 113 additions and 157 deletions
+42 -103
View File
@@ -484,13 +484,6 @@ td {
-webkit-flex: 1;
flex: 1;
}
.pos .orders {
display: -webkit-flex;
display: flex;
vertical-align: top;
margin-left: 0px;
overflow: hidden;
}
/* c) The session buttons */
@@ -1259,7 +1252,6 @@ td {
.pos .screen {
position:absolute;
text-align: center;
top:0px;
bottom:0px;
width:100%;
@@ -2880,59 +2872,6 @@ td {
/* Order Management */
.order-row {
display: flex;
flex-direction: row;
justify-content: space-evenly;
background-color: rgb(230,230,230);
}
.order-list .order-row:hover {
color: white;
background-color: rgb(110,200,155);
font-weight: bold;
}
.order-row.highlight {
color: white;
background-color: rgb(110,200,155);
font-weight: bold;
}
.order-row.lighter {
background-color: #f5f5f5;
cursor: pointer;
}
.order-row .header {
font-size: medium;
font-weight: bolder;
flex-grow: 1;
flex-basis: 0;
text-align: left;
padding: 10px 10px;
background-color: #cecece;
border-bottom: solid 1px;
border-top: solid 1px
}
.order-row .header.total {
text-align: right;
}
.order-row .item {
font-size: medium;
flex-grow: 1;
flex-basis: 0;
text-align: left;
padding: 10px 10px;
border-bottom: solid rgb(150,150,150) 1px;
}
.order-row .item.total {
text-align: right;
}
.item .page-controls {
display: flex;
flex-direction: row;
@@ -3101,53 +3040,71 @@ td {
/* TICKET SCREEN */
.ticket-screen .orders {
display: flex;
flex-flow: column nowrap;
overflow: hidden;
overflow-y: hidden;
.pos .orders {
overflow-y: auto;
font-size: medium;
}
.ticket-screen .orders .header-row{
.pos .orders .header-row{
display: flex;
flex-flow: row nowrap;
flex: 1;
justify-content: space-evenly;
background: #868686;
color: white;
}
.ticket-screen .orders .order-row {
display: flex;
flex-flow: row nowrap;
flex: 1;
justify-content: space-evenly;
@media screen and (min-width: 768px) {
.pos .orders .order-row {
display: flex;
cursor: pointer;
}
.pos .orders .order-row:nth-child(odd) {
background: #DDD;
}
.pos .orders .order-row:nth-child(even) {
background: white;
}
}
@media screen and (max-width: 768px) {
.pos .orders .order-row {
margin: 5px;
border: 1px solid #C9CCD2; /* $border-color */
background: white; /* $o-view-background-color */
}
}
.ticket-screen .orders .order-row.highlight {
.pos .orders .order-row:hover, .pos .orders .order-row.highlight {
color: white;
background-color: rgb(110,200,155);
}
.ticket-screen .orders .col {
.pos .orders .col {
display: flex;
justify-content: space-between;
flex: 1;
padding: 10px;
text-align: start;
}
.ticket-screen .orders .col.start {
justify-content: flex-start;
@media screen and (min-width: 768px) {
.pos .orders .col.end {
justify-content: flex-end;
}
}
.ticket-screen .orders .col.center {
justify-content: center;
}
@media screen and (max-width: 768px) {
.pos .orders .order-row > .col > div:first-child {
font-weight: bold;
}
.ticket-screen .orders .col.end {
justify-content: flex-end;
.ticket-screen .order-row .delete-button {
margin-top: 5px;
justify-content: center;
background: #d23f3a /* o-text-color('danger') */ ;
color: white;
}
.ticket-screen .order-row .delete-button .fa-trash {
margin-right: 5px;
}
}
.ticket-screen .orders .col.very-narrow {
@@ -3162,19 +3119,6 @@ td {
flex: 1.5;
}
.ticket-screen .order-row:nth-child(odd) {
background: #DDD;
}
.ticket-screen .order-row:nth-child(even) {
background: white;
}
.ticket-screen .order-row:hover {
background: rgb(110,200,155);
color: white;
}
.ticket-screen .empty-order-list {
text-align: center;
margin: 48px;
@@ -3189,16 +3133,11 @@ td {
font-size: 64px;
}
.ticket-screen .pointer {
cursor: pointer;
}
.ticket-screen .controls {
display: flex;
justify-content: space-between;
align-items: center;
margin: 0px 10px;
border-bottom: dashed 1px rgb(215,215,215);
flex: 0 0 80px;
}
@@ -54,43 +54,50 @@
<div class="orders">
<t t-set="_filteredOrderList" t-value="getFilteredOrderList()" />
<t t-if="_filteredOrderList.length !== 0">
<div class="header-row">
<div class="col start wide">Date</div>
<div class="col start wide">Receipt Number</div>
<div class="col start">Customer</div>
<div class="col start wide" t-if="showCardholderName()">Cardholder Name</div>
<div class="col start">Employee</div>
<div class="header-row" t-att-class="{ oe_hidden: env.isMobile }">
<div class="col wide">Date</div>
<div class="col wide">Receipt Number</div>
<div class="col">Customer</div>
<div class="col wide" t-if="showCardholderName()">Cardholder Name</div>
<div class="col">Employee</div>
<div class="col end">Total</div>
<div class="col start narrow">Status</div>
<div class="col center very-narrow" name="delete"></div>
<div class="col narrow">Status</div>
<div class="col very-narrow" name="delete"></div>
</div>
<t t-foreach="_filteredOrderList" t-as="order" t-key="order.cid">
<div class="order-row pointer" t-att-class="{ highlight: isHighlighted(order) }" t-on-click="trigger('click-order', order)">
<div class="col start wide">
<t t-esc="getDate(order)"></t>
<div class="order-row" t-att-class="{ highlight: isHighlighted(order) }" t-on-click="trigger('click-order', order)">
<div class="col wide">
<div t-if="env.isMobile">Date</div>
<div><t t-esc="getDate(order)"></t></div>
</div>
<div class="col start wide">
<t t-esc="order.name"></t>
<div class="col wide">
<div t-if="env.isMobile">Receipt Number</div>
<div><t t-esc="order.name"></t></div>
</div>
<div class="col start">
<t t-esc="getCustomer(order)"></t>
<div class="col">
<div t-if="env.isMobile">Customer</div>
<div><t t-esc="getCustomer(order)"></t></div>
</div>
<div t-if="showCardholderName()" class="col start">
<t t-esc="getCardholderName(order)"></t>
<div t-if="showCardholderName()" class="col">
<div t-if="env.isMobile">Cardholder Name</div>
<div><t t-esc="getCardholderName(order)"></t></div>
</div>
<div class="col start">
<t t-esc="getEmployee(order)"></t>
<div class="col">
<div t-if="env.isMobile">Employee</div>
<div><t t-esc="getEmployee(order)"></t></div>
</div>
<div class="col end">
<t t-esc="getTotal(order)"></t>
<div t-if="env.isMobile">Total</div>
<div><t t-esc="getTotal(order)"></t></div>
</div>
<div class="col start narrow">
<t t-esc="getStatus(order)"></t>
<div class="col narrow">
<div t-if="env.isMobile">Status</div>
<div><t t-esc="getStatus(order)"></t></div>
</div>
<div t-if="!shouldHideDeleteButton(order)" class="col center very-narrow delete-button" name="delete" t-on-click.stop="trigger('delete-order', order)">
<i class="fa fa-trash" aria-hidden="true"></i>
<div t-if="!shouldHideDeleteButton(order)" class="col very-narrow delete-button" name="delete" t-on-click.stop="trigger('delete-order', order)">
<i class="fa fa-trash" aria-hidden="true"/><t t-if="env.isMobile"> Delete</t>
</div>
<div t-else="" class="col center very-narrow delete-button"></div>
<div t-else="" class="col very-narrow"></div>
</div>
</t>
</t>
@@ -3,15 +3,17 @@
<t t-name="TicketScreen" t-inherit="point_of_sale.TicketScreen" t-inherit-mode="extension" owl="1">
<xpath expr="//div[hasclass('header-row')]//div[@name='delete']" position="before">
<div t-if="env.pos.config.iface_floorplan" class="col start" name="table">Table</div>
<div t-if="env.pos.config.iface_floorplan" class="col" name="table">Table</div>
<div t-if="_state.ui.filter == 'TIPPING'" class="col end narrow" name="tip">Tip</div>
</xpath>
<xpath expr="//div[hasclass('order-row')]//div[@name='delete']" position="before">
<div t-if="env.pos.config.iface_floorplan" class="col start" name="table">
<t t-esc="getTable(order)"></t>
<div t-if="env.pos.config.iface_floorplan" class="col" name="table">
<div t-if="env.isMobile">Table</div>
<div><t t-esc="getTable(order)"></t></div>
</div>
<div t-if="_state.ui.filter == 'TIPPING'" class="col end narrow" name="tip">
<TipCell order="order" />
<div t-if="env.isMobile">Tip</div>
<div><TipCell order="order" /></div>
</div>
</xpath>
<xpath expr="//div[hasclass('buttons')]" position="inside">
@@ -11,16 +11,6 @@
height: 100%;
}
.order-management-screen .orders {
display: flex;
flex-direction: column;
}
.order-management-screen .order-list {
flex: 1;
overflow-y: auto;
}
.order-management-screen .control-panel {
display: flex;
flex-direction: row;
@@ -34,7 +34,7 @@ odoo.define('pos_sale.SaleOrderManagementScreen', function (require) {
// So the result is only accurate if each row is just single line.
const flexContainer = this.el.querySelector('.flex-container');
const cpEl = this.el.querySelector('.control-panel');
const headerEl = this.el.querySelector('.order-row.header');
const headerEl = this.el.querySelector('.header-row');
const val = Math.trunc(
(flexContainer.offsetHeight - cpEl.offsetHeight - headerEl.offsetHeight) /
headerEl.offsetHeight
@@ -3,13 +3,13 @@
<t t-name="SaleOrderList" owl="1">
<div class="orders">
<div class="order-row header">
<div class="header name">Order</div>
<div class="header date">Date</div>
<div class="header customer">Customer</div>
<div class="header salesman">Salesperson</div>
<div class="header total">Total</div>
<div class="header state">State</div>
<div class="header-row" t-att-class="{ oe_hidden: env.isMobile }">
<div class="col name">Order</div>
<div class="col date">Date</div>
<div class="col customer">Customer</div>
<div class="col salesman">Salesperson</div>
<div class="col end total">Total</div>
<div class="col state">State</div>
</div>
<div class="order-list">
<t t-foreach="props.orders" t-as="order" t-key="order.id">
@@ -5,7 +5,7 @@
<div class="control-panel">
<div class="item button back" t-on-click="trigger('close-screen')">
<i class="fa fa-angle-double-left"></i>
<span> Back</span>
<span t-if="!env.isMobile"> Back</span>
</div>
<div class="item search-box">
<span class="icon">
@@ -5,12 +5,30 @@
<div class="order-row"
t-att-class="{ highlight: highlighted }"
t-on-click="trigger('click-sale-order', props.order)">
<div class="item name"><t t-esc="name" /></div>
<div class="item date"><t t-esc="date" /></div>
<div class="item customer"><t t-esc="customer" /></div>
<div class="item salesman"><t t-esc="salesman" /></div>
<div class="item total"><t t-esc="total" /></div>
<div class="item state"><t t-esc="state" /></div>
<div class="col name">
<div t-if="env.isMobile">Order</div>
<div><t t-esc="name"/></div>
</div>
<div class="col date">
<div t-if="env.isMobile">Date</div>
<div><t t-esc="date"/></div>
</div>
<div class="col customer">
<div t-if="env.isMobile">Customer</div>
<div><t t-esc="customer"/></div>
</div>
<div class="col salesman">
<div t-if="env.isMobile">Salesman</div>
<div><t t-esc="salesman"/></div>
</div>
<div class="col end total">
<div t-if="env.isMobile">Total</div>
<div><t t-esc="total"/></div>
</div>
<div class="col state">
<div t-if="env.isMobile">State</div>
<div><t t-esc="state"/></div>
</div>
</div>
</t>