polish(stocktake-pdf): status anchors right edge, gaps between columns

- Add width: 100% to table/thead/tr so the row actually fills
  the landscape A4 page width (was collapsing to ~70% of page)
- Move Status to the rightmost column with right-aligned bold
  'Out of stock' as the visual anchor operator scans for
- Drop the trailing spacer column
- Re-balance widths: Name gets the lion's share (30%), Supplier
  shrinks (11%), Current/Min/Max narrower (6/5/6%) and pushed
  further right with explicit gap columns
- Small 2% gap between SKU and Name, 4% gaps between the
  other pairs so the eye groups {SKU, Name, Supplier} as 'what'
  and {Current, Min, Max, Status} as 'how much / how urgent'

Co-authored-by: Orca <help@stably.ai>
This commit is contained in:
SJCoetz 2026-08-03 19:00:29 +02:00
parent b84aefc2e2
commit b506670dde

View file

@ -55,16 +55,25 @@ const styles = StyleSheet.create({
// and bold, right-aligned at the right edge of the row so "Out of
// stock" sits as the visual anchor the operator scans for.
tdStatus: { fontSize: 9, fontFamily: "Helvetica-Bold", textAlign: "right" },
// Columns mirror the on-screen /stock table — Location dropped, Target
// renamed to "Max". Layout is landscape A4: Name gets the lion's share
// of the row, the numeric columns (Current/Min/Max) are narrow, and
// Status is the rightmost column (no trailing spacer).
cSku: { width: "8%" },
cName: { width: "34%" },
cSupplier: { width: "14%" },
cCurrent: { width: "8%", paddingRight: 6 },
cMin: { width: "6%", paddingRight: 6 },
cMax: { width: "8%", paddingRight: 6 },
// The empty `gap*` styles are intentional separator columns. React-
// pdf's flexbox doesn't support per-child gaps, so we render the
// gaps as zero-content `<Text>` elements. The small gap between SKU
// and Name visually separates the identifier from the label; the
// larger gaps between Name/Supplier/Current/Min/Max push the numeric
// columns further to the right so the eye groups {SKU, Name,
// Supplier} as "what" and {Current, Min, Max, Status} as "how much
// / how urgent".
cSku: { width: "6%" },
gapSkuName: { width: "2%" },
cName: { width: "30%" },
gapNameSupplier: { width: "4%" },
cSupplier: { width: "11%" },
gapSupplierCurrent: { width: "4%" },
cCurrent: { width: "6%" },
gapCurrentMin: { width: "4%" },
cMin: { width: "5%" },
gapMinMax: { width: "4%" },
cMax: { width: "6%" },
cStatus: { width: "18%" },
empty: { marginTop: 24, color: "#666", fontSize: 10, textAlign: "center" },
});
@ -99,14 +108,19 @@ export function StockItemStocktakeDocument({
<View style={styles.thead} fixed>
<Text style={[styles.th, styles.cSku]}>SKU</Text>
<Text style={[styles.th, styles.gapSkuName]}>{""}</Text>
<Text style={[styles.th, styles.cName]}>Name</Text>
<Text style={[styles.th, styles.gapNameSupplier]}>{""}</Text>
<Text style={[styles.th, styles.cSupplier]}>Supplier</Text>
<Text style={[styles.th, styles.gapSupplierCurrent]}>{""}</Text>
<Text style={[styles.th, styles.cCurrent, { textAlign: "right" }]}>
Current
</Text>
<Text style={[styles.th, styles.gapCurrentMin]}>{""}</Text>
<Text style={[styles.th, styles.cMin, { textAlign: "right" }]}>
Min
</Text>
<Text style={[styles.th, styles.gapMinMax]}>{""}</Text>
<Text style={[styles.th, styles.cMax, { textAlign: "right" }]}>
Max
</Text>
@ -136,15 +150,20 @@ export function StockItemStocktakeDocument({
return (
<View key={item.id} style={rowStyle} wrap={false}>
<Text style={[styles.td, styles.cSku]}>{item.sku || "—"}</Text>
<Text style={[styles.td, styles.gapSkuName]}>{""}</Text>
<Text style={[styles.td, styles.cName]}>{item.name}</Text>
<Text style={[styles.td, styles.gapNameSupplier]}>{""}</Text>
<Text style={[styles.td, styles.cSupplier]}>
{item.expand?.supplier?.suppliername || "—"}
</Text>
<Text style={[styles.td, styles.gapSupplierCurrent]}>{""}</Text>
<Text style={[styles.tdRight, styles.cCurrent]}>
{currentQty}
{item.unit ? ` ${item.unit}` : ""}
</Text>
<Text style={[styles.td, styles.gapCurrentMin]}>{""}</Text>
<Text style={[styles.tdRight, styles.cMin]}>{minQty}</Text>
<Text style={[styles.td, styles.gapMinMax]}>{""}</Text>
<Text style={[styles.tdRight, styles.cMax]}>
{maxQty !== null && maxQty > 0 ? maxQty : "—"}
</Text>