mirror of https://github.com/OCA/web.git
[MIG] web_widget_x2many_2d_matrix: Migration to 17.0
parent
9d17fbd853
commit
5fbf76500c
|
@ -219,6 +219,7 @@ Contributors
|
||||||
|
|
||||||
- Adrià Gil Sorribes <adria.gil@forgeflow.com>
|
- Adrià Gil Sorribes <adria.gil@forgeflow.com>
|
||||||
- Christopher Ormaza <chris.ormaza@forgeflow.com>
|
- Christopher Ormaza <chris.ormaza@forgeflow.com>
|
||||||
|
- SodexisTeam <dev@sodexis.com>
|
||||||
|
|
||||||
Maintainers
|
Maintainers
|
||||||
-----------
|
-----------
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||||
{
|
{
|
||||||
"name": "2D matrix for x2many fields",
|
"name": "2D matrix for x2many fields",
|
||||||
"version": "16.0.1.1.3",
|
"version": "17.0.1.0.0",
|
||||||
"maintainers": ["ChrisOForgeFlow"],
|
"maintainers": ["ChrisOForgeFlow"],
|
||||||
"development_status": "Production/Stable",
|
"development_status": "Production/Stable",
|
||||||
"author": (
|
"author": (
|
||||||
|
@ -35,7 +35,6 @@
|
||||||
"x2many_2d_matrix_field.xml",
|
"x2many_2d_matrix_field.xml",
|
||||||
"web_widget_x2many_2d_matrix/static/src/components/x2many_2d_matrix_field/"
|
"web_widget_x2many_2d_matrix/static/src/components/x2many_2d_matrix_field/"
|
||||||
"x2many_2d_matrix_field.scss",
|
"x2many_2d_matrix_field.scss",
|
||||||
"web_widget_x2many_2d_matrix/static/src/views/fields/boolean/boolean_field.esm.js",
|
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,3 +9,4 @@
|
||||||
- Alexey Pelykh \<<alexey.pelykh@corphub.eu>\>
|
- Alexey Pelykh \<<alexey.pelykh@corphub.eu>\>
|
||||||
- Adrià Gil Sorribes \<<adria.gil@forgeflow.com>\>
|
- Adrià Gil Sorribes \<<adria.gil@forgeflow.com>\>
|
||||||
- Christopher Ormaza \<<chris.ormaza@forgeflow.com>\>
|
- Christopher Ormaza \<<chris.ormaza@forgeflow.com>\>
|
||||||
|
- SodexisTeam \<<dev@sodexis.com>\>
|
||||||
|
|
|
@ -574,6 +574,7 @@ If you spotted it first, help us to smash it by providing a detailed and welcome
|
||||||
</li>
|
</li>
|
||||||
<li>Adrià Gil Sorribes <<a class="reference external" href="mailto:adria.gil@forgeflow.com">adria.gil@forgeflow.com</a>></li>
|
<li>Adrià Gil Sorribes <<a class="reference external" href="mailto:adria.gil@forgeflow.com">adria.gil@forgeflow.com</a>></li>
|
||||||
<li>Christopher Ormaza <<a class="reference external" href="mailto:chris.ormaza@forgeflow.com">chris.ormaza@forgeflow.com</a>></li>
|
<li>Christopher Ormaza <<a class="reference external" href="mailto:chris.ormaza@forgeflow.com">chris.ormaza@forgeflow.com</a>></li>
|
||||||
|
<li>SodexisTeam <<a class="reference external" href="mailto:dev@sodexis.com">dev@sodexis.com</a>></li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
<div class="section" id="maintainers">
|
<div class="section" id="maintainers">
|
||||||
|
|
|
@ -12,89 +12,46 @@ export class X2Many2DMatrixField extends Component {
|
||||||
}
|
}
|
||||||
|
|
||||||
getList() {
|
getList() {
|
||||||
return this.props.value;
|
return this.props.record.data[this.props.name];
|
||||||
}
|
}
|
||||||
|
|
||||||
get list() {
|
get list() {
|
||||||
return this.getList();
|
return this.getList();
|
||||||
}
|
}
|
||||||
|
|
||||||
_getDefaultRecordValues() {
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
|
|
||||||
async commitChange(x, y, value) {
|
|
||||||
const fields = this.props.matrixFields;
|
|
||||||
const values = this._getDefaultRecordValues();
|
|
||||||
|
|
||||||
const matchingRecords = this.list.records.filter((record) => {
|
|
||||||
let recordX = record.data[fields.x];
|
|
||||||
let recordY = record.data[fields.y];
|
|
||||||
if (record.fields[fields.x].type === "many2one") {
|
|
||||||
recordX = recordX[0];
|
|
||||||
}
|
|
||||||
if (record.fields[fields.y].type === "many2one") {
|
|
||||||
recordY = recordY[0];
|
|
||||||
}
|
|
||||||
return recordX === x && recordY === y;
|
|
||||||
});
|
|
||||||
if (matchingRecords.length === 1) {
|
|
||||||
values[fields.value] = value;
|
|
||||||
await matchingRecords[0].update(values);
|
|
||||||
} else {
|
|
||||||
values[fields.x] = x;
|
|
||||||
values[fields.y] = y;
|
|
||||||
|
|
||||||
if (this.list.fields[this.props.matrixFields.x].type === "many2one") {
|
|
||||||
values[fields.x] = [x, "/"];
|
|
||||||
}
|
|
||||||
if (this.list.fields[this.props.matrixFields.y].type === "many2one") {
|
|
||||||
values[fields.y] = [y, "/"];
|
|
||||||
}
|
|
||||||
|
|
||||||
let total = 0;
|
|
||||||
if (matchingRecords.length) {
|
|
||||||
total = matchingRecords
|
|
||||||
.map((r) => r.data[fields.value])
|
|
||||||
.reduce((aggr, v) => aggr + v);
|
|
||||||
}
|
|
||||||
const diff = value - total;
|
|
||||||
values[fields.value] = diff;
|
|
||||||
const record = await this.list.addNew({
|
|
||||||
mode: "edit",
|
|
||||||
});
|
|
||||||
await record.update(values);
|
|
||||||
}
|
|
||||||
this.props.setDirty(false);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
X2Many2DMatrixField.template = "web_widget_x2many_2d_matrix.X2Many2DMatrixField";
|
X2Many2DMatrixField.template = "web_widget_x2many_2d_matrix.X2Many2DMatrixField";
|
||||||
X2Many2DMatrixField.props = {
|
X2Many2DMatrixField.props = {
|
||||||
...standardFieldProps,
|
...standardFieldProps,
|
||||||
matrixFields: Object,
|
list: {type: Object, optional: true},
|
||||||
isXClickable: Boolean,
|
matrixFields: {type: Object, optional: true},
|
||||||
isYClickable: Boolean,
|
isXClickable: {type: Boolean, optional: true},
|
||||||
showRowTotals: Boolean,
|
isYClickable: {type: Boolean, optional: true},
|
||||||
showColumnTotals: Boolean,
|
showRowTotals: {type: Boolean, optional: true},
|
||||||
};
|
showColumnTotals: {type: Boolean, optional: true},
|
||||||
X2Many2DMatrixField.components = {X2Many2DMatrixRenderer};
|
|
||||||
X2Many2DMatrixField.extractProps = ({attrs}) => {
|
|
||||||
return {
|
|
||||||
matrixFields: {
|
|
||||||
value: attrs.field_value,
|
|
||||||
x: attrs.field_x_axis,
|
|
||||||
y: attrs.field_y_axis,
|
|
||||||
},
|
|
||||||
isXClickable: archParseBoolean(attrs.x_axis_clickable),
|
|
||||||
isYClickable: archParseBoolean(attrs.y_axis_clickable),
|
|
||||||
showRowTotals:
|
|
||||||
"show_row_totals" in attrs ? archParseBoolean(attrs.show_row_totals) : true,
|
|
||||||
showColumnTotals:
|
|
||||||
"show_column_totals" in attrs
|
|
||||||
? archParseBoolean(attrs.show_column_totals)
|
|
||||||
: true,
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
registry.category("fields").add("x2many_2d_matrix", X2Many2DMatrixField);
|
X2Many2DMatrixField.components = {X2Many2DMatrixRenderer};
|
||||||
|
export const x2Many2DMatrixField = {
|
||||||
|
component: X2Many2DMatrixField,
|
||||||
|
extractProps({attrs}) {
|
||||||
|
return {
|
||||||
|
matrixFields: {
|
||||||
|
value: attrs.field_value,
|
||||||
|
x: attrs.field_x_axis,
|
||||||
|
y: attrs.field_y_axis,
|
||||||
|
},
|
||||||
|
isXClickable: archParseBoolean(attrs.x_axis_clickable),
|
||||||
|
isYClickable: archParseBoolean(attrs.y_axis_clickable),
|
||||||
|
showRowTotals:
|
||||||
|
"show_row_totals" in attrs
|
||||||
|
? archParseBoolean(attrs.show_row_totals)
|
||||||
|
: true,
|
||||||
|
showColumnTotals:
|
||||||
|
"show_column_totals" in attrs
|
||||||
|
? archParseBoolean(attrs.show_column_totals)
|
||||||
|
: true,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
};
|
||||||
|
registry.category("fields").add("x2many_2d_matrix", x2Many2DMatrixField);
|
||||||
|
|
|
@ -6,6 +6,10 @@ $x2many_2d_matrix_max_height: 450px;
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.o_input {
|
||||||
|
padding: 1px 0px;
|
||||||
|
}
|
||||||
|
|
||||||
.table {
|
.table {
|
||||||
> thead > tr > th {
|
> thead > tr > th {
|
||||||
white-space: pre-line;
|
white-space: pre-line;
|
||||||
|
@ -31,18 +35,23 @@ $x2many_2d_matrix_max_height: 450px;
|
||||||
}
|
}
|
||||||
|
|
||||||
> td {
|
> td {
|
||||||
text-align: left;
|
text-align: right;
|
||||||
|
|
||||||
|
.o_field_many2one_selection {
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
|
||||||
&:first-child {
|
&:first-child {
|
||||||
position: sticky;
|
position: sticky;
|
||||||
left: 0;
|
left: 0;
|
||||||
|
text-align: left;
|
||||||
border-right-width: 1px;
|
border-right-width: 1px;
|
||||||
border-right-color: $gray-300;
|
border-right-color: $gray-300;
|
||||||
border-right-style: solid;
|
border-right-style: solid;
|
||||||
box-shadow: -1px 5px 10px $gray-300;
|
box-shadow: -1px 5px 10px $gray-300;
|
||||||
}
|
}
|
||||||
&.row-total {
|
&.row-total {
|
||||||
padding: 0.75rem;
|
padding: 0.5rem 0.75rem;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
position: sticky;
|
position: sticky;
|
||||||
right: 0;
|
right: 0;
|
||||||
|
@ -56,17 +65,18 @@ $x2many_2d_matrix_max_height: 450px;
|
||||||
}
|
}
|
||||||
|
|
||||||
> tfoot > tr > th {
|
> tfoot > tr > th {
|
||||||
padding: 0.75rem;
|
text-align: right;
|
||||||
text-align: left;
|
|
||||||
background-color: $o-list-footer-bg-color;
|
background-color: $o-list-footer-bg-color;
|
||||||
position: sticky;
|
position: sticky;
|
||||||
bottom: 0;
|
bottom: 0;
|
||||||
|
|
||||||
&.col-total {
|
&.col-total {
|
||||||
|
padding: 0.75rem;
|
||||||
right: 0;
|
right: 0;
|
||||||
border-left-width: 1px;
|
border-left-width: 1px;
|
||||||
border-left-color: $gray-300;
|
border-left-color: $gray-300;
|
||||||
border-left-style: solid;
|
border-left-style: solid;
|
||||||
|
background-color: white;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,14 +1,12 @@
|
||||||
<?xml version="1.0" encoding="UTF-8" ?>
|
<?xml version="1.0" encoding="UTF-8" ?>
|
||||||
<templates>
|
<templates>
|
||||||
<t t-name="web_widget_x2many_2d_matrix.X2Many2DMatrixField" owl="1">
|
<t t-name="web_widget_x2many_2d_matrix.X2Many2DMatrixField">
|
||||||
<div class="table-responsive">
|
<div class="table-responsive">
|
||||||
<X2Many2DMatrixRenderer
|
<X2Many2DMatrixRenderer
|
||||||
list="list"
|
list="list"
|
||||||
matrixFields="props.matrixFields"
|
matrixFields="props.matrixFields"
|
||||||
showRowTotals="props.showRowTotals"
|
showRowTotals="props.showRowTotals"
|
||||||
showColumnTotals="props.showColumnTotals"
|
showColumnTotals="props.showColumnTotals"
|
||||||
setDirty="(isDirty) => this.setDirty(isDirty)"
|
|
||||||
onUpdate="(x, y, value) => this.commitChange(x, y, value)"
|
|
||||||
readonly="props.readonly"
|
readonly="props.readonly"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
|
|
||||||
import {Component, onWillUpdateProps} from "@odoo/owl";
|
import {Component, onWillUpdateProps} from "@odoo/owl";
|
||||||
import {registry} from "@web/core/registry";
|
import {registry} from "@web/core/registry";
|
||||||
|
const fieldRegistry = registry.category("fields");
|
||||||
|
|
||||||
export class X2Many2DMatrixRenderer extends Component {
|
export class X2Many2DMatrixRenderer extends Component {
|
||||||
setup() {
|
setup() {
|
||||||
|
@ -9,6 +10,7 @@ export class X2Many2DMatrixRenderer extends Component {
|
||||||
this.columns = this._getColumns();
|
this.columns = this._getColumns();
|
||||||
this.rows = this._getRows();
|
this.rows = this._getRows();
|
||||||
this.matrix = this._getMatrix();
|
this.matrix = this._getMatrix();
|
||||||
|
this.ValueFieldType = this._getValueFieldType();
|
||||||
|
|
||||||
onWillUpdateProps((newProps) => {
|
onWillUpdateProps((newProps) => {
|
||||||
this.columns = this._getColumns(newProps.list.records);
|
this.columns = this._getColumns(newProps.list.records);
|
||||||
|
@ -90,30 +92,48 @@ export class X2Many2DMatrixRenderer extends Component {
|
||||||
}
|
}
|
||||||
|
|
||||||
_getValueFieldComponent() {
|
_getValueFieldComponent() {
|
||||||
const field = this.list.activeFields[this.matrixFields.value];
|
const field = this.list.fields[this.matrixFields.value];
|
||||||
if (!field.widget) {
|
if (!field.widget) {
|
||||||
return this.list.activeFields[this.matrixFields.value].FieldComponent;
|
return fieldRegistry.get(field.type).component;
|
||||||
}
|
}
|
||||||
return registry.category("fields").get(field.widget);
|
return fieldRegistry.get(field.widget).component;
|
||||||
|
}
|
||||||
|
|
||||||
|
_getValueFieldType() {
|
||||||
|
const field = this.list.fields[this.matrixFields.value];
|
||||||
|
return field.type;
|
||||||
}
|
}
|
||||||
|
|
||||||
_aggregateRow(row) {
|
_aggregateRow(row) {
|
||||||
const y = this.rows.findIndex((r) => r.value === row);
|
const y = this.rows.findIndex((r) => r.value === row);
|
||||||
return this.matrix[y].map((r) => r.value).reduce((aggr, x) => aggr + x);
|
const total = this.matrix[y].map((r) => r.value).reduce((aggr, x) => aggr + x);
|
||||||
|
if (this.ValueFieldType === "integer") {
|
||||||
|
return total;
|
||||||
|
}
|
||||||
|
return Number(total).toFixed(2);
|
||||||
}
|
}
|
||||||
|
|
||||||
_aggregateColumn(column) {
|
_aggregateColumn(column) {
|
||||||
const x = this.columns.findIndex((c) => c.value === column);
|
const x = this.columns.findIndex((c) => c.value === column);
|
||||||
return this.matrix
|
|
||||||
|
const total = this.matrix
|
||||||
.map((r) => r[x])
|
.map((r) => r[x])
|
||||||
.map((r) => r.value)
|
.map((r) => r.value)
|
||||||
.reduce((aggr, y) => aggr + y);
|
.reduce((aggr, y) => aggr + y);
|
||||||
|
if (this.ValueFieldType === "integer") {
|
||||||
|
return total;
|
||||||
|
}
|
||||||
|
return Number(total).toFixed(2);
|
||||||
}
|
}
|
||||||
|
|
||||||
_aggregateAll() {
|
_aggregateAll() {
|
||||||
return this.matrix
|
const total = this.matrix
|
||||||
.map((r) => r.map((x) => x.value).reduce((aggr, x) => aggr + x))
|
.map((r) => r.map((x) => x.value).reduce((aggr, x) => aggr + x))
|
||||||
.reduce((aggr, y) => aggr + y);
|
.reduce((aggr, y) => aggr + y);
|
||||||
|
if (this.ValueFieldType === "integer") {
|
||||||
|
return total;
|
||||||
|
}
|
||||||
|
return Number(total).toFixed(2);
|
||||||
}
|
}
|
||||||
|
|
||||||
_canAggregate() {
|
_canAggregate() {
|
||||||
|
@ -122,18 +142,9 @@ export class X2Many2DMatrixRenderer extends Component {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
update(x, y, value) {
|
|
||||||
this.matrix[y][x].value = value;
|
|
||||||
const xFieldValue = this.columns[x].value;
|
|
||||||
const yFieldValue = this.rows[y].value;
|
|
||||||
|
|
||||||
this.props.onUpdate(xFieldValue, yFieldValue, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
getValueFieldProps(column, row) {
|
getValueFieldProps(column, row) {
|
||||||
const x = this.columns.findIndex((c) => c.value === column);
|
const x = this.columns.findIndex((c) => c.value === column);
|
||||||
const y = this.rows.findIndex((r) => r.value === row);
|
const y = this.rows.findIndex((r) => r.value === row);
|
||||||
const {props, propsFromAttrs} = this.list.activeFields[this.matrixFields.value];
|
|
||||||
let record = null;
|
let record = null;
|
||||||
let value = null;
|
let value = null;
|
||||||
if (
|
if (
|
||||||
|
@ -144,18 +155,9 @@ export class X2Many2DMatrixRenderer extends Component {
|
||||||
record = this.matrix[y][x].records[0];
|
record = this.matrix[y][x].records[0];
|
||||||
value = this.matrix[y][x].value;
|
value = this.matrix[y][x].value;
|
||||||
}
|
}
|
||||||
if (this.list.fields[this.matrixFields.value].type === "boolean") {
|
value = record ? record.data[this.matrixFields.value] : value;
|
||||||
record.bypass_readonly = true;
|
this.matrix[y][x].value = value;
|
||||||
}
|
|
||||||
value =
|
|
||||||
!this._canAggregate() && record
|
|
||||||
? record.data[this.matrixFields.value]
|
|
||||||
: value;
|
|
||||||
const result = {
|
const result = {
|
||||||
...props,
|
|
||||||
...propsFromAttrs,
|
|
||||||
value: value,
|
|
||||||
update: (val) => this.update(x, y, val),
|
|
||||||
readonly: this.props.readonly,
|
readonly: this.props.readonly,
|
||||||
record: record,
|
record: record,
|
||||||
name: this.matrixFields.value,
|
name: this.matrixFields.value,
|
||||||
|
@ -169,11 +171,9 @@ export class X2Many2DMatrixRenderer extends Component {
|
||||||
|
|
||||||
X2Many2DMatrixRenderer.template = "web_widget_x2many_2d_matrix.X2Many2DMatrixRenderer";
|
X2Many2DMatrixRenderer.template = "web_widget_x2many_2d_matrix.X2Many2DMatrixRenderer";
|
||||||
X2Many2DMatrixRenderer.props = {
|
X2Many2DMatrixRenderer.props = {
|
||||||
list: Object,
|
list: {type: Object, optional: true},
|
||||||
matrixFields: Object,
|
matrixFields: {type: Object, optional: true},
|
||||||
setDirty: Function,
|
readonly: {type: Boolean, optional: true},
|
||||||
onUpdate: Function,
|
showRowTotals: {type: Boolean, optional: true},
|
||||||
readonly: Boolean,
|
showColumnTotals: {type: Boolean, optional: true},
|
||||||
showRowTotals: Boolean,
|
|
||||||
showColumnTotals: Boolean,
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<?xml version="1.0" encoding="UTF-8" ?>
|
<?xml version="1.0" encoding="UTF-8" ?>
|
||||||
<templates>
|
<templates>
|
||||||
<t t-name="web_widget_x2many_2d_matrix.X2Many2DMatrixRenderer" owl="1">
|
<t t-name="web_widget_x2many_2d_matrix.X2Many2DMatrixRenderer">
|
||||||
<table
|
<table
|
||||||
class="o_list_table table table-responsive table-sm table-hover position-relative mb-0 o_list_table_ungrouped table-striped"
|
class="o_list_table table table-responsive table-sm table-hover position-relative mb-0 o_list_table_ungrouped table-striped"
|
||||||
t-if="rows.length > 0"
|
t-if="rows.length > 0"
|
||||||
|
@ -28,17 +28,14 @@
|
||||||
<t
|
<t
|
||||||
t-component="ValueFieldComponent"
|
t-component="ValueFieldComponent"
|
||||||
t-props="getValueFieldProps(column.value, row.value)"
|
t-props="getValueFieldProps(column.value, row.value)"
|
||||||
|
record="getValueFieldProps(column.value, row.value).record"
|
||||||
/>
|
/>
|
||||||
</td>
|
</td>
|
||||||
<td
|
<td
|
||||||
t-if="props.showRowTotals and _canAggregate()"
|
t-if="props.showRowTotals and _canAggregate()"
|
||||||
class="row-total"
|
class="row-total"
|
||||||
>
|
>
|
||||||
<t
|
<span t-esc="_aggregateRow(row.value)" />
|
||||||
t-component="ValueFieldComponent"
|
|
||||||
readonly="true"
|
|
||||||
value="_aggregateRow(row.value)"
|
|
||||||
/>
|
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
|
@ -46,18 +43,10 @@
|
||||||
<tr t-if="props.showColumnTotals and _canAggregate()">
|
<tr t-if="props.showColumnTotals and _canAggregate()">
|
||||||
<th />
|
<th />
|
||||||
<th t-foreach="columns" t-as="column" t-key="column.value">
|
<th t-foreach="columns" t-as="column" t-key="column.value">
|
||||||
<t
|
<span t-esc="_aggregateColumn(column.value)" />
|
||||||
t-component="ValueFieldComponent"
|
|
||||||
readonly="true"
|
|
||||||
value="_aggregateColumn(column.value)"
|
|
||||||
/>
|
|
||||||
</th>
|
</th>
|
||||||
<th t-if="props.showRowTotals" class="col-total">
|
<th t-if="props.showRowTotals" class="col-total">
|
||||||
<t
|
<span t-esc="_aggregateAll()" />
|
||||||
t-component="ValueFieldComponent"
|
|
||||||
readonly="true"
|
|
||||||
value="_aggregateAll()"
|
|
||||||
/>
|
|
||||||
</th>
|
</th>
|
||||||
</tr>
|
</tr>
|
||||||
</tfoot>
|
</tfoot>
|
||||||
|
|
|
@ -1,13 +0,0 @@
|
||||||
/** @odoo-module **/
|
|
||||||
|
|
||||||
import {BooleanField} from "@web/views/fields/boolean/boolean_field";
|
|
||||||
import {patch} from "@web/core/utils/patch";
|
|
||||||
|
|
||||||
patch(BooleanField.prototype, "web_widget_x2many_2d_matrix", {
|
|
||||||
get isReadonly() {
|
|
||||||
if (this.props.record.bypass_readonly) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return this._super(...arguments);
|
|
||||||
},
|
|
||||||
});
|
|
Loading…
Reference in New Issue