diff --git a/addons/point_of_sale/static/src/app/navbar/navbar.js b/addons/point_of_sale/static/src/app/navbar/navbar.js index d8480fb0cdf..36378c6c1d2 100644 --- a/addons/point_of_sale/static/src/app/navbar/navbar.js +++ b/addons/point_of_sale/static/src/app/navbar/navbar.js @@ -14,6 +14,7 @@ import { BackButton } from "@point_of_sale/app/navbar/back_button/back_button"; import { Component, useState, useExternalListener } from "@odoo/owl"; import { ClosePosPopup } from "@point_of_sale/app/navbar/closing_popup/closing_popup"; import { _t } from "@web/core/l10n/translation"; +import { ProductScreen } from "@point_of_sale/app/screens/product_screen/product_screen"; export class Navbar extends Component { static template = "point_of_sale.Navbar"; @@ -107,4 +108,14 @@ export class Navbar extends Component { showBackButton() { return this.pos.showBackButton() && this.ui.isSmall; } + + toggleProductView() { + const newView = this.pos.productListView === "grid" ? "list" : "grid"; + window.localStorage.setItem("productListView", newView); + this.pos.productListView = this.pos.productListView === "grid" ? "list" : "grid"; + } + + get showToggleProductView() { + return this.pos.mainScreen.component === ProductScreen && this.ui.isSmall; + } } diff --git a/addons/point_of_sale/static/src/app/navbar/navbar.xml b/addons/point_of_sale/static/src/app/navbar/navbar.xml index 192f3f8b863..b29d3d559d1 100644 --- a/addons/point_of_sale/static/src/app/navbar/navbar.xml +++ b/addons/point_of_sale/static/src/app/navbar/navbar.xml @@ -43,6 +43,11 @@ Close Session + diff --git a/addons/point_of_sale/static/src/app/screens/product_screen/product/product.xml b/addons/point_of_sale/static/src/app/screens/product_screen/product/product.xml index 6095f0a60f5..74b8210522e 100644 --- a/addons/point_of_sale/static/src/app/screens/product_screen/product/product.xml +++ b/addons/point_of_sale/static/src/app/screens/product_screen/product/product.xml @@ -2,15 +2,13 @@ -
- -
- -
-
+
+ +
diff --git a/addons/point_of_sale/static/src/app/screens/product_screen/product_list/control_panel/control_panel.js b/addons/point_of_sale/static/src/app/screens/product_screen/product_list/control_panel/control_panel.js index 71ad8935685..43fb1650357 100644 --- a/addons/point_of_sale/static/src/app/screens/product_screen/product_list/control_panel/control_panel.js +++ b/addons/point_of_sale/static/src/app/screens/product_screen/product_list/control_panel/control_panel.js @@ -20,7 +20,6 @@ export class ProductsWidgetControlPanel extends Component { this.updateSearch = debounce(this.updateSearch, 100); this.state = useState({ mobileSearchBarIsShown: false, isMobile: false }); this.productsWidgetControl = useRef("products-widget-control"); - this.ui = useService("ui"); const toggleIsMobile = () => this.toggleIsMobile(); onMounted(() => { diff --git a/addons/point_of_sale/static/src/app/screens/product_screen/product_list/product_list.xml b/addons/point_of_sale/static/src/app/screens/product_screen/product_list/product_list.xml index c581cdfc9d5..cdda273460d 100644 --- a/addons/point_of_sale/static/src/app/screens/product_screen/product_list/product_list.xml +++ b/addons/point_of_sale/static/src/app/screens/product_screen/product_list/product_list.xml @@ -13,7 +13,7 @@ hasNoCategories="hasNoCategories" loadProductFromServer.bind="onPressEnterKey" />
-
+
diff --git a/addons/point_of_sale/static/src/app/store/pos_store.js b/addons/point_of_sale/static/src/app/store/pos_store.js index bae7e17b5b0..e3497ed84dd 100644 --- a/addons/point_of_sale/static/src/app/store/pos_store.js +++ b/addons/point_of_sale/static/src/app/store/pos_store.js @@ -80,18 +80,20 @@ export class PosStore extends Reactive { "number_buffer", "barcode_reader", "hardware_proxy", + "ui", ]; constructor() { super(); this.ready = this.setup(...arguments).then(() => this); } // use setup instead of constructor because setup can be patched. - async setup(env, { popup, orm, number_buffer, hardware_proxy, barcode_reader }) { + async setup(env, { popup, orm, number_buffer, hardware_proxy, barcode_reader, ui }) { this.env = env; this.orm = orm; this.popup = popup; this.numberBuffer = number_buffer; this.barcodeReader = barcode_reader; + this.ui = ui; this.db = new PosDB(); // a local database used to search trough products and categories & store pending orders this.unwatched = markRaw({}); @@ -120,6 +122,7 @@ export class PosStore extends Reactive { this.numpadMode = "quantity"; this.mobile_pane = "right"; + this.productListView = window.localStorage.getItem("productListView") || "grid"; // Record this.toRefundLines = {}; @@ -174,7 +177,9 @@ export class PosStore extends Reactive { this.preloadImages(); this.showScreen("ProductScreen"); } - + get productListViewMode() { + return this.productListView && this.ui.isSmall ? this.productListView : "grid"; + } getDefaultSearchDetails() { return { fieldName: "RECEIPT_NUMBER", diff --git a/addons/point_of_sale/static/src/scss/pos.scss b/addons/point_of_sale/static/src/scss/pos.scss index 53018297b73..63247604c6e 100644 --- a/addons/point_of_sale/static/src/scss/pos.scss +++ b/addons/point_of_sale/static/src/scss/pos.scss @@ -852,7 +852,7 @@ td { /* ********* The product list ********* */ -.pos .product-list { +.pos .product-list.grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(122px, 1fr)); padding: 3px; @@ -1112,28 +1112,49 @@ td { /* e) the product */ .pos .product { - position:relative; - background:#fff; - overflow: hidden; - cursor: pointer; display: flex; - flex-direction: column; + position:relative; + cursor: pointer; + overflow: hidden; + background:#fff; align-items: stretch; } +.pos .product.grid { + height: 170px; + flex-direction: column; +} +.pos .product.list { + height: 90px; + flex-direction: row-reverse; + margin: 3px; + justify-content: space-between; +} .pos .product-content { display: flex; flex-direction: column; justify-content: space-between; +} +.pos .product.list .product-content { height: 100%; } - +.pos .product.grid .product-img { + height: 100px; + width: 100%; + overflow: hidden; + margin: 3px; +} +.pos .product.list .product-img { + height: 84px; + width: 84px; + margin: 3px; + overflow: hidden; +} .pos .product .product-img img { width: 100%; height: 100px; - object-fit: contain; + object-fit: cover; } - @media screen and (max-width: 768px) { .pos .product:active { box-shadow: 0 0 0 3px $primary;