Default widths were too narrow for the header labels, causing them to
overlap and become unreadable (140->200 and 110->150).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
EMCO Compliant is maintained manually in BC, so the pricing column now
fetches it from the new /api/bc-empco endpoint (items API, field
empCOCompliant) on every app load instead of reading the Dropbox matrix.
One fetch per page load, cached across tab switches; sorting uses the
live map.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Read-only Yes/No badge sourced from the matrix EmpCO_Compliant column
(detected dynamically by header; shows '-' until the new matrix layout
is live in Dropbox). Sortable, pinnable and resizable like the rest.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- Update default column indices to July 2026 layout (EmpCO_Compliant,
Comments, Categorisation Code, Ingredients added; PM Classification
removed; downstream columns shifted)
- Seed internal Categorisation Code from the new Excel column while
keeping app-side edits as the source of truth
- Guard legacy CPNP index-77 fallbacks: only trusted when the current
layout still holds CPNP there (new layout stores Item To Root Units)
- Use resolved column index for forced zero stock instead of static one
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Removed h-full and overflow-auto from the root grid div. h-full was
constraining the grid to the viewport height, causing CSS grid to
shrink rows to fit instead of overflowing. Parent <main> already has
overflow-auto, so removing the height constraint lets content expand
naturally and scroll correctly on small screens.
Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
- Show total record count and filtered count in subtitle
- Add #N global number to each history entry row
- Add # column index inside each change detail table
- Column header already shown via headers[i] — now labeled "Column"
Co-Authored-By: claude-flow <ruv@ruv.net>
- Add bc-proxy and bc-export serverless API handlers
- Add businessCentral service with updateCpnpNoInBC and downloadBusinessCentralItemsExcel
- Sync cpnpNo to BC on save (CosmeticItemsView and handleSaveAll)
- Parallelize handleSaveAll with Promise.all
- Fix array index key, a11y click/keyboard handlers, autoFocus
- Grant Change History and Pending Validation access to jingying.shi@craze-group.com
Co-Authored-By: claude-flow <ruv@ruv.net>
- saveRowToSupabase now accepts optional status param (default 'pending')
- CosmeticItemsView saves CPNP with status 'edited' so resetAllPendingRows
does not affect it and it survives the startup merge
- Re-added CPNP_NO to editableColumns so the merge restores it from Supabase
Co-Authored-By: claude-flow <ruv@ruv.net>
Bypasses the pending queue timing issue by calling saveRowToSupabase
directly after onSaveRow. Shows a spinner while saving. Alert on error.
Co-Authored-By: claude-flow <ruv@ruv.net>
Items with a CPNP number now display it in green. Empty cells still show
the dashed 'Click to fill...' button. Both are clickable to edit inline.
Co-Authored-By: claude-flow <ruv@ruv.net>
CPNP_NO re-added to COLUMN_PATTERNS so resolveColumnIndices maps it to
the real Excel column index. Removed it from VIRTUAL_COLS and editableColumns
in App.tsx since data comes from the spreadsheet, not Supabase-only storage.
Co-Authored-By: claude-flow <ruv@ruv.net>
CPNP_NO must stay hardcoded at index 107. Removed it from COLUMN_PATTERNS
and added guard to skip empty patterns in resolveColumnIndices.
Co-Authored-By: claude-flow <ruv@ruv.net>
Show all cosmetic products regardless of CPNP status. Column filter on
CPNP No. lets user isolate items with empty value.
Co-Authored-By: claude-flow <ruv@ruv.net>