From f097db007ef6116f7537087901e05b16b9e5483d Mon Sep 17 00:00:00 2001 From: Suherdy Yacob Date: Sun, 7 Jun 2026 19:40:16 +0700 Subject: [PATCH] feat: implement order pagination and reduce duration update frequency to optimize KDS performance --- README.rst | 9 +++++ __manifest__.py | 2 + .../src/app/components/order/order_patch.js | 13 ++++++ .../preparation_display_patch.js | 40 +++++++++++++++++++ .../preparation_display_patch.xml | 39 ++++++++++++++++++ 5 files changed, 103 insertions(+) create mode 100644 static/src/app/components/preparation_display/preparation_display_patch.js create mode 100644 static/src/app/components/preparation_display/preparation_display_patch.xml diff --git a/README.rst b/README.rst index 2bb6dca..3612d94 100644 --- a/README.rst +++ b/README.rst @@ -87,6 +87,15 @@ Installation 3. Search for "POS KDS Stage Reset Fix" and install it. 4. No additional configuration is required. +Performance Optimization +------------------------ + +This module also optimizes the Preparation Display's rendering and idle CPU usage for low RAM devices: + +- Order Pagination: Limits rendering to 16 order cards per page, significantly reducing DOM nodes. +- Pagination Controls: Adds Page Navigation buttons at the bottom of the main orders area. +- Timer Refresh Rate: Reduces the order age/duration update frequency from 1 second to 15 seconds. + Compatibility ------------- diff --git a/__manifest__.py b/__manifest__.py index 8986d5c..970f592 100644 --- a/__manifest__.py +++ b/__manifest__.py @@ -21,6 +21,8 @@ and todo status of previously processed prep order lines. 'pos_preparation_display.assets': [ 'pos_kds_fix/static/src/app/components/orderline/orderline_patch.js', 'pos_kds_fix/static/src/app/components/order/order_patch.js', + 'pos_kds_fix/static/src/app/components/preparation_display/preparation_display_patch.js', + 'pos_kds_fix/static/src/app/components/preparation_display/preparation_display_patch.xml', ], }, 'installable': True, diff --git a/static/src/app/components/order/order_patch.js b/static/src/app/components/order/order_patch.js index ccceb83..1cba417 100644 --- a/static/src/app/components/order/order_patch.js +++ b/static/src/app/components/order/order_patch.js @@ -4,6 +4,19 @@ import { Order } from "@pos_enterprise/app/components/order/order"; import { patch } from "@web/core/utils/patch"; patch(Order.prototype, { + setup() { + super.setup(); + if (this.interval) { + clearInterval(this.interval); + this.interval = setInterval(() => { + if (this.order && this.order.pos_order_id) { + this._updateDuration(); + } else { + clearInterval(this.interval); + } + }, 15000); // Update every 15 seconds instead of 1 second + } + }, get pdisNotes() { try { return JSON.parse(this.order.pos_order_id.internal_note || "[]"); diff --git a/static/src/app/components/preparation_display/preparation_display_patch.js b/static/src/app/components/preparation_display/preparation_display_patch.js new file mode 100644 index 0000000..6e2ce30 --- /dev/null +++ b/static/src/app/components/preparation_display/preparation_display_patch.js @@ -0,0 +1,40 @@ +/** @odoo-module **/ + +import { PrepDisplay } from "@pos_enterprise/app/components/preparation_display/preparation_display"; +import { patch } from "@web/core/utils/patch"; + +patch(PrepDisplay.prototype, { + setup() { + super.setup(); + this.state.currentPage = 1; + this.state.pageSize = 16; // 16 orders per page + this.lastFilterState = ""; + }, + get totalPages() { + const orders = this.prepDisplay.filteredOrders || []; + return Math.max(1, Math.ceil(orders.length / this.state.pageSize)); + }, + get paginatedOrders() { + const orders = this.prepDisplay.filteredOrders || []; + const currentStageId = this.prepDisplay.selectedStageId; + const filterState = `${currentStageId}-${Array.from(this.prepDisplay.selectedCategoryIds).join(',')}-${Array.from(this.prepDisplay.selectedProductIds).join(',')}-${Array.from(this.prepDisplay.selectedTimeIds).join(',')}-${Array.from(this.prepDisplay.selectedPresetIds).join(',')}`; + + if (this.lastFilterState !== filterState) { + this.lastFilterState = filterState; + this.state.currentPage = 1; + } + + const totalPages = this.totalPages; + if (this.state.currentPage > totalPages) { + this.state.currentPage = totalPages; + } + const start = (this.state.currentPage - 1) * this.state.pageSize; + return orders.slice(start, start + this.state.pageSize); + }, + changePage(offset) { + const targetPage = this.state.currentPage + offset; + if (targetPage >= 1 && targetPage <= this.totalPages) { + this.state.currentPage = targetPage; + } + } +}); diff --git a/static/src/app/components/preparation_display/preparation_display_patch.xml b/static/src/app/components/preparation_display/preparation_display_patch.xml new file mode 100644 index 0000000..bd368cd --- /dev/null +++ b/static/src/app/components/preparation_display/preparation_display_patch.xml @@ -0,0 +1,39 @@ + + + + + + this.paginatedOrders + + + + + o_pdis_main_area w-100 h-100 overflow-hidden d-flex flex-column + + + + + o_pdis_orders position-relative d-grid flex-grow-1 gap-3 text-reset p-3 overflow-auto + + + + +
+ + + Page of + (Total orders) + + +
+
+
+