diff --git a/oo_list_manager/__manifest__.py b/oo_list_manager/__manifest__.py index 009e97d58..2f43ab785 100644 --- a/oo_list_manager/__manifest__.py +++ b/oo_list_manager/__manifest__.py @@ -31,6 +31,7 @@ Long description of module's purpose 'license': 'LGPL-3', 'assets': { 'web.assets_backend': [ + 'oo_list_manager/static/src/core/ensure_jquery.js', 'oo_list_manager/static/src/views/list/*', 'oo_list_manager/static/src/views/auto_hide_list/*', ] diff --git a/oo_list_manager/static/src/views/list/list_renderer.js b/oo_list_manager/static/src/views/list/list_renderer.js index a67760924..02710d24a 100644 --- a/oo_list_manager/static/src/views/list/list_renderer.js +++ b/oo_list_manager/static/src/views/list/list_renderer.js @@ -1,24 +1,26 @@ /** @odoo-module **/ -import { ListRenderer } from "@web/views/list/list_renderer"; -import { patch } from "@web/core/utils/patch"; -import { loadJS, loadCSS } from "@web/core/assets"; -import { ListRendererCust } from "@tree_view_advanced_filter/tree_view_advanced_filter/tree" -import { onWillDestroy, useEffect } from "@odoo/owl"; +import {ListRenderer} from "@web/views/list/list_renderer"; +import {patch} from "@web/core/utils/patch"; +import {loadJS, loadCSS} from "@web/core/assets"; +import {ListRendererCust} from "@tree_view_advanced_filter/tree_view_advanced_filter/tree" +import {onWillDestroy, useEffect} from "@odoo/owl"; +import { ensureJQuery } from '../../core/ensure_jquery'; patch(ListRenderer.prototype, { setup() { super.setup(); - if (this.isX2Many) { - this.props.ooManagerSerialNum = true; - } + // 注释掉 X2Many 自动启用序号,避免布局错位 + // if (this.isX2Many) { + // this.props.ooManagerSerialNum = true; + // } const computeFunction = this.computeFreeze.bind(this); const resizeObserver = new ResizeObserver(computeFunction); + + useEffect( (tableEl) => { if (tableEl) { - // Lucky by 2025/08/08添加此行:设置 table-layout: fixed,先注释反馈有Bug - // tableEl.style.setProperty('table-layout', 'fixed', 'important'); resizeObserver.observe(tableEl); return () => resizeObserver.unobserve(tableEl); } @@ -34,10 +36,15 @@ patch(ListRenderer.prototype, { freezeColumnWidths() { super.freezeColumnWidths(); const table = this.tableRef.el; + if (!table) return; + const headers = [...table.querySelectorAll("thead th:not(.o_list_actions_header)")]; headers.forEach((th, index) => { - th.style.minWidth = `${Math.floor(this.columnWidths[index])}px`; + // 只有在自定义列宽存在时才设置 minWidth + if (this.columnWidths[index]) { + th.style.minWidth = `${Math.floor(this.columnWidths[index])}px`; + } }); this._computeLock(); }, @@ -53,10 +60,63 @@ patch(ListRenderer.prototype, { setTimeout(computeFunction, 200); }); }, + + // _computeLock() { + // const table = this.tableRef.el; + // if (!table) return; + + // const thead = [...table.querySelectorAll('thead tr:first-child th')]; + // const filterBox = [...table.querySelectorAll('thead .o_filter_box td')]; + // const tbody = [...table.querySelectorAll('tbody tr')]; + // const tfoot = [...table.querySelectorAll('tfoot tr')]; + + // const setStyle = (element, left, z = 10) => { + // element.classList.add('position-sticky', 'o_column_freeze'); + // Object.assign(element.style, { + // left: `${left}px`, + // zIndex: `${z}`, + // }); + // }; + + // const removeStyle = (element) => { + // element.classList.remove('position-sticky', 'o_column_freeze'); + // element.style.left = ''; + // element.style.zIndex = ''; + // }; + + // for (let i = 0; i < thead.length; i++) { + // const th = thead[i]; + // const shouldFreeze = th.classList.contains('o_column_freeze') || + // th.classList.contains('o_list_record_selector') || + // th.classList.contains('list-number'); + + // if (shouldFreeze) { + // let left = 0; + // for (let j = 0; j < i; j++) { + // left += thead[j].getBoundingClientRect().width; + // } + + // setStyle(th, left, 20); + // if (filterBox[i]) setStyle(filterBox[i], left, 30); + // tbody.forEach(tr => tr.classList.contains('o_data_row') && setStyle(tr.children[i], left, 10)); + // tfoot.forEach(tr => setStyle(tr.children[i], left, 10)); + // } else { + // removeStyle(th); + // if (filterBox[i]) removeStyle(filterBox[i]); + // tbody.forEach(tr => tr.classList.contains('o_data_row') && removeStyle(tr.children[i])); + // tfoot.forEach(tr => removeStyle(tr.children[i])); + // } + // } + // }, _computeLock() { const table = this.tableRef.el; if (!table) return; + // 对于 X2Many 字段,如果没有启用列管理功能,则不应用列冻结 + if (this.isX2Many && !this.props.ooManagerColumns) { + return; + } + const thead = [...table.querySelectorAll('thead tr:first-child th')]; const filterBox = [...table.querySelectorAll('thead .o_filter_box td')]; const tbody = [...table.querySelectorAll('tbody tr')]; @@ -64,6 +124,7 @@ patch(ListRenderer.prototype, { const groupHeaders = [...table.querySelectorAll('tbody tr.o_group_header')]; const setStyle = (element, left, z = 10) => { + if (!element) return; element.classList.add('position-sticky', 'o_column_freeze'); Object.assign(element.style, { left: `${left}px`, @@ -72,6 +133,7 @@ patch(ListRenderer.prototype, { }; const removeStyle = (element) => { + if (!element) return; element.classList.remove('position-sticky', 'o_column_freeze'); element.style.left = ''; element.style.zIndex = ''; @@ -108,14 +170,11 @@ patch(ListRenderer.prototype, { const cell = tr.children[i]; if (cell) setStyle(cell, left, 10); }); - console.log('groupHeaders',groupHeaders) + // 冻结分组行 groupHeaders.forEach(tr => { const cell = tr.children[i]; - - //if (cell) setStyle(cell, left, 4); // 比 body 高,比 header 低 - // 分组头部是不是 left= 0 就行. 头部都固定左侧. - if(cell) setStyle(cell, 0, 4); + if (cell) setStyle(cell, left, 15); // 比 body 高,比 header 低 }); } else { @@ -146,6 +205,7 @@ patch(ListRenderer.prototype, { // 针对右侧的(尾列的数据冻结功能) // 样式增加 hover const setRightStyle = (element, right) => { + if (!element) return; element.classList.add('position-sticky', 'position-sticky-right'); Object.assign(element.style, { right: `${right}px`, @@ -155,12 +215,15 @@ patch(ListRenderer.prototype, { } const resetRightStyle = (element) => { - element.classList.remove('position-sticky'); - element.style.right = 'auto'; + if (!element) return; + element.classList.remove('position-sticky', 'position-sticky-right'); + element.style.right = ''; + element.style.backgroundColor = ''; element.style.zIndex = ''; } if (this.props.ooManagerStickyEnd) { + console.log('ooManagerStickyEnd') let rightOffset = 0; const rightStickyIndices = []; @@ -216,6 +279,7 @@ patch(ListRenderer.prototype, { * @returns {boolean} */ get hasOptionalFields() { + console.log('hasOptionalFields') return false }, get displayOptionalFields() { @@ -225,6 +289,7 @@ patch(ListRenderer.prototype, { getActiveColumns(list) { if (this.props.ooManagerColumns) { + // console.log(this.allColumns) const columns = this.allColumns.filter((col) => { if (list.isGrouped && col.widget === "handle") return false; const mColumn = this.props.ooManagerColumns.find(item => item.id === col.id); @@ -269,16 +334,20 @@ patch(ListRenderer.prototype, { computeColumnWidthsFromContent(allowedWidth) { const columnWidths = super.computeColumnWidthsFromContent(allowedWidth); if (!this.props.ooManagerColumns) return columnWidths; + const table = this.tableRef.el; + if (!table) return columnWidths; table.classList.add("o_list_computing_widths"); const headers = [...table.querySelectorAll("thead th")]; headers.forEach((th, index) => { const id = th.getAttribute('data-id'); - const mColumn = this.props.ooManagerColumns.find(item => item.id === id); - if (mColumn && mColumn.width) { - columnWidths[index] = mColumn.width; + if (id) { + const mColumn = this.props.ooManagerColumns.find(item => item.id === id); + if (mColumn && mColumn.width && mColumn.width > 0) { + columnWidths[index] = mColumn.width; + } } }); @@ -289,38 +358,31 @@ patch(ListRenderer.prototype, { getColumnStyle(column) { if (!this.props.ooManagerColumns) return ''; const mColumn = this.props.ooManagerColumns.find(item => item.id === column.id); - const styles = []; - if (mColumn?.width) { - styles.push(`width: ${mColumn.width}px`); - styles.push(`min-width: ${mColumn.width}px`); - styles.push(`max-width: ${mColumn.width}px`); + if (mColumn && mColumn.color) { + return `color: ${mColumn.color};`; } - - if (mColumn?.color) { - styles.push(`color: ${mColumn.color}`); - } - - return styles.join('; '); + return ''; }, _renderSearchPanel: async function () { + await ensureJQuery(); if (this.isX2Many) { return ListRendererCust._renderSearchPanel.call(this); } if (!this.props.archInfo.advanced_filter) { - $('.o_filter_box').remove(); + $('.o_filter_box').remove(); // $ is not defined + // document.querySelectorAll('.o_filter_box').forEach(el => el.remove()); } else { + await loadJS("/tree_view_advanced_filter/static/src/libs/moment/moment.min.js"); await loadJS("/tree_view_advanced_filter/static/src/libs/daterangepicker.min.js"); await loadCSS("/tree_view_advanced_filter/static/src/libs/daterangepicker.css"); - await loadJS("/tree_view_advanced_filter/static/src/libs/moment/moment.min.js"); - const List = this.props.list; const rootRef = this.rootRef.el; const tableRef = this.tableRef.el; tableRef.removeAttribute('style'); const columns = this.getActiveColumns(this.props.list); - const $tr1 = $('