Draft
Conversation
- 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>
The legacy web framework (BasicView, AbstractModel, AbstractController, AbstractRenderer) was removed in Odoo 16. Rewrite all JS files as OWL components and ES6 classes. Replace web.assets_qweb (dropped in v16) by including the XML template directly in web.assets_backend. Replace the deprecated name_get() call with display_name. Bump version to 16.0.1.0.0. Generated by Claude Code 2.1.84 model claude-sonnet-4-6 Co-Authored-By: Mathieu Benoit <mathben@technolibre.ca>
Provides developer and user reference for the diagram view module: architecture overview, arch attribute reference, Odoo 16 migration notes, view switcher limitation with recommended workaround, and JSON-RPC endpoint signature. Generated by Claude Code 2.1.85 model claude-sonnet-4-6 Co-Authored-By: Mathieu Benoit <mathben@technolibre.ca>
- tools.ustr() was removed in Odoo 17; replaced with str() - web.qunit_suite_tests renamed to web.assets_unit_tests in Odoo 18 - Legacy JS tests (odoo.define + testUtils.createView) removed in Odoo 17; rewritten with @odoo/hoot describe/test/expect - graph.py operator spacing, comment formatting and long line wrapping updated to pass OCA ruff/pre-commit checks Generated by Claude Code 2.1.85 model claude-sonnet-4-6 Co-Authored-By: Mathieu Benoit <mathben@technolibre.ca>
- Move lxml import to module top (PEP 8, isort) - Rename PascalCase/uppercase locals to snake_case in graph_get() - Rename builtin-shadowing param id -> rec_id in graph_get() - Remove stale version references from docstrings - Remove unused variable cnt in graph.find_starts() - Tighten DiagramController.props (replace wildcard ["*"]) - Delete dead view_registry.js (not in manifest) - Add readme/SECURITY.rst documenting access control policy Generated by Claude Code 2.1.85 model claude-sonnet-4-6 Co-Authored-By: Mathieu Benoit <mathben@technolibre.ca>
jQuery was removed from Odoo 18's standard asset bundles, causing a
"jQuery is not defined" crash that broke the entire /web frontend
whenever web_diagram was installed.
Replace the jQuery mousewheel plugin with a native wheel event listener
(addEventListener + event.preventDefault + {passive: false}) and delete
the jquery.mousewheel.js library file.
Generated by Claude Code 2.1.85 model claude-sonnet-4-6
Co-Authored-By: Mathieu Benoit <mathben@technolibre.ca>
The explicit props definition added in cf2901a used { type: [...] } syntax which OWL 3 (Odoo 18) rejects with "Invalid object: 'type' is not valid", crashing the entire web.assets_backend bundle and breaking all pages under /web. Revert to the ["*"] wildcard which works across all OWL versions. Generated by Claude Code 2.1.85 model claude-sonnet-4-6 Co-Authored-By: Mathieu Benoit <mathben@technolibre.ca>
In Odoo 18, the view registry validates the view definition object and
rejects the 'type' key — the view type is now the registry key itself
('diagram' in registry.category("views").add("diagram", ...)).
Including 'type' caused "Invalid object: 'type' is not valid" which
crashed the entire web.assets_backend bundle.
Generated by Claude Code 2.1.85 model claude-sonnet-4-6
Co-Authored-By: Mathieu Benoit <mathben@technolibre.ca>
OWL 3 rejects { type: X } prop specs that have no other options
(optional, validate, etc.) with "Invalid object: 'type' is not valid".
The correct OWL 3 syntax is to pass the constructor directly.
Generated by Claude Code 2.1.85 model claude-sonnet-4-6
Co-Authored-By: Mathieu Benoit <mathben@technolibre.ca>
In Odoo 18, the view registry validates every entry against a schema that requires a 'type' field whose value must exist in session.view_info. session.view_info is built from ir.ui.view._get_view_info(), which only lists standard view types. Without extending _get_view_info(), "diagram" is absent from session.view_info, causing the JS validation to throw "Invalid object: 'type' is not valid" in debug/assets mode. Fix: override _get_view_info() in the diagram module to add the "diagram" entry, and restore type: "diagram" in the JS view definition (required by the registry validation schema). Generated by Claude Code 2.1.85 model claude-sonnet-4-6 Co-Authored-By: Mathieu Benoit <mathben@technolibre.ca>
In Odoo 18, the rpc service was removed from the service registry.
The rpc function is now a standalone export from
@web/core/network/rpc and must be imported directly instead of
obtained via useService("rpc").
Generated by Claude Code 2.1.85 model claude-sonnet-4-6
Co-Authored-By: Mathieu Benoit <mathben@technolibre.ca>
…Odoo 18 When switching to the diagram view via the control panel view switcher, Odoo's switchView() passes no resId prop — it falls back to action.res_id which is stale (false) for actions opened from a list. The form view's currentState.resId is never forwarded to the new controller. Read router.current.resId as a fallback at setup() time. This is safe because router.pushState() is debounced (setTimeout), so the router state still holds the form view's resId when setup() runs. Generated by Claude Code 2.1.85 model claude-sonnet-4-6 Co-Authored-By: Mathieu Benoit <mathben@technolibre.ca>
…ller When a page is loaded/reloaded from a URL with resId (e.g. a bookmarked form record), loadState() creates a lazy breadcrumb controller for the multi-record view. This controller gets action.jsId assigned but never receives a 'view' property. switchView() then iterates the controllerStack checking: ct.action.jsId === X && !ct.view.multiRecord The lazy controller matches on jsId but ct.view is undefined → TypeError. Patch actionService.start() to catch this specific TypeError and fall back to doAction() with stackPosition:"replaceCurrentAction", which uses a different findIndex that only checks jsId (no ct.view access). This also cleans the lazy controller out of the stack as a side effect. Generated by Claude Code 2.1.85 model claude-sonnet-4-6 Co-Authored-By: Mathieu Benoit <mathben@technolibre.ca>
Integrate the Layout component from @web/search/layout so that the diagram view shows the standard Odoo 18 control panel, giving users breadcrumb navigation and the form/diagram view-switcher buttons. The "New Node" button is placed in the control-panel-top-left slot so it appears alongside the standard controls. Generated by Claude Code 2.1.85 model claude-sonnet-4-6 Co-Authored-By: Mathieu Benoit <mathben@technolibre.ca>
The slot name was wrong (control-panel-top-left does not exist in the ControlPanel template). The correct slot is control-panel-create-button, which is the standard slot for primary action buttons. Generated by Claude Code 2.1.85 model claude-sonnet-4-6 Co-Authored-By: Mathieu Benoit <mathben@technolibre.ca>
Odoo 18 webclient_layout.scss sizes the view via:
.o_content > .o_view_controller { position: absolute; inset: 0; }
Without the o_view_controller class the diagram container had no height,
causing the Raphael canvas to render as 0px and nodes to be invisible.
Add o_view_controller to the diagram wrapper div and update the SCSS to
use flex layout instead of the now-redundant height:100%.
Generated by Claude Code 2.1.85 model claude-sonnet-4-6
Co-Authored-By: Mathieu Benoit <mathben@technolibre.ca>
Pager: - Load the ordered ID list (matching the action domain) on startup. - Show a Pager in the control-panel-navigation-additional slot when there are multiple records. - onPagerUpdate reloads the diagram for the new record and calls router.pushState to keep the URL in sync. - addNode now uses _currentResId (updated by pager) instead of the stale props.resId, so new nodes are always attached to the displayed record. URL fix: - Patch actionService.switchView to inject the current resId into props before delegating to the original implementation, whenever the target view is non-multiRecord. Without this the action service falls back to action.res_id (often false for list-opened actions), dropping the record ID from the URL and causing form-view to open a blank new record on switch-back. Generated by Claude Code 2.1.85 model claude-sonnet-4-6 Co-Authored-By: Mathieu Benoit <mathben@technolibre.ca>
Browsers render SVG elements at a default intrinsic height of 150px when height="100%" cannot resolve against an explicit parent height. Even though .o_diagram gets its height from flex layout (flex:1 1 auto), CSS percentage resolution for grandchildren is unreliable without a definite parent height. Make .o_diagram a positioning context (position:relative) and set the SVG to position:absolute with inset:0, so it fills the container independently of how the flex algorithm sizes the parent. Generated by Claude Code 2.1.85 model claude-sonnet-4-6 Co-Authored-By: Mathieu Benoit <mathben@technolibre.ca>
…nates Applying position:absolute directly to the Raphael SVG element breaks its internal coordinate system and makes nodes invisible. The root cause is that height="100%" on the SVG cannot resolve against a flex-grown parent. Instead, wrap .o_diagram in a new .o_diagram_canvas div that is the flex item (flex:1 1 auto; position:relative). .o_diagram itself is then position:absolute with inset:0, giving it a definite pixel height that the SVG's height="100%" resolves against correctly. Generated by Claude Code 2.1.85 model claude-sonnet-4-6 Co-Authored-By: Mathieu Benoit <mathben@technolibre.ca>
… + 0px SVG Root cause: new Raphael(div, "100%", "100%") in an off-screen div with no explicit dimensions resolves "100%" to 0px. Raphael always sets overflow:hidden on the SVG (inline style), so all content drawn at y>0 is clipped by the 0px viewport and never rendered visibly. Fix: read container.offsetWidth/offsetHeight before creating the Raphael paper, passing real pixel values so the coordinate system and overflow clipping match the visible area. Fall back to 800x600 if the container has not yet been laid out (rare, but avoids a blank diagram on first mount). Also change .o_diagram overflow from hidden to auto so that if the diagram is larger than the viewport the user can scroll, consistent with the original Odoo 13 behaviour. Generated by Claude Code 2.1.85 model claude-sonnet-4-6 Co-Authored-By: Mathieu Benoit <mathben@technolibre.ca>
Odoo 18 reuses the controller instance when navigating within the same action, so onWillStart does not re-run. Add onWillUpdateProps to reload fresh data on every re-activation. Also wire up Pager's updateTotal prop so clicking the total triggers a manual refresh (replaces oe_pager_refresh). Generated by Claude Code 2.1.85 model claude-sonnet-4-6 Co-Authored-By: Mathieu Benoit <mathben@technolibre.ca>
The off-screen div approach created a fixed-pixel SVG that did not fill the container, making nodes invisible when the container had different dimensions. Rendering Raphael directly in .o_diagram (which has an explicit height via position:absolute+inset:0 inside .o_diagram_canvas) lets height="100%" on the SVG resolve to the full available space and overflow:hidden clip at the correct boundary. Generated by Claude Code 2.1.85 model claude-sonnet-4-6 Co-Authored-By: Mathieu Benoit <mathben@technolibre.ca>
height="100%" on the SVG never resolves inside Odoo 18's Layout because no CSS ancestor provides an explicit height. Use getBoundingClientRect() to measure how much viewport space remains below the container and pass that as an explicit pixel height to Raphael. Remove the o_diagram_canvas wrapper and the position:absolute CSS chain that were added as workarounds but caused nodes to be invisible. Generated by Claude Code 2.1.85 model claude-sonnet-4-6 Co-Authored-By: Mathieu Benoit <mathben@technolibre.ca>
Apply a Bootstrap 5 / Odoo 18 inspired colour palette and card look: - Nodes: rounded corners (r=8), light border (#CED4DA), near-black text, soft blue-grey fill (#EEF0F4) instead of medium grey - Selected state: Bootstrap primary blue (#0D6EFD), thicker stroke - Edges: softer blue-grey (#8C96A5), explicit fill:none on path - Typography: Helvetica Neue / Arial stack on all labels - Close button / connector: muted grey tones Two new style keys consumed by graph.js: node_border_radius, font_family. Generated by Claude Code 2.1.85 model claude-sonnet-4-6 Co-Authored-By: Mathieu Benoit <mathben@technolibre.ca>
When a start node has no outgoing transitions (isolated root with flow_start=True but no children), make_acyclic returns [] and tree_list[start] is empty. A previous start whose own tree has only one edge trivially passes the same-tree subset check (empty [1:] slice), so roots becomes non-empty and the code tries tree_list[start][0][1] on the empty list — IndexError. Guard the roots block with an additional check that tree_list[self.start] is non-empty; isolated roots keep their position from tree_order() and simply skip the multi-root alignment step. Generated by Claude Code 2.1.85 model claude-sonnet-4-6 Co-Authored-By: Mathieu Benoit <mathben@technolibre.ca>
Raphael sets overflow:hidden on its SVG element, clipping any node placed beyond the initial paper height. When many nodes are present, the layout algorithm places them at large y-coordinates (140px × rank) that exceed the viewport-based height (~600px), making all but the first few nodes invisible. Derive the required height from the actual node coordinates before creating the Raphael paper so all nodes fit. Generated by Claude Code 2.1.85 model claude-sonnet-4-6 Co-Authored-By: Mathieu Benoit <mathben@technolibre.ca>
The graph algorithm was designed for single-root DAGs. With multiple flow_start nodes (e.g. 149 partner roots), process() only ran make_acyclic from start_nodes[0], so find_starts() re-discovered all other roots and added them to start_nodes again as duplicates. Each root was then laid out twice, scrambling y-coordinates and hiding all but the first few visible nodes. Three targeted fixes: - process(): traverse ALL provided start nodes before find_starts so every root's subtree is already in partial_order — find_starts only picks up truly disconnected remainder nodes. - find_starts(): guard against adding a node already in start_nodes. - init_order(): use `is None` instead of falsy check so nodes correctly placed at y=0 are not re-initialised on a second pass. Generated by Claude Code 2.1.85 model claude-sonnet-4-6 Co-Authored-By: Mathieu Benoit <mathben@technolibre.ca>
2f4c4c1 to
cbc7677
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Migrate from #3493
Overview : #3489
Improve user experience and fix bug from version Odoo 13
https://github.com/odoo/odoo/tree/13.0/addons/web_diagram