fix(jobs): Record Inputs v3 wizard — visual bug fixes (v19.0.8.16.1)
Four visible bugs reported by user after deploy:
1. Type + Unit pills overlapped at top-right of every card.
Root cause: both <field>s carried the same .o_fp_iw_meta class
AND both mapped to grid-area: meta. CSS Grid stacked them on
top of each other so the labels rendered as overlap garbage
(e.g. "eachnber", "Time(secs)Time(seconds)").
Fix: distinct classes (.o_fp_iw_meta_type / .o_fp_iw_meta_unit)
each in its own grid column. Grid is now 4 columns wide:
"prompt | type | unit | trash"
2. Input borders barely visible in dark mode (#343942 on #22262d).
Operators couldn't tell where to click.
Fix: brighter border using $fp-iw-ink-faint instead of $fp-iw-border.
Hover bumps to $fp-iw-ink-mute. Focus uses brand purple. Also
added a slight surface tint ($fp-iw-page) so empty inputs read
as obviously-interactive instead of blending into the card.
3. Photo widget rendered enormous (full card width).
Root cause: max-width applied only to the preview image, not
to the .o_field_image container itself.
Fix: max-width 240px on .o_field_image AND its inner controls.
4. Numeric values floated centered in empty space.
Root cause: input width wasn't stretching to its grid cell;
default Odoo numeric-cell text-align: right plus our missing
width: 100% left tiny inputs centered in the value area.
Fix: explicit width: 100%, text-align: left, and 420px
max-width on the .o_field_widget container.
Bonus polish:
* Trash icon hidden by default (opacity: 0), reveals to 0.6 on
row hover, full opacity on direct hover. Reduces visual noise
for the common case where operator just types and saves.
* Boolean toggle scale bumped from 1.4 to 1.5 + adds left margin
so the switch sits properly inside the value cell.
* Mobile (<900px) grid collapses to: prompt|trash / type|unit /
value / extras — keeps the type+unit pair on one row but lets
them flow naturally below the prompt.
No model changes. SCSS + XML view only. v2 view still in place
for instant rollback.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -3,7 +3,7 @@
|
||||
# License OPL-1 (Odoo Proprietary License v1.0)
|
||||
{
|
||||
'name': 'Fusion Plating — Native Jobs',
|
||||
'version': '19.0.8.16.0',
|
||||
'version': '19.0.8.16.1',
|
||||
'category': 'Manufacturing/Plating',
|
||||
'summary': 'Native plating job model — replaces mrp.production / mrp.workorder bridge.',
|
||||
'author': 'Nexa Systems Inc.',
|
||||
|
||||
@@ -154,15 +154,17 @@ $fp-iw-pill-bg : var(--fp-pill-bg, #{$_fp-iw-pill-bg-hex});
|
||||
gap: 12px;
|
||||
}
|
||||
|
||||
// Each row becomes a card
|
||||
// Each row becomes a card. Five-column grid so the meta cells
|
||||
// (input_type pill, target_unit pill) each land in their own
|
||||
// column instead of stacking on top of each other.
|
||||
tr.o_data_row {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr auto;
|
||||
grid-template-columns: 1fr auto auto auto;
|
||||
grid-template-areas:
|
||||
"prompt meta"
|
||||
"value value"
|
||||
"extras extras";
|
||||
gap: 8px 16px;
|
||||
"prompt type unit trash"
|
||||
"value value value value"
|
||||
"extras extras extras extras";
|
||||
gap: 10px 12px;
|
||||
align-items: start;
|
||||
padding: 16px 20px;
|
||||
background-color: $fp-iw-card;
|
||||
@@ -229,13 +231,15 @@ $fp-iw-pill-bg : var(--fp-pill-bg, #{$_fp-iw-pill-bg-hex});
|
||||
// XML view via a span sibling (.o_fp_iw_required_marker).
|
||||
}
|
||||
|
||||
// ---------- Meta — type + unit pill, target range ----------
|
||||
// ---------- Meta pills — type + unit each in its OWN column ----
|
||||
// Both fields carry the .o_fp_iw_meta class for shared
|
||||
// pill styling, plus a distinct class (_type / _unit) so
|
||||
// CSS Grid can put each in its own area.
|
||||
td.o_fp_iw_meta_type { grid-area: type; }
|
||||
td.o_fp_iw_meta_unit { grid-area: unit; }
|
||||
|
||||
td.o_fp_iw_meta {
|
||||
grid-area: meta;
|
||||
display: flex;
|
||||
gap: 8px;
|
||||
align-items: center;
|
||||
justify-content: flex-end;
|
||||
align-self: center;
|
||||
font-size: 0.75rem;
|
||||
color: $fp-iw-ink-mute;
|
||||
|
||||
@@ -243,8 +247,13 @@ $fp-iw-pill-bg : var(--fp-pill-bg, #{$_fp-iw-pill-bg-hex});
|
||||
width: auto;
|
||||
}
|
||||
|
||||
// Type/unit selection looks like a pill
|
||||
select, input {
|
||||
// The pill itself — applied to whatever input/select
|
||||
// Odoo renders for the field type (Selection → select).
|
||||
select,
|
||||
input,
|
||||
.o_input,
|
||||
.o_field_widget > span {
|
||||
display: inline-block;
|
||||
font-size: 0.75rem;
|
||||
padding: 4px 10px !important;
|
||||
background-color: $fp-iw-pill-bg !important;
|
||||
@@ -254,36 +263,55 @@ $fp-iw-pill-bg : var(--fp-pill-bg, #{$_fp-iw-pill-bg-hex});
|
||||
line-height: 1.2 !important;
|
||||
height: auto !important;
|
||||
min-height: 0 !important;
|
||||
box-shadow: none !important;
|
||||
width: auto !important;
|
||||
}
|
||||
}
|
||||
|
||||
// ---------- Value — the live widget for this row's type ----------
|
||||
// ---------- Value — the live widget for this row's type --------
|
||||
td.o_fp_iw_value {
|
||||
grid-area: value;
|
||||
max-width: 360px;
|
||||
|
||||
// Numeric / text / date inputs — large + comfortable
|
||||
// Make the value widget container fill the available
|
||||
// grid area, no centering, no shrinking.
|
||||
.o_field_widget {
|
||||
display: block;
|
||||
width: 100%;
|
||||
max-width: 420px;
|
||||
}
|
||||
|
||||
// Inputs — number/text/date/etc. all share the same
|
||||
// chrome. Brighter border + slight surface tint so
|
||||
// empty inputs are obviously interactive in dark mode.
|
||||
input[type="text"],
|
||||
input[type="number"],
|
||||
input[type="datetime-local"],
|
||||
input.o_input,
|
||||
input:not([type]) {
|
||||
width: 100% !important;
|
||||
text-align: left !important;
|
||||
font-size: 1.125rem;
|
||||
font-weight: 500;
|
||||
padding: 10px 14px;
|
||||
padding: 10px 14px !important;
|
||||
min-height: 48px;
|
||||
background-color: $fp-iw-card;
|
||||
color: $fp-iw-ink;
|
||||
border: 1px solid $fp-iw-border;
|
||||
border-radius: 8px;
|
||||
box-shadow: none;
|
||||
background-color: $fp-iw-page !important;
|
||||
color: $fp-iw-ink !important;
|
||||
border: 1px solid $fp-iw-ink-faint !important;
|
||||
border-radius: 8px !important;
|
||||
box-shadow: none !important;
|
||||
transition: border-color 120ms ease,
|
||||
box-shadow 120ms ease;
|
||||
box-shadow 120ms ease,
|
||||
background-color 120ms ease;
|
||||
|
||||
&:hover {
|
||||
border-color: $fp-iw-ink-mute !important;
|
||||
}
|
||||
&:focus {
|
||||
border-color: $fp-iw-border-focus;
|
||||
border-color: $fp-iw-border-focus !important;
|
||||
background-color: $fp-iw-card !important;
|
||||
box-shadow: 0 0 0 3px
|
||||
color-mix(in srgb,
|
||||
#{$fp-iw-border-focus} 25%, transparent);
|
||||
#{$fp-iw-border-focus} 25%, transparent) !important;
|
||||
outline: none;
|
||||
}
|
||||
|
||||
@@ -293,16 +321,24 @@ $fp-iw-pill-bg : var(--fp-pill-bg, #{$_fp-iw-pill-bg-hex});
|
||||
}
|
||||
}
|
||||
|
||||
// Boolean toggle — make the pill bigger, easier to tap
|
||||
.o_boolean_toggle {
|
||||
transform: scale(1.4);
|
||||
// Boolean toggle — bigger pill for fat fingers
|
||||
.o_boolean_toggle,
|
||||
.form-switch {
|
||||
transform: scale(1.5);
|
||||
transform-origin: left center;
|
||||
margin: 8px 0;
|
||||
margin: 12px 0 12px 16px;
|
||||
}
|
||||
|
||||
// Image / photo widget
|
||||
// Image / photo widget — constrain the WHOLE field
|
||||
// (upload area + preview) so it doesn't blow up to
|
||||
// fill the whole card width.
|
||||
.o_field_image {
|
||||
img, .o_image, .o_form_uri {
|
||||
max-width: 240px;
|
||||
|
||||
img,
|
||||
.o_image,
|
||||
.o_form_uri,
|
||||
.o_form_image_controls {
|
||||
max-width: 240px;
|
||||
max-height: 180px;
|
||||
border-radius: 8px;
|
||||
@@ -311,46 +347,51 @@ $fp-iw-pill-bg : var(--fp-pill-bg, #{$_fp-iw-pill-bg-hex});
|
||||
}
|
||||
}
|
||||
|
||||
// ---------- Extras — composite types (multi-point, panel) ----------
|
||||
// ---------- Extras — composite types (multi-point, panel) ----
|
||||
td.o_fp_iw_extra {
|
||||
grid-area: extras;
|
||||
display: inline-flex;
|
||||
gap: 8px;
|
||||
align-items: baseline;
|
||||
margin-right: 8px;
|
||||
gap: 6px;
|
||||
align-items: center;
|
||||
margin-right: 12px;
|
||||
|
||||
// Compact label-above-input grouping
|
||||
// Compact label-before-input grouping
|
||||
&::before {
|
||||
content: attr(data-label);
|
||||
display: block;
|
||||
display: inline-block;
|
||||
font-size: 0.75rem;
|
||||
color: $fp-iw-ink-mute;
|
||||
margin-right: 4px;
|
||||
}
|
||||
|
||||
input {
|
||||
input,
|
||||
input.o_input {
|
||||
width: 80px !important;
|
||||
text-align: left !important;
|
||||
font-size: 1rem;
|
||||
padding: 6px 10px;
|
||||
padding: 6px 10px !important;
|
||||
min-height: 38px;
|
||||
background-color: $fp-iw-card;
|
||||
color: $fp-iw-ink;
|
||||
border: 1px solid $fp-iw-border;
|
||||
border-radius: 6px;
|
||||
background-color: $fp-iw-page !important;
|
||||
color: $fp-iw-ink !important;
|
||||
border: 1px solid $fp-iw-ink-faint !important;
|
||||
border-radius: 6px !important;
|
||||
box-shadow: none !important;
|
||||
}
|
||||
}
|
||||
|
||||
// Trash button column — small, right-aligned, low contrast
|
||||
// Trash button — hidden by default to declutter the card.
|
||||
// Operators rarely need to delete authored prompts; ad-hoc
|
||||
// rows can still be removed via the row's context menu.
|
||||
// Show on row hover for power users.
|
||||
td.o_list_record_remove {
|
||||
grid-area: meta;
|
||||
align-self: start;
|
||||
grid-area: trash;
|
||||
align-self: center;
|
||||
justify-self: end;
|
||||
opacity: 0.4;
|
||||
|
||||
&:hover { opacity: 1; }
|
||||
opacity: 0;
|
||||
transition: opacity 120ms ease;
|
||||
|
||||
button {
|
||||
color: $fp-iw-ink-mute;
|
||||
color: $fp-iw-ink-faint;
|
||||
background: transparent !important;
|
||||
border: none !important;
|
||||
padding: 4px;
|
||||
@@ -360,6 +401,14 @@ $fp-iw-pill-bg : var(--fp-pill-bg, #{$_fp-iw-pill-bg-hex});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&:hover td.o_list_record_remove,
|
||||
&:focus-within td.o_list_record_remove {
|
||||
opacity: 0.6;
|
||||
}
|
||||
td.o_list_record_remove:hover {
|
||||
opacity: 1 !important;
|
||||
}
|
||||
}
|
||||
|
||||
// "Add a line" footer — make it a tasteful CTA card
|
||||
@@ -398,25 +447,21 @@ $fp-iw-pill-bg : var(--fp-pill-bg, #{$_fp-iw-pill-bg-hex});
|
||||
|
||||
@media (max-width: 900px) {
|
||||
.o_fp_input_card_list .o_list_table tr.o_data_row {
|
||||
grid-template-columns: 1fr;
|
||||
grid-template-columns: 1fr auto;
|
||||
grid-template-areas:
|
||||
"prompt"
|
||||
"meta"
|
||||
"value"
|
||||
"extras";
|
||||
"prompt trash"
|
||||
"type unit"
|
||||
"value value"
|
||||
"extras extras";
|
||||
|
||||
td.o_fp_iw_meta {
|
||||
justify-content: flex-start;
|
||||
td.o_fp_iw_meta_type,
|
||||
td.o_fp_iw_meta_unit {
|
||||
justify-self: start;
|
||||
}
|
||||
|
||||
td.o_fp_iw_value {
|
||||
max-width: 100%;
|
||||
|
||||
.o_field_widget { max-width: 100%; }
|
||||
input { min-height: 56px; }
|
||||
}
|
||||
|
||||
td.o_list_record_remove {
|
||||
justify-self: end;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -151,15 +151,18 @@
|
||||
placeholder="e.g. Oven Temp, Bath Reading, Operator Initials"
|
||||
class="o_fp_iw_prompt"/>
|
||||
|
||||
<!-- Meta — type + unit rendered as pills (top-right) -->
|
||||
<!-- Meta — type + unit rendered as pills (top-right).
|
||||
Distinct classes so each pill lands in its own
|
||||
grid column (otherwise they stack on top of
|
||||
each other and the labels overlap). -->
|
||||
<field name="input_type"
|
||||
string="Type"
|
||||
readonly="is_authored"
|
||||
class="o_fp_iw_meta"/>
|
||||
class="o_fp_iw_meta o_fp_iw_meta_type"/>
|
||||
<field name="target_unit"
|
||||
string="Unit"
|
||||
readonly="is_authored"
|
||||
class="o_fp_iw_meta"
|
||||
class="o_fp_iw_meta o_fp_iw_meta_unit"
|
||||
optional="show"/>
|
||||
|
||||
<!-- Hidden by default — operator can opt in via the cog menu
|
||||
|
||||
Reference in New Issue
Block a user