模块列表分页器隐藏"/总数",只显示1-50

实训模块/应用主页的 ir.module.module 看板:
- KanbanController.setup 在 env.config 打隐藏标记(仅 kanban,list 不受影响)
- Pager.setup 读到标记后挂载时加 class o_pager_hide_total
- JS 注入 CSS 隐藏分页器的" / "分隔 span 和总数 span
- 真实总数照常统计,只是不显示;翻页/锁50行为不变
- 本地已用 ir.qweb._get_asset_content 真实编译 bundle 验证补丁在位
This commit is contained in:
qitangbo
2026-10-16 17:42:52 +08:00
parent befeb1b60c
commit 371ff7a2c8
+60 -3
View File
@@ -1,11 +1,11 @@
/**
* 模块列表(ir.module.module)每页数量锁定为 50。
* 模块列表(ir.module.module)每页数量锁定为 50,并隐藏分页器里的 "/ 总数"。
*
* 覆盖两个入口(同一模型、同款 kanban,一起受益):
* 1. 应用主页(Odoo 自带「应用」菜单)
* 2. 实训模块页(college 自定义 action)
*
* 原理(两个 patch,全在数据链路上,不碰 Odoo 源码、不删任何模块):
* 原理(四个 patch,全在数据链路上,不碰 Odoo 源码、不删任何模块):
* Patch 1 KanbanController.prototype.modelParams(getter):
* 模型为 ir.module.module 时,把初始每页数 limit 钉为 50,
* 并在 modelConfig 上打一个标记(__yuthon_module_list_cap)。
@@ -15,8 +15,19 @@
* 这是翻页/手输每页数的唯一数据出口(Pager.onUpdate 最终就是调到
* model.root.load({offset, limit}))。带标记且调用方传了 limit 时,
* 强制压回 offset=0 / limit=50 —— 第 2 页进不去、每页数改了也白改。
* Patch 3 KanbanController.prototype.setup:
* 同样是 ir.module.module 看板时,在 env.config 上打一个标记
* (__yuthon_hide_pager_total)。usePager() 在 setup 里通过
* useSubEnv 把 pagerProps 挂到 env.config,control panel 的
* <Pager t-props="pagerProps"/> 渲染时 env 一路继承到这里,
* 所以 Pager 侧能读到该标记(list 视图不经过这里,不受影响)。
* Patch 4 Pager.prototype.setup:
* 读到标记后,挂载时给根节点 nav.o_pager 加 class
* o_pager_hide_total,由本文件注入的 CSS 把
* " / " 分隔 span 和总数 span(o_pager_limit)隐藏掉,
* 分页器只剩 "1-50"(真实总数照常统计,只是不显示)。
*
* 效果:页面永远只显示前 50 个模块,总数仍正常显示(如 1-50 / 56);
* 效果:页面永远只显示前 50 个模块,分页器只显示 "1-50"(不显示 "/ 56");
* 搜索照常能用,结果同样只取前 50;其他所有页面零影响。
*
* 注意:本文件必须注册进 __manifest__.py 的 web.assets_backend 才会生效;
@@ -24,13 +35,32 @@
* 仅 git pull + 重启不会重建前端资源包。
*/
/** @odoo-module **/
import { onMounted } from "@odoo/owl";
import { patch } from "@web/core/utils/patch";
import { KanbanController } from "@web/views/kanban/kanban_controller";
import { DynamicList } from "@web/model/relational_model/dynamic_list";
import { Pager } from "@web/core/pager/pager";
const MODULE_MODEL = "ir.module.module";
const PAGE_LIMIT = 50;
const CAP_FLAG = "__yuthon_module_list_cap";
const HIDE_TOTAL_FLAG = "__yuthon_hide_pager_total";
const HIDE_TOTAL_STYLE_ID = "yuthon-pager-hide-total-style";
// 隐藏分页器 " / 总数" 的样式(只对带 o_pager_hide_total 的分页器生效)。
// .o_pager_value 后面紧跟的裸 span 就是模板里的 "<span> / </span>",
// 配合 .o_pager_limit(总数)一起隐藏;编辑态(input)时同样只剩输入框。
if (!document.getElementById(HIDE_TOTAL_STYLE_ID)) {
const style = document.createElement("style");
style.id = HIDE_TOTAL_STYLE_ID;
style.textContent = [
".o_pager.o_pager_hide_total .o_pager_value + span,",
".o_pager.o_pager_hide_total .o_pager_limit {",
" display: none !important;",
"}",
].join("\n");
document.head.appendChild(style);
}
// Patch 1:kanban 初始每页数锁 50,并给数据链路打标记(仅 kanban,list 不打)
patch(KanbanController.prototype, {
@@ -46,6 +76,18 @@ patch(KanbanController.prototype, {
},
});
// Patch 3:给分页器链路打隐藏标记(usePager 的 useSubEnv 在 setup 内完成,
// super.setup() 之后 env.config.pagerProps 已就位;此处只动 env.config,
// 不碰 pagerProps 对象本身,避免给 Pager 传未声明的 prop)
patch(KanbanController.prototype, {
setup() {
super.setup();
if (this.props.resModel === MODULE_MODEL) {
this.env.config[HIDE_TOTAL_FLAG] = true;
}
},
});
// Patch 2:翻页/手输的唯一数据出口,强制压回第 1 页、每页 50 条
patch(DynamicList.prototype, {
load(params) {
@@ -56,3 +98,18 @@ patch(DynamicList.prototype, {
return super.load(params);
},
});
// Patch 4:带标记的 Pager 挂载后加 class,由上面的 CSS 隐藏 "/ 总数"
patch(Pager.prototype, {
setup() {
super.setup();
const config = this.env && this.env.config;
if (config && config[HIDE_TOTAL_FLAG]) {
onMounted(() => {
if (this.root.el) {
this.root.el.classList.add("o_pager_hide_total");
}
});
}
},
});