diff --git a/web_refresher/README.rst b/web_refresher/README.rst index 36b0c16bc..9e8ba0498 100644 --- a/web_refresher/README.rst +++ b/web_refresher/README.rst @@ -7,7 +7,7 @@ Web Refresher !! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - !! source digest: sha256:4ef545bbf655053c91d43dc4f35993c3a7e5cbe1c0989e5ca8a6d25bab77851b + !! source digest: sha256:72dfc3fadb6b640422ed2786d2036e3c550c09a4a55fed57e92c3caeb4b1b176 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! .. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png diff --git a/web_refresher/__manifest__.py b/web_refresher/__manifest__.py index e9395c9ca..c398d33fa 100644 --- a/web_refresher/__manifest__.py +++ b/web_refresher/__manifest__.py @@ -9,13 +9,9 @@ "auto_install": False, "assets": { "web.assets_backend": [ - "web_refresher/static/src/scss/refresher.scss", - "web_refresher/static/src/js/refresher.esm.js", - "web_refresher/static/src/js/control_panel.esm.js", - "web_refresher/static/src/js/pager.esm.js", - "web_refresher/static/src/xml/refresher.xml", - "web_refresher/static/src/xml/control_panel.xml", - "web_refresher/static/src/xml/pager.xml", + "web_refresher/static/src/**/*.scss", + "web_refresher/static/src/**/*.esm.js", + "web_refresher/static/src/**/*.xml", ], }, } diff --git a/web_refresher/static/description/index.html b/web_refresher/static/description/index.html index 476f12858..05d40bc08 100644 --- a/web_refresher/static/description/index.html +++ b/web_refresher/static/description/index.html @@ -1,3 +1,4 @@ +
@@ -366,7 +367,7 @@ ul.auto-toc { !! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -!! source digest: sha256:4ef545bbf655053c91d43dc4f35993c3a7e5cbe1c0989e5ca8a6d25bab77851b +!! source digest: sha256:72dfc3fadb6b640422ed2786d2036e3c550c09a4a55fed57e92c3caeb4b1b176 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->Adds a button next to the pager (in trees/kanban views) to refresh the displayed list.
diff --git a/web_refresher/static/src/js/control_panel.esm.js b/web_refresher/static/src/js/control_panel.esm.js index 972d07784..2a63c2fd6 100644 --- a/web_refresher/static/src/js/control_panel.esm.js +++ b/web_refresher/static/src/js/control_panel.esm.js @@ -1,9 +1,27 @@ /** @odoo-module **/ -/* Copyright 2024 Tecnativa - Carlos Roca +/* Copyright 2022 Tecnativa - Alexandre D. Díaz + * Copyright 2022 Tecnativa - Carlos Roca + * Copyright 2023 Taras Shabaranskyi * License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). */ + import {ControlPanel} from "@web/search/control_panel/control_panel"; import {Refresher} from "./refresher.esm"; +import {patch} from "@web/core/utils/patch"; ControlPanel.components = Object.assign({}, ControlPanel.components, { Refresher, }); + +patch(ControlPanel.prototype, "web_refresher.ControlPanel", { + setup() { + this._super(...arguments); + const {config, searchModel} = this.env; + const forbiddenSubType = ["base_settings"]; + if (!forbiddenSubType.includes(config.viewSubType)) { + this.refresherProps = { + searchModel: searchModel, + pagerProps: this.pagerProps, + }; + } + }, +}); diff --git a/web_refresher/static/src/js/pager.esm.js b/web_refresher/static/src/js/pager.esm.js deleted file mode 100644 index 06f9ec77c..000000000 --- a/web_refresher/static/src/js/pager.esm.js +++ /dev/null @@ -1,9 +0,0 @@ -/** @odoo-module **/ -/* Copyright 2022 Tecnativa - Carlos Roca - * License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). */ -import {Pager} from "@web/core/pager/pager"; -import {Refresher} from "./refresher.esm"; - -Pager.components = Object.assign({}, Pager.components, { - Refresher, -}); diff --git a/web_refresher/static/src/js/refresher.esm.js b/web_refresher/static/src/js/refresher.esm.js index a006e0e4c..60c570ad9 100644 --- a/web_refresher/static/src/js/refresher.esm.js +++ b/web_refresher/static/src/js/refresher.esm.js @@ -1,36 +1,109 @@ /** @odoo-module **/ /* Copyright 2022 Tecnativa - Alexandre D. Díaz * Copyright 2022 Tecnativa - Carlos Roca + * Copyright 2023 Taras Shabaranskyi * License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). */ -const {Component} = owl; -import {useService} from "@web/core/utils/hooks"; +import {Component} from "@odoo/owl"; +import {useDebounced} from "@web/core/utils/timing"; + +export function useRefreshAnimation(timeout) { + const refreshClass = "o_content__refresh"; + let timeoutId = null; + + /** + * @returns {DOMTokenList|null} + */ + function contentClassList() { + const content = document.querySelector(".o_content"); + return content ? content.classList : null; + } + + function clearAnimationTimeout() { + if (timeoutId) { + clearTimeout(timeoutId); + } + timeoutId = null; + } + + function animate() { + clearAnimationTimeout(); + contentClassList().add(refreshClass); + timeoutId = setTimeout(() => { + contentClassList().remove(refreshClass); + clearAnimationTimeout(); + }, timeout); + } + + return animate; +} export class Refresher extends Component { setup() { super.setup(); - this.action = useService("action"); + this.refreshAnimation = useRefreshAnimation(1000); + this.onClickRefresh = useDebounced(this.onClickRefresh, 200); } - async _doRefresh() { - const viewAction = this.action.currentController.action; - // Allow refresh reports - if (["ir.actions.report", "ir.actions.client"].includes(viewAction.type)) { - const options = {}; - if (this.env.config.breadcrumbs.length > 1) { - const breadcrumb = this.env.config.breadcrumbs.slice(-1); - await this.action.restore(breadcrumb.jsId); - } else { - options.clearBreadcrumbs = true; - } - return this.action.doAction(viewAction, options); + + /** + * @returns {Boolean} + */ + get displayButton() { + const {searchModel, pagerProps} = this.props; + const hasSearchModel = searchModel && searchModel.search; + return Boolean(hasSearchModel || (pagerProps && pagerProps.onUpdate)); + } + + /** + * @returns {Boolean} + * @private + */ + _searchModelRefresh() { + const {searchModel} = this.props; + if (searchModel && typeof searchModel.search === "function") { + searchModel.search(); + return true; } - // Note: here we use the pager props, see xml - const {limit, offset} = this.props; - if (!limit && !offset) { - return; + return false; + } + + /** + * @returns {Promise