From dcbe8305d0075e7611404f2f6e35665c1de88768 Mon Sep 17 00:00:00 2001 From: gsinghpal Date: Tue, 12 May 2026 08:13:46 -0400 Subject: [PATCH] ui(process-tree): back to Work Order + pulsing green for done steps Two improvements to the Process Tree visualization opened from the Work Order's Process Tree header button: 1. Back button returns to the Work Order (job form) instead of Plant Overview. fp.job.action_open_process_tree now passes back_job_id in the client-action context; process_tree.js reads it via a new backJobId getter, updates the button label to "Back to Work Order", and routes onBack to fp.job form. The Plant Overview fallback stays for callers that don't pass either back_step_id or back_job_id. 2. Completed operation/step cards now have a green fill (#1e8449) and a subtle pulsing glow (box-shadow animation, 2.6s alternate) so finished work pops against still-pending dark cards. Hover pauses the animation so the click target is steady. Reuses the same green the workflow-state slice already used. Co-Authored-By: Claude Opus 4.7 (1M context) --- .../fusion_plating_jobs/__manifest__.py | 2 +- .../fusion_plating_jobs/models/fp_job.py | 5 +++- .../fusion_plating_shopfloor/__manifest__.py | 2 +- .../static/src/js/process_tree.js | 18 +++++++++++- .../static/src/scss/process_tree.scss | 28 +++++++++++++++++++ 5 files changed, 51 insertions(+), 4 deletions(-) diff --git a/fusion_plating/fusion_plating_jobs/__manifest__.py b/fusion_plating/fusion_plating_jobs/__manifest__.py index 03a706ab..c8f69525 100644 --- a/fusion_plating/fusion_plating_jobs/__manifest__.py +++ b/fusion_plating/fusion_plating_jobs/__manifest__.py @@ -3,7 +3,7 @@ # License OPL-1 (Odoo Proprietary License v1.0) { 'name': 'Fusion Plating — Native Jobs', - 'version': '19.0.8.20.9', + 'version': '19.0.8.21.0', 'category': 'Manufacturing/Plating', 'summary': 'Native plating job model — replaces mrp.production / mrp.workorder bridge.', 'author': 'Nexa Systems Inc.', diff --git a/fusion_plating/fusion_plating_jobs/models/fp_job.py b/fusion_plating/fusion_plating_jobs/models/fp_job.py index de74b609..c10d4df0 100644 --- a/fusion_plating/fusion_plating_jobs/models/fp_job.py +++ b/fusion_plating/fusion_plating_jobs/models/fp_job.py @@ -1064,7 +1064,10 @@ class FpJob(models.Model): return { 'type': 'ir.actions.client', 'tag': 'fp_process_tree', - 'context': {'job_id': self.id}, + 'context': { + 'job_id': self.id, + 'back_job_id': self.id, + }, 'name': 'Process Tree — %s' % (self.name or ''), 'target': 'current', } diff --git a/fusion_plating/fusion_plating_shopfloor/__manifest__.py b/fusion_plating/fusion_plating_shopfloor/__manifest__.py index 3684c87b..b59f4089 100644 --- a/fusion_plating/fusion_plating_shopfloor/__manifest__.py +++ b/fusion_plating/fusion_plating_shopfloor/__manifest__.py @@ -5,7 +5,7 @@ { 'name': 'Fusion Plating — Shop Floor', - 'version': '19.0.25.1.0', + 'version': '19.0.25.2.0', 'category': 'Manufacturing/Plating', 'summary': 'Shop-floor tablet stations, QR scanning, bake window enforcer, ' 'first-piece inspection gates.', diff --git a/fusion_plating/fusion_plating_shopfloor/static/src/js/process_tree.js b/fusion_plating/fusion_plating_shopfloor/static/src/js/process_tree.js index 0d694205..75173b8b 100644 --- a/fusion_plating/fusion_plating_shopfloor/static/src/js/process_tree.js +++ b/fusion_plating/fusion_plating_shopfloor/static/src/js/process_tree.js @@ -66,8 +66,13 @@ export class ProcessTree extends Component { get backStepId() { return this._ctx.back_step_id || this._ctx.back_workorder_id || null; } + get backJobId() { + return this._ctx.back_job_id || null; + } get backLabel() { - return this.backStepId ? "Back to Step" : "Plant Overview"; + if (this.backStepId) return "Back to Step"; + if (this.backJobId) return "Back to Work Order"; + return "Plant Overview"; } // ---- Data --------------------------------------------------------------- @@ -137,6 +142,17 @@ export class ProcessTree extends Component { }); return; } + const jobId = this.backJobId; + if (jobId) { + this.action.doAction({ + type: "ir.actions.act_window", + res_model: "fp.job", + res_id: parseInt(jobId, 10), + views: [[false, "form"]], + target: "current", + }); + return; + } this.action.doAction("fusion_plating_shopfloor.action_fp_plant_overview"); } diff --git a/fusion_plating/fusion_plating_shopfloor/static/src/scss/process_tree.scss b/fusion_plating/fusion_plating_shopfloor/static/src/scss/process_tree.scss index b168c32a..f2c62e16 100644 --- a/fusion_plating/fusion_plating_shopfloor/static/src/scss/process_tree.scss +++ b/fusion_plating/fusion_plating_shopfloor/static/src/scss/process_tree.scss @@ -228,9 +228,37 @@ $pt-line-width : 2px; background-color: #1e8449; // green for completed slice color: #fff; } + // Operation / step cards that have completed — green fill + subtle + // pulsing glow so finished work pops against the still-pending dark + // cards. Animation pauses on hover so the click target is steady. + &.o_fp_pt_state_done.o_fp_pt_type_operation, + &.o_fp_pt_state_done.o_fp_pt_type_step { + background-color: #1e8449; + color: #fff; + box-shadow: 0 0 0 1px rgba(30, 132, 73, 0.65), + 0 0 10px rgba(30, 132, 73, 0.30); + animation: fp_pt_done_glow 2.6s ease-in-out infinite alternate; + + &:hover { + animation: none; + box-shadow: 0 0 0 1px rgba(30, 132, 73, 0.85), + 0 0 14px rgba(30, 132, 73, 0.55); + } + } &.o_fp_pt_state_cancel { opacity: 0.55; } } +@keyframes fp_pt_done_glow { + 0% { + box-shadow: 0 0 0 1px rgba(30, 132, 73, 0.50), + 0 0 4px rgba(30, 132, 73, 0.18); + } + 100% { + box-shadow: 0 0 0 1px rgba(30, 132, 73, 0.85), + 0 0 16px rgba(30, 132, 73, 0.55); + } + } + .o_fp_pt_card_icon { flex: 0 0 auto; width: 18px;