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:
gsinghpal
2026-04-18 23:38:19 -04:00
parent e983a370aa
commit 484314625e

View File

@@ -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; }
}
}