Skip to content

[15.0][ADD] web_diagram_builder: build interactive dependency diagrams from any many2one field#3540

Open
mmaanneell wants to merge 23 commits into
OCA:15.0from
mmaanneell:15.0_add_web_diagram_builder
Open

[15.0][ADD] web_diagram_builder: build interactive dependency diagrams from any many2one field#3540
mmaanneell wants to merge 23 commits into
OCA:15.0from
mmaanneell:15.0_add_web_diagram_builder

Conversation

@mmaanneell
Copy link
Copy Markdown

Summary

  • Adds a new module web_diagram_builder that generates interactive hierarchy diagrams from any Odoo model with a recursive many2one field (e.g. parent_id)
  • Uses Cytoscape.js with dagre layout for automatic hierarchical rendering
  • Includes CSV import/export, path-finding between nodes (LCA algorithm), in-app tutorial, fr_CA translations, Python unit tests, and predefined templates
  • Migrates web_diagram renderer from Raphael.js to Cytoscape.js for Odoo 15
  • Adapts the diagram help widget for Odoo 15 legacy Widget system (Backbone.js style events, trigger_up)

Related PRs

Test plan

  • Install web_diagram_builder on a fresh Odoo 15 database
  • Create a diagram using res.partner + parent_id
  • Click Generate Diagram and verify the Cytoscape layout renders correctly
  • Export PNG and verify the download
  • Use Find Path Between Two Nodes and verify shortest path is highlighted
  • Run Python unit tests: pytest addons/web_diagram_builder/tests/

🤖 Generated with Claude Code

mathben and others added 23 commits March 26, 2026 16:32
- apply OCA script migration with OpenUpgrade
In Odoo 14, the test bundle was renamed from web.qunit_suite to
web.qunit_suite_tests. The old xpath also referenced kanban_tests.js
which no longer exists at the expected path, causing an install
error. Use expr="." position="inside" for a stable injection.

Generated by Claude Code 2.1.84 model claude-sonnet-4-6

Co-Authored-By: Mathieu Benoit <mathben@technolibre.ca>
Odoo 14 validates the type field of ir.ui.view against a selection
list. Without extending the model to add ("diagram", "Diagram"),
installing any module with a diagram view raises:
"Wrong value for ir.ui.view.type: 'diagram'".
Follows the same pattern as OCA web_timeline.

Generated by Claude Code 2.1.84 model claude-sonnet-4-6

Co-Authored-By: Mathieu Benoit <mathben@technolibre.ca>
Odoo 14's view postprocessor validates all <field> elements against
the main diagram model via NameManager. Since <node> and <arrow>
each declare their own 'object' model, their child fields must be
validated against that model instead. Without this, installing any
module with a diagram view raises a field-not-found error on the
connector's source/destination fields.

Generated by Claude Code 2.1.84 model claude-sonnet-4-6

Co-Authored-By: Mathieu Benoit <mathben@technolibre.ca>
BasicView._processNode traverses all <field> elements in the arch
and looks them up in fv.viewFields (the main model's fields). For
diagram views, <node> and <arrow> fields belong to their own object
models, causing field to be undefined and crashing _getFieldWidgetClass
at field.type. Stop traversal into those tags and guard field lookups
in init against undefined.

Generated by Claude Code 2.1.84 model claude-sonnet-4-6

Co-Authored-By: Mathieu Benoit <mathben@technolibre.ca>
ir.ui.view.graph_get() was dropped from Odoo core when the diagram
view was removed in v14. The diagram controller still calls it to
compute node positions and transitions. Port the Odoo 13 implementation
into the module's own ir.ui.view override so the method is available.

Generated by Claude Code 2.1.84 model claude-sonnet-4-6

Co-Authored-By: Mathieu Benoit <mathben@technolibre.ca>
odoo.tools.graph was dropped in Odoo 14 along with the diagram view.
Port the Odoo 13 implementation into the module under tools/graph.py
and update the import to use the local copy.

Generated by Claude Code 2.1.84 model claude-sonnet-4-6

Co-Authored-By: Mathieu Benoit <mathben@technolibre.ca>
Odoo 15 dropped the `qweb` manifest key and the XML template
inheritance pattern for assets. Assets must now be declared under
the `assets` key in __manifest__.py using named bundles
(web.assets_backend, web.assets_qweb, web.qunit_suite_tests).
Remove the now-obsolete views/web_diagram_templates.xml.

Generated by Claude Code 2.1.84 model claude-sonnet-4-6

Co-Authored-By: Mathieu Benoit <mathben@technolibre.ca>
In Odoo 15, NameManager.__init__ no longer accepts a validate flag,
postprocess() was removed in favour of a stack loop inside
_postprocess_view(), and check_view_fields() was renamed to check().
Replace the manual NameManager/postprocess pattern with a wrapper
element passed to _postprocess_view() against the node/arrow object
model, which handles the full processing pipeline correctly.

Generated by Claude Code 2.1.84 model claude-sonnet-4-6

Co-Authored-By: Mathieu Benoit <mathben@technolibre.ca>
Recursive dependency diagram builder for any many2one field.
Includes node/link generation, template system, diagram and form views.
Adapted for Odoo 15: no view_widgets registry, attrs= syntax,
post_init_hook(cr, registry). Diagram rendered by existing Raphael.js.

Co-Authored-By: Manel Guechetouli <manelguechetouli@gmail.com>
Generated by Claude Code claude-sonnet-4-6
Add CSV import with validation report and result models, plus dedicated
form and list views for nodes and links.

Co-Authored-By: Manel Guechetouli <manelguechetouli@gmail.com>
Generated by Claude Code claude-sonnet-4-6
Co-Authored-By: Manel Guechetouli <manelguechetouli@gmail.com>
Generated by Claude Code claude-sonnet-4-6
… menu)

Add step-by-step help wizard and cron-based Quick Guide data.

Co-Authored-By: Manel Guechetouli <manelguechetouli@gmail.com>
Generated by Claude Code claude-sonnet-4-6
Add wizard and BFS algorithm to find the shortest path between
any two nodes in the dependency graph.

Co-Authored-By: Manel Guechetouli <manelguechetouli@gmail.com>
Generated by Claude Code claude-sonnet-4-6
Co-Authored-By: Manel Guechetouli <manelguechetouli@gmail.com>
Generated by Claude Code claude-sonnet-4-6
Skip label 'for' validation in diagram nodes/arrows, replace invalidate_recordset()
with invalidate_cache() (Odoo 16+ API removed in 15), and guard empty tree_list
in process_order to avoid IndexError on leaf start nodes.

Co-Authored-By: Manel Guechetouli <manelguechetouli@gmail.com>
Generated by Claude Code claude-sonnet-4-6
…+ dagre

Rewrite diagram_renderer.js using Cytoscape.js with the dagre layout algorithm
for client-side graph positioning. Remove Raphael.js jsLibs dependency and the
getController workaround. Keyboard shortcuts: +/- zoom, arrows pan, F fit.

Co-Authored-By: Manel Guechetouli <manelguechetouli@gmail.com>
Generated by Claude Code claude-sonnet-4-6
…tcuts

Add web.diagram.nav.help transient model with bilingual HTML content listing
keyboard shortcuts (zoom, pan, fit). The Help button in the diagram toolbar
opens the popup via do_action on the form view action.

Co-Authored-By: Manel Guechetouli <manelguechetouli@gmail.com>
Generated by Claude Code claude-sonnet-4-6
Add Export PNG button to the diagram toolbar. Uses cy.png({ full: true }) to
capture the entire graph regardless of the visible viewport, with automatic
scale fallback (1.5x → 1x → 0.5x) if the canvas is too large.

Co-Authored-By: Manel Guechetouli <manelguechetouli@gmail.com>
Generated by Claude Code claude-sonnet-4-6
Test _validate_tag_label (label 'for' bypass in diagram views),
_postprocess_tag_node/arrow (unknown model silently ignored), and
graph_get (correct structure with nodes, transitions, blank_nodes).

Co-Authored-By: Manel Guechetouli <manelguechetouli@gmail.com>
Generated by Claude Code claude-sonnet-4-6
Add _getPagingInfo() and _onPagerChanged() to DiagramController so the control
panel displays previous/next arrows when multiple records are open. Add reloadWithId()
to DiagramModel to reload with a different record ID without remounting the view.

Co-Authored-By: Manel Guechetouli <manelguechetouli@gmail.com>
Generated by Claude Code claude-sonnet-4-6
Add OCA-required fields (author, website, maintainers, development_status),
pyproject.toml, readme/ fragments, and copyright header on __init__.py.
Remove invalid 'test' key from manifest.

Co-Authored-By: Manel Guechetouli <manelguechetouli@gmail.com>
Generated by Claude Code claude-sonnet-4-6
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

mod:web_diagram_builder Module web_diagram_builder mod:web_diagram Module web_diagram series:15.0

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants