This commit is contained in:
李鹏宇
2025-07-08 09:27:15 +08:00
parent ac695353eb
commit 5ca922b5b8
6 changed files with 144 additions and 3 deletions
@@ -69,11 +69,40 @@ patch(ListController.prototype, {
}
},
/**
* 固定列
* @param ev
*/
onClickLock(ev){
this.isChange = true;
const id = ev.currentTarget.dataset.id;
const columns = [...this.ooManager.columns];
const columnIdx = columns.findIndex(item => item.id === id);
if (columnIdx >= 0) {
columns[columnIdx].lock = !columns[columnIdx].lock;
}
const lockedTrue = columns.filter(item => item.lock);
const lockedFalse = columns.filter(item => !item.lock);
lockedTrue.forEach((column, i) => {
column.seq = i + 1;
});
lockedFalse.forEach((column, i) => {
column.seq = i + 1 + lockedTrue.length;
});
this.ooManager.columns = [...lockedTrue, ...lockedFalse];
},
/**
* 序号
*/
onChangeSerialNum() {
this.isChange = true;
this.ooManager.serial_num = !this.ooManager.serial_num;
},
/**
* 表头搜索
*/
onChangeFilter() {
this.isChange = true;
this.ooManager.filter = !this.ooManager.filter;
@@ -35,12 +35,15 @@
<div class="o-checkbox form-check form-switch">
<input type="checkbox" class="form-check-input" t-att-checked="column.visibility" t-on-click="onChangeVisibility" t-att-data-id="column.id"/>
</div>
<input type="text" class="form-control" t-att-value="column.string" disabled="true"/>
<input type="text" class="form-control" t-model="column.string" t-on-blur="onChangeColumns"/>
<input type="number" class="form-control o_width_input" t-model="column.width" t-on-blur="onChangeColumns"/>
<input type="color" class="o_color_input" t-model="column.color" t-on-blur="onChangeColumns"/>
<div class="oo_sort_cell" t-if="!this.ooManager.key">
<i class="btn fa fa-arrows"/>
</div>
<div class="o_lock_box" t-on-click="onClickLock" t-att-data-id="column.id">
<i class="fa fa-thumb-tack" t-att-class="{'active': column.lock}"/>
</div>
</div>
</div>
</div>
@@ -4,13 +4,28 @@ 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";
patch(ListRenderer.prototype, {
setup() {
super.setup();
if(this.isX2Many) {
if (this.isX2Many) {
this.props.ooManagerSerialNum = true;
}
const computeFunction = this.computeFreeze.bind(this);
const resizeObserver = new ResizeObserver(computeFunction);
useEffect(
(tableEl) => {
if (tableEl) {
resizeObserver.observe(tableEl);
return () => resizeObserver.unobserve(tableEl);
}
},
() => [this.tableRef.el]
);
onWillDestroy(() => {
resizeObserver.disconnect();
});
},
getActiveColumns(list) {
@@ -38,6 +53,13 @@ patch(ListRenderer.prototype, {
return seqX - seqY;
});
for (const column of columns) {
const mColumn = this.props.ooManagerColumns.find(item => item.id === column.id)
if (mColumn) {
column.label = mColumn.string;
}
}
return columns
} else {
@@ -53,6 +75,89 @@ patch(ListRenderer.prototype, {
headers.forEach((th, index) => {
th.style.minWidth = `${Math.floor(this.columnWidths[index])}px`;
});
this._computeLock();
},
computeFreeze() {
const computeFunction = this._computeLock.bind(this);
const compute = () => {
computeFunction();
window.removeEventListener('scroll', compute, true)
}
window.addEventListener('scroll', compute, true);
return new Promise(resolve => {
setTimeout(computeFunction, 200);
})
},
_computeLock() {
const table = this.tableRef.el;
if (!table) return;
const thead = [...table.querySelectorAll('thead tr th')];
const filter_box = [...table.querySelectorAll('thead .o_filter_box td')];
const tbody = [...table.querySelectorAll('tbody tr')];
const tfoot = [...table.querySelectorAll('tfoot tr')];
const setStyle = (element, left) => {
element.classList.add('position-sticky');
Object.assign(element.style, {
left: `${left}px`,
backgroundColor: 'white',
zIndex: '4'
})
}
const removeStyle = (element) => {
element.classList.remove('position-sticky');
element.style.left = 'auto';
element.style.zIndex = '';
}
for (let i = 0; i < thead.length; i++) {
const theadThClassList = thead[i].classList
if (theadThClassList.contains('o_column_freeze') || theadThClassList.contains('o_list_record_selector') || theadThClassList.contains('list-number')) {
let left = 0;
for (let j = 0; j < i; j++) {
left += thead[j].getBoundingClientRect().width;
}
for (const tbodyTrElement of tbody) {
if (tbodyTrElement.classList.contains('o_data_row')) {
const td = tbodyTrElement.querySelectorAll('td')[i];
td && setStyle(td, left);
}
}
for (const tfootTrElement of tfoot) {
const td = tfootTrElement.querySelectorAll('td')[i];
td && setStyle(td, left);
}
setStyle(thead[i], left);
if (filter_box[i]) {
setStyle(filter_box[i], left);
}
} else {
removeStyle(thead[i]);
if (filter_box[i]) {
removeStyle(filter_box[i]);
}
for (const tbodyTrElement of tbody) {
if (tbodyTrElement.classList.contains('o_data_row')) {
const td = tbodyTrElement.querySelectorAll('td')[i];
td && removeStyle(td);
}
}
for (const tfootTrElement of tfoot) {
const td = tfootTrElement.querySelectorAll('td')[i];
td && removeStyle(td);
}
}
}
},
getColumnClass(column) {
const classNames = super.getColumnClass(column);
if (!this.props.ooManagerColumns) return classNames;
const mColumn = this.props.ooManagerColumns.find(item => item.id === column.id);
if (mColumn && mColumn.lock) {
return classNames + ' o_column_freeze';
}
return classNames;
},
/**
@@ -0,0 +1,3 @@
.o_column_freeze {
}
@@ -17,6 +17,7 @@
<td/>
</t>
</xpath>
<xpath expr="//i[hasclass('fa-thumb-tack')]" position="replace"/>
</t>
<t t-inherit="web.ListRenderer.RecordRow" t-inherit-mode="extension">
@@ -355,7 +355,7 @@
</field>
</record>
<record id="view_employee_inherit_del_tree" model="ir.ui.view">
<field name="name">hr.employee.inherit.del.form</field>
<field name="name">hr.employee.inherit.del.tree</field>
<field name="model">hr.employee</field>
<field name="inherit_id" ref="hr.view_employee_tree"/>
<field name="arch" type="xml">