From 0fb2e02b5626e9dfd4fcebf6511c62b6d05f1352 Mon Sep 17 00:00:00 2001 From: Saqib Ansari Date: Mon, 9 Nov 2020 23:51:24 +0530 Subject: [PATCH] feat: pos item selector new ui --- erpnext/public/build.json | 3 +- erpnext/public/scss/point-of-sale.scss | 145 ++++++++++++++++++ .../page/point_of_sale/pos_controller.js | 4 +- .../page/point_of_sale/pos_item_selector.js | 42 +++-- 4 files changed, 168 insertions(+), 26 deletions(-) create mode 100644 erpnext/public/scss/point-of-sale.scss diff --git a/erpnext/public/build.json b/erpnext/public/build.json index 2695502269..78128a105d 100644 --- a/erpnext/public/build.json +++ b/erpnext/public/build.json @@ -2,7 +2,8 @@ "css/erpnext.css": [ "public/less/erpnext.less", "public/less/hub.less", - "public/less/call_popup.less" + "public/less/call_popup.less", + "public/scss/point-of-sale.scss" ], "css/marketplace.css": [ "public/less/hub.less" diff --git a/erpnext/public/scss/point-of-sale.scss b/erpnext/public/scss/point-of-sale.scss new file mode 100644 index 0000000000..1d01496277 --- /dev/null +++ b/erpnext/public/scss/point-of-sale.scss @@ -0,0 +1,145 @@ +.point-of-sale-app { + display: grid; + grid-template-columns: repeat(10, minmax(0, 1fr)); + gap: var(--margin-md); + + section { + min-height: 45rem; + max-height: calc(100vh - 200px); + } + + .frappe-control { + margin: 0 !important; + padding: 5px 5px; + width: 100%; + } + + .form-group { + margin-bottom: 0px !important; + } + + .pointer-no-select { + cursor: pointer; + user-select: none; + } + + .nowrap { + overflow: hidden; + white-space: nowrap; + } + + .image { + height: 100% !important; + object-fit: cover; + } + + .abbr { + background-color: var(--gray-50); + font-size: var(--text-3xl); + } + + .label { + display: flex; + align-items: center; + font-weight: 700; + font-size: var(--text-lg); + } + + .pos-card { + background-color: var(--fg-color); + box-shadow: var(--shadow-base); + border-radius: var(--border-radius-md); + } + + > .items-selector { + grid-column: span 6 / span 6; + display: flex; + flex-direction: column; + overflow-y: scroll; + overflow-x: hidden; + + > .filter-section { + display: grid; + grid-template-columns: repeat(12, minmax(0, 1fr)); + background-color: var(--fg-color); + position: sticky; + top: -1px; + z-index: 1; + padding: var(--padding-md); + padding-bottom: var(--padding-sm); + align-items: center; + + > .label { + @extend .label; + grid-column: span 4 / span 4; + padding: var(--padding-xs); + padding-top: 0px; + } + + > .search-field { + grid-column: span 5 / span 5; + display: flex; + align-items: center; + } + + > .item-group-field { + grid-column: span 3 / span 3; + display: flex; + align-items: center; + } + } + + > .items-container { + display: grid; + grid-template-columns: repeat(4, minmax(0, 1fr)); + gap: var(--margin-lg); + flex: 1 1 0%; + padding: var(--padding-lg); + padding-top: var(--padding-xs); + + > .item-wrapper { + @extend .pointer-no-select; + border-radius: var(--border-radius-md); + box-shadow: var(--shadow-base); + + .item-display { + display: flex; + align-items: center; + justify-content: center; + border-radius: var(--border-radius-md); + margin: var(--margin-sm); + margin-bottom: 0px; + min-height: 8rem; + height: 8rem; + color: var(--gray-500); + + > img { + @extend .image; + } + } + + > .item-detail { + display: flex; + flex-direction: column; + justify-content: center; + min-height: 3.5rem; + height: 3.5rem; + padding-left: var(--padding-sm); + padding-right: var(--padding-sm); + + > .item-name { + @extend .nowrap; + display: flex; + align-items: center; + font-size: var(--text-md); + } + + > .item-rate { + font-weight: 700; + } + } + + } + } + } +} \ No newline at end of file diff --git a/erpnext/selling/page/point_of_sale/pos_controller.js b/erpnext/selling/page/point_of_sale/pos_controller.js index 288084d245..8cbd59086c 100644 --- a/erpnext/selling/page/point_of_sale/pos_controller.js +++ b/erpnext/selling/page/point_of_sale/pos_controller.js @@ -157,10 +157,10 @@ erpnext.PointOfSale.Controller = class { prepare_dom() { this.wrapper.append( - `
` + `
` ); - this.$components_wrapper = this.wrapper.find('.app'); + this.$components_wrapper = this.wrapper.find('.point-of-sale-app'); } prepare_components() { diff --git a/erpnext/selling/page/point_of_sale/pos_item_selector.js b/erpnext/selling/page/point_of_sale/pos_item_selector.js index 49d42814ab..4195d93d4e 100644 --- a/erpnext/selling/page/point_of_sale/pos_item_selector.js +++ b/erpnext/selling/page/point_of_sale/pos_item_selector.js @@ -17,18 +17,13 @@ erpnext.PointOfSale.ItemSelector = class { prepare_dom() { this.wrapper.append( - `
-
-
-
-
-
-
-
ALL ITEMS
-
-
-
+ `
+
+
All Items
+
+
+
` ); @@ -80,27 +75,28 @@ erpnext.PointOfSale.ItemSelector = class { function get_item_image_html() { if (item_image) { - return `
- ${frappe.get_abbr(item.item_name)} -
` + return `
+ ${frappe.get_abbr(item.item_name)} +
`; } else { - return `
- ${frappe.get_abbr(item.item_name)} -
` + return `
${frappe.get_abbr(item.item_name)}
`; } } return ( - `
+ ${get_item_image_html()} -
-
+ +
+
${frappe.ellipsis(item.item_name, 18)}
-
${format_currency(item.price_list_rate, item.currency, 0) || 0}
+
${format_currency(item.price_list_rate, item.currency, 0) || 0}
` ) @@ -115,7 +111,7 @@ erpnext.PointOfSale.ItemSelector = class { df: { label: __('Search'), fieldtype: 'Data', - placeholder: __('Search by item code, serial number, batch no or barcode') + placeholder: __('Search by item code, serial number or barcode') }, parent: this.$component.find('.search-field'), render_input: true,