- t-dialog-bin-editor: tabs (Corners|Fields|Contents), field rows, contents list
- t-bin-content-row: row template for bin content items
- t-dialog-bin-content: dialog for adding/editing component or free-text items
- t-dialog-bin-type: append field rows section below existing form fields
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Bin types store a name, physical W×H in mm, and optional description.
When editing a bin, a type can be selected from a dropdown; this
pre-fills and locks the dimension inputs. Custom dimensions remain
available when no type is selected.
- lib/storage.mjs: bin type CRUD with bt: prefix
- server.mjs: /api/bin-types CRUD routes; type_id accepted on bin
create/update routes; DELETE protected if any bin references the type;
type dims copied onto bin when type_id is set
- public/lib/api.mjs: bin type wrappers; rename_bin → update_bin (accepts
any fields)
- public/templates.html: Types tab in bins section; t-bin-type-row;
t-dialog-bin-type; type selector in bin editor dialog
- public/app.mjs: all_bin_types state loaded at startup; render_bin_types_list();
open_bin_type_dialog(); type selector in open_bin_editor(); /bins/types routing
- public/style.css: bin types list styles
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
When de-perspectiving a bin photo taken at an angle, inferring the
output size from the quadrilateral shape squishes the result. Entering
real-world W×H (mm) lets the server use the correct aspect ratio,
scaled to the same resolution as the inferred size.
- Bin editor dialog: W×H number inputs, pre-filled from saved phys_w/phys_h
- PUT /api/bins/:id/corners: accepts optional phys_w/phys_h; when provided,
derives bin_w/bin_h from the physical aspect ratio at equivalent area
- phys_w/phys_h stored on the bin record for re-use on next edit
- future-plans.md: bin types note (reusable dimensions per model)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
New top-level nav section showing all source images in a list view
with checkboxes to edit the uses array (grid, bin) per image. Allows
correcting wrongly-tagged images without code changes.
Server PUT /api/source-images/:id was already in place; re-added the
frontend API wrapper that was prematurely removed.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Bins section now mirrors the grids section with two tabs:
- Bins: gallery of processed bin records
- Sources: source images tagged with uses=['bin'], with upload and
'+ Bin' button to create a bin record from an existing source image
Server: POST /api/bins/from-source accepts source_id, creates bin
record and adds 'bin' to the source image's uses array.
URL state: /bins → bins tab, /bins/sources → sources tab.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- lib/storage.mjs: bin CRUD with bin: prefix
- lib/grid-image.mjs: compute_bin_size() capped at 1024px
- server.mjs: POST/GET/PUT/DELETE /api/bins routes; PUT /api/bins/:id/corners
re-processes image via process_grid_image with rows=1 cols=1
- public/lib/api.mjs: bin API wrappers including upload_bin()
- public/index.html: Bins nav button
- public/templates.html: t-section-bins, t-bin-card, t-dialog-bin-editor
- public/app.mjs: render_bins(), open_bin_editor() using Grid_Setup,
save/cancel wiring in init()
- public/style.css: bin gallery and card styles
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- 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>
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>
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>
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>
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>
- New 'grid' location type on inventory entries (grid_id, grid_row, grid_col)
- Clicking a grid cell shows a popup with what's stored there
- Popup has '+ Add entry' pre-filled with the cell coordinates
- Inventory dialog: 'New...' button next to component selector opens
component creation dialog on top, returns with new component selected
- Grid entries display as e.g. 'Black Component Box R3C5' in lists
- Store original filename on source image upload
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>