Skip to content

Commit ce23749

Browse files
committed
[IMP] web: field service: add loadFieldInfo and loadPathDescription
We remove the two hooks useLoadFieldInfo and useLoadPathDescription and add two corresponding functions loadFieldInfo and loadPathDescription in the field service. Part-of: odoo#216038 Related: odoo/enterprise#88759 Signed-off-by: Michaël Mattiello (mcm) <[email protected]>
1 parent f6d7f4f commit ce23749

File tree

5 files changed

+75
-68
lines changed

5 files changed

+75
-68
lines changed

addons/web/static/src/core/field_service.js

Lines changed: 64 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,13 @@ function getRelation(fieldDef, followRelationalProperties = false) {
1919

2020
export const fieldService = {
2121
dependencies: ["orm"],
22-
async: ["loadFields", "loadPath", "loadPropertyDefinitions"],
22+
async: [
23+
"loadFieldInfo",
24+
"loadFields",
25+
"loadPath",
26+
"loadPropertyDefinitions",
27+
"loadPathDescription",
28+
],
2329
start(env, { orm }) {
2430
/**
2531
* @param {string} resModel
@@ -154,7 +160,63 @@ export const fieldService = {
154160
return _loadPath(resModel, fieldDefs, path.split("."), followRelationalProperties);
155161
}
156162

157-
return { loadFields, loadPath, loadPropertyDefinitions };
163+
/**
164+
* @param {string} resModel
165+
* @param {string} path
166+
* @returns {Promise<Object>}
167+
*/
168+
async function loadFieldInfo(resModel, path) {
169+
if (typeof path !== "string" || !path || path === "*") {
170+
return { resModel, fieldDef: null };
171+
}
172+
const { isInvalid, names, modelsInfo } = await loadPath(resModel, path);
173+
if (isInvalid) {
174+
return { resModel, fieldDef: null };
175+
}
176+
const name = names.at(-1);
177+
const modelInfo = modelsInfo.at(-1);
178+
return { resModel: modelInfo.resModel, fieldDef: modelInfo.fieldDefs[name] };
179+
}
180+
181+
function makeString(value) {
182+
return String(value ?? "-");
183+
}
184+
185+
async function loadPathDescription(resModel, path, allowEmpty) {
186+
if ([0, 1].includes(path)) {
187+
return { isInvalid: false, displayNames: [makeString(path)] };
188+
}
189+
if (allowEmpty && !path) {
190+
return { isInvalid: false, displayNames: [] };
191+
}
192+
if (typeof path !== "string" || !path || path === "*") {
193+
return { isInvalid: true, displayNames: [makeString()] };
194+
}
195+
const { isInvalid, modelsInfo, names } = await loadPath(resModel, path);
196+
const result = { isInvalid: !!isInvalid, displayNames: [] };
197+
if (!isInvalid) {
198+
const lastName = names.at(-1);
199+
const lastFieldDef = modelsInfo.at(-1).fieldDefs[lastName];
200+
if (["properties", "properties_definition"].includes(lastFieldDef.type)) {
201+
// there is no known case where we want to select a 'properties' field directly
202+
result.isInvalid = true;
203+
}
204+
}
205+
for (let index = 0; index < names.length; index++) {
206+
const name = names[index];
207+
const fieldDef = modelsInfo[index]?.fieldDefs[name];
208+
result.displayNames.push(fieldDef?.string || makeString(name));
209+
}
210+
return result;
211+
}
212+
213+
return {
214+
loadFieldInfo,
215+
loadFields,
216+
loadPath,
217+
loadPathDescription,
218+
loadPropertyDefinitions,
219+
};
158220
},
159221
};
160222

addons/web/static/src/core/model_field_selector/model_field_selector.js

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
import { Component, onWillStart, onWillUpdateProps, useState } from "@odoo/owl";
2+
import { usePopover } from "@web/core/popover/popover_hook";
23
import { KeepLast } from "@web/core/utils/concurrency";
4+
import { useService } from "@web/core/utils/hooks";
35
import { ModelFieldSelectorPopover } from "./model_field_selector_popover";
4-
import { useLoadFieldInfo, useLoadPathDescription } from "./utils";
5-
import { usePopover } from "@web/core/popover/popover_hook";
66

77
export class ModelFieldSelector extends Component {
88
static template = "web._ModelFieldSelector";
@@ -33,13 +33,15 @@ export class ModelFieldSelector extends Component {
3333
};
3434

3535
setup() {
36-
this.loadPathDescription = useLoadPathDescription();
37-
const loadFieldInfo = useLoadFieldInfo();
36+
this.fieldService = useService("field");
3837
this.popover = usePopover(this.constructor.components.Popover, {
3938
popoverClass: "o_popover_field_selector",
4039
onClose: async () => {
4140
if (this.newPath !== null) {
42-
const fieldInfo = await loadFieldInfo(this.props.resModel, this.newPath);
41+
const fieldInfo = await this.fieldService.loadFieldInfo(
42+
this.props.resModel,
43+
this.newPath
44+
);
4345
this.props.update(this.newPath, fieldInfo);
4446
}
4547
},
@@ -76,7 +78,7 @@ export class ModelFieldSelector extends Component {
7678

7779
async updateState(params, isConcurrent) {
7880
const { resModel, path, allowEmpty } = params;
79-
let prom = this.loadPathDescription(resModel, path, allowEmpty);
81+
let prom = this.fieldService.loadPathDescription(resModel, path, allowEmpty);
8082
if (isConcurrent) {
8183
prom = this.keepLast.add(prom);
8284
}

addons/web/static/src/core/model_field_selector/utils.js

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

addons/web/static/src/core/tree_editor/tree_editor.js

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
import { Component, onWillStart, onWillUpdateProps } from "@odoo/owl";
22
import { Dropdown } from "@web/core/dropdown/dropdown";
33
import { DropdownItem } from "@web/core/dropdown/dropdown_item";
4-
import { useLoadFieldInfo } from "@web/core/model_field_selector/utils";
54
import { cloneTree, connector, isTree, TRUE_TREE } from "@web/core/tree_editor/condition_tree";
65
import {
76
getDefaultValue,
@@ -49,7 +48,6 @@ export class TreeEditor extends Component {
4948
this.isTree = isTree;
5049
this.fieldService = useService("field");
5150
this.nameService = useService("name");
52-
this.loadFieldInfo = useLoadFieldInfo(this.fieldService);
5351
this.makeGetFieldDef = useMakeGetFieldDef(this.fieldService);
5452
this.makeGetConditionDescription = useMakeGetConditionDescription(
5553
this.fieldService,
@@ -197,7 +195,7 @@ export class TreeEditor extends Component {
197195
}
198196

199197
async _updatePath(node, path) {
200-
const { fieldDef } = await this.loadFieldInfo(this.props.resModel, path);
198+
const { fieldDef } = await this.fieldService.loadFieldInfo(this.props.resModel, path);
201199
node.path = path;
202200
node.negate = false;
203201
node.operator = this.props.getDefaultOperator(fieldDef);

addons/web/static/src/core/tree_editor/utils.js

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ import {
55
formatDateTime,
66
} from "@web/core/l10n/dates";
77
import { _t } from "@web/core/l10n/translation";
8-
import { useLoadFieldInfo, useLoadPathDescription } from "@web/core/model_field_selector/utils";
98
import {
109
condition,
1110
Expression,
@@ -80,15 +79,14 @@ export function disambiguate(value, displayNames) {
8079

8180
export function useMakeGetFieldDef(fieldService) {
8281
fieldService ||= useService("field");
83-
const loadFieldInfo = useLoadFieldInfo(fieldService);
8482
return async (resModel, tree, additionalsPath = []) => {
8583
const pathsInTree = getPathsInTree(tree, true);
8684
const paths = new Set([...pathsInTree, ...additionalsPath]);
8785
const promises = [];
8886
const fieldDefs = {};
8987
for (const path of paths) {
9088
promises.push(
91-
loadFieldInfo(resModel, path).then(({ fieldDef }) => {
89+
fieldService.loadFieldInfo(resModel, path).then(({ fieldDef }) => {
9290
fieldDefs[path] = fieldDef;
9391
})
9492
);
@@ -105,14 +103,13 @@ export function useMakeGetFieldDef(fieldService) {
105103

106104
function useGetTreePathDescription(fieldService) {
107105
fieldService ||= useService("field");
108-
const loadPathDescription = useLoadPathDescription(fieldService);
109106
return async (resModel, tree) => {
110107
const paths = getPathsInTree(tree);
111108
const promises = [];
112109
const pathDescriptions = new Map();
113110
for (const path of paths) {
114111
promises.push(
115-
loadPathDescription(resModel, path).then(({ displayNames }) => {
112+
fieldService.loadPathDescription(resModel, path).then(({ displayNames }) => {
116113
pathDescriptions.set(path, displayNames.join(" \u2794 "));
117114
})
118115
);

0 commit comments

Comments
 (0)