feat(jobs): Sub 14 polish — workflow state form layout + Simple Editor field
Two follow-ups on the workflow state work:
1) Form layout
The "How triggers combine" help text was crammed into a 2-column
group, taking ~25% of the available width. Pulled it out of the
group and rendered as a full-width <div class="alert alert-info">
below the trigger fields. Same fix applied to Notes — uses a
<separator> + bare <field> for full sheet width.
2) Simple Recipe Editor support
The trigger field was only exposed in the Tree Editor. Added it
to the Simple Editor's inline library form too:
* fp.step.template.triggers_workflow_state_id (new Many2one) —
per-template default, snapshot-copied to recipe nodes when
dropped into a recipe (added to _SNAPSHOT_FIELDS).
* /fp/simple_recipe/workflow_states/list — new endpoint to feed
the dropdown. Soft-fails when fusion_plating_jobs isn't
installed (returns []).
* Library editor JS — _fpEnsureWorkflowStatesLoaded helper
caches the catalog on first open (create + edit paths both
warm it). Save vals carry the trigger id.
* Library editor XML — dropdown rendered after the flag
checkboxes. Hidden when the catalog is empty so the form
doesn't show a useless "— None —" pick.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -24,6 +24,7 @@ _SNAPSHOT_FIELDS = [
|
||||
'voltage_target', 'viscosity_target',
|
||||
'requires_signoff', 'requires_predecessor_done',
|
||||
'parallel_start',
|
||||
'triggers_workflow_state_id', # Sub 14 — workflow milestone trigger
|
||||
'requires_rack_assignment', 'requires_transition_form',
|
||||
'default_kind',
|
||||
]
|
||||
@@ -195,6 +196,15 @@ class SimpleRecipeController(http.Controller):
|
||||
'requires_signoff': tpl.requires_signoff,
|
||||
'requires_predecessor_done': tpl.requires_predecessor_done,
|
||||
'parallel_start': tpl.parallel_start,
|
||||
# Sub 14 — workflow trigger (id + name for display)
|
||||
'triggers_workflow_state_id': (
|
||||
tpl.triggers_workflow_state_id.id
|
||||
if tpl.triggers_workflow_state_id else False
|
||||
),
|
||||
'triggers_workflow_state_name': (
|
||||
tpl.triggers_workflow_state_id.name
|
||||
if tpl.triggers_workflow_state_id else ''
|
||||
),
|
||||
'requires_rack_assignment': tpl.requires_rack_assignment,
|
||||
'requires_transition_form': tpl.requires_transition_form,
|
||||
'tank_ids': [
|
||||
@@ -230,6 +240,7 @@ class SimpleRecipeController(http.Controller):
|
||||
'name', 'code', 'icon', 'default_kind', 'description',
|
||||
'requires_signoff', 'requires_predecessor_done',
|
||||
'parallel_start',
|
||||
'triggers_workflow_state_id', # Sub 14
|
||||
'requires_rack_assignment', 'requires_transition_form',
|
||||
'tank_ids',
|
||||
}
|
||||
@@ -320,6 +331,34 @@ class SimpleRecipeController(http.Controller):
|
||||
],
|
||||
}
|
||||
|
||||
@http.route('/fp/simple_recipe/workflow_states/list',
|
||||
type='jsonrpc', auth='user')
|
||||
def workflow_states_list(self):
|
||||
"""Sub 14 — workflow-state picker for the inline library form.
|
||||
Returns active states ordered by sequence so the dropdown
|
||||
renders left-to-right matching the status bar.
|
||||
|
||||
Soft-fail when fp.job.workflow.state isn't installed (rare,
|
||||
only when fusion_plating_jobs is missing) — empty list lets the
|
||||
dropdown render disabled instead of throwing.
|
||||
"""
|
||||
WS = request.env.get('fp.job.workflow.state')
|
||||
if WS is None:
|
||||
return {'workflow_states': []}
|
||||
return {
|
||||
'workflow_states': [
|
||||
{
|
||||
'id': ws.id,
|
||||
'name': ws.name or '',
|
||||
'code': ws.code or '',
|
||||
'sequence': ws.sequence,
|
||||
}
|
||||
for ws in WS.search(
|
||||
[('active', '=', True)], order='sequence, id',
|
||||
)
|
||||
],
|
||||
}
|
||||
|
||||
# ------------------------------------------------------------------ step
|
||||
@http.route('/fp/simple_recipe/step/insert', type='jsonrpc', auth='user')
|
||||
def step_insert(self, recipe_id, template_id=False, position=99, vals=None):
|
||||
|
||||
Reference in New Issue
Block a user