feat(shopfloor): match Bake Windows + First-Piece Gates kanbans to Plant Overview
The two standalone menu pages (Bake Windows, First-Piece Gates) were still on the older o_fp_card design from a pre-Plant-Overview pass — visually drifted from the polished kanban-pattern cards we settled on for Plant Overview. Pulling them onto the same design language without rewriting them as OWL client actions (the 'Option A' from chat). What changed ============ New shared SCSS — fp_kanbans.scss --------------------------------- Defines .o_fp_kcard as the base kanban card surface. Mirrors the Plant Overview .o_fp_po_card recipe: white $fp-card surface, 1px $fp-border, $fp-radius-md corners, soft $fp-elev-1 shadow, hover lift, 4px state stripe via ::before clipped by overflow:hidden. Sub-elements (title, sub, metric, meta line, footer chip) get their own classes so per-page tweaks stay surgical. Page-scoped wrappers (.o_fp_bw_kanban, .o_fp_fpg_kanban) carry the state/result → stripe colour mapping plus exception-state tints (missed_window + fail get a soft danger wash so the card stands out in a sea of normal ones). Bake Window kanban ------------------ Rebuilt template — title (window name), part_ref subtitle, big time-remaining metric (the operator's primary cue), meta line for lot/customer/qty, footer with oven badge + state chip. data-state attribute drives the stripe colour: awaiting_bake → warning bake_in_progress → info baked → success missed_window → danger + soft red wash scrapped → muted + dimmed First-Piece Gate kanban ----------------------- Rebuilt template — title (gate name), part_ref subtitle, bath + customer meta, inspector + first_piece_produced timestamp, footer with result chip and an optional 'Released' badge when the lot has been signed off. data-result attribute drives the stripe colour: pending → warning pass → success fail → danger + soft red wash Shopfloor manifest bumped to 19.0.12.0.0 and the new SCSS is registered in web.assets_backend after manager_dashboard.scss so the design tokens it references are already in scope. Plant Overview's existing .o_fp_po_card classes are deliberately untouched — the OWL client action and the new kanbans share the visual language but stay loosely coupled. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,187 @@
|
||||
// =============================================================================
|
||||
// Fusion Plating — Shared kanban card style for menu pages
|
||||
// Copyright 2026 Nexa Systems Inc. · License OPL-1
|
||||
//
|
||||
// This file styles the standalone Bake Windows and First-Piece Gates kanban
|
||||
// pages so they match the Plant Overview client action's card look. Plant
|
||||
// Overview is a full custom OWL component and has its own .o_fp_po_card
|
||||
// styles (see plant_overview.scss); we deliberately copy the visual
|
||||
// language here rather than reuse those classes so the OWL component and
|
||||
// the standard Odoo kanbans stay loosely coupled.
|
||||
//
|
||||
// Design recipe (matches plant_overview.scss):
|
||||
// - white surface ($fp-card), 1px $fp-border, $fp-radius-md corners
|
||||
// - soft elevation, hover lifts subtly
|
||||
// - 4px state stripe on the left, clipped to corners via overflow:hidden
|
||||
// - status colours pulled from $fp-ok / $fp-warn / $fp-bad / $fp-info
|
||||
// =============================================================================
|
||||
|
||||
|
||||
// Generic kanban card shared by Bake Windows + First-Piece Gates.
|
||||
// Per-page tweaks live in the .o_fp_bw_kanban and .o_fp_fpg_kanban
|
||||
// blocks below.
|
||||
.o_fp_kcard {
|
||||
position: relative;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: $fp-space-2;
|
||||
background-color: $fp-card;
|
||||
color: $fp-ink;
|
||||
border: 1px solid #{$fp-border};
|
||||
border-radius: $fp-radius-md;
|
||||
// Clip the ::before stripe to the rounded corners. Shadows render
|
||||
// outside the box so they're unaffected.
|
||||
overflow: hidden;
|
||||
padding: $fp-space-3 $fp-space-4;
|
||||
box-shadow: $fp-elev-1;
|
||||
transition: transform $fp-dur-fast $fp-ease,
|
||||
box-shadow $fp-dur $fp-ease,
|
||||
border-color $fp-dur $fp-ease;
|
||||
|
||||
@include fp-hover-only {
|
||||
&:hover {
|
||||
transform: translateY(-1px);
|
||||
box-shadow: $fp-elev-2;
|
||||
border-color: color-mix(in srgb, #{$fp-accent} 45%, #{$fp-border});
|
||||
}
|
||||
}
|
||||
|
||||
// Left state stripe — driven by data-state / data-result attribute on
|
||||
// the card. Default is the muted ink-faint colour; specific states
|
||||
// override below.
|
||||
&::before {
|
||||
content: "";
|
||||
position: absolute;
|
||||
left: 0; top: 0; bottom: 0;
|
||||
width: 4px;
|
||||
background-color: $fp-ink-faint;
|
||||
}
|
||||
|
||||
// -- Title row -----------------------------------------------------
|
||||
.o_fp_kcard_title {
|
||||
font-size: $fp-text-base;
|
||||
font-weight: $fp-weight-semibold;
|
||||
letter-spacing: -0.01em;
|
||||
color: $fp-ink;
|
||||
overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
|
||||
}
|
||||
|
||||
// -- Subtitle (part ref / lot / customer one-liner) ----------------
|
||||
.o_fp_kcard_sub {
|
||||
font-size: $fp-text-xs;
|
||||
color: $fp-ink-mute;
|
||||
overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
|
||||
}
|
||||
|
||||
// -- Big metric (time remaining etc.) ------------------------------
|
||||
// Used when the card has one number that matters more than the rest
|
||||
// (bake countdown, qty pending). Stays compact — this is a kanban,
|
||||
// not a billboard.
|
||||
.o_fp_kcard_metric {
|
||||
display: inline-flex; align-items: baseline; gap: $fp-space-1;
|
||||
margin-top: $fp-space-1;
|
||||
font-variant-numeric: tabular-nums;
|
||||
|
||||
.o_fp_kcard_metric_value {
|
||||
font-size: $fp-text-md;
|
||||
font-weight: $fp-weight-bold;
|
||||
color: $fp-ink;
|
||||
letter-spacing: -0.01em;
|
||||
}
|
||||
.o_fp_kcard_metric_label {
|
||||
font-size: $fp-text-xs;
|
||||
color: $fp-ink-mute;
|
||||
}
|
||||
}
|
||||
|
||||
// -- Meta line — small key/value pairs separated by mid-dots -------
|
||||
.o_fp_kcard_meta {
|
||||
font-size: $fp-text-xs;
|
||||
color: $fp-ink-mute;
|
||||
display: flex; flex-wrap: wrap; gap: $fp-space-1;
|
||||
|
||||
.o_fp_kcard_meta_sep {
|
||||
color: $fp-ink-faint;
|
||||
}
|
||||
}
|
||||
|
||||
// -- Footer — chip + secondary tags --------------------------------
|
||||
.o_fp_kcard_footer {
|
||||
display: flex; justify-content: space-between; align-items: center;
|
||||
gap: $fp-space-2;
|
||||
margin-top: auto; // sticks footer to the bottom even at varying heights
|
||||
}
|
||||
|
||||
// Inline chip for state / result. Mirrors the Plant Overview chip
|
||||
// styling but locally scoped to keep the surface independent.
|
||||
.o_fp_kcard_chip {
|
||||
display: inline-flex; align-items: center;
|
||||
padding: 2px 10px;
|
||||
border-radius: $fp-radius-pill;
|
||||
font-size: 0.7rem;
|
||||
font-weight: $fp-weight-bold;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.06em;
|
||||
|
||||
&.tone-info { @include fp-pill(--bs-info); }
|
||||
&.tone-success { @include fp-pill(--bs-success); }
|
||||
&.tone-warning { @include fp-pill(--bs-warning); }
|
||||
&.tone-danger { @include fp-pill(--bs-danger); }
|
||||
&.tone-muted { background-color: $fp-card-soft; color: $fp-ink-mute; }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// =============================================================================
|
||||
// Bake Windows — state-driven stripe + soft danger wash on missed jobs
|
||||
// =============================================================================
|
||||
.o_fp_bw_kanban {
|
||||
.o_fp_kcard {
|
||||
&[data-state="awaiting_bake"] { &::before { background-color: $fp-warn; } }
|
||||
&[data-state="bake_in_progress"] { &::before { background-color: $fp-info; } }
|
||||
&[data-state="baked"] { &::before { background-color: $fp-ok; } }
|
||||
&[data-state="missed_window"] {
|
||||
&::before { background-color: $fp-bad; }
|
||||
// Missed windows are an exception state — softly tint the
|
||||
// whole card so it stands out in a sea of normal ones.
|
||||
background-color: fp-wash(--bs-danger, 6%);
|
||||
border-color: color-mix(in srgb, #{$fp-bad} 35%, #{$fp-border});
|
||||
}
|
||||
&[data-state="scrapped"] {
|
||||
&::before { background-color: $fp-ink-faint; }
|
||||
opacity: 0.65;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// =============================================================================
|
||||
// First-Piece Gates — result-driven stripe (pending = warn, fail = bad)
|
||||
// =============================================================================
|
||||
.o_fp_fpg_kanban {
|
||||
.o_fp_kcard {
|
||||
&[data-result="pending"] { &::before { background-color: $fp-warn; } }
|
||||
&[data-result="pass"] { &::before { background-color: $fp-ok; } }
|
||||
&[data-result="fail"] {
|
||||
&::before { background-color: $fp-bad; }
|
||||
background-color: fp-wash(--bs-danger, 6%);
|
||||
border-color: color-mix(in srgb, #{$fp-bad} 35%, #{$fp-border});
|
||||
}
|
||||
}
|
||||
|
||||
// Subtle "released" badge — visible only when the lot has been
|
||||
// released after a passing first-piece. Sits next to the result chip.
|
||||
.o_fp_fpg_released {
|
||||
display: inline-flex; align-items: center; gap: 4px;
|
||||
padding: 2px 8px;
|
||||
border-radius: $fp-radius-pill;
|
||||
font-size: 0.65rem;
|
||||
font-weight: $fp-weight-bold;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.06em;
|
||||
background-color: color-mix(in srgb, #{$fp-ok} 14%, transparent);
|
||||
color: $fp-ok;
|
||||
|
||||
.fa { font-size: 0.7rem; }
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user