fix(configurator): proper column widths via arch + show blanket SO checkbox

Root cause for column widths: Odoo 19's column_width_hook.js dynamically
sets inline widths on every cell at render time, overriding any CSS
width on td/th selectors. Confirmed by reading the hook source on
entech: 'A width can also be hardcoded in the arch (width="60px").'

Fix: set width='Npx' as an ARCH ATTRIBUTE on each <field> in the line
list:
- Part Number 230px, Line Job # 80px, Thickness 100px, Mask 55px,
  Bake 120px, Qty 55px, Price 80px, Subtotal 90px, Action stack 60px
- Specification + Internal Notes get NO width → take remaining flex
  space (responsive: layout adapts to viewport)

Root cause for missing checkbox: my SCSS underline-style override
selected ALL .o_field_widget input including type=checkbox, rendering
checkboxes as 30px-tall full-width transparent text inputs.

Fix: exclude type=checkbox/radio/file from the underline rule, and
add explicit rendering for type=checkbox (18px square, accent-coloured)
inside .o_fp_xpr_cell. The Blanket Sales Order checkbox + the inline
Block partial shipments checkbox are now both visible.
This commit is contained in:
gsinghpal
2026-05-26 22:48:59 -04:00
parent 15e25ca50b
commit faffdca592
2 changed files with 38 additions and 50 deletions

View File

@@ -66,8 +66,11 @@
display: block;
}
// Field input visual — underline style like the mockup
.o_input, .o_field_widget input,
// Field input visual — underline style like the mockup.
// EXCLUDES checkboxes / radios / file inputs (they have their own
// visual treatment and would disappear under this style).
.o_input,
.o_field_widget input:not([type="checkbox"]):not([type="radio"]):not([type="file"]),
.o_field_widget select {
border: none;
border-bottom: 1px solid $xpr-border-strong;
@@ -91,6 +94,17 @@
}
.o_field_widget select { cursor: pointer; }
// Native checkboxes inside Express cells — keep them visible at
// a comfortable size. Boolean toggle widget retains its own look.
.o_field_widget input[type="checkbox"] {
width: 18px;
height: 18px;
min-height: 18px;
margin: 6px 0;
cursor: pointer;
accent-color: $xpr-accent;
}
// Ensure Boolean/toggle aligns visually with the underline
.o_field_boolean,
.o_field_boolean_toggle {
@@ -216,47 +230,15 @@
table-layout: auto;
}
// Column widths — give Part Number + Specification room,
// tighten Qty/Price/Subtotal/Mask
// Column widths are set via `width="Npx"` ARCH ATTRIBUTES on the
// <field> elements (the proper Odoo 19 mechanism). The
// column_width_hook.js dynamically applies inline widths after
// render and overrides any CSS-only width, so we don't fight it
// here. We only add a few visual tweaks per-column:
.o_fp_xpr_lines .o_list_view {
th[data-name="part_catalog_id"],
td[name="part_catalog_id"] {
min-width: 230px;
width: 230px;
}
th[data-name="line_description"],
td[name="line_description"] {
min-width: 220px;
}
th[data-name="customer_line_ref"],
td[name="customer_line_ref"] { width: 75px; }
th[data-name="thickness_range"],
td[name="thickness_range"] { width: 110px; }
th[data-name="masking_enabled"],
td[name="masking_enabled"] {
width: 55px;
text-align: center;
}
th[data-name="bake_instructions"],
td[name="bake_instructions"] { width: 130px; }
th[data-name="internal_description"],
td[name="internal_description"] { min-width: 140px; }
th[data-name="quantity"],
td[name="quantity"] { width: 60px; }
th[data-name="unit_price"],
td[name="unit_price"] { width: 80px; }
th[data-name="line_subtotal"],
td[name="line_subtotal"] {
width: 90px;
font-weight: 600;
}
// Stacked DWG / OPEN action column
th[data-name="action_btns_anchor"],
td[name="action_btns_anchor"] {
width: 60px;
text-align: center;
padding: 2px !important;
}
td[name="masking_enabled"] { text-align: center; }
td[name="line_subtotal"] { font-weight: 600; }
td[name="action_btns_anchor"] { padding: 2px !important; text-align: center; }
}
.o_fp_xpr_lines .o_list_view thead th {
background: $xpr-table-head;

View File

@@ -223,6 +223,7 @@
<field name="part_catalog_id"
string="Part Number"
widget="fp_express_part_cell"
width="230px"
context="{'default_partner_id': parent.partner_id, 'default_revision': 'A'}"
domain="[('partner_id', '=', parent.partner_id), ('is_latest_revision', '=', True)]"
options="{'no_quick_create': True}"/>
@@ -236,29 +237,34 @@
options="{'no_quick_create': False, 'color_field': 'state_color'}"
domain="[('part_id', '=', part_catalog_id)]"
column_invisible="1"/>
<!-- Specification + Internal Notes: NO width attr, let them grow with available space -->
<field name="line_description" string="Specification (Customer-Facing)"/>
<field name="customer_line_ref" string="Line Job #" placeholder="ABC"/>
<field name="thickness_range" string="Thickness" placeholder=".0005-.0010"/>
<field name="masking_enabled" string="Mask" widget="boolean_toggle"/>
<field name="customer_line_ref" string="Line Job #" placeholder="ABC" width="80px"/>
<field name="thickness_range" string="Thickness" placeholder=".0005-.0010" width="100px"/>
<field name="masking_enabled" string="Mask" widget="boolean_toggle" width="55px"/>
<!-- Bake pill — click to edit -->
<field name="bake_instructions"
string="Bake"
widget="fp_express_bake_pill"/>
widget="fp_express_bake_pill"
width="120px"/>
<field name="internal_description" string="Internal Notes" optional="show"/>
<field name="quantity" string="Qty"/>
<field name="quantity" string="Qty" width="55px"/>
<field name="unit_price"
string="Price"
widget="monetary"
options="{'currency_field': 'currency_id'}"/>
options="{'currency_field': 'currency_id'}"
width="80px"/>
<field name="line_subtotal"
string="Subtotal"
widget="monetary"
options="{'currency_field': 'currency_id'}"
sum="Total"/>
sum="Total"
width="90px"/>
<!-- Stacked DWG / OPEN buttons in ONE column -->
<field name="action_btns_anchor"
string=" "
widget="fp_express_action_btns"/>
widget="fp_express_action_btns"
width="60px"/>
<field name="process_variant_id"
string="Process / Recipe"
options="{'no_quick_create': True}"