feat(portal): rewrite /my/jobs list with V2 stepper cards

Drops the old 3-segment progress bar in favour of the dashboard's
5-step circle-and-line stepper for consistency. Uses the same
state_to_idx mapping so all 6 fp.portal.job states (including
'complete') render correctly.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
gsinghpal
2026-05-17 02:50:30 -04:00
parent 55ac05667c
commit c8deef1482

View File

@@ -432,63 +432,47 @@
<t t-call="portal.portal_layout"> <t t-call="portal.portal_layout">
<t t-set="breadcrumbs_searchbar" t-value="True"/> <t t-set="breadcrumbs_searchbar" t-value="True"/>
<t t-call="portal.portal_searchbar"> <t t-call="portal.portal_searchbar">
<t t-set="title">Parts Portal</t> <t t-set="title">Work Orders</t>
</t> </t>
<t t-if="not jobs"> <t t-if="not jobs">
<div class="o_fp_portal_card card bg-body-tertiary border-0 p-4 text-center"> <div class="o_fp_card text-center text-muted">
<p class="text-muted mb-0">You have no plating jobs yet.</p> <p class="mb-2">You have no plating jobs yet.</p>
<a href="/my/configurator" class="o_fp_btn_primary o_fp_btn_sm">+ Get Your First Quote</a>
</div> </div>
</t> </t>
<t t-if="jobs"> <t t-if="jobs">
<div class="o_fp_jobs_list"> <div class="o_fp_dashboard">
<t t-foreach="jobs" t-as="job"> <t t-foreach="jobs" t-as="job">
<div class="card mb-3 o_fp_portal_card"> <div class="o_fp_job_card">
<div class="card-body"> <div class="o_fp_job_header">
<div class="d-flex justify-content-between align-items-start mb-2">
<div> <div>
<a t-att-href="'/my/jobs/%s' % job.id" <a t-att-href="'/my/jobs/%s' % job.id"
class="fs-6 fw-semibold text-decoration-none" class="o_fp_job_ref text-decoration-none"
t-out="job.name"/> t-out="job.name"/>
<div class="text-muted small"> <span class="o_fp_job_meta">
<span t-if="job.received_date"> <t t-if="job.quantity"><t t-out="job.quantity"/> units</t>
Received: <span t-field="job.received_date" t-options='{"widget": "date"}'/> <t t-if="job.target_ship_date"> · ETA <span t-field="job.target_ship_date" t-options='{"widget": "date"}'/></t>
</span> </span>
<span t-if="job.target_ship_date" class="ms-3">
Target: <span t-field="job.target_ship_date" t-options='{"widget": "date"}'/>
</span>
<span class="ms-3">Qty: <span t-out="job.quantity"/></span>
</div> </div>
</div> <t t-call="fusion_plating_portal.fp_portal_status_badge">
<span t-attf-class="badge #{ <t t-set="state" t-value="job.state"/>
'text-bg-info' if job.state == 'received' else <t t-set="label" t-value="dict(job._fields['state']._description_selection(job.env)).get(job.state)"/>
'text-bg-primary' if job.state == 'in_progress' else </t>
'text-bg-warning' if job.state == 'quality_check' else
'text-bg-secondary' if job.state == 'ready_to_ship' else
'text-bg-success' if job.state == 'shipped' else
'text-bg-success'}"
t-out="dict(job._fields['state']._description_selection(job.env)).get(job.state)"/>
</div> </div>
<!-- Segmented progress bar --> <!-- State -> active step index map (same as dashboard) -->
<t t-set="pct" t-value="job._progress_percent()"/> <t t-set="state_to_idx" t-value="{'received': 0, 'in_progress': 2, 'quality_check': 3, 'ready_to_ship': 4, 'shipped': 5, 'complete': 5}"/>
<div class="o_fp_seg_progress d-flex" style="height: 10px; border-radius: 5px; overflow: hidden; background: var(--bs-secondary-bg);"> <t t-set="state_idx" t-value="state_to_idx.get(job.state, 0)"/>
<!-- Receiving segment (green) --> <t t-set="steps" t-value="[
<div t-attf-style="width: 20%; opacity: #{1 if pct >= 10 else 0.2};" {'label': 'Received', 'status': 'done' if state_idx > 0 else 'active', 'time_label': ''},
style="background-color: var(--bs-success);"/> {'label': 'Inspected', 'status': 'done' if state_idx > 1 else ('active' if state_idx == 1 else 'pending'), 'time_label': ''},
<!-- In Progress segment (orange) --> {'label': 'Plating', 'status': 'done' if state_idx > 2 else ('active' if state_idx == 2 else 'pending'), 'time_label': ''},
<div t-attf-style="width: 50%; opacity: #{1 if pct >= 35 else 0.2};" {'label': 'QC', 'status': 'done' if state_idx > 3 else ('active' if state_idx == 3 else 'pending'), 'time_label': ''},
style="background-color: var(--bs-warning); margin-left: 2px;"/> {'label': 'Ship', 'status': 'done' if state_idx > 4 else ('active' if state_idx == 4 else 'pending'), 'time_label': ''},
<!-- Shipping segment (blue/green) --> ]"/>
<div t-attf-style="width: 30%; opacity: #{1 if pct >= 80 else 0.2};" <t t-set="active_state" t-value="'warn' if job.state == 'quality_check' else 'normal'"/>
style="background-color: var(--bs-info); margin-left: 2px;"/> <t t-call="fusion_plating_portal.fp_portal_stepper"/>
</div>
<div class="d-flex justify-content-between mt-1" style="font-size: 0.7rem;">
<span class="text-muted">Receiving</span>
<span class="text-muted">In Progress</span>
<span class="text-muted">Shipping</span>
</div>
</div>
</div> </div>
</t> </t>
</div> </div>