- Upload dialog now has distinct display name + filename fields, both pre-filled
from the uploaded file but independently editable
- Rename in file picker shows and edits both display name and filename separately
- Filename conflict checked against both KV store and disk (via rename_no_replace)
- Display name and filename are fully independent — no longer derived from each other
- Add find_pdf_references() helper in storage.mjs for future use
- CSS: fp-name-wrap shows display name + dim monospace filename below it;
rename mode stacks two inputs; fp-field-label for upload form labels
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Fix MV_SYNC path: ../tools resolved to /workspace/tools, should be ./tools
relative to server.mjs entry point
- Pre-populate display name input when file is selected (strips .pdf extension),
only if the field is currently empty so manual edits are not overwritten
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Components URL reflects selected component (/components/:id), survives refresh
- Word-split search: "0603 res" matches "Resistor 0603"
- Left pane resizable with localStorage persistence
- Field values rendered via central render_field_value() (units, URLs, extensible)
- Fields sorted alphabetically in both detail view and edit dialog
- Edit component dialog widened; field rows use shared grid columns (table-like)
- No space between value and unit (supports prefix suffixes like k, M, µ)
- Grid viewer highlights and scrolls to cell when navigating from component detail
- Cell inventory overlay items are <a> tags — middle-click opens in new tab
- PDF files stored with sanitized human-readable filename, not random ID
- PDF rename also renames file on disk
- Atomic rename via renameat2(RENAME_NOREPLACE) through tools/mv-sync
- Fix .cell-thumb-link → .cell-thumb-preview (div, not anchor), cursor: zoom-in
- Fix field name overflow in detail view (auto column width, overflow-wrap)
- Fix link color: use --accent instead of browser default dark blue
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Labels now overlay image with gradient background and visible colour.
Green badge top-right shows number of inventory entries for that cell.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Click a cell in the visual grid to select it. Cell images shown where
available. Selected cell highlighted with accent border.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Click any thumbnail to open full-size in overlay. Click backdrop or
press Escape to close. PDF thumbs now clickable too.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Generated at upload time, stored alongside the PDF in data/pdfs/.
Shown in the file picker (48px) and component detail view (80px).
Gracefully skipped if pdftoppm is unavailable.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
body was silently clipping all horizontal overflow. min-width:0 on
#main prevents flex child from expanding beyond container.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Cells are sized in CSS px to fit at load time. Browser zoom now scales
everything uniformly; grid scrolls horizontally instead of reflowing.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Images and labels scale together with a range slider (40–300px).
Grid scrolls horizontally when cells exceed viewport width.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Grid-type inventory entries now display the warped cell image from the
grid as a read-only thumbnail (highlighted with accent border) alongside
any user-uploaded images for that entry.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Enter a JS snippet returning a fields object (e.g. return { resistance: '10k' })
to preview the formatter against synthetic data instead of the first real component.
Both the formatter and test data textareas update the preview on input.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
c.fields was keyed by generated field IDs, so c.fields?.resistance
was always undefined. Now fields are remapped by name before being
passed to formatters, so the documented API works as expected.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Templates section:
- Define JS formatter functions per template (e.g. resistor, capacitor)
- First non-null result from any formatter is used as display name
- Live preview in template editor against first component
- Display names applied in component list, detail view, and inventory rows
Grid navigation:
- Grid-type inventory entries in component detail view show a '⊞' button
to navigate directly to that grid's viewer
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Component dialog: 'New...' button next to field selector creates a
new field definition and immediately adds it to the component form
- Inventory dialog: same pattern for component selector
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>