Merge pull request !287 from 李鹏宇/dev_zhou
This commit is contained in:
李鹏宇
2024-10-15 03:39:50 +00:00
committed by Gitee
12 changed files with 406 additions and 0 deletions
+1
View File
@@ -0,0 +1 @@
# -*- coding: utf-8 -*-
+29
View File
@@ -0,0 +1,29 @@
# -*- coding: utf-8 -*-
{
'name': "ylhc_list",
'summary': "advance list for odoo",
'description': """
advance list
fixed column list
""",
'author': "crax",
'website': "https://www.ylhc.com",
'category': 'apps/list',
'version': '17.0.0.1',
'depends': ['base', 'web'],
'price': 9999,
'data': [],
'assets': {
'web.assets_backend': [
'ylhc_list/static/src/*.*'
]
}
}
+2
View File
@@ -0,0 +1,2 @@
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
access_xc_list_xc_list,xc_list.xc_list,model_xc_list_xc_list,base.group_user,1,1,1,1
1 id name model_id:id group_id:id perm_read perm_write perm_create perm_unlink
2 access_xc_list_xc_list xc_list.xc_list model_xc_list_xc_list base.group_user 1 1 1 1
Binary file not shown.

After

Width:  |  Height:  |  Size: 62 KiB

@@ -0,0 +1,9 @@
/** @odoo-module **/
import { _t } from "@web/core/l10n/translation";
import { ListController } from "@web/views/list/list_controller";
export class YlhcListController extends ListController {
}
+136
View File
@@ -0,0 +1,136 @@
/** @odoo-module **/
import { ListRenderer } from "@web/views/list/list_renderer";
import { _t } from "@web/core/l10n/translation";
import { xml } from "@odoo/owl";
export class YlhcListRenderer extends ListRenderer {
setup() {
super.setup();
this.hasExpander = this._hasExpander();
this.subRowTemplate = this.getSubRowTemplate();
}
/**
* check if tree_column in column option
*/
isTreeColumn(column) {
return column.options.tree_column;
}
isExpanderColumn(column) {
return column.options.expander;
}
_hasExpander() {
let columns = this.state.columns || [];
for (let i = 0; i < columns.length; i++) {
if (this.isExpanderColumn(columns[i])) {
return true;
}
}
return false;
}
getSubRowTemplate() {
let columns = this.state.columns || [];
for (let i = 0; i < columns.length; i++) {
if (this.isExpanderColumn(columns[i])) {
let sub_row_template = columns[i].options.sub_row_template;
if (columns[i].options.sub_row_template) {
return sub_row_template;
}
}
}
return xml`<div>can find the sub rwo template !!!</div>`;
}
getSubRowColumnSpan() {
let columns = this.state.columns || [];
if (this.hasSelectors) {
return columns.length + 1;
}
return columns.length;
}
/**
* parent_path is used to check if the column is a tree column
*/
checkParentPath() {
let columns = this.state.columns || [];
// find parent path
let parentPath = columns.find(column => column.name == 'parent_path');
if (parentPath) {
return true;
}
return false;
}
getTreeLevel(record) {
let parentPath = record.data.parent_path;
if (parentPath) {
return parentPath.split('/').length;
}
return 0;
}
/**
* get children of a record
* @param {*} record
* */
hasChildren(record) {
let records = this.props.list.records;
let index = records.indexOf(record);
let parent_path = record.data.parent_path;
for (let i = index + 1; i < records.length; i++) {
if (records[i].data.parent_path.startsWith(parent_path)) {
return true
} else {
break;
}
}
return false;
}
getChildren(record) {
let records = this.props.list.records;
let index = records.indexOf(record);
let parent_path = record.data.parent_path;
let children = [];
for (let i = index + 1; i < records.length; i++) {
if (records[i].data.parent_path.startsWith(parent_path)) {
children.push(records[i]);
} else {
break;
}
}
return children;
}
/**
* click the expand button
**/
toggleRecord(record) {
let children = this.getChildren(record);
if (record.folded) {
for (let i = 0; i < children.length; i++) {
children[i].hide = false;
}
} else {
for (let i = 0; i < children.length; i++) {
children[i].hide = true;
}
}
record.folded = !record.folded;
this.render();
}
toggleExpander(record) {
record.sub_row_folded = !record.sub_row_folded;
this.render();
}
}
YlhcListRenderer.recordRowTemplate = "ylhc_list.ListRenderer.RecordRow";
+154
View File
@@ -0,0 +1,154 @@
<?xml version="1.0" encoding="UTF-8"?>
<templates xml:space="preserve">
<t t-name="ylhc_list.ListRenderer.RecordRow">
<tr class="o_data_row"
t-if="!record.hide"
t-att-class="getRowClass(record)"
t-att-data-id="record.id"
t-on-click.capture="(ev) => this.onClickCapture(record, ev)"
t-on-mouseover.capture="(ev) => this.ignoreEventInSelectionMode(ev)"
t-on-mouseout.capture="(ev) => this.ignoreEventInSelectionMode(ev)"
t-on-mouseenter.capture="(ev) => this.ignoreEventInSelectionMode(ev)"
t-on-touchstart="(ev) => this.onRowTouchStart(record, ev)"
t-on-touchend="() => this.onRowTouchEnd(record)"
t-on-touchmove="() => this.onRowTouchMove(record)"
>
<td t-on-keydown.synthetic="(ev) => this.onCellKeydown(ev, group, record)" t-if="hasSelectors" class="o_list_record_selector user-select-none" t-on-click.stop="() => this.toggleRecordSelection(record)" tabindex="-1">
<CheckBox disabled="!canSelectRecord" value="record.selected" onChange.alike="() => this.toggleRecordSelection(record)" />
</td>
<t t-foreach="getColumns(record)" t-as="column" t-key="column.id">
<t t-if="column.type === 'field'">
<t t-set="isInvisible" t-value="evalInvisible(column.invisible, record) or !(column.name in record.data)"/>
<td t-on-keydown.synthetic="(ev) => this.onCellKeydown(ev, group, record)"
class="o_data_cell cursor-pointer"
t-att-class="getCellClass(column, record)"
t-att-name="column.name"
t-att-colspan="column.colspan"
t-att-data-tooltip="!isInvisible ? getCellTitle(column, record) : false"
data-tooltip-delay="1000"
t-on-click="(ev) => this.onCellClicked(record, column, ev)" tabindex="-1">
<t t-if="!isInvisible">
<t t-if="isTreeColumn(column)">
<t t-set="levels" t-value="getTreeLevel(record)"/>
<span class="tree_toggle" t-on-click.prevent.stop="() => this.toggleRecord(record)" t-att-style="'width:' + 20 * levels + 'px'">
<i t-if="hasChildren(record)" class="fa fa-lg fa-fw fa-caret-down" t-att-style="`transform:${record.folded ? 'rotate(-90deg)' : 'rotate(0deg)'}`"/>
</span>
</t>
<t t-if="isExpanderColumn(column)">
<span class="expander_toggle" t-on-click.prevent.stop="() => this.toggleExpander(record)">
<i class="fa fa-lg fa-fw fa-caret-down" t-att-style="`transform:${record.sub_row_folded ? 'rotate(-90deg)' : 'rotate(0deg)'}`"/>
</span>
</t>
<t t-if="canUseFormatter(column, record)" t-out="getFormattedValue(column, record)"/>
<Field t-else="" name="column.name" record="record" type="column.widget" class="getFieldClass(column)" fieldInfo="column" t-props="getFieldProps(record, column)"/>
</t>
</td>
</t>
<t t-if="column.type === 'button_group'">
<td t-on-keydown.synthetic="(ev) => this.onCellKeydown(ev, group, record)" class="o_data_cell cursor-pointer" t-att-class="getCellClass(column, record)" t-on-click="(ev) => this.onButtonCellClicked(record, column, ev)" tabindex="-1">
<t t-foreach="column.buttons" t-as="button" t-key="button.id">
<ViewButton t-if="!evalInvisible(button.invisible, record)"
className="button.className"
clickParams="button.clickParams"
defaultRank="button.defaultRank"
disabled="button.disabled"
icon="button.icon"
record="record"
string="button.string"
title="button.title"
tabindex="props.list.editedRecord ? '-1' : '0'"
onClick="isX2Many and record.isNew ? displaySaveNotification.bind(this) : ''"
/>
</t>
</td>
</t>
<t t-if="column.type === 'widget'">
<td class="o_data_cell" t-att-class="getCellClass(column, record)">
<Widget t-props="column.props" record="record"/>
</td>
</t>
</t>
<t t-if="props.onOpenFormView">
<td class="o_list_record_open_form_view text-center"
t-on-keydown.synthetic="(ev) => this.onCellKeydown(ev, group, record)"
t-on-click.stop="() => props.onOpenFormView(record)"
tabindex="-1"
>
<button class="btn btn-link text-end"
name="Open in form view"
aria-label="Open in form view"
tabindex="-1"
>View</button>
</td>
</t>
<t t-set="useUnlink" t-value="'unlink' in activeActions" />
<t t-set="hasX2ManyAction" t-value="isX2Many and (useUnlink ? activeActions.unlink : activeActions.delete)" />
<t t-if="displayOptionalFields or hasX2ManyAction">
<t t-if="hasX2ManyAction">
<td class="o_list_record_remove text-center"
t-on-keydown.synthetic="(ev) => this.onCellKeydown(ev, group, record)"
t-on-click.stop="() => this.onDeleteRecord(record)"
tabindex="-1"
>
<button class="fa"
t-att-class="{
'fa-trash-o': !useUnlink and activeActions.delete,
'fa-times': useUnlink and activeActions.unlink,
}"
name="delete"
aria-label="Delete row"
tabindex="-1"
/>
</td>
</t>
<td t-else="" tabindex="-1" />
</t>
</tr>
<tr t-if="hasExpander &amp;&amp; !record.sub_row_folded">
<td t-attf-colspan="{{getSubRowColumnSpan()}}">
<t t-call="{{subRowTemplate}}" />
</td>
</tr>
</t>
<t t-name="ylhc_list.default_sub_template">
<div>
<h2>Product Information</h2>
<table>
<tr>
<th>Product Name</th>
<td>Example Product</td>
</tr>
<tr>
<th>Product Description</th>
<td>This is an example product used for demonstration purposes.</td>
</tr>
<tr>
<th>Main Features</th>
<td>Feature 1, Feature 2, Feature 3</td>
</tr>
<tr>
<th>Price</th>
<td>$100</td>
</tr>
<tr>
<th>Stock Quantity</th>
<td>50</td>
</tr>
<tr>
<th>Product Image</th>
<td><img src="example.jpg" alt="Example Product Image" width="100" /></td>
</tr>
<tr>
<th>Additional Information</th>
<td>Any additional information can go here.</td>
</tr>
</table>
</div>
</t>
</templates>
+21
View File
@@ -0,0 +1,21 @@
/** @odoo-module */
import { registry } from "@web/core/registry";
import { ListArchParser } from "@web/views/list/list_arch_parser";
import { listView } from "@web/views/list/list_view";
import { YlhcListController } from "./ylhc_list_controller";
import { YlhcListRenderer } from "./ylhc_list_renderer";
import { YlhcRelationalModel } from "./ylhc_relation_model";
export const YlhcListView = {
...listView,
Controller: YlhcListController,
Renderer: YlhcListRenderer,
ArchParser: ListArchParser,
Model: YlhcRelationalModel,
};
registry.category("views").add("ylhc_list_view", YlhcListView);
+9
View File
@@ -0,0 +1,9 @@
.tree_toggle {
display: inline-block;
text-align: right;
}
.expander_toggle {
display: inline-block;
}
+21
View File
@@ -0,0 +1,21 @@
/* @odoo-module */
import { _t } from "@web/core/l10n/translation";
import { Record } from "@web/model/relational_model/record";
export class YlhcRecord extends Record {
/**
* @param {any} env
* @param {any} model
* @param {any} id
* @param {any} fields
* @param {any} options
*/
constructor(env, model, id, fields, options) {
super(env, model, id, fields, options);
this._isYlhcRecord = true;
this.folded = false;
this.sub_row_folded = true;
this.hide = false;
}
}
@@ -0,0 +1,23 @@
/* @odoo-module */
import { RelationalModel } from "@web/model/relational_model/relational_model";
import { YlhcRecord } from "./ylhc_record";
export class YlhcRelationalModel extends RelationalModel {
static Record = YlhcRecord;
/**
* @param {any} env
* @param {any} modelInfo
* @param {any} params
*/
constructor(env, modelInfo, params) {
super(env, modelInfo, params);
this._isYlhcRelationalModel = true;
}
}
@@ -48,6 +48,7 @@ class YuthonProperty(models.Model):
management_area = fields.Float(string="管理面积")
rentable_area = fields.Float(string="可租面积")
is_meter = fields.Boolean(string="是否支持多个水表")
is_electricity_meter = fields.Boolean(string="是否支持多个电表")
is_hvac = fields.Boolean(string="是否中央空调")
manage_standard = fields.Char(string="物业管理费标准")