feat(jobs): Record Inputs OWL Dialog (v4) — replaces list-as-cards hack
Scrapped the v2/v3 form-view + list-as-cards CSS approach after
extensive failure to make Odoo's editable list look like cards.
Built a proper OWL Dialog component instead, mirroring the pattern
used by fusion_plating_shopfloor's move_parts_dialog.js.
What changed
============
* New OWL Dialog: fp_record_inputs_dialog.js
- Loads step + prompt definitions via /fp/record_inputs/load
- Renders each prompt as a semantic <div class="o_fp_ri_card">
- Per-row widget chosen by input_type:
numeric/temperature/thickness/time_seconds/ph -> number input
boolean/pass_fail -> custom CSS toggle (clearer than Bootstrap)
date -> datetime-local input
photo -> file picker w/ preview + clear
multi_point_thickness -> 5-cell grid + live average
bath_chemistry_panel -> pH/Conc/Temp/Bath grid
selection -> dropdown sourced from selection_options
text/signature/... -> text input
- Live in-range hint for numeric prompts
("in range" / "below target" / "above target")
- Save validates ad-hoc rows have a Prompt label
- Save dispatches the next_action returned by the wizard model
(e.g. action_finish_and_advance for the Finish & Next flow)
* New XML template: fp_record_inputs_dialog.xml
Full DOM control. No fighting Odoo's list view, no class-stripping
bugs from canUseFormatter, no read-mode-vs-edit-mode CSS dance.
* New SCSS: fp_record_inputs_dialog.scss
- Dark mode aware (compile-time @if $o-webclient-color-scheme==dark)
- Pure semantic selectors (.o_fp_ri_card, .o_fp_ri_input, etc.)
- 14 surface tokens with light/dark hex pairs
- Tablet polish via @media (max-width: 768px)
- Custom toggle widget (no <input type="checkbox"> hidden trick)
* New controller: controllers/record_inputs.py
- /fp/record_inputs/load: returns step + prompts payload
- /fp/record_inputs/commit: creates a wizard, populates lines,
calls action_commit (reuses existing audit-trail / synthetic
move semantics — no commit logic duplicated)
* fp_job_step.py wired to dispatch the new action
- _fp_open_input_wizard returns
{ type: 'ir.actions.client', tag: 'fp_record_inputs_dialog' }
- action_open_input_wizard same
- Contract-review redirect gate preserved (Sub 4 work intact)
* Manifest registers JS/XML/SCSS in BOTH backend + dark bundles
per the dark-mode pattern in CLAUDE.md.
What was kept
=============
* fp.job.step.input.wizard TransientModel — UNCHANGED. The new
controller's commit endpoint creates a wizard record and calls
action_commit() on it, so all the audit-trail / synthetic-move
/ chatter logic stays in Python where it belongs.
* v2 + v3 form views still exist in the XML file. If the OWL
dialog ever fails, switch action_open_input_wizard back to
ir.actions.act_window with view_id=v2 or v3.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -481,26 +481,24 @@ class FpJobStep(models.Model):
|
||||
return already == 0
|
||||
|
||||
def _fp_open_input_wizard(self, advance_after=False):
|
||||
"""Open the simplified Record Inputs dialog. When advance_after
|
||||
is True, the wizard's Save button finishes the step and starts
|
||||
the next one as a single atomic flow."""
|
||||
"""Open the Record Inputs OWL dialog (Sub 12e v4).
|
||||
|
||||
Replaces the form-view-based wizard with a custom OWL Dialog
|
||||
component (fp_record_inputs_dialog.js). The dialog renders
|
||||
each prompt as a proper card with semantic HTML — no more
|
||||
list-cell-as-card CSS hacks.
|
||||
|
||||
When advance_after is True, the dialog's Save button commits
|
||||
values then dispatches the result of action_finish_and_advance
|
||||
so the step finishes + auto-starts the next step in one flow.
|
||||
"""
|
||||
self.ensure_one()
|
||||
view = self.env.ref(
|
||||
'fusion_plating_jobs.view_fp_job_step_input_wizard_form_v3'
|
||||
)
|
||||
return {
|
||||
'type': 'ir.actions.act_window',
|
||||
'res_model': 'fp.job.step.input.wizard',
|
||||
'view_mode': 'form',
|
||||
'view_id': view.id,
|
||||
'views': [(view.id, 'form')],
|
||||
'target': 'new',
|
||||
'name': _('Record Inputs — %s') % self.name,
|
||||
'context': {
|
||||
**dict(self.env.context),
|
||||
'default_step_id': self.id,
|
||||
'active_id': self.id,
|
||||
'fp_advance_after_save': advance_after,
|
||||
'type': 'ir.actions.client',
|
||||
'tag': 'fp_record_inputs_dialog',
|
||||
'params': {
|
||||
'step_id': self.id,
|
||||
'advance_after': bool(advance_after),
|
||||
},
|
||||
}
|
||||
|
||||
@@ -916,24 +914,23 @@ class FpJobStep(models.Model):
|
||||
}
|
||||
|
||||
def action_open_input_wizard(self):
|
||||
"""Open the Input Recording wizard for this step.
|
||||
"""Open the Record Inputs OWL dialog from the per-row Record
|
||||
button on the job form.
|
||||
|
||||
Contract-review steps redirect to the QA-005 form (same gate as
|
||||
action_finish_and_advance) so the per-row "Record" button stays
|
||||
consistent with "Finish & Next".
|
||||
action_finish_and_advance) so the per-row Record button stays
|
||||
consistent with Finish & Next.
|
||||
"""
|
||||
self.ensure_one()
|
||||
cr_action = self._fp_contract_review_redirect()
|
||||
if cr_action:
|
||||
return cr_action
|
||||
return {
|
||||
'type': 'ir.actions.act_window',
|
||||
'res_model': 'fp.job.step.input.wizard',
|
||||
'view_mode': 'form',
|
||||
'target': 'new',
|
||||
'name': _('Record Inputs — %s') % self.name,
|
||||
'context': {
|
||||
'default_step_id': self.id,
|
||||
'type': 'ir.actions.client',
|
||||
'tag': 'fp_record_inputs_dialog',
|
||||
'params': {
|
||||
'step_id': self.id,
|
||||
'advance_after': False,
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user