1
This commit is contained in:
@@ -0,0 +1,4 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
from . import controllers
|
||||
from . import models
|
||||
@@ -0,0 +1,38 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
{
|
||||
'name': "oo_list_manager",
|
||||
|
||||
'summary': "Short (1 phrase/line) summary of the module's purpose",
|
||||
|
||||
'description': """
|
||||
Long description of module's purpose
|
||||
""",
|
||||
|
||||
'author': "My Company",
|
||||
'website': "https://www.yourcompany.com",
|
||||
|
||||
# Categories can be used to filter modules in modules listing
|
||||
# Check https://github.com/odoo/odoo/blob/15.0/odoo/addons/base/data/ir_module_category_data.xml
|
||||
# for the full list
|
||||
'category': 'Uncategorized',
|
||||
'version': '0.1',
|
||||
|
||||
# any module necessary for this one to work correctly
|
||||
'depends': ['base', 'web', 'tree_view_advanced_filter'],
|
||||
|
||||
# always loaded
|
||||
'data': [
|
||||
# 'security/ir.model.access.csv',
|
||||
],
|
||||
# only loaded in demonstration mode
|
||||
"application": True,
|
||||
"auto_install": False,
|
||||
'license': 'LGPL-3',
|
||||
'assets': {
|
||||
'web.assets_backend': [
|
||||
'oo_list_manager/static/src/views/list/*',
|
||||
'oo_list_manager/static/src/views/auto_hide_list/*',
|
||||
]
|
||||
},
|
||||
}
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
from . import controllers
|
||||
@@ -0,0 +1,22 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# from odoo import http
|
||||
|
||||
|
||||
# class OoListManager(http.Controller):
|
||||
# @http.route('/oo_list_manager/oo_list_manager', auth='public')
|
||||
# def index(self, **kw):
|
||||
# return "Hello, world"
|
||||
|
||||
# @http.route('/oo_list_manager/oo_list_manager/objects', auth='public')
|
||||
# def list(self, **kw):
|
||||
# return http.request.render('oo_list_manager.listing', {
|
||||
# 'root': '/oo_list_manager/oo_list_manager',
|
||||
# 'objects': http.request.env['oo_list_manager.oo_list_manager'].search([]),
|
||||
# })
|
||||
|
||||
# @http.route('/oo_list_manager/oo_list_manager/objects/<model("oo_list_manager.oo_list_manager"):obj>', auth='public')
|
||||
# def object(self, obj, **kw):
|
||||
# return http.request.render('oo_list_manager.object', {
|
||||
# 'object': obj
|
||||
# })
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
from . import ir_ui_view
|
||||
@@ -0,0 +1,20 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
from odoo import models, fields, api
|
||||
|
||||
|
||||
class IrUiView(models.Model):
|
||||
_inherit = 'ir.ui.view'
|
||||
|
||||
manager_data = fields.Json(string='data')
|
||||
|
||||
def get_manager_data(self):
|
||||
self.ensure_one()
|
||||
return self.manager_data or {}
|
||||
|
||||
def save_manager_data(self, manager_data):
|
||||
self.ensure_one()
|
||||
self.sudo().write({
|
||||
'manager_data': manager_data
|
||||
})
|
||||
return True
|
||||
@@ -0,0 +1,2 @@
|
||||
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
|
||||
access_oo_list_manager_oo_list_manager,oo_list_manager.oo_list_manager,model_oo_list_manager_oo_list_manager,base.group_user,1,1,1,1
|
||||
|
@@ -0,0 +1,30 @@
|
||||
/** @odoo-module **/
|
||||
|
||||
import {ListRenderer} from "@web/views/list/list_renderer";
|
||||
|
||||
export class AutoHideListRenderer 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;
|
||||
})
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
/** @odoo-module */
|
||||
|
||||
import { registry } from "@web/core/registry";
|
||||
import { listView } from "@web/views/list/list_view";
|
||||
import { AutoHideListRenderer } from "./auto_hide_list_renderer";
|
||||
|
||||
export const autoHideListView = {
|
||||
...listView,
|
||||
Renderer: AutoHideListRenderer
|
||||
}
|
||||
|
||||
registry.category("views").add("autoHideListView", autoHideListView);
|
||||
@@ -0,0 +1,156 @@
|
||||
/** @odoo-module **/
|
||||
|
||||
import {ListController} from "@web/views/list/list_controller";
|
||||
import {patch} from "@web/core/utils/patch";
|
||||
import {onWillStart, useState, useRef, useExternalListener} from "@odoo/owl";
|
||||
import {Dropdown} from "@web/core/dropdown/dropdown";
|
||||
import {CheckBox} from "@web/core/checkbox/checkbox";
|
||||
import {useSortable} from "@web/core/utils/sortable_owl";
|
||||
import {useService} from "@web/core/utils/hooks";
|
||||
import {usePosition} from "@web/core/position_hook";
|
||||
|
||||
|
||||
patch(ListController.prototype, {
|
||||
setup() {
|
||||
super.setup();
|
||||
this.isChange = false;
|
||||
this.orm = useService('orm');
|
||||
this.ooColumnsRef = useRef('ooColumnsRef');
|
||||
this.ooManagerRef = useRef('ooManagerRef');
|
||||
this.ooListRef = useRef('ooListRef');
|
||||
|
||||
this.ooManager = useState({
|
||||
state: false,
|
||||
key: '',
|
||||
filter: false,
|
||||
serial_num: false,
|
||||
columns: this.archInfo.columns.filter((column) => {
|
||||
if (column.type === "field" && column.widget !== 'handle') {
|
||||
return column
|
||||
}
|
||||
})
|
||||
});
|
||||
|
||||
onWillStart(async () => {
|
||||
const manager_data = await this.orm.call('ir.ui.view', 'get_manager_data', [this.env.config.viewId]);
|
||||
if (!Object.keys(manager_data).length) {
|
||||
this.ooManager.columns.forEach(val => {
|
||||
val.visibility = !!!val.column_invisible;
|
||||
})
|
||||
} else {
|
||||
Object.assign(this.ooManager, manager_data);
|
||||
this.archInfo.advanced_filter = this.ooManager.filter;
|
||||
}
|
||||
})
|
||||
|
||||
usePosition('ooListRef', () => this.ooManagerRef.el, {
|
||||
position: "bottom-start",
|
||||
})
|
||||
|
||||
useSortable({
|
||||
ref: this.ooColumnsRef,
|
||||
elements: ".oo_column",
|
||||
handle: ".oo_sort_cell",
|
||||
cursor: "move",
|
||||
onDrop: (params) => this.sortColumnDrop(params)
|
||||
})
|
||||
|
||||
useExternalListener(window, "click", this.onGlobalClick.bind(this));
|
||||
},
|
||||
|
||||
onGlobalClick(ev) {
|
||||
if (this.ooListRef.el && !this.ooListRef.el.contains(ev.target)) {
|
||||
this.ooManager.state = false;
|
||||
this.ooManager.key = '';
|
||||
if (this.isChange) {
|
||||
return this.saveManagerData();
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
onChangeSerialNum() {
|
||||
this.isChange = true;
|
||||
this.ooManager.serial_num = !this.ooManager.serial_num;
|
||||
},
|
||||
|
||||
onChangeFilter() {
|
||||
this.isChange = true;
|
||||
this.ooManager.filter = !this.ooManager.filter;
|
||||
this.archInfo.advanced_filter = this.ooManager.filter;
|
||||
},
|
||||
|
||||
onChangeColumns() {
|
||||
const columns = [...this.ooManager.columns];
|
||||
this.isChange = true;
|
||||
this.ooManager.columns = columns;
|
||||
},
|
||||
|
||||
/**
|
||||
* 控制列显示/隐藏
|
||||
* @param ev
|
||||
*/
|
||||
onChangeVisibility(ev) {
|
||||
const id = ev.currentTarget.dataset.id;
|
||||
const columns = [...this.ooManager.columns];
|
||||
const columnIdx = columns.findIndex(item => item.id === id);
|
||||
if (columnIdx >= 0) {
|
||||
columns[columnIdx].visibility = !columns[columnIdx].visibility;
|
||||
}
|
||||
this.isChange = true;
|
||||
this.ooManager.columns = columns;
|
||||
},
|
||||
|
||||
/**
|
||||
* 排序
|
||||
* @param params
|
||||
*/
|
||||
sortColumnDrop(params) {
|
||||
const {element, previous} = params;
|
||||
|
||||
const fromId = element.dataset.id;
|
||||
const toId = previous ? previous.dataset.id : null;
|
||||
const columns = [...this.ooManager.columns];
|
||||
const fromIndex = columns.findIndex((d) => d.id === fromId);
|
||||
let toIndex = 0;
|
||||
if (toId !== null) {
|
||||
const targetIndex = columns.findIndex((d) => d.id === toId);
|
||||
toIndex = fromIndex > targetIndex ? targetIndex + 1 : targetIndex;
|
||||
}
|
||||
|
||||
// 取出被拖拽的元素
|
||||
const [moved] = columns.splice(fromIndex, 1);
|
||||
// 插入到新位置
|
||||
columns.splice(toIndex, 0, moved);
|
||||
columns.forEach((column, i) => {
|
||||
column.seq = i + 1;
|
||||
});
|
||||
this.isChange = true;
|
||||
this.ooManager.columns = columns;
|
||||
},
|
||||
|
||||
/**
|
||||
* 保存
|
||||
* @returns {*}
|
||||
*/
|
||||
saveManagerData() {
|
||||
this.isChange = false;
|
||||
return this.orm.call(
|
||||
'ir.ui.view',
|
||||
'save_manager_data',
|
||||
[
|
||||
this.env.config.viewId,
|
||||
{
|
||||
columns: this.ooManager.columns,
|
||||
filter: this.ooManager.filter,
|
||||
serial_num: this.ooManager.serial_num,
|
||||
}
|
||||
]
|
||||
);
|
||||
},
|
||||
})
|
||||
|
||||
ListController.components = {
|
||||
...ListController.components,
|
||||
Dropdown,
|
||||
CheckBox
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
.oo_list_manager {
|
||||
padding: 10px 10px 0 10px;
|
||||
overflow: hidden;
|
||||
display: flex !important;
|
||||
flex-direction: column;
|
||||
z-index: 999999999999999;
|
||||
left: 0;
|
||||
|
||||
.oo_columns {
|
||||
overflow: auto;
|
||||
|
||||
.oo_column {
|
||||
background-color: white;
|
||||
|
||||
.o_width_input {
|
||||
width: 50px;
|
||||
appearance: textfield;
|
||||
margin: 0 5px 0 5px;
|
||||
|
||||
&::-webkit-outer-spin-button,
|
||||
&::-webkit-inner-spin-button {
|
||||
appearance: none;
|
||||
margin: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.o_lock_box {
|
||||
margin: 0 5px 0 5px;
|
||||
padding: 0 5px 0 5px;
|
||||
|
||||
i {
|
||||
display: block;
|
||||
font-size: 1.4rem;
|
||||
cursor: pointer;
|
||||
|
||||
&:hover {
|
||||
color: #27ae60;
|
||||
}
|
||||
}
|
||||
|
||||
.active {
|
||||
color: #27ae60;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<templates xml:space="preserve">
|
||||
|
||||
<t t-inherit="web.ListView" t-inherit-mode="extension">
|
||||
<xpath expr="//t[@t-set-slot='layout-buttons']" position="inside">
|
||||
<div class="o-dropdown dropdown o-dropdown--no-caret" t-ref="ooManagerRef">
|
||||
<button type="button" class="btn btn-primary" t-on-click="()=>this.ooManager.state = !this.ooManager.state">
|
||||
<i class="fa fa-cogs" />
|
||||
</button>
|
||||
<div class="oo_list_manager o-dropdown--menu dropdown-menu d-block" t-if="ooManager.state" t-ref="ooListRef">
|
||||
<div class="d-flex align-items-center pb-2">
|
||||
<div class="d-flex align-items-center">
|
||||
<div class="d-flex align-items-center">
|
||||
表头查询:
|
||||
</div>
|
||||
<div class="o-checkbox form-check form-switch">
|
||||
<input type="checkbox" class="form-check-input" t-model="ooManager.filter" t-on-click="onChangeFilter"/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="d-flex align-items-center">
|
||||
<div class="d-flex align-items-center">
|
||||
行号:
|
||||
</div>
|
||||
<div class="o-checkbox form-check form-switch">
|
||||
<input type="checkbox" class="form-check-input" t-model="ooManager.serial_num" t-on-click="onChangeSerialNum"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="d-flex align-items-center pb-2">
|
||||
<input type="text" class="form-control" t-model="ooManager.key"/>
|
||||
<i class="btn btn-primary fa fa-refresh ms-2" t-on-click="()=>this.ooManager.key = ''"/>
|
||||
</div>
|
||||
<div class="d-flex flex-column oo_columns" t-ref="ooColumnsRef">
|
||||
<div class="pb-2 d-flex align-items-center oo_column" t-foreach="ooManager.columns" t-as="column" t-key="column.id" t-att-data-id="column.id" t-if="column.string.includes(ooManager.key)">
|
||||
<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="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>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</xpath>
|
||||
<xpath expr="//t[@t-component='props.Renderer']" position="replace">
|
||||
<t t-component="props.Renderer"
|
||||
list="model.root"
|
||||
activeActions="activeActions"
|
||||
archInfo="archInfo"
|
||||
allowSelectors="props.allowSelectors"
|
||||
editable="editable"
|
||||
onOpenFormView="onOpenFormView"
|
||||
openRecord.bind="openRecord"
|
||||
noContentHelp="props.info.noContentHelp"
|
||||
onAdd.bind="createRecord"
|
||||
onOptionalFieldsChanged.bind="onOptionalFieldsChanged"
|
||||
evalViewModifier.bind="evalViewModifier"
|
||||
ooManagerColumns="ooManager.columns"
|
||||
ooManagerFilter="ooManager.filter"
|
||||
ooManagerSerialNum="ooManager.serial_num"
|
||||
/>
|
||||
</xpath>
|
||||
</t>
|
||||
|
||||
</templates>
|
||||
@@ -0,0 +1,147 @@
|
||||
/** @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"
|
||||
|
||||
patch(ListRenderer.prototype, {
|
||||
setup() {
|
||||
super.setup();
|
||||
if(this.isX2Many) {
|
||||
this.props.ooManagerSerialNum = true;
|
||||
}
|
||||
},
|
||||
|
||||
getActiveColumns(list) {
|
||||
if (this.props.ooManagerColumns) {
|
||||
const columns = this.allColumns.filter((col) => {
|
||||
if (list.isGrouped && col.widget === "handle") {
|
||||
return false; // no handle column if the list is grouped
|
||||
}
|
||||
const mColumn = this.props.ooManagerColumns.find(item => item.id === col.id)
|
||||
if (mColumn) {
|
||||
return mColumn.visibility;
|
||||
}
|
||||
if (col.optional && !this.optionalActiveFields[col.name]) {
|
||||
return false;
|
||||
}
|
||||
if (this.evalColumnInvisible(col.column_invisible)) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
});
|
||||
|
||||
columns.sort((x, y) => {
|
||||
const seqX = this.props.ooManagerColumns.find(item => item.id === x.id)?.seq || 0;
|
||||
const seqY = this.props.ooManagerColumns.find(item => item.id === y.id)?.seq || 0;
|
||||
return seqX - seqY;
|
||||
});
|
||||
|
||||
return columns
|
||||
|
||||
} else {
|
||||
return super.getActiveColumns(list);
|
||||
}
|
||||
},
|
||||
|
||||
freezeColumnWidths() {
|
||||
super.freezeColumnWidths();
|
||||
const table = this.tableRef.el;
|
||||
const headers = [...table.querySelectorAll("thead th:not(.o_list_actions_header)")];
|
||||
|
||||
headers.forEach((th, index) => {
|
||||
th.style.minWidth = `${Math.floor(this.columnWidths[index])}px`;
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 宽度
|
||||
* @param allowedWidth
|
||||
* @returns {*}
|
||||
*/
|
||||
computeColumnWidthsFromContent(allowedWidth) {
|
||||
const columnWidths = super.computeColumnWidthsFromContent(allowedWidth);
|
||||
if (!this.props.ooManagerColumns) return columnWidths;
|
||||
const table = this.tableRef.el;
|
||||
|
||||
// Toggle a className used to remove style that could interfere with the ideal width
|
||||
// computation algorithm (e.g. prevent text fields from being wrapped during the
|
||||
// computation, to prevent them from being completely crushed)
|
||||
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;
|
||||
}
|
||||
});
|
||||
|
||||
// We are no longer computing widths, so restore the normal style
|
||||
table.classList.remove("o_list_computing_widths");
|
||||
return columnWidths;
|
||||
},
|
||||
|
||||
/**
|
||||
* 样式
|
||||
* @param column
|
||||
* @returns {string}
|
||||
*/
|
||||
getColumnStyle(column) {
|
||||
if (!this.props.ooManagerColumns) return '';
|
||||
const mColumn = this.props.ooManagerColumns.find(item => item.id === column.id);
|
||||
if (mColumn && mColumn.color) {
|
||||
return 'color: ' + mColumn.color;
|
||||
} else {
|
||||
return '';
|
||||
}
|
||||
},
|
||||
|
||||
_renderSearchPanel: async function () {
|
||||
if (this.isX2Many) {
|
||||
return ListRendererCust._renderSearchPanel.call(this);
|
||||
}
|
||||
if (!this.props.archInfo.advanced_filter) {
|
||||
$('.o_filter_box').remove();
|
||||
} else {
|
||||
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");
|
||||
var List = this.props.list;
|
||||
const bm_params = List.model.__bm_load_params__;
|
||||
const rootRef = this.rootRef.el
|
||||
const tableRef = this.tableRef.el;
|
||||
tableRef.removeAttribute('style')
|
||||
const columns = this.getActiveColumns(this.props.list);
|
||||
|
||||
var $tr1 = $('<tr>', {class: 'o_filter_box'}).append(columns.map(columns => this._renderHeaderCellSearch(columns)));
|
||||
// 添加行号占位td
|
||||
$tr1.prepend($('<td>').addClass('web_list_num'));
|
||||
if (this.hasSelectors) {
|
||||
$tr1.prepend($('<td>').addClass('o_list_record_selector'));
|
||||
}
|
||||
|
||||
if (this.isStudioEditable || this.displayOptionalFields) {
|
||||
$tr1.append($('<td>').addClass('o_list_record_selector'));
|
||||
}
|
||||
|
||||
if ($(tableRef).find('.search_td').length) {
|
||||
$(tableRef).find('.search_td').parent().replaceWith($tr1)
|
||||
} else {
|
||||
$tr1.insertAfter($(tableRef).find('tr')[0]);
|
||||
}
|
||||
|
||||
rootRef.querySelectorAll('thead tr td.search_td input').forEach((a) => a.addEventListener('keyup', this._onfilter.bind(this)));
|
||||
rootRef.querySelectorAll('.search_button').forEach((a) => a.addEventListener('click', this._onSearch.bind(this)));
|
||||
rootRef.querySelectorAll('.remove_button').forEach((a) => a.addEventListener('click', this._onRemove.bind(this)));
|
||||
rootRef.querySelectorAll('thead tr td').forEach((a) => a.addEventListener('keypress', this._onKeyPress.bind(this)));
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
ListRenderer.props.push('ooManagerColumns?')
|
||||
ListRenderer.props.push('ooManagerFilter?')
|
||||
ListRenderer.props.push('ooManagerSerialNum?')
|
||||
@@ -0,0 +1,57 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<templates xml:space="preserve">
|
||||
|
||||
<t t-inherit="web.ListRenderer" t-inherit-mode="extension">
|
||||
<xpath expr="//th[@t-att-data-name='column.name']" position="attributes">
|
||||
<attribute name="t-att-data-id">column.id</attribute>
|
||||
<attribute name="t-att-style">getColumnStyle(column)</attribute>
|
||||
</xpath>
|
||||
|
||||
<xpath expr="//thead//t[@t-if='numSwitch']" position="replace">
|
||||
<t t-if="props.ooManagerSerialNum">
|
||||
<th class="list-number">#</th>
|
||||
</t>
|
||||
</xpath>
|
||||
<xpath expr="//tfoot//t[@t-if='numSwitch']" position="replace">
|
||||
<t t-if="props.ooManagerSerialNum">
|
||||
<td/>
|
||||
</t>
|
||||
</xpath>
|
||||
</t>
|
||||
|
||||
<t t-inherit="web.ListRenderer.RecordRow" t-inherit-mode="extension">
|
||||
<xpath expr="//td[@t-att-name='column.name']" position="attributes">
|
||||
<attribute name="t-att-style">getColumnStyle(column)</attribute>
|
||||
</xpath>
|
||||
|
||||
<xpath expr="//t[@t-if='numSwitch']" position="replace">
|
||||
<t t-if="props.ooManagerSerialNum">
|
||||
<t t-set="num" t-value="(record_index + 1) + list.offset"/>
|
||||
<td t-esc="num" t-att-data-tooltip="num" class="cursor-pointer"/>
|
||||
</t>
|
||||
</xpath>
|
||||
</t>
|
||||
|
||||
<t t-inherit="web.ListRenderer.Rows" t-inherit-mode="extension">
|
||||
<xpath expr="//tr[@t-foreach='getEmptyRowIds']//t[@t-if='numSwitch']" position="replace">
|
||||
<t t-if="props.ooManagerSerialNum">
|
||||
<td/>
|
||||
</t>
|
||||
</xpath>
|
||||
<xpath expr="//t[@t-if='numSwitch']" position="replace">
|
||||
<t t-if="props.ooManagerSerialNum">
|
||||
<td/>
|
||||
</t>
|
||||
</xpath>
|
||||
</t>
|
||||
|
||||
<t t-inherit="web.ListRenderer.GroupRow" t-inherit-mode="extension">
|
||||
<xpath expr="//t[@t-if='numSwitch']" position="replace">
|
||||
<t t-if="props.ooManagerSerialNum">
|
||||
<t t-set="num" t-value="(group_index + 1) + list.offset"/>
|
||||
<td t-esc="num" t-att-data-tooltip="num" class="cursor-pointer"/>
|
||||
</t>
|
||||
</xpath>
|
||||
</t>
|
||||
|
||||
</templates>
|
||||
Reference in New Issue
Block a user