diff --git a/list_view_sticky_header_and_column/static/src/js/list_view_sticky_header_and_column.js b/list_view_sticky_header_and_column/static/src/js/list_view_sticky_header_and_column.js
index 3ab2197b4..2bb60c6ea 100644
--- a/list_view_sticky_header_and_column/static/src/js/list_view_sticky_header_and_column.js
+++ b/list_view_sticky_header_and_column/static/src/js/list_view_sticky_header_and_column.js
@@ -1,13 +1,16 @@
/** @odoo-module **/
/** This file will used to stick the selected header and column in the list view **/
-import { patch } from "@web/core/utils/patch";
-import { ListRenderer } from "@web/views/list/list_renderer";
+import {patch} from "@web/core/utils/patch";
+import {ListRenderer} from "@web/views/list/list_renderer";
+
patch(ListRenderer.prototype, {
/** super the setup function **/
setup() {
super.setup();
+
},
+
/**
* function defining the button having t-on-click _onClick
*/
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 23d445dc8..7e4af5c07 100644
--- a/oo_list_manager/static/src/views/list/list_renderer.js
+++ b/oo_list_manager/static/src/views/list/list_renderer.js
@@ -1,10 +1,10 @@
/** @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";
patch(ListRenderer.prototype, {
setup() {
@@ -14,6 +14,8 @@ patch(ListRenderer.prototype, {
}
const computeFunction = this.computeFreeze.bind(this);
const resizeObserver = new ResizeObserver(computeFunction);
+
+
useEffect(
(tableEl) => {
if (tableEl) {
@@ -28,6 +30,7 @@ patch(ListRenderer.prototype, {
});
},
+
freezeColumnWidths() {
super.freezeColumnWidths();
const table = this.tableRef.el;
@@ -358,7 +361,7 @@ patch(ListRenderer.prototype, {
tableRef.removeAttribute('style');
const columns = this.getActiveColumns(this.props.list);
- const $tr1 = $('
', {class: 'o_filter_box'}).append(columns.map(col => this._renderHeaderCellSearch(col)));
if (this.props.ooManagerSerialNum) $tr1.prepend($('| ').addClass('web_list_num'));
if (this.hasSelectors) $tr1.prepend($(' | ').addClass('o_list_record_selector'));
if (this.isStudioEditable || this.displayOptionalFields) $tr1.append($(' | ').addClass('o_list_record_selector'));
diff --git a/tree_view_advanced_filter/static/src/list_view_sticky_header_and_column/scss/list_view_sticky_header_and_column.scss b/tree_view_advanced_filter/static/src/list_view_sticky_header_and_column/scss/list_view_sticky_header_and_column.scss
index 8bc0078b0..fe1f837af 100644
--- a/tree_view_advanced_filter/static/src/list_view_sticky_header_and_column/scss/list_view_sticky_header_and_column.scss
+++ b/tree_view_advanced_filter/static/src/list_view_sticky_header_and_column/scss/list_view_sticky_header_and_column.scss
@@ -25,7 +25,7 @@
overflow: visible;
}
.o_list_view .table-responsive .table thead {
- z-index: 5;
+ z-index: 20;
}
.o_list_renderer .o_list_table thead {
position: sticky;
diff --git a/yuthon_salary/__manifest__.py b/yuthon_salary/__manifest__.py
index ad878561f..e14ba9adb 100644
--- a/yuthon_salary/__manifest__.py
+++ b/yuthon_salary/__manifest__.py
@@ -3,14 +3,14 @@
'name': "yuthon salary",
'summary': "薪资管理",
'description': """
-
- """,
+
+ """,
'author': 'pengyuthon',
'website': 'https://www.pengyuthon.com',
'category': 'Human Resources/Attendances',
'version': '0.1',
'license': 'LGPL-3',
- 'depends': ['mail', 'base', 'hr', 'yuthon_hr_employee','hr_payroll'],
+ 'depends': ['mail', 'base', 'hr', 'yuthon_hr_employee', 'hr_payroll'],
'data': [
'security/ir.model.access.csv',
'security/salary_security_rule.xml',
@@ -47,26 +47,28 @@
'wizard/salary_print_wizard_views.xml',
],
'assets': {
- 'web.assets_backend': [
- 'yuthon_salary/static/scss/approval.scss',
- 'yuthon_salary/static/src/js/salary_documents_button.js',
- 'yuthon_salary/static/src/js/salary_create_button.js',
- 'yuthon_salary/static/src/js/salary_payslip_button.js',
- 'yuthon_salary/static/src/js/salary_labor_button.js',
- 'yuthon_salary/static/src/js/salary_return_button.js',
- 'yuthon_salary/static/src/js/salary_retired_button.js',
- 'yuthon_salary/static/src/js/salary_validation_button.js',
- 'yuthon_salary/static/src/js/salary_year_button.js',
- 'yuthon_salary/static/src/xml/salary_create_button.xml',
- 'yuthon_salary/static/src/xml/salary_labor_button.xml',
- 'yuthon_salary/static/src/xml/salary_retired_button.xml',
- 'yuthon_salary/static/src/xml/salary_payslip_button.xml',
- 'yuthon_salary/static/src/xml/salary_documents_button.xml',
- 'yuthon_salary/static/src/xml/salary_validation_button.xml',
- 'yuthon_salary/static/src/xml/salary_return_button.xml',
- 'yuthon_salary/static/src/xml/salary_year_button.xml',
- ],
- },
+ 'web.assets_backend': [
+ 'yuthon_salary/static/scss/approval.scss',
+ 'yuthon_salary/static/src/js/js_auto_hide_list_renderer.js',
+ 'yuthon_salary/static/src/js/salary_documents_button.js',
+ 'yuthon_salary/static/src/js/salary_create_button.js',
+ 'yuthon_salary/static/src/js/salary_payslip_button.js',
+ 'yuthon_salary/static/src/js/salary_labor_button.js',
+ 'yuthon_salary/static/src/js/salary_return_button.js',
+ 'yuthon_salary/static/src/js/salary_retired_button.js',
+ 'yuthon_salary/static/src/js/salary_validation_button.js',
+ 'yuthon_salary/static/src/js/salary_year_button.js',
+ 'yuthon_salary/static/src/xml/salary_create_button.xml',
+ 'yuthon_salary/static/src/xml/salary_labor_button.xml',
+ 'yuthon_salary/static/src/xml/salary_retired_button.xml',
+ 'yuthon_salary/static/src/xml/salary_payslip_button.xml',
+ 'yuthon_salary/static/src/xml/salary_documents_button.xml',
+ 'yuthon_salary/static/src/xml/salary_validation_button.xml',
+ 'yuthon_salary/static/src/xml/salary_return_button.xml',
+ 'yuthon_salary/static/src/xml/salary_year_button.xml',
+ 'yuthon_salary/static/src/views/list/*',
+ ]
+ },
'installable': True,
'application': True,
}
diff --git a/yuthon_salary/static/src/js/js_auto_hide_list_renderer.js b/yuthon_salary/static/src/js/js_auto_hide_list_renderer.js
new file mode 100644
index 000000000..925dafd4d
--- /dev/null
+++ b/yuthon_salary/static/src/js/js_auto_hide_list_renderer.js
@@ -0,0 +1,35 @@
+/** @odoo-module **/
+
+import { ListRenderer } from "@web/views/list/list_renderer";
+
+export class JsAutoHideListRenderer extends ListRenderer {
+
+ getActiveColumns(list) {
+ const columns = super.getActiveColumns(list);
+ return columns
+ let values;
+ if (this.props.list.selection && this.props.list.selection.length) {
+ values = this.props.list.selection.map((r) => r.data);
+ } else if (this.props.list.isGrouped) {
+ values = this.props.list.groups.map((g) => g.aggregates);
+ } else {
+ values = this.props.list.records.map((r) => r.data);
+ }
+ return columns.filter(column => {
+ const fieldInfo = list.fields[column.name];
+ if (!fieldInfo) {
+ return true;
+ }
+ if (["float", "monetary"].includes(fieldInfo.type)) {
+ const fieldValues = values.map((v) => v[fieldInfo.name] || 0);
+ const aggregateValue = fieldValues.reduce((acc, val) => acc + val);
+ if (!aggregateValue) {
+ console.log(column)
+ return true;
+ }
+ }
+ return true;
+ })
+ }
+
+}
\ No newline at end of file
diff --git a/yuthon_salary/static/src/js/salary_create_button.js b/yuthon_salary/static/src/js/salary_create_button.js
index f87e8a948..624152f31 100644
--- a/yuthon_salary/static/src/js/salary_create_button.js
+++ b/yuthon_salary/static/src/js/salary_create_button.js
@@ -1,7 +1,8 @@
/** @odoo-module */
-import { ListController } from "@web/views/list/list_controller";
-import { registry } from '@web/core/registry';
-import { listView } from '@web/views/list/list_view';
+import {ListController} from "@web/views/list/list_controller";
+import {registry} from '@web/core/registry';
+import {listView} from '@web/views/list/list_view';
+import {JsAutoHideListRenderer} from "./js_auto_hide_list_renderer";
export class CustomSalaryStatementsController extends ListController {
setup() {
@@ -25,5 +26,5 @@ export class CustomSalaryStatementsController extends ListController {
registry.category("views").add("custom_salary_button", {
...listView,
Controller: CustomSalaryStatementsController,
- buttonTemplate: "salary_module.ListView.Buttons",
+ buttonTemplate: "salary_module.ListView.Buttons"
});
\ No newline at end of file
diff --git a/yuthon_salary/static/src/views/js_auto_hide_list/js_auto_hide_list_renderer.js b/yuthon_salary/static/src/views/js_auto_hide_list/js_auto_hide_list_renderer.js
new file mode 100644
index 000000000..119ee286a
--- /dev/null
+++ b/yuthon_salary/static/src/views/js_auto_hide_list/js_auto_hide_list_renderer.js
@@ -0,0 +1,30 @@
+/** @odoo-module **/
+
+import { ListRenderer } from "@web/views/list/list_renderer";
+
+export class JsAutoHideListRenderer extends ListRenderer {
+
+ getActiveColumns(list) {
+ const columns = super.getActiveColumns(list);
+ let values;
+ if (this.props.list.selection && this.props.list.selection.length) {
+ values = this.props.list.selection.map((r) => r.data);
+ } else if (this.props.list.isGrouped) {
+ values = this.props.list.groups.map((g) => g.aggregates);
+ } else {
+ values = this.props.list.records.map((r) => r.data);
+ }
+ return columns.filter(column => {
+ const fieldInfo = list.fields[column.name];
+ if (["float", "integer", "monetary"].includes(fieldInfo.type)) {
+ const fieldValues = values.map((v) => v[fieldInfo.name] || 0);
+ const aggregateValue = fieldValues.reduce((acc, val) => acc + val);
+ if (!aggregateValue) {
+ return false;
+ }
+ }
+ return true;
+ })
+ }
+
+}
\ No newline at end of file
diff --git a/yuthon_salary/static/src/views/js_auto_hide_list/js_auto_hide_list_view.js b/yuthon_salary/static/src/views/js_auto_hide_list/js_auto_hide_list_view.js
new file mode 100644
index 000000000..ae29f6817
--- /dev/null
+++ b/yuthon_salary/static/src/views/js_auto_hide_list/js_auto_hide_list_view.js
@@ -0,0 +1,12 @@
+/** @odoo-module */
+
+import { registry } from "@web/core/registry";
+import { listView } from "@web/views/list/list_view";
+import { JsAutoHideListRenderer } from "./js_auto_hide_list_renderer";
+
+export const JsAutoHideListView = {
+ ...listView,
+ Renderer: JsAutoHideListRenderer
+}
+
+registry.category("views").add("jsAutoHideListView", JsAutoHideListView);
\ No newline at end of file
diff --git a/yuthon_salary/static/src/views/list/list_renderer.js b/yuthon_salary/static/src/views/list/list_renderer.js
new file mode 100644
index 000000000..648fbabdd
--- /dev/null
+++ b/yuthon_salary/static/src/views/list/list_renderer.js
@@ -0,0 +1,142 @@
+/** @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, onMounted} from "@odoo/owl";
+
+patch(ListRenderer.prototype, {
+ setup() {
+ super.setup();
+ // 固定两列
+ onMounted(() => {
+ this.freezeTwoColumns()
+ })
+ },
+ /**
+ * 根据类名固定前两列和最后一列
+ */
+ freezeTwoColumns() {
+
+
+ const root = this.rootRef.el.closest('.sticky-enabled-two-columns');
+
+ if (!root) return;
+ //
+ const headers = this.rootRef.el.querySelectorAll("thead th");
+ const dataRows = this.rootRef.el.querySelectorAll("tbody tr.o_data_row");
+ const groupRows = this.rootRef.el.querySelectorAll("tbody tr.o_group_header");
+
+ //
+ if (headers.length < 3) return; // 至少需要3列才能固定前两和最后一列
+
+ // 动态获取前两列宽度
+ const leftOffsets = [];
+ const colWidths = [];
+ let leftWidthTotal = 0
+ for (let i = 0; i < 5; i++) {
+ const width = headers[i].getBoundingClientRect().width;
+ colWidths.push(width);
+ leftWidthTotal = leftWidthTotal + width
+ leftOffsets.push(leftWidthTotal)
+ }
+ console.log(leftOffsets)
+
+ const lastIndex = headers.length - 1;
+
+ // 前两列累计偏移
+
+
+ // 固定前两列 header
+ for (let i = 0; i < 5; i++) {
+ this._makeSticky(headers[i], i === 0 ? 0 : leftOffsets[i - 1], "left");
+ }
+
+ // 固定最后一列 header
+ this._makeSticky(headers[lastIndex], 0, "right");
+
+ // 固定数据行的对应列
+ dataRows.forEach(row => {
+ for (let i = 0; i < 5; i++) {
+ this._makeSticky(row.children[i], i === 0 ? 0 : leftOffsets[i - 1], "left");
+ }
+ this._makeSticky(row.children[lastIndex], 0, "right");
+ });
+
+ // 固定分组标题行(有些分组行列数会少于 header)
+ // 分组只固定 前2 列
+ groupRows.forEach(row => {
+ const cells = row.querySelectorAll("td");
+
+ // 分组第一个必然固定
+ this._makeSticky(cells[0], 0, "left", true);
+ // 全部固定
+ const cellThs = row.querySelectorAll("th")
+ for (let i = 0; i < cellThs.length; i++) {
+ const offset = leftOffsets[i];
+ this._makeSticky(cellThs[i], offset, "left", true);
+ }
+ });
+ },
+ _makeSticky(cell, offset = 0, align = "left", isGroup = false) {
+
+ if (!cell) return;
+ // cell 添加 class position-sticky
+ cell.classList.add("position-sticky");
+ cell.style.zIndex = isGroup ? "15" : "10";
+ cell.style.background = "#fff";
+ if (align === "left") {
+ cell.style.left = `${offset}px`;
+ } else if (align === "right") {
+ cell.style.right = `${offset}px`;
+ }
+ },
+
+ toggleGroup(group) {
+ super.toggleGroup(group)
+ setTimeout(() => {
+ this.freezeTwoColumns()
+ }, 500)
+
+ },
+
+ getActiveColumns(list) {
+ const columns = super.getActiveColumns(list);
+ console.log(this.props.archInfo.className)
+ // 判断 sticky-enabled-two-columns 在 this.props.archInfo.className
+ if (!this.props.archInfo.className.includes('sticky-enabled-two-columns')) {
+ return columns
+ }
+
+ let values;
+ if (this.props.list.selection && this.props.list.selection.length) {
+ values = this.props.list.selection.map((r) => r.data);
+ } else if (this.props.list.isGrouped) {
+ values = this.props.list.groups.map((g) => g.aggregates);
+ } else {
+ values = this.props.list.records.map((r) => r.data);
+ }
+ return columns.filter(column => {
+ const fieldInfo = list.fields[column.name];
+ if (!fieldInfo) {
+ return true;
+ }
+ if (["float","int", "monetary"].includes(fieldInfo.type)) {
+ const fieldValues = values.map((v) => v[fieldInfo.name] || 0);
+ const aggregateValue = fieldValues.reduce((acc, val) => acc + val);
+ if (!aggregateValue) {
+ console.log(column)
+ return false;
+ }
+ }
+ return true;
+ })
+ }
+
+});
+
+// ListRenderer.props.push('ooManagerColumns?');
+// ListRenderer.props.push('ooManagerFilter?');
+// ListRenderer.props.push('ooManagerSerialNum?');
+// ListRenderer.props.push('ooManagerStickyEnd?');
diff --git a/yuthon_salary/views/inherit_hr_payslip_views.xml b/yuthon_salary/views/inherit_hr_payslip_views.xml
index f9003f0ea..da91c27ba 100644
--- a/yuthon_salary/views/inherit_hr_payslip_views.xml
+++ b/yuthon_salary/views/inherit_hr_payslip_views.xml
@@ -10,6 +10,7 @@
custom_salary_validation_button
employee_id
20
+ sticky-enabled-two-columns
false
@@ -415,7 +416,7 @@
hr.payslip.tree.jtbb
hr.payslip
-
+
|