Commit Graph

5 Commits

Author SHA1 Message Date
25e78b4754 Fix module drag: TypeError on droppableContainers.filter() crashing collision detection
droppableContainers in @dnd-kit/core collision detection args is a custom
NodeMap class, not a plain Array. It implements [Symbol.iterator] (so
for...of works internally in closestCenter/pointerWithin) but does NOT
have Array.prototype methods like .filter().

Calling args.droppableContainers.filter(...) threw:
  TypeError: args.droppableContainers.filter is not a function

dnd-kit silently catches errors in the collision detection callback and
treats them as no collision (over = null). Every module drag ended with
over = null, hitting the early return in handleDragEnd, causing the module
to snap back to its original slot every time.

Fix: Array.from(args.droppableContainers) converts the NodeMap iterable
to a plain array before filtering for dropType === 'slot' containers.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-22 08:23:51 -05:00
a11634070f Fix module drag drop (collision detection) + widen rack to fix port clipping
Collision detection root cause:
  pointerWithin returns ALL droppables containing the pointer, in
  registration order — not sorted by element size. Rack columns register
  via useSortable before their child RackSlots, so they always came first
  in the result list. over.data.current was { dragType: 'rack' }, never
  { dropType: 'slot' }, so handleDragEnd's slot check never matched and
  the module snapped back.

Fix: filter droppableContainers to elements with data.current.dropType
=== 'slot' before running pointerWithin. This does an exact pointer
hit-test against only the 44px slot rects. If no slot is hit (e.g. the
pointer is in a gap or over a rack header), fall back to closestCenter
over all droppables so rack-column reorder still works.

Width fix:
  24 ports * 10px + 23 gaps * 3px = 309px
  + px-2 padding (16px) + border-l-4 (4px) = 329px minimum
  w-80 (320px) was 9px short, clipping port 24.
  Increased to w-96 (384px) / min-w-[384px] — 55px of breathing room.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-22 08:15:45 -05:00
172896b85f Fix module drag-and-drop: custom collision detection to hit slots over racks
Root cause: SortableContext registers each rack column as a droppable.
Each column is ~1800px tall (42U x 44px). The default closestCenter
algorithm compared center-to-center distances, so the rack column's
center consistently beat the 44px RackSlot's center — meaning over.data
resolved to { dragType: 'rack' } and handleDragEnd's check for
dropType === 'slot' never matched. Drops silently did nothing.

Fix: replace closestCenter with a two-phase collision detection:
  1. pointerWithin — returns droppables whose bounding rect contains
     the actual pointer position. Slots are exactly hit-tested.
  2. closestCenter fallback — used when the pointer is not within any
     registered droppable (e.g. dragging a rack header between columns
     for sortable reorder where the pointer may be in the gap).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-22 07:55:35 -05:00
bcb8a95fae Switch auth to plain-text password env var (remove bcrypt)
- Replace ADMIN_PASSWORD_HASH with ADMIN_PASSWORD in auth route and docker-compose
- Remove bcryptjs / @types/bcryptjs dependencies
- Delete scripts/hashPassword.ts (no longer needed)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-21 22:05:42 -05:00
231de3d005 Initial scaffold: full-stack RackMapper application
Complete project scaffold with working auth, REST API, Prisma/SQLite
schema, Docker config, and React frontend for both Rack Planner and
Service Mapper modules. Both server and client pass TypeScript strict
mode with zero errors. Initial migration applied.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-21 21:48:56 -05:00