feat(configurator): Express form layout rebuild — match mockup

Restructures the Express form to align with the brainstorming mockup:

Header (4-column grid via <group col='4'>):
- Row 1: Customer (colspan=2) + Shipping Address (colspan=2)
- Row 2: Consolidated PO Block (colspan=2 with PO#/PDF/Pending toggle/
  Expected date stacked + chase warning inline) + Customer Job # + Job Sorting
- Row 3: Material/Process Tag + Lead Time (X to Y inline) + Payment Terms + Delivery Method
- Row 4: Blanket SO + Currency/Pricelist + Quote Validity + Invoice Strategy

Lines: 13 inline columns including the Express-specific Line Job #,
masking toggle, bake text, plus per-line action buttons (DWG, OPEN,
+ bulk) wired to the Phase B helpers.

Footer: side-by-side cards — Notes + Terms stacked in the left card,
Totals card on the right with Total Lines / Total Qty / Grand Total
+ currency pill.

SCSS adds:
- PO block: accent-bordered card-within-card
- Lines: tight spreadsheet borders, hover row highlight
- Bake column: amber pill style, italic 'no bake' for empty
- Customer Line Job #: bold, uppercase, narrow column
- Inline action buttons: small uppercase bordered chips
- Footer cards with prominent Grand Total + currency pill

OWL multi-row Part cell (FpExpressPartCell) and click-to-edit Bake
pill (FpExpressBakePill) are still deferred — they need real OWL
components, separate pass.
This commit is contained in:
gsinghpal
2026-05-26 21:35:54 -04:00
parent 43abb8ef25
commit 713ba17e37
2 changed files with 369 additions and 185 deletions

View File

@@ -1,19 +1,58 @@
// Express Orders — base styles (C3 v1 / 2026-05-26)
// Express Orders — main stylesheet (v1.5 / 2026-05-26)
//
// Tokens load FIRST via the manifest's web.assets_backend ordering;
// $xpr-* are CSS custom-property wrappers from _express_tokens.scss.
//
// Goals (matching the .claude/mockups/express_orders.html mockup):
// - Header reads as a single 4-col grid (not stacked groups)
// - PO block reads as a single consolidated card-within-card
// - Lines feel like a spreadsheet (tight borders, bordered cells)
// - Bake column reads as a coloured pill, "no bake" reads italic muted
// - Customer Line Job # reads bold + uppercase
// - Footer is side-by-side Notes/Terms left + Totals right
// - Grand Total shows a prominent currency pill
.o_fp_express_order {
// ---- Header banners — slightly tighter than stock alerts ----
.alert {
margin-bottom: 8px;
// ============================================================
// Header — 4-col grid (.o_fp_express_header)
// ============================================================
.o_fp_express_header {
// Group renders as a table by default. Tighten spacing and let
// the colspan-2 spans on customer + shipping breathe.
td.o_td_label > label { font-weight: 600; font-size: 12px; }
}
// ---- Table — spreadsheet feel ----
.o_list_view {
// ============================================================
// PO Block — consolidated inside the header (.o_fp_po_block)
// ============================================================
.o_fp_po_block {
background: $xpr-accent-bg;
border: 1px solid $xpr-accent;
border-left: 4px solid $xpr-accent;
border-radius: 4px;
padding: 4px 8px;
margin: 4px 0;
.o_horizontal_separator {
color: $xpr-accent;
font-weight: 700;
font-size: 11px;
text-transform: uppercase;
letter-spacing: 0.4px;
border-top: none;
padding-top: 2px;
margin-bottom: 4px;
}
}
// ============================================================
// Lines list — spreadsheet feel (.o_fp_express_lines)
// ============================================================
.o_fp_express_lines .o_list_view {
table {
border-collapse: collapse;
border: 1px solid $xpr-border-table;
}
thead th {
background: $xpr-table-head;
@@ -22,31 +61,31 @@
text-transform: uppercase;
letter-spacing: 0.3px;
font-weight: 600;
border-bottom: 1px solid $xpr-border-table;
border-bottom: 2px solid $xpr-border-table;
border-right: 1px solid $xpr-border-table;
padding: 6px 8px;
&:last-child { border-right: none; }
}
tbody td {
border-bottom: 1px solid $xpr-border-table;
border-right: 1px solid $xpr-border-table;
padding: 4px 8px;
&:last-child { border-right: none; }
}
tbody tr:hover {
background: $xpr-row-hover;
}
tbody tr.o_data_row:focus-within {
background: $xpr-cell-focus;
}
}
// ---- Mask toggle — make it pop a bit more in the list ----
.o_list_view .o_field_boolean_toggle {
// Slightly larger so it reads at a glance in the column
.form-check-input { transform: scale(1.1); }
}
// ---- Bake column (text input) — give the cell an inset pill feel ----
// (Until C5 OWL widget lands, this is the simplest visual nudge.)
.o_list_view td[name="bake_instructions"] input[type="text"] {
// ============================================================
// Bake column — coloured pill (text-input visual)
// ============================================================
.o_fp_express_lines .o_list_view td[name="bake_instructions"] input[type="text"] {
background: $xpr-bake-bg;
color: $xpr-bake-text;
border: 1px solid $xpr-bake-border;
@@ -54,27 +93,142 @@
padding: 2px 8px;
font-size: 12px;
font-weight: 500;
min-width: 100px;
&::placeholder {
color: $xpr-text-dim;
font-style: italic;
font-weight: 400;
background: transparent;
}
&:focus {
background: $xpr-cell-focus;
border-color: $xpr-accent;
outline: none;
}
// Empty cell → render as muted italic "no bake"
&:not(:focus):placeholder-shown {
background: $xpr-card-soft;
border-color: $xpr-border-strong;
color: $xpr-text-muted;
font-style: italic;
}
}
// ---- Customer Line Job # — narrow, bold, accent colour ----
.o_list_view td[name="customer_line_ref"] input {
// ============================================================
// Customer Line Job # — bold, uppercase, narrow
// ============================================================
.o_fp_express_lines .o_list_view td[name="customer_line_ref"] input {
font-weight: 600;
letter-spacing: 0.5px;
text-transform: uppercase;
max-width: 70px;
}
// ---- Bullet section markers ----
.o_group > .o_horizontal_separator {
// ============================================================
// Masking toggle — bigger so it reads at a glance
// ============================================================
.o_fp_express_lines .o_list_view td[name="masking_enabled"] {
.form-check-input,
.o_field_boolean_toggle .form-check-input { transform: scale(1.15); }
}
// ============================================================
// Inline action buttons (DWG / OPEN / + bulk)
// ============================================================
.o_fp_express_lines .o_fp_inline_btn {
font-size: 10px !important;
font-weight: 600 !important;
letter-spacing: 0.5px;
text-transform: uppercase;
padding: 1px 6px !important;
border: 1px solid $xpr-border-strong;
border-radius: 3px;
color: $xpr-text-muted !important;
background: transparent;
margin: 0 2px;
&:hover {
color: $xpr-accent !important;
border-color: $xpr-accent;
background: $xpr-accent-bg;
text-decoration: none !important;
}
}
// ============================================================
// Footer — Notes / Terms (left card) + Totals (right card)
// ============================================================
.o_fp_express_footer {
> .o_group { gap: 16px; }
.o_fp_footer_left,
.o_fp_footer_totals {
background: $xpr-card;
border: 1px solid $xpr-border;
border-radius: 4px;
padding: 12px 16px;
}
.o_fp_footer_left {
.o_horizontal_separator {
color: $xpr-text-muted;
font-size: 11px;
text-transform: uppercase;
letter-spacing: 0.4px;
font-weight: 700;
margin-top: 4px;
}
.o_horizontal_separator:first-child { margin-top: 0; }
textarea { min-height: 80px; }
}
.o_fp_footer_totals {
.o_horizontal_separator {
color: $xpr-text-muted;
font-size: 11px;
text-transform: uppercase;
letter-spacing: 0.4px;
font-weight: 700;
margin-bottom: 8px;
}
}
}
// ============================================================
// Grand Total — bigger + currency pill
// ============================================================
.o_fp_grand_total_label {
font-size: 14px;
font-weight: 700;
color: $xpr-text;
padding-top: 6px;
border-top: 2px solid $xpr-text;
margin-top: 4px;
}
.o_fp_grand_total {
font-size: 20px;
font-weight: 700;
color: $xpr-text;
padding-top: 6px;
border-top: 2px solid $xpr-text;
margin-top: 4px;
}
.o_fp_currency_pill {
background: $xpr-accent-bg;
color: $xpr-accent;
padding: 2px 10px;
border-radius: 3px;
font-size: 11px;
font-weight: 700;
letter-spacing: 0.5px;
}
// ============================================================
// Section separators inside the sheet
// ============================================================
> .o_form_sheet .o_horizontal_separator {
font-size: 13px;
font-weight: 600;
color: $xpr-accent;
@@ -84,10 +238,9 @@
}
}
// ---- view_source badge column on drafts list ----
// The Drafts list view shows a small EXPRESS/LEGACY chip. Stock Odoo
// badge widget styling is fine; this just bumps the Express variant
// a touch more visible via the accent colour.
// ============================================================
// view_source badge column — Express vs Legacy in drafts list
// ============================================================
.o_list_view .badge.text-bg-info {
background-color: $xpr-accent !important;
}