diff --git a/custom-addons/spreadsheet_dashboard_script/models/spreadsheet_dashboard.py b/custom-addons/spreadsheet_dashboard_script/models/spreadsheet_dashboard.py index 812cca7..368de3d 100644 --- a/custom-addons/spreadsheet_dashboard_script/models/spreadsheet_dashboard.py +++ b/custom-addons/spreadsheet_dashboard_script/models/spreadsheet_dashboard.py @@ -22,9 +22,23 @@ def get_dashboard_files(self): dashboard_modules = modules.filtered(lambda m: 'spreadsheet_dashboard' in m.dependencies_id.mapped('name')) for module in dashboard_modules: for path in self._get_data_filepaths(module.name): - for dashboard_file in self._parse_xml(path): - with file_open(dashboard_file, mode='r') as f: - result[dashboard_file] = json.load(f) + for files in self._parse_xml(path): + for dashboard_file in [files["data"], files["sample"]]: + with file_open(dashboard_file, mode='r') as f: + result[dashboard_file] = json.load(f) + return result + + @api.model + def get_dashboard_files_for_sample(self): + result = {} + modules = self.env['ir.module.module'].search([]) + dashboard_modules = modules.filtered(lambda m: 'spreadsheet_dashboard' in m.dependencies_id.mapped('name')) + for module in dashboard_modules: + for path in self._get_data_filepaths(module.name): + files = self._parse_xml(path) + for r in files: + with file_open(r["data"], mode='r') as f: + result[r["sample"]] = json.load(f) return result @api.model @@ -47,10 +61,18 @@ def _parse_xml(self, filepath): tree = etree.fromstring('') files = [] for node in tree.xpath("//record[@model='spreadsheet.dashboard']"): + data, sample = None, None for field_node in node.iterchildren(): field_name = field_node.get('name') if field_name == 'spreadsheet_binary_data': - files.append(field_node.get('file')) + data = field_node.get('file') elif field_name == 'sample_dashboard_file_path': - files.append(field_node.text) + sample = field_node.text + if data and sample: + files.append({ + "data": data, + "sample": sample, + }) + else: + raise ValueError(f"Invalid record in {filepath}: missing 'spreadsheet_binary_data' or 'sample_dashboard_file_path'") return files diff --git a/custom-addons/spreadsheet_dashboard_script/static/src/menu_items.js b/custom-addons/spreadsheet_dashboard_script/static/src/menu_items.js index 3ab353f..6093d2e 100644 --- a/custom-addons/spreadsheet_dashboard_script/static/src/menu_items.js +++ b/custom-addons/spreadsheet_dashboard_script/static/src/menu_items.js @@ -2,6 +2,10 @@ import { registries } from "@odoo/o-spreadsheet"; import * as scripts from "./scripts/index"; +import { + createSpreadsheetModel, + freezeOdooData, +} from "@spreadsheet/helpers/model"; const { topbarMenuRegistry } = registries; topbarMenuRegistry.addChild("dashboard-scripts", ["file"], { @@ -26,3 +30,33 @@ for (const script of Object.values(scripts)) { }) } + +/** + * To use the following menu item, you need to have all spreadsheet_dashboard_* + * modules installed and the demo data loaded. + * + * You can find (at the time of this commit) the command line to load all the + * spreadsheet_dashboard_* modules in runbot, in the build "fast testing" + */ +topbarMenuRegistry.addChild("create_sample", ["file", "dashboard-scripts"], { + name: "Create sample dashboards", + async execute(env) { + const result = {}; + const dashboards = await env.services.orm.call( + "spreadsheet.dashboard", + "get_dashboard_files_for_sample", + ); + for (const [file, data] of Object.entries(dashboards)) { + const model = createSpreadsheetModel({ env, data }); + const dataFrozen = await freezeOdooData(model); + dataFrozen.sheets = dataFrozen.sheets.slice(0, -1); // remove last sheet (global filters) + dataFrozen.globalFilters = []; + result[file] = dataFrozen; + } + await env.services.orm.call( + "spreadsheet.dashboard", + "write_dashboard_files", + [result] + ); + }, +});