144 lines
5.1 KiB
JavaScript
144 lines
5.1 KiB
JavaScript
import { rpcBus } from "@web/core/network/rpc";
|
|
import { registry } from "@web/core/registry";
|
|
import { UPDATE_METHODS } from "@web/core/orm_service";
|
|
|
|
/**
|
|
* @typedef {Object} IrFilter
|
|
* @property {[number, string] | false} user_id
|
|
* @property {string} sort
|
|
* @property {string} context
|
|
* @property {string} name
|
|
* @property {string} domain
|
|
* @property {number} id
|
|
* @property {boolean} is_default
|
|
* @property {string} model_id
|
|
* @property {[number, string] | false} action_id
|
|
* @property {number | false} embedded_action_id
|
|
* @property {number | false} embedded_parent_res_id
|
|
*/
|
|
|
|
/**
|
|
* @typedef {Object} ViewDescription
|
|
* @property {string} arch
|
|
* @property {number|false} id
|
|
* @property {number|null} [custom_view_id]
|
|
* @property {Object} [actionMenus] // for views other than search
|
|
* @property {IrFilter[]} [irFilters] // for search view
|
|
*/
|
|
|
|
/**
|
|
* @typedef {Object} LoadViewsParams
|
|
* @property {string} resModel
|
|
* @property {[number, string][]} views
|
|
* @property {Object} context
|
|
*/
|
|
|
|
/**
|
|
* @typedef {Object} LoadViewsOptions
|
|
* @property {number|false} actionId
|
|
* @property {boolean} loadActionMenus
|
|
* @property {boolean} loadIrFilters
|
|
*/
|
|
|
|
export const viewService = {
|
|
dependencies: ["orm"],
|
|
start(env, { orm }) {
|
|
let cache = {};
|
|
|
|
function clearCache() {
|
|
cache = {};
|
|
const processedArchs = registry.category("__processed_archs__");
|
|
processedArchs.content = {};
|
|
processedArchs.trigger("UPDATE");
|
|
}
|
|
|
|
env.bus.addEventListener("CLEAR-CACHES", clearCache);
|
|
rpcBus.addEventListener("RPC:RESPONSE", (ev) => {
|
|
const { model, method } = ev.detail.data.params;
|
|
if (["ir.ui.view", "ir.filters"].includes(model)) {
|
|
if (UPDATE_METHODS.includes(method)) {
|
|
clearCache();
|
|
}
|
|
}
|
|
});
|
|
|
|
/**
|
|
* Loads various information concerning views: fields_view for each view,
|
|
* fields of the corresponding model, and optionally the filters.
|
|
*
|
|
* @param {LoadViewsParams} params
|
|
* @param {LoadViewsOptions} [options={}]
|
|
* @returns {Promise<ViewDescriptions>}
|
|
*/
|
|
async function loadViews(params, options = {}) {
|
|
const { context, resModel, views } = params;
|
|
const loadViewsOptions = {
|
|
action_id: options.actionId || false,
|
|
embedded_action_id: options.embeddedActionId || false,
|
|
embedded_parent_res_id: options.embeddedParentResId || false,
|
|
load_filters: options.loadIrFilters || false,
|
|
toolbar: (!context?.disable_toolbar && options.loadActionMenus) || false,
|
|
};
|
|
for (const key in options) {
|
|
if (
|
|
![
|
|
"actionId",
|
|
"embeddedActionId",
|
|
"embeddedParentResId",
|
|
"loadIrFilters",
|
|
"loadActionMenus",
|
|
].includes(key)
|
|
) {
|
|
loadViewsOptions[key] = options[key];
|
|
}
|
|
}
|
|
if (env.isSmall) {
|
|
loadViewsOptions.mobile = true;
|
|
}
|
|
const filteredContext = Object.fromEntries(
|
|
Object.entries(context || {}).filter(
|
|
([k, v]) => k == "lang" || k.endsWith("_view_ref")
|
|
)
|
|
);
|
|
|
|
const key = JSON.stringify([resModel, views, filteredContext, loadViewsOptions]);
|
|
if (!cache[key]) {
|
|
cache[key] = orm
|
|
.call(resModel, "get_views", [], {
|
|
context: filteredContext,
|
|
views,
|
|
options: loadViewsOptions,
|
|
})
|
|
.then((result) => {
|
|
const { models, views } = result;
|
|
const viewDescriptions = {
|
|
fields: models[resModel].fields,
|
|
relatedModels: models,
|
|
views: {},
|
|
};
|
|
for (const viewType in views) {
|
|
const { arch, toolbar, id, filters, custom_view_id } = views[viewType];
|
|
const viewDescription = { arch, id, custom_view_id };
|
|
if (toolbar) {
|
|
viewDescription.actionMenus = toolbar;
|
|
}
|
|
if (filters) {
|
|
viewDescription.irFilters = filters;
|
|
}
|
|
viewDescriptions.views[viewType] = viewDescription;
|
|
}
|
|
return viewDescriptions;
|
|
})
|
|
.catch((error) => {
|
|
delete cache[key];
|
|
return Promise.reject(error);
|
|
});
|
|
}
|
|
return cache[key];
|
|
}
|
|
return { loadViews };
|
|
},
|
|
};
|
|
|
|
registry.category("services").add("view", viewService);
|