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

@@ -5,7 +5,7 @@
{
'name': 'Fusion Plating',
'version': '19.0.7.0.0',
'version': '19.0.7.1.0',
'category': 'Manufacturing/Plating',
'summary': 'Core plating / metal finishing ERP: facilities, processes, tanks, baths, jobs, operators.',
'description': """

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

View File

@@ -241,10 +241,10 @@ $re-line-w : 2px;
display: inline-flex;
align-items: center;
gap: 10px;
min-width: 240px;
max-width: 380px;
min-width: 260px;
max-width: 460px;
min-height: $re-card-h;
padding: 8px 12px;
padding: 10px 12px;
background-color: #2b2f36;
color: #f1f3f5;
border-radius: 10px;
@@ -343,10 +343,15 @@ $re-line-w : 2px;
gap: 2px;
}
.o_fp_re_title {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
// Let long node names wrap onto multiple lines so the card shows
// the whole title (e.g. "Final Inspection / Packaging") instead
// of cutting to "Final I…". word-break handles CJK / no-space
// strings gracefully; line-height keeps the card compact.
font-weight: 600;
white-space: normal;
overflow-wrap: anywhere;
word-break: break-word;
line-height: 1.25;
}
.o_fp_re_meta {
font-size: 0.72rem;