feat(jobs): step details quick-look modal for backend managers

Click a step's name in the embedded job-form list → opens a read-only
modal with everything a manager wants in one scroll: equipment,
schedule, master collect-measurements banner, operator instructions
(rich-text from recipe_node.description), measurement prompts list,
and values recorded so far.

Implementation: separate read-only form view bound to the embedded
field via context={'form_view_ref': '...'}. The standalone editable
form view stays registered for the Job Steps menu, so direct
navigation still loads the editable variant.

Three new computed/related fields on fp.job.step:
- quick_look_instructions (Html, related from recipe_node_id.description)
- quick_look_prompt_ids (filtered+sorted recipe_node.input_ids, step_input only)
- quick_look_recorded_value_ids (search across moves: input_value rows
  whose move.from_step_id == self.id)

Plus a small action_open_full_form method that escapes from the modal
to the editable form when the manager actually needs to edit.

Edge cases:
- No recipe_node_id → instructions panel shows empty-state hint
- collect_measurements=False → amber banner: "Master switch off — no
  values will be collected at runtime"
- Multiple moves on same step → values list shows all, newest first

Spec: docs/superpowers/specs/2026-04-30-step-details-modal-design.md.
Verified on entech: step "11. Hard Anodize Type III" populates with
516 chars instructions + 7 prompts.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
gsinghpal
2026-04-29 23:35:08 -04:00
parent 875548c547
commit 555dd5421f
5 changed files with 241 additions and 2 deletions

View File

@@ -75,7 +75,8 @@
sees on the tablet; Running Min ticks on every refresh
for the active step. -->
<xpath expr="//page[@name='steps']/field[@name='step_ids']" position="replace">
<field name="step_ids" mode="list">
<field name="step_ids" mode="list"
context="{'form_view_ref': 'fusion_plating_jobs.view_fp_job_step_quick_look_form'}">
<list editable="bottom"
decoration-info="state in ('ready', 'in_progress')"
decoration-success="state == 'done'"

View File

@@ -0,0 +1,115 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
Copyright 2026 Nexa Systems Inc.
License OPL-1 (Odoo Proprietary License v1.0)
Part of the Fusion Plating product family.
Read-only "Step Details" quick-look modal. Triggered by clicking a
step's name in the embedded step list inside fp.job's form. Bound
via context="{'form_view_ref': '...'}" on the parent — see
fp_job_form_inherit.xml. The standalone editable form view stays
registered for the Job Steps menu / direct navigation.
-->
<odoo>
<record id="view_fp_job_step_quick_look_form" model="ir.ui.view">
<field name="name">fp.job.step.quick.look.form</field>
<field name="model">fp.job.step</field>
<field name="priority">50</field>
<field name="arch" type="xml">
<form string="Step Details" edit="false" create="false" delete="false">
<sheet>
<div class="oe_title">
<h1>
<field name="name" readonly="1"/>
</h1>
<div class="text-muted">
<field name="sequence" readonly="1"/> ·
<field name="kind" readonly="1"/> ·
<field name="state" widget="badge"
decoration-info="state == 'in_progress'"
decoration-success="state == 'done'"
decoration-warning="state == 'paused'"
decoration-muted="state in ('skipped','cancelled')"/>
</div>
</div>
<group>
<group string="Equipment">
<field name="work_centre_id" readonly="1"/>
<field name="tank_id" readonly="1"/>
<field name="bath_id" readonly="1"/>
<field name="rack_id" readonly="1"/>
</group>
<group string="Schedule">
<field name="duration_expected" readonly="1"/>
<field name="duration_actual" readonly="1"/>
<field name="assigned_user_id" readonly="1"/>
</group>
</group>
<!-- Master switch banner -->
<field name="quick_look_collect_master" invisible="1"/>
<div class="alert alert-warning"
role="alert"
invisible="quick_look_collect_master or not recipe_node_id">
<i class="fa fa-exclamation-triangle"/>
<strong> Master switch off</strong> — no values will be collected at runtime for this step.
</div>
<separator string="Operator Instructions"/>
<div style="max-height: 40vh; overflow: auto; padding: 8px; background: #f8f9fa; border: 1px solid #d8dadd; border-radius: 4px;">
<field name="quick_look_instructions" nolabel="1" readonly="1"/>
</div>
<p class="text-muted small"
invisible="quick_look_instructions">
No instructions authored for this step.
</p>
<separator string="Measurement Prompts"/>
<field name="quick_look_prompt_ids" nolabel="1" readonly="1">
<list create="false" delete="false" edit="false">
<field name="collect" widget="boolean_toggle" readonly="1" string="Collect"/>
<field name="name"/>
<field name="input_type"/>
<field name="target_min" optional="show"/>
<field name="target_max" optional="show"/>
<field name="target_unit" optional="show"/>
<field name="required" widget="boolean_toggle" readonly="1"/>
<field name="hint" optional="hide"/>
</list>
</field>
<p class="text-muted small"
invisible="quick_look_prompt_ids">
No measurement prompts authored for this step.
</p>
<separator string="Values Recorded So Far"/>
<field name="quick_look_recorded_value_ids" nolabel="1" readonly="1">
<list create="false" delete="false" edit="false" default_order="create_date desc">
<field name="node_input_id" string="Prompt"/>
<field name="value_text" optional="show"/>
<field name="value_number" optional="show"/>
<field name="value_boolean" optional="hide"/>
<field name="value_date" optional="hide"/>
<field name="value_attachment_id" optional="hide"/>
<field name="create_uid" string="Recorded By"/>
<field name="create_date" string="When"/>
</list>
</field>
<p class="text-muted small"
invisible="quick_look_recorded_value_ids">
No values recorded yet.
</p>
</sheet>
<footer>
<button name="action_open_full_form" type="object"
string="Open Full Form" class="btn-primary"/>
<button string="Close" class="btn-secondary"
special="cancel"/>
</footer>
</form>
</field>
</record>
</odoo>