fix(plating): tree editor — title wrapping + import hierarchy

Two bugs reported on the tree editor after the move/import feature
shipped:

1. Card titles truncated to "Contrac…" because .o_fp_re_title had
   white-space: nowrap + text-overflow: ellipsis. Swapped to
   white-space: normal + overflow-wrap: anywhere so long names
   wrap onto multiple lines inside the card. Widened card max-
   width 380→460px and bumped min-width 240→260px so wrapped
   titles have room.

2. Import-children was flattening the tree — all operations AND
   their step children landed at the top level instead of staying
   nested under their operations.

   Root cause: src_node.copy({'parent_id': new_parent.id, ...})
   on a _parent_store model behaved unpredictably — in some runs
   the override in copy_vals didn't stick and child recursion
   ended up with a wrong parent_id. Rewrote _copy_subtree to use
   copy_data() + Node.create() so parent_id is set explicitly and
   child_ids / parent_path are stripped (we recurse ourselves).

   Smoke verified on entech: General Processing (1 root + 5 ops
   + 7 steps = 13 nodes) imports with hierarchy bit-identical to
   source.

fusion_plating → 19.0.7.1.0

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
gsinghpal
2026-04-23 08:08:55 -04:00
parent 8853cdd0c6
commit 03f41422de
3 changed files with 32 additions and 16 deletions

View File

@@ -233,15 +233,26 @@ class FpRecipeController(http.Controller):
max_seq = max((c.sequence for c in target.child_ids), default=0)
def _copy_subtree(src_node, new_parent, base_seq):
"""Deep-copy src_node under new_parent, recursing children."""
copy_vals = {
'parent_id': new_parent.id,
'sequence': base_seq,
}
# copy() picks up every other field; we only override parent + seq.
new_node = src_node.copy(copy_vals)
# Recurse — child_ids of the copy are blank (Odoo doesn't
# deep-copy one2many children by default for this model)
"""Deep-copy src_node under new_parent, recursing children.
Uses copy_data() + manual create() rather than copy() so we
have full control over what's carried:
* strip child_ids (we recurse ourselves)
* strip parent_path (Odoo recomputes from parent_id)
* force parent_id + sequence to our target values
The previous copy()-based version sometimes produced a
flattened tree because copy() on a _parent_store model can
leave parent_id pointed at the original source when the
override in copy_vals collides with the field's copy= flag.
copy_data() returns a plain dict — safer.
"""
[vals] = src_node.copy_data()
vals.pop('child_ids', None)
vals.pop('parent_path', None)
vals['parent_id'] = new_parent.id
vals['sequence'] = base_seq
new_node = Node.create(vals)
for i, child in enumerate(src_node.child_ids.sorted('sequence'), 1):
_copy_subtree(child, new_node, i * 10)
return new_node