Skip to content

Commit 69ae03c

Browse files
[MIG] spreadsheet_oca: Migration to 18.0
1 parent 06cecb1 commit 69ae03c

30 files changed

+661
-499
lines changed

spreadsheet_oca/README.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ Spreadsheet Oca
77
!! This file is generated by oca-gen-addon-readme !!
88
!! changes will be overwritten. !!
99
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
10-
!! source digest: sha256:2e54effb5771467ddab39e872bcddddc5e7a900f7afb88dd3bb87ac26d195ca5
10+
!! source digest: sha256:a7edc105b2730d126fc787ef8ef2c8c1d293b8e18e94402ff7db7d044ee863cd
1111
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
1212
1313
.. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png

spreadsheet_oca/__manifest__.py

Lines changed: 9 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
"name": "Spreadsheet Oca",
66
"summary": """
77
Allow to edit spreadsheets""",
8-
"version": "17.0.1.0.3",
8+
"version": "18.0.1.0.0",
99
"license": "AGPL-3",
1010
"author": "CreuBlanca,Odoo Community Association (OCA)",
1111
"website": "https://github.com/OCA/spreadsheet",
@@ -25,28 +25,19 @@
2525
"spreadsheet_oca/static/src/spreadsheet_tree/spreadsheet_tree_view.xml",
2626
"spreadsheet_oca/static/src/spreadsheet/spreadsheet.scss",
2727
"spreadsheet_oca/static/src/spreadsheet/spreadsheet_action.esm.js",
28-
"spreadsheet_oca/static/src/spreadsheet/pivot_controller.esm.js",
29-
"spreadsheet_oca/static/src/spreadsheet/graph_controller.esm.js",
3028
"spreadsheet_oca/static/src/spreadsheet/list_controller.esm.js",
3129
"spreadsheet_oca/static/src/spreadsheet/list_renderer.esm.js",
32-
(
33-
"after",
34-
"web/static/src/views/graph/graph_controller.xml",
35-
"spreadsheet_oca/static/src/spreadsheet/graph_controller.xml",
36-
),
37-
(
38-
"after",
39-
"web/static/src/views/list/list_controller.xml",
40-
"spreadsheet_oca/static/src/spreadsheet/list_controller.xml",
41-
),
42-
(
43-
"after",
44-
"web/static/src/views/pivot/pivot_controller.xml",
45-
"spreadsheet_oca/static/src/spreadsheet/pivot_controller.xml",
46-
),
30+
"spreadsheet_oca/static/src/spreadsheet/list_controller.xml",
31+
],
32+
"web.assets_backend_lazy": [
33+
"spreadsheet_oca/static/src/spreadsheet/pivot_controller.esm.js",
34+
"spreadsheet_oca/static/src/spreadsheet/graph_controller.esm.js",
35+
"spreadsheet_oca/static/src/spreadsheet/pivot_controller.xml",
36+
"spreadsheet_oca/static/src/spreadsheet/graph_controller.xml",
4737
],
4838
"spreadsheet.o_spreadsheet": [
4939
"spreadsheet_oca/static/src/spreadsheet/bundle/spreadsheet.xml",
40+
"spreadsheet_oca/static/src/spreadsheet/bundle/image_file_store.esm.js",
5041
"spreadsheet_oca/static/src/spreadsheet/bundle/filter.esm.js",
5142
"spreadsheet_oca/static/src/spreadsheet/bundle/filter_panel_datasources.esm.js",
5243
"spreadsheet_oca/static/src/spreadsheet/bundle/spreadsheet_renderer.esm.js",

spreadsheet_oca/migrations/17.0.1.0.0/pre-migrate.py

Lines changed: 0 additions & 17 deletions
This file was deleted.

spreadsheet_oca/models/ir_websocket.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,9 +58,9 @@ def _build_bus_channel_list(self, channels):
5858
channels.append(
5959
(
6060
self.env.registry.db_name,
61-
"spreadsheet_oca",
6261
model_name,
6362
res_id,
63+
"spreadsheet_oca",
6464
)
6565
)
6666
return super()._build_bus_channel_list(channels)

spreadsheet_oca/models/spreadsheet_abstract.py

Lines changed: 42 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,18 @@
33

44
import base64
55
import json
6+
from typing import Any
67

78
from odoo import _, api, fields, models
89
from odoo.exceptions import AccessError
910

11+
CollaborationMessage = dict[str, Any]
12+
1013

1114
class SpreadsheetAbstract(models.AbstractModel):
1215
_name = "spreadsheet.abstract"
1316
_description = "Spreadsheet abstract for inheritance"
17+
_inherit = ["bus.listener.mixin"]
1418

1519
name = fields.Char(required=True)
1620
spreadsheet_binary_data = fields.Binary(
@@ -76,8 +80,7 @@ def get_spreadsheet_data(self):
7680
self.ensure_one()
7781
mode = "normal"
7882
try:
79-
self.check_access_rights("write")
80-
self.check_access_rule("write")
83+
self.check_access("write")
8184
except AccessError:
8285
mode = "readonly"
8386
return {
@@ -106,11 +109,31 @@ def open_spreadsheet(self):
106109
"params": {"spreadsheet_id": self.id, "model": self._name},
107110
}
108111

109-
def send_spreadsheet_message(self, message):
112+
def send_spreadsheet_message(
113+
self, message: CollaborationMessage, access_token=None
114+
):
110115
self.ensure_one()
111-
channel = (self.env.cr.dbname, "spreadsheet_oca", self._name, self.id)
112-
message.update({"res_model": self._name, "res_id": self.id})
113116
if message["type"] in ["REVISION_UNDONE", "REMOTE_REVISION", "REVISION_REDONE"]:
117+
self._check_access_spreadsheet("write")
118+
self.env["spreadsheet.oca.revision"].create(
119+
{
120+
"model": self._name,
121+
"res_id": self.id,
122+
"type": message["type"],
123+
"client_id": message.get("clientId"),
124+
"next_revision_id": message["nextRevisionId"],
125+
"server_revision_id": message["serverRevisionId"],
126+
"commands": json.dumps(
127+
self._build_spreadsheet_revision_commands_data(message)
128+
),
129+
}
130+
)
131+
self._bus_send(
132+
"notification", dict(message, id=self.id), subchannel="spreadsheet_oca"
133+
)
134+
return True
135+
elif message["type"] == "SNAPSHOT":
136+
self._check_access_spreadsheet("write")
114137
self.env["spreadsheet.oca.revision"].create(
115138
{
116139
"model": self._name,
@@ -124,7 +147,20 @@ def send_spreadsheet_message(self, message):
124147
),
125148
}
126149
)
127-
self.env["bus.bus"]._sendone(channel, "spreadsheet_oca", message)
150+
return True
151+
elif message["type"] in ["CLIENT_JOINED", "CLIENT_LEFT", "CLIENT_MOVED"]:
152+
self._check_access_spreadsheet("read")
153+
self._bus_send(
154+
"notification", dict(message, id=self.id), subchannel="spreadsheet_oca"
155+
)
156+
return True
157+
return False
158+
159+
def _check_access_spreadsheet(self, operation: str):
160+
try:
161+
self.check_access(operation)
162+
except AccessError as e:
163+
raise e
128164
return True
129165

130166
@api.model

spreadsheet_oca/static/description/index.html

Lines changed: 37 additions & 43 deletions
Large diffs are not rendered by default.

spreadsheet_oca/static/src/pivot/pivot_table.esm.js

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
1-
/** @odoo-module */
21
/* Copyright 2024 Tecnativa - Carlos Roca
32
* License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl). */
4-
import {SpreadsheetPivotTable} from "@spreadsheet/pivot/pivot_table";
3+
import {SpreadsheetPivotTable} from "@odoo/o-spreadsheet";
54
import {patch} from "@web/core/utils/patch";
65

76
patch(SpreadsheetPivotTable.prototype, {

spreadsheet_oca/static/src/spreadsheet/bundle/chart_panel.esm.js

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
/** @odoo-module */
2-
31
import * as spreadsheet from "@odoo/o-spreadsheet";
42
import {patch} from "@web/core/utils/patch";
53

spreadsheet_oca/static/src/spreadsheet/bundle/chart_panels.esm.js

Lines changed: 23 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,17 @@
1-
/** @odoo-module */
2-
31
import * as spreadsheet from "@odoo/o-spreadsheet";
42
import {Domain} from "@web/core/domain";
5-
63
import {Many2XAutocomplete} from "@web/views/fields/relational_utils";
4+
import {_t} from "@web/core/l10n/translation";
75
import {patch} from "@web/core/utils/patch";
86
import {useService} from "@web/core/utils/hooks";
9-
import {_t} from "@web/core/l10n/translation";
107

11-
const {LineBarPieConfigPanel, ScorecardChartConfigPanel, GaugeChartConfigPanel} =
12-
spreadsheet.components;
8+
const {
9+
GenericChartConfigPanel,
10+
LineConfigPanel,
11+
BarConfigPanel,
12+
ScorecardChartConfigPanel,
13+
GaugeChartConfigPanel,
14+
} = spreadsheet.components;
1315

1416
const menuChartProps = {
1517
setup() {
@@ -55,7 +57,6 @@ const menuChartProps = {
5557
return;
5658
}
5759
const menu = this.env.model.getters.getIrMenu(menuId[0].id);
58-
console.log(menu);
5960
this.env.model.dispatch("LINK_ODOO_MENU_TO_CHART", {
6061
chartId: this.props.figureId,
6162
odooMenuId: menu.xmlid || menu.id,
@@ -77,9 +78,21 @@ const menuChartProps = {
7778
},
7879
};
7980

80-
patch(LineBarPieConfigPanel.prototype, menuChartProps);
81-
LineBarPieConfigPanel.components = {
82-
...LineBarPieConfigPanel.components,
81+
patch(GenericChartConfigPanel.prototype, menuChartProps);
82+
GenericChartConfigPanel.components = {
83+
...GenericChartConfigPanel.components,
84+
Many2XAutocomplete,
85+
};
86+
87+
patch(LineConfigPanel.prototype, menuChartProps);
88+
LineConfigPanel.components = {
89+
...LineConfigPanel.components,
90+
Many2XAutocomplete,
91+
};
92+
93+
patch(BarConfigPanel.prototype, menuChartProps);
94+
BarConfigPanel.components = {
95+
...BarConfigPanel.components,
8396
Many2XAutocomplete,
8497
};
8598

spreadsheet_oca/static/src/spreadsheet/bundle/filter.esm.js

Lines changed: 56 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
1-
/** @odoo-module **/
2-
31
import * as spreadsheet from "@odoo/o-spreadsheet";
42
import {Component, onWillStart, useState} from "@odoo/owl";
5-
import {_lt, _t} from "@web/core/l10n/translation";
3+
64
import {FilterValue} from "@spreadsheet/global_filters/components/filter_value/filter_value";
75
import {ModelFieldSelector} from "@web/core/model_field_selector/model_field_selector";
86
import {ModelSelector} from "@web/core/model_selector/model_selector";
97
import {RELATIVE_DATE_RANGE_TYPES} from "@spreadsheet/helpers/constants";
8+
9+
import {_t} from "@web/core/l10n/translation";
1010
import {globalFiltersFieldMatchers} from "@spreadsheet/global_filters/plugins/global_filters_core_plugin";
1111
import {useService} from "@web/core/utils/hooks";
1212

@@ -123,10 +123,10 @@ export class EditFilterPanel extends Component {
123123
get dateOffset() {
124124
return [
125125
{value: 0, name: ""},
126-
{value: -1, name: _lt("Previous")},
127-
{value: -2, name: _lt("Before Previous")},
128-
{value: 1, name: _lt("Next")},
129-
{value: 2, name: _lt("After next")},
126+
{value: -1, name: _t("Previous")},
127+
{value: -2, name: _t("Before Previous")},
128+
{value: 1, name: _t("Next")},
129+
{value: 2, name: _t("After next")},
130130
];
131131
}
132132
onChangeFieldMatchOffset(object, ev) {
@@ -144,26 +144,25 @@ export class EditFilterPanel extends Component {
144144
const action = this.props.filter.id
145145
? "EDIT_GLOBAL_FILTER"
146146
: "ADD_GLOBAL_FILTER";
147-
this.env.openSidePanel("FilterPanel", {});
148-
var filter = {
147+
148+
const filter = {
149149
id: this.props.filter.id || uuidGenerator.uuidv4(),
150150
type: this.state.type,
151151
label: this.state.label,
152152
defaultValue: this.state.defaultValue,
153153
rangeType: this.state.rangeType,
154154
modelName: this.state.modelName.technical,
155155
};
156-
var filterMatching = {};
156+
const filterMatching = {};
157157
Object.values(this.state.objects).forEach((object) => {
158158
filterMatching[object.type] = filterMatching[object.type] || {};
159-
filterMatching[object.type][object.objectId] = {...object.fieldMatch};
159+
const fieldMatch = object.fieldMatch ? {...object.fieldMatch} : {};
160+
filterMatching[object.type][object.objectId] = fieldMatch;
160161
});
161162
this.env.model.dispatch(action, {
162-
id: filter.id,
163163
filter,
164164
...filterMatching,
165165
});
166-
167166
this.env.openSidePanel("FilterPanel", {});
168167
}
169168
onCancel() {
@@ -177,13 +176,54 @@ export class EditFilterPanel extends Component {
177176
}
178177
this.env.openSidePanel("FilterPanel", {});
179178
}
180-
onFieldMatchUpdate(object, name) {
181-
this.state.objects[object.id].fieldMatch.chain = name;
182-
this.state.objects[object.id].fieldMatch.type = object.fields[name]?.type;
179+
onFieldMatchUpdate(object, path, fieldInfo) {
180+
if (!path) {
181+
// Clear the field match if no path selected
182+
this.state.objects[object.id].fieldMatch = {};
183+
return;
184+
}
185+
// Extract field definition from fieldInfo (V18> structure)
186+
const fieldDef =
187+
fieldInfo && fieldInfo.fieldDef ? fieldInfo.fieldDef : fieldInfo;
188+
this.state.objects[object.id].fieldMatch = {
189+
chain: path,
190+
type: fieldDef?.type || "",
191+
};
183192
}
184193
toggleDateDefaultValue(ev) {
185194
this.state.defaultValue = ev.target.checked ? "this_month" : undefined;
186195
}
196+
getModelField(fieldMatch) {
197+
if (!fieldMatch || !fieldMatch.chain) {
198+
return "";
199+
}
200+
return fieldMatch.chain;
201+
}
202+
filterModelFieldSelectorField(field, path, coModel) {
203+
if (!field.searchable) {
204+
return false;
205+
}
206+
207+
// TODO: Define allowed field types based on filter type
208+
const ALLOWED_FIELD_TYPES = [
209+
"char",
210+
"text",
211+
"selection",
212+
"many2one",
213+
"date",
214+
"datetime",
215+
];
216+
217+
if (field.name === "id" && this.state.type === "relation") {
218+
const paths = path.split(".");
219+
const lastField = paths.at(-2);
220+
if (!lastField || (lastField.relation && lastField.relation === coModel)) {
221+
return true;
222+
}
223+
return false;
224+
}
225+
return ALLOWED_FIELD_TYPES.includes(field.type) || Boolean(field.relation);
226+
}
187227
}
188228

189229
EditFilterPanel.template = "spreadsheet_oca.EditFilterPanel";

0 commit comments

Comments
 (0)