From 621c8cf5fe9e7a183990dc52dd55dd0029b59f45 Mon Sep 17 00:00:00 2001 From: Samuel Degueldre Date: Fri, 10 Feb 2023 14:36:12 +0000 Subject: [PATCH] [REF] pos_restaurant: rewrite resize logic for tables on floor screen The previous code had a lot of repetition and made use of deprecated features such as useListener. This commit refactors the resize logic by creating a simple ResizeHandle component that encapsulates the drag handle logic, it then communicates delta in x and y to the EditableTable which applies it to the correct side and adds constraints on the coordinates. It also slightly improves the UX for round tables by also giving them "corner" drag handles, which let you resize two dimensions at once instead of just one, this also makes the code more uniform between the table types, the only difference being where we position the drag handles so that they're visible. closes odoo/odoo#112430 Signed-off-by: Trinh Jacky (trj) --- .../static/src/app/floor_screen/edit_bar.js | 24 ++ .../floor_screen/edit_bar.xml} | 2 +- .../src/app/floor_screen/editable_table.js | 121 +++++++ .../src/app/floor_screen/editable_table.xml | 20 ++ .../floor_screen/floor_screen.js} | 24 +- .../floor_screen/floor_screen.xml} | 6 +- .../src/app/floor_screen/resize_handle.js | 64 ++++ .../src/app/floor_screen/resize_handle.xml | 6 + .../floor_screen/table.js} | 65 ++-- .../floor_screen/table.xml} | 6 +- .../static/src/app/pos_store.js | 2 +- .../static/src/js/Resizeable.js | 325 ------------------ .../src/js/Screens/FloorScreen/EditBar.js | 14 - .../js/Screens/FloorScreen/EditableTable.js | 59 ---- .../js/Screens/ReceiptScreen/ReceiptScreen.js | 2 +- .../static/src/scss/restaurant.scss | 11 +- .../static/src/xml/Resizeable.xml | 8 - .../xml/Screens/FloorScreen/EditableTable.xml | 31 -- 18 files changed, 288 insertions(+), 502 deletions(-) create mode 100644 addons/pos_restaurant/static/src/app/floor_screen/edit_bar.js rename addons/pos_restaurant/static/src/{xml/Screens/FloorScreen/EditBar.xml => app/floor_screen/edit_bar.xml} (99%) create mode 100644 addons/pos_restaurant/static/src/app/floor_screen/editable_table.js create mode 100644 addons/pos_restaurant/static/src/app/floor_screen/editable_table.xml rename addons/pos_restaurant/static/src/{js/Screens/FloorScreen/FloorScreen.js => app/floor_screen/floor_screen.js} (94%) rename addons/pos_restaurant/static/src/{xml/Screens/FloorScreen/FloorScreen.xml => app/floor_screen/floor_screen.xml} (91%) create mode 100644 addons/pos_restaurant/static/src/app/floor_screen/resize_handle.js create mode 100644 addons/pos_restaurant/static/src/app/floor_screen/resize_handle.xml rename addons/pos_restaurant/static/src/{js/Screens/FloorScreen/TableWidget.js => app/floor_screen/table.js} (59%) rename addons/pos_restaurant/static/src/{xml/Screens/FloorScreen/TableWidget.xml => app/floor_screen/table.xml} (80%) delete mode 100644 addons/pos_restaurant/static/src/js/Resizeable.js delete mode 100644 addons/pos_restaurant/static/src/js/Screens/FloorScreen/EditBar.js delete mode 100644 addons/pos_restaurant/static/src/js/Screens/FloorScreen/EditableTable.js delete mode 100644 addons/pos_restaurant/static/src/xml/Resizeable.xml delete mode 100644 addons/pos_restaurant/static/src/xml/Screens/FloorScreen/EditableTable.xml diff --git a/addons/pos_restaurant/static/src/app/floor_screen/edit_bar.js b/addons/pos_restaurant/static/src/app/floor_screen/edit_bar.js new file mode 100644 index 00000000000..0b3357bd7f9 --- /dev/null +++ b/addons/pos_restaurant/static/src/app/floor_screen/edit_bar.js @@ -0,0 +1,24 @@ +/** @odoo-module */ + +import { Component, useState } from "@odoo/owl"; + +export class EditBar extends Component { + static template = "pos_restaurant.EditBar"; + static props = { + selectedTable: [{ type: Object, shape: { shape: String, "*": true } }, { value: false }], + floorMapScrollTop: Number, + createTable: Function, + duplicateTable: Function, + renameTable: Function, + changeSeatsNum: Function, + changeShape: Function, + setTableColor: Function, + setFloorColor: Function, + deleteTable: Function, + }; + + setup() { + super.setup(); + this.state = useState({ isColorPicker: false }); + } +} diff --git a/addons/pos_restaurant/static/src/xml/Screens/FloorScreen/EditBar.xml b/addons/pos_restaurant/static/src/app/floor_screen/edit_bar.xml similarity index 99% rename from addons/pos_restaurant/static/src/xml/Screens/FloorScreen/EditBar.xml rename to addons/pos_restaurant/static/src/app/floor_screen/edit_bar.xml index 76aff3d9f5d..cd734cd3196 100644 --- a/addons/pos_restaurant/static/src/xml/Screens/FloorScreen/EditBar.xml +++ b/addons/pos_restaurant/static/src/app/floor_screen/edit_bar.xml @@ -1,7 +1,7 @@ - +
diff --git a/addons/pos_restaurant/static/src/app/floor_screen/editable_table.js b/addons/pos_restaurant/static/src/app/floor_screen/editable_table.js new file mode 100644 index 00000000000..8ab8f3e9f72 --- /dev/null +++ b/addons/pos_restaurant/static/src/app/floor_screen/editable_table.js @@ -0,0 +1,121 @@ +/** @odoo-module */ + +import { Draggable } from "@point_of_sale/js/Misc/Draggable"; +import { ResizeHandle } from "./resize_handle"; +import { onWillUnmount, useEffect, useRef, Component } from "@odoo/owl"; +import { Table } from "./table"; + +const MIN_TABLE_SIZE = 30; // px + +function constrain(num, [min, max]) { + return Math.min(Math.max(num, min), max); +} +export class EditableTable extends Component { + static template = "pos_restaurant.EditableTable"; + static components = { Draggable, ResizeHandle }; + static props = { + onSaveTable: Function, + limit: { type: Object, shape: { el: [HTMLElement, { value: null }] } }, + table: Table.props.table, + }; + + setup() { + super.setup(); + useEffect(this._setElementStyle.bind(this)); + this.root = useRef("root"); + this.handles = { + "top left": ["minX", "minY"], + "top right": ["maxX", "minY"], + "bottom left": ["minX", "maxY"], + "bottom right": ["maxX", "maxY"], + }; + onWillUnmount(() => this.props.onSaveTable(this.props.table)); + } + + onHandleMoveStart() { + this.startTable = { ...this.props.table }; + } + + onHandleMove(dir, { dx, dy }) { + const table = this.startTable; + // Working with min/max x and y makes constraints much easier to apply uniformly + const { width, height, position_h: minX, position_v: minY } = table; + const maxX = minX + width; + const maxY = minY + height; + const newTable = { minX, minY, maxX, maxY }; + + const [moveX, moveY] = this.handles[dir]; + const { limits } = this; + const bounds = { + maxX: [minX + MIN_TABLE_SIZE, limits.maxX], + minX: [limits.minX, maxX - MIN_TABLE_SIZE], + maxY: [minY + MIN_TABLE_SIZE, limits.maxY], + minY: [limits.minY, maxY - MIN_TABLE_SIZE], + }; + newTable[moveX] = constrain(newTable[moveX] + dx, bounds[moveX]); + newTable[moveY] = constrain(newTable[moveY] + dy, bounds[moveY]); + + // Convert back to server format at the end + this.props.table.position_h = newTable.minX; + this.props.table.position_v = newTable.minY; + this.props.table.width = newTable.maxX - newTable.minX; + this.props.table.height = newTable.maxY - newTable.minY; + this._setElementStyle(); + } + /** + * Offsets the resize handles from the edge of the table. For square tables, + * the offset is half the width of the handle (we just want a quarter circle + * to be visible), for round tables it's half the width plus the distance of + * the middle of the rounded border's arc to the edge. + * + * @param {`${'top'|'bottom'} ${'left'|'right'}`} handleName the handle for + * which to compute the style + * @returns {string} the value of the style attribute for the given handle + */ + computeHandleStyle(handleName) { + const table = this.props.table; + // 24 is half the handle's width + let offset = -24; + if (table.shape === "round") { + // min(width/2, height/2) is the real border radius + // 0.2929 is (1 - cos(45°)) to get in the middle of the border's arc + offset += Math.min(table.width / 2, table.height / 2) * 0.2929; + } + return handleName + .split(" ") + .map((dir) => `${dir}: ${offset}px;`) + .join(" "); + } + + get limits() { + const limitRect = this.props.limit.el.getBoundingClientRect(); + const offsetParentRect = this.root.el.offsetParent.getBoundingClientRect(); + return { + minY: limitRect.top - offsetParentRect.top, + minX: limitRect.left - offsetParentRect.left, + maxY: limitRect.top - offsetParentRect.top + limitRect.height, + maxX: limitRect.left - offsetParentRect.left + limitRect.width, + }; + } + + _setElementStyle() { + const table = this.props.table; + Object.assign(this.root.el.style, { + left: `${table.position_h}px`, + top: `${table.position_v}px`, + width: `${table.width}px`, + height: `${table.height}px`, + background: table.color || "rgb(53, 211, 116)", + "line-height": `${table.height}px`, + "border-radius": table.shape === "round" ? "1000px" : "3px", + "font-size": table.height >= 150 && table.width >= 150 ? "32px" : "16px", + }); + } + + onDragEnd(event) { + const { loc } = event.detail; + const table = this.props.table; + table.position_v = loc.top; + table.position_h = loc.left; + } +} diff --git a/addons/pos_restaurant/static/src/app/floor_screen/editable_table.xml b/addons/pos_restaurant/static/src/app/floor_screen/editable_table.xml new file mode 100644 index 00000000000..f4579672a7a --- /dev/null +++ b/addons/pos_restaurant/static/src/app/floor_screen/editable_table.xml @@ -0,0 +1,20 @@ + + + + + +
+ + + + + + + + + +
+
+
+ +
diff --git a/addons/pos_restaurant/static/src/js/Screens/FloorScreen/FloorScreen.js b/addons/pos_restaurant/static/src/app/floor_screen/floor_screen.js similarity index 94% rename from addons/pos_restaurant/static/src/js/Screens/FloorScreen/FloorScreen.js rename to addons/pos_restaurant/static/src/app/floor_screen/floor_screen.js index a3248a6879e..7d6141b11a6 100644 --- a/addons/pos_restaurant/static/src/js/Screens/FloorScreen/FloorScreen.js +++ b/addons/pos_restaurant/static/src/app/floor_screen/floor_screen.js @@ -1,6 +1,5 @@ /** @odoo-module */ -import { LegacyComponent } from "@web/legacy/legacy_component"; import { debounce } from "@web/core/utils/timing"; import { registry } from "@web/core/registry"; @@ -8,27 +7,24 @@ import { TextInputPopup } from "@point_of_sale/js/Popups/TextInputPopup"; import { NumberPopup } from "@point_of_sale/js/Popups/NumberPopup"; import { ConfirmPopup } from "@point_of_sale/js/Popups/ConfirmPopup"; -import { EditableTable } from "./EditableTable"; -import { EditBar } from "./EditBar"; -import { TableWidget } from "./TableWidget"; +import { EditableTable } from "./editable_table"; +import { EditBar } from "./edit_bar"; +import { Table } from "./table"; import { usePos } from "@point_of_sale/app/pos_hook"; import { useService } from "@web/core/utils/hooks"; +import { Component, onPatched, onMounted, onWillUnmount, useRef, useState } from "@odoo/owl"; -const { onPatched, onMounted, onWillUnmount, useRef, useState } = owl; - -export class FloorScreen extends LegacyComponent { - static components = { EditableTable, EditBar, TableWidget }; - static template = "FloorScreen"; +export class FloorScreen extends Component { + static components = { EditableTable, EditBar, Table }; + static template = "pos_restaurant.FloorScreen"; + static props = { isShown: Boolean, floor: { type: true, optional: true } }; static storeOnOrder = false; - /** - * @param {Object} props - * @param {Object} props.floor - */ setup() { super.setup(); this.pos = usePos(); this.popup = useService("popup"); + this.rpc = useService("rpc"); const floor = this.props.floor ? this.props.floor : this.env.pos.floors[0]; this.state = useState({ selectedFloorId: floor.id, @@ -93,6 +89,7 @@ export class FloorScreen extends LegacyComponent { height: 75, shape: "square", seats: 1, + color: "rgb(53, 211, 116)", }; } newTable.name = this._getNewTableName(newTable.name); @@ -298,6 +295,7 @@ export class FloorScreen extends LegacyComponent { return; } const originalSelectedTableId = this.state.selectedTableId; + this.env.pos.tables_by_id[originalSelectedTableId].active = false; await this.rpc({ model: "restaurant.table", method: "create_from_ui", diff --git a/addons/pos_restaurant/static/src/xml/Screens/FloorScreen/FloorScreen.xml b/addons/pos_restaurant/static/src/app/floor_screen/floor_screen.xml similarity index 91% rename from addons/pos_restaurant/static/src/xml/Screens/FloorScreen/FloorScreen.xml rename to addons/pos_restaurant/static/src/app/floor_screen/floor_screen.xml index 2b67a5f7b3c..fa3d98dd682 100644 --- a/addons/pos_restaurant/static/src/xml/Screens/FloorScreen/FloorScreen.xml +++ b/addons/pos_restaurant/static/src/app/floor_screen/floor_screen.xml @@ -1,7 +1,7 @@ - +
@@ -29,8 +29,8 @@
- - + + { + this.onMove({ x: ev.clientX, y: ev.clientY }); + }; + this.onTouchMove = (ev) => { + this.onMove({ + x: ev.touches[0].clientX, + y: ev.touches[0].clientY, + }); + }; + onWillUnmount(() => { + document.removeEventListener("mousemove", this.onMouseMove); + document.removeEventListener("touchmove", this.onTouchMove); + }); + } + + onMouseDown(ev) { + this.startPosition = { x: ev.clientX, y: ev.clientY }; + this.props.onMoveStart(); + document.addEventListener("mousemove", this.onMouseMove); + document.addEventListener( + "mouseup", + (ev) => { + ev.stopPropagation(); + document.removeEventListener("mousemove", this.onMouseMove); + }, + { once: true, capture: true } + ); + } + + onTouchStart(ev) { + this.startPosition = { x: ev.touches[0].clientX, y: ev.touches[0].clientY }; + this.props.onMoveStart(); + document.addEventListener("touchmove", this.onTouchMove); + document.addEventListener( + "touchend", + (ev) => { + ev.stopPropagation(); + document.removeEventListener("touchmove", this.onTouchMove); + }, + { once: true, capture: true } + ); + } + + /** + * Calls the onMove props with the delta x/y since the dragging began. + * + * @param {{x: number, y: number}} param0 the new position of the cursor + */ + onMove({ x, y }) { + this.props.onMove({ + dx: x - this.startPosition.x, + dy: y - this.startPosition.y, + }); + } +} diff --git a/addons/pos_restaurant/static/src/app/floor_screen/resize_handle.xml b/addons/pos_restaurant/static/src/app/floor_screen/resize_handle.xml new file mode 100644 index 00000000000..82d897ad9b7 --- /dev/null +++ b/addons/pos_restaurant/static/src/app/floor_screen/resize_handle.xml @@ -0,0 +1,6 @@ + + + + + + diff --git a/addons/pos_restaurant/static/src/js/Screens/FloorScreen/TableWidget.js b/addons/pos_restaurant/static/src/app/floor_screen/table.js similarity index 59% rename from addons/pos_restaurant/static/src/js/Screens/FloorScreen/TableWidget.js rename to addons/pos_restaurant/static/src/app/floor_screen/table.js index e6ba281c3a4..ac054345d65 100644 --- a/addons/pos_restaurant/static/src/js/Screens/FloorScreen/TableWidget.js +++ b/addons/pos_restaurant/static/src/app/floor_screen/table.js @@ -1,42 +1,39 @@ /** @odoo-module */ -import { LegacyComponent } from "@web/legacy/legacy_component"; +import { Component } from "@odoo/owl"; -/** - * props: { - * onClick: callback, - * table: table object, - * } - */ -export class TableWidget extends LegacyComponent { - static template = "TableWidget"; +export class Table extends Component { + static template = "pos_restaurant.Table"; + static props = { + onClick: Function, + table: { + type: Object, + shape: { + position_h: Number, + position_v: Number, + width: Number, + height: Number, + shape: String, + color: [String, { value: false }], + name: String, + seats: Number, + "*": true, + }, + }, + }; - setup() { - owl.onMounted(this.onMounted); - } - onMounted() { + get style() { const table = this.props.table; - function unit(val) { - return `${val}px`; - } - const style = { - width: unit(table.width), - height: unit(table.height), - "line-height": unit(table.height), - top: unit(table.position_v), - left: unit(table.position_h), - "border-radius": table.shape === "round" ? unit(1000) : "3px", - }; - if (table.color) { - style.background = table.color; - } - if (table.height >= 150 && table.width >= 150) { - style["font-size"] = "32px"; - } - Object.assign(this.el.style, style); - - const tableCover = this.el.querySelector(".table-cover"); - Object.assign(tableCover.style, { height: `${Math.ceil(this.fill * 100)}%` }); + return ` + width: ${table.width}px; + height: ${table.height}px; + line-height: ${table.height}px; + top: ${table.position_v}px; + left: ${table.position_h}px; + border-radius: ${table.shape === "round" ? 1000 : 3}px; + background: ${table.color || "rgb(53, 211, 116)"}; + font-size: ${table.height >= 150 && table.width >= 150 ? 32 : 16}px; + `; } get fill() { const customerCount = this.env.pos.getCustomerCount(this.props.table.id); diff --git a/addons/pos_restaurant/static/src/xml/Screens/FloorScreen/TableWidget.xml b/addons/pos_restaurant/static/src/app/floor_screen/table.xml similarity index 80% rename from addons/pos_restaurant/static/src/xml/Screens/FloorScreen/TableWidget.xml rename to addons/pos_restaurant/static/src/app/floor_screen/table.xml index 12838995a82..e7a6819cb89 100644 --- a/addons/pos_restaurant/static/src/xml/Screens/FloorScreen/TableWidget.xml +++ b/addons/pos_restaurant/static/src/app/floor_screen/table.xml @@ -1,9 +1,9 @@ - -
- + +
+ diff --git a/addons/pos_restaurant/static/src/app/pos_store.js b/addons/pos_restaurant/static/src/app/pos_store.js index c1d201f4cc2..d290ce3e338 100644 --- a/addons/pos_restaurant/static/src/app/pos_store.js +++ b/addons/pos_restaurant/static/src/app/pos_store.js @@ -3,7 +3,7 @@ import { patch } from "@web/core/utils/patch"; import { PosStore } from "@point_of_sale/app/pos_store"; import { PaymentScreen } from "@point_of_sale/js/Screens/PaymentScreen/PaymentScreen"; -import { FloorScreen } from "@pos_restaurant/js/Screens/FloorScreen/FloorScreen"; +import { FloorScreen } from "@pos_restaurant/app/floor_screen/floor_screen"; const NON_IDLE_EVENTS = [ "mousemove", diff --git a/addons/pos_restaurant/static/src/js/Resizeable.js b/addons/pos_restaurant/static/src/js/Resizeable.js deleted file mode 100644 index 36e1c1c4c89..00000000000 --- a/addons/pos_restaurant/static/src/js/Resizeable.js +++ /dev/null @@ -1,325 +0,0 @@ -/** @odoo-module */ - -import { useListener } from "@web/core/utils/hooks"; -import { LegacyComponent } from "@web/legacy/legacy_component"; - -const { onMounted, useExternalListener } = owl; - -export class Resizeable extends LegacyComponent { - static template = "Resizeable"; - - setup() { - super.setup(); - useExternalListener(document, "mousemove", this.resizeN); - useExternalListener(document, "mouseup", this.endResizeN); - useListener("mousedown", ".resize-handle-n", this.startResizeN); - - useExternalListener(document, "mousemove", this.resizeS); - useExternalListener(document, "mouseup", this.endResizeS); - useListener("mousedown", ".resize-handle-s", this.startResizeS); - - useExternalListener(document, "mousemove", this.resizeW); - useExternalListener(document, "mouseup", this.endResizeW); - useListener("mousedown", ".resize-handle-w", this.startResizeW); - - useExternalListener(document, "mousemove", this.resizeE); - useExternalListener(document, "mouseup", this.endResizeE); - useListener("mousedown", ".resize-handle-e", this.startResizeE); - - useExternalListener(document, "mousemove", this.resizeNW); - useExternalListener(document, "mouseup", this.endResizeNW); - useListener("mousedown", ".resize-handle-nw", this.startResizeNW); - - useExternalListener(document, "mousemove", this.resizeNE); - useExternalListener(document, "mouseup", this.endResizeNE); - useListener("mousedown", ".resize-handle-ne", this.startResizeNE); - - useExternalListener(document, "mousemove", this.resizeSW); - useExternalListener(document, "mouseup", this.endResizeSW); - useListener("mousedown", ".resize-handle-sw", this.startResizeSW); - - useExternalListener(document, "mousemove", this.resizeSE); - useExternalListener(document, "mouseup", this.endResizeSE); - useListener("mousedown", ".resize-handle-se", this.startResizeSE); - - useExternalListener(document, "touchmove", this.resizeN); - useExternalListener(document, "touchend", this.endResizeN); - useListener("touchstart", ".resize-handle-n", this.startResizeN); - - useExternalListener(document, "touchmove", this.resizeS); - useExternalListener(document, "touchend", this.endResizeS); - useListener("touchstart", ".resize-handle-s", this.startResizeS); - - useExternalListener(document, "touchmove", this.resizeW); - useExternalListener(document, "touchend", this.endResizeW); - useListener("touchstart", ".resize-handle-w", this.startResizeW); - - useExternalListener(document, "touchmove", this.resizeE); - useExternalListener(document, "touchend", this.endResizeE); - useListener("touchstart", ".resize-handle-e", this.startResizeE); - - useExternalListener(document, "touchmove", this.resizeNW); - useExternalListener(document, "touchend", this.endResizeNW); - useListener("touchstart", ".resize-handle-nw", this.startResizeNW); - - useExternalListener(document, "touchmove", this.resizeNE); - useExternalListener(document, "touchend", this.endResizeNE); - useListener("touchstart", ".resize-handle-ne", this.startResizeNE); - - useExternalListener(document, "touchmove", this.resizeSW); - useExternalListener(document, "touchend", this.endResizeSW); - useListener("touchstart", ".resize-handle-sw", this.startResizeSW); - - useExternalListener(document, "touchmove", this.resizeSE); - useExternalListener(document, "touchend", this.endResizeSE); - useListener("touchstart", ".resize-handle-se", this.startResizeSE); - - this.size = { height: 0, width: 0 }; - this.loc = { top: 0, left: 0 }; - this.tempSize = {}; - - onMounted(() => { - this.limitArea = this.props.limitArea - ? document.querySelector(this.props.limitArea) - : this.el.offsetParent; - this.limitAreaBoundingRect = this.limitArea.getBoundingClientRect(); - if (this.limitArea === this.el.offsetParent) { - this.limitLeft = 0; - this.limitTop = 0; - this.limitRight = this.limitAreaBoundingRect.width; - this.limitBottom = this.limitAreaBoundingRect.height; - } else { - this.limitLeft = -this.el.offsetParent.offsetLeft; - this.limitTop = -this.el.offsetParent.offsetTop; - this.limitRight = - this.limitAreaBoundingRect.width - this.el.offsetParent.offsetLeft; - this.limitBottom = - this.limitAreaBoundingRect.height - this.el.offsetParent.offsetTop; - } - this.limitAreaWidth = this.limitAreaBoundingRect.width; - this.limitAreaHeight = this.limitAreaBoundingRect.height; - }); - } - startResizeN(event) { - let realEvent; - if (event instanceof CustomEvent) { - realEvent = event.detail; - } else { - realEvent = event; - } - const { y } = this._getEventLoc(realEvent); - this.isResizingN = true; - this.startY = y; - this.size.height = this.el.offsetHeight; - this.loc.top = this.el.offsetTop; - event.stopPropagation(); - } - resizeN(event) { - if (this.isResizingN) { - const { y: newY } = this._getEventLoc(event); - let dY = newY - this.startY; - if (dY < 0 && Math.abs(dY) > this.loc.top) { - dY = -this.loc.top; - } else if (dY > 0 && dY > this.size.height) { - dY = this.size.height; - } - this.el.style.height = `${this.size.height - dY}px`; - this.el.style.top = `${this.loc.top + dY}px`; - } - } - endResizeN() { - if (this.isResizingN && !this.isResizingE && !this.isResizingW && !this.isResizingS) { - this.isResizingN = false; - this._triggerResizeEnd(); - } - } - startResizeS(event) { - let realEvent; - if (event instanceof CustomEvent) { - realEvent = event.detail; - } else { - realEvent = event; - } - const { y } = this._getEventLoc(realEvent); - this.isResizingS = true; - this.startY = y; - this.size.height = this.el.offsetHeight; - this.loc.top = this.el.offsetTop; - event.stopPropagation(); - } - resizeS(event) { - if (this.isResizingS) { - const { y: newY } = this._getEventLoc(event); - let dY = newY - this.startY; - if (dY > 0 && dY > this.limitAreaHeight - (this.size.height + this.loc.top)) { - dY = this.limitAreaHeight - (this.size.height + this.loc.top); - } else if (dY < 0 && Math.abs(dY) > this.size.height) { - dY = -this.size.height; - } - this.el.style.height = `${this.size.height + dY}px`; - } - } - endResizeS() { - if (!this.isResizingN && !this.isResizingE && !this.isResizingW && this.isResizingS) { - this.isResizingS = false; - this._triggerResizeEnd(); - } - } - startResizeW(event) { - let realEvent; - if (event instanceof CustomEvent) { - realEvent = event.detail; - } else { - realEvent = event; - } - const { x } = this._getEventLoc(realEvent); - this.isResizingW = true; - this.startX = x; - this.size.width = this.el.offsetWidth; - this.loc.left = this.el.offsetLeft; - event.stopPropagation(); - } - resizeW(event) { - if (this.isResizingW) { - const { x: newX } = this._getEventLoc(event); - let dX = newX - this.startX; - if (dX > 0 && dX > this.size.width) { - dX = this.size.width; - } else if (dX < 0 && Math.abs(dX) > this.loc.left + Math.abs(this.limitLeft)) { - dX = -this.loc.left + this.limitLeft; - } - this.el.style.width = `${this.size.width - dX}px`; - this.el.style.left = `${this.loc.left + dX}px`; - } - } - endResizeW() { - if (!this.isResizingN && !this.isResizingE && this.isResizingW && !this.isResizingS) { - this.isResizingW = false; - this._triggerResizeEnd(); - } - } - startResizeE(event) { - let realEvent; - if (event instanceof CustomEvent) { - realEvent = event.detail; - } else { - realEvent = event; - } - const { x } = this._getEventLoc(realEvent); - this.isResizingE = true; - this.startX = x; - this.size.width = this.el.offsetWidth; - this.loc.left = this.el.offsetLeft; - event.stopPropagation(); - } - resizeE(event) { - if (this.isResizingE) { - const { x: newX } = this._getEventLoc(event); - let dX = newX - this.startX; - if ( - dX > 0 && - dX > - this.limitAreaWidth - - (this.size.width + this.loc.left + Math.abs(this.limitLeft)) - ) { - dX = - this.limitAreaWidth - - (this.size.width + this.loc.left + Math.abs(this.limitLeft)); - } else if (dX < 0 && Math.abs(dX) > this.size.width) { - dX = -this.size.width; - } - this.el.style.width = `${this.size.width + dX}px`; - } - } - endResizeE() { - if (!this.isResizingN && this.isResizingE && !this.isResizingW && !this.isResizingS) { - this.isResizingE = false; - this._triggerResizeEnd(); - } - } - startResizeNW(event) { - this.startResizeN(event); - this.startResizeW(event); - } - resizeNW(event) { - this.resizeN(event); - this.resizeW(event); - } - endResizeNW() { - if (this.isResizingN && !this.isResizingE && this.isResizingW && !this.isResizingS) { - this.isResizingN = false; - this.isResizingW = false; - this._triggerResizeEnd(); - } - } - startResizeNE(event) { - this.startResizeN(event); - this.startResizeE(event); - } - resizeNE(event) { - this.resizeN(event); - this.resizeE(event); - } - endResizeNE() { - if (this.isResizingN && this.isResizingE && !this.isResizingW && !this.isResizingS) { - this.isResizingN = false; - this.isResizingE = false; - this._triggerResizeEnd(); - } - } - startResizeSE(event) { - this.startResizeS(event); - this.startResizeE(event); - } - resizeSE(event) { - this.resizeS(event); - this.resizeE(event); - } - endResizeSE() { - if (!this.isResizingN && this.isResizingE && !this.isResizingW && this.isResizingS) { - this.isResizingS = false; - this.isResizingE = false; - this._triggerResizeEnd(); - } - } - startResizeSW(event) { - this.startResizeS(event); - this.startResizeW(event); - } - resizeSW(event) { - this.resizeS(event); - this.resizeW(event); - } - endResizeSW() { - if (!this.isResizingN && !this.isResizingE && this.isResizingW && this.isResizingS) { - this.isResizingS = false; - this.isResizingW = false; - this._triggerResizeEnd(); - } - } - _getEventLoc(event) { - let coordX, coordY; - if (event.touches && event.touches[0]) { - coordX = event.touches[0].clientX; - coordY = event.touches[0].clientY; - } else { - coordX = event.clientX; - coordY = event.clientY; - } - return { - x: coordX, - y: coordY, - }; - } - _triggerResizeEnd() { - const size = { - height: this.el.offsetHeight, - width: this.el.offsetWidth, - }; - const loc = { - top: this.el.offsetTop, - left: this.el.offsetLeft, - }; - this.trigger("resize-end", { size, loc }); - } -} diff --git a/addons/pos_restaurant/static/src/js/Screens/FloorScreen/EditBar.js b/addons/pos_restaurant/static/src/js/Screens/FloorScreen/EditBar.js deleted file mode 100644 index 4d9a2589f90..00000000000 --- a/addons/pos_restaurant/static/src/js/Screens/FloorScreen/EditBar.js +++ /dev/null @@ -1,14 +0,0 @@ -/** @odoo-module */ - -import { LegacyComponent } from "@web/legacy/legacy_component"; - -const { useState } = owl; - -export class EditBar extends LegacyComponent { - static template = "EditBar"; - - setup() { - super.setup(); - this.state = useState({ isColorPicker: false }); - } -} diff --git a/addons/pos_restaurant/static/src/js/Screens/FloorScreen/EditableTable.js b/addons/pos_restaurant/static/src/js/Screens/FloorScreen/EditableTable.js deleted file mode 100644 index c00bdaf842f..00000000000 --- a/addons/pos_restaurant/static/src/js/Screens/FloorScreen/EditableTable.js +++ /dev/null @@ -1,59 +0,0 @@ -/** @odoo-module */ - -import { useListener } from "@web/core/utils/hooks"; -import { LegacyComponent } from "@web/legacy/legacy_component"; - -import { Draggable } from "@point_of_sale/js/Misc/Draggable"; -import { Resizeable } from "../../Resizeable"; - -const { onMounted, onPatched } = owl; - -export class EditableTable extends LegacyComponent { - static template = "EditableTable"; - static components = { Draggable, Resizeable }; - - setup() { - super.setup(); - useListener("resize-end", this._onResizeEnd); - useListener("drag-end", this._onDragEnd); - onPatched(this._setElementStyle.bind(this)); - onMounted(this._setElementStyle.bind(this)); - } - _setElementStyle() { - const table = this.props.table; - function unit(val) { - return `${val}px`; - } - const style = { - width: unit(table.width), - height: unit(table.height), - "line-height": unit(table.height), - top: unit(table.position_v), - left: unit(table.position_h), - "border-radius": table.shape === "round" ? unit(1000) : "3px", - }; - if (table.color) { - style.background = table.color; - } - if (table.height >= 150 && table.width >= 150) { - style["font-size"] = "32px"; - } - Object.assign(this.el.style, style); - } - _onResizeEnd(event) { - const { size, loc } = event.detail; - const table = this.props.table; - table.width = size.width; - table.height = size.height; - table.position_v = loc.top; - table.position_h = loc.left; - this.props.onSaveTable(this.props.table); - } - _onDragEnd(event) { - const { loc } = event.detail; - const table = this.props.table; - table.position_v = loc.top; - table.position_h = loc.left; - this.props.onSaveTable(this.props.table); - } -} diff --git a/addons/pos_restaurant/static/src/js/Screens/ReceiptScreen/ReceiptScreen.js b/addons/pos_restaurant/static/src/js/Screens/ReceiptScreen/ReceiptScreen.js index 6707a32d020..fa3bfb13129 100644 --- a/addons/pos_restaurant/static/src/js/Screens/ReceiptScreen/ReceiptScreen.js +++ b/addons/pos_restaurant/static/src/js/Screens/ReceiptScreen/ReceiptScreen.js @@ -4,7 +4,7 @@ import { ReceiptScreen } from "@point_of_sale/js/Screens/ReceiptScreen/ReceiptSc import { usePos } from "@point_of_sale/app/pos_hook"; import { patch } from "@web/core/utils/patch"; import { onWillUnmount } from "@odoo/owl"; -import { FloorScreen } from "@pos_restaurant/js/Screens/FloorScreen/FloorScreen"; +import { FloorScreen } from "@pos_restaurant/app/floor_screen/floor_screen"; patch(ReceiptScreen, "pos_restaurant.ReceiptScreen", { showBackToFloorButton: true, diff --git a/addons/pos_restaurant/static/src/scss/restaurant.scss b/addons/pos_restaurant/static/src/scss/restaurant.scss index d1f1f4f5384..43117554882 100644 --- a/addons/pos_restaurant/static/src/scss/restaurant.scss +++ b/addons/pos_restaurant/static/src/scss/restaurant.scss @@ -77,7 +77,7 @@ border-radius: 3px; cursor: pointer; box-shadow: 0px 3px rgba(0,0,0,0.07); - transition: background, background-color 300ms ease-in-out; + transition: background-color 300ms ease-in-out; overflow: hidden; } .floor-map .table .table-cover { @@ -217,26 +217,19 @@ position: absolute; width: 48px; height: 48px; - left: 50%; - top: 50%; border-radius: 24px; background: white; box-shadow: 0px 2px 3px rgba(0,0,0,0.2); /* See o-grab-cursor mixin */ cursor: url(/web/static/img/openhand.cur), grab; - transition: all 150ms linear; + transition: width 150ms linear, height 150ms linear; z-index: 100; - transform: translate(-50%, -50%); } .floor-map .table.selected .table-handle:hover { width: 60px; height: 60px; border-radius: 30px; } -.floor-map .table .table-handle.top { top: 0; } -.floor-map .table .table-handle.bottom { top: 100%; } -.floor-map .table .table-handle.left { left: 0; } -.floor-map .table .table-handle.right { left: 100%; } .floor-map .table .order-count { position: absolute; diff --git a/addons/pos_restaurant/static/src/xml/Resizeable.xml b/addons/pos_restaurant/static/src/xml/Resizeable.xml deleted file mode 100644 index 169c888e415..00000000000 --- a/addons/pos_restaurant/static/src/xml/Resizeable.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - - diff --git a/addons/pos_restaurant/static/src/xml/Screens/FloorScreen/EditableTable.xml b/addons/pos_restaurant/static/src/xml/Screens/FloorScreen/EditableTable.xml deleted file mode 100644 index 9c3a6079a1e..00000000000 --- a/addons/pos_restaurant/static/src/xml/Screens/FloorScreen/EditableTable.xml +++ /dev/null @@ -1,31 +0,0 @@ - - - - - - -
- - - - - - - -
-
-
-
-
- - - - - - -
-
-
-
- -