mirror of
https://github.com/screentinker/screentinker.git
synced 2026-06-29 09:23:16 -06:00
Option A: tile-on-tile (same section) reorders; tile-on-section / cross- section stays group-assign (existing behavior untouched). Ordering is cosmetic (dashboard only — nothing the device/player reads). Backend: - Migration: devices.sort_order column (idempotent ALTER; default 0). - GET /api/devices ordering: sort_order ASC, created_at ASC (was created_at). - POST /api/devices/reorder — ordered id array -> transactional UPDATE sort_order=index, scoped WHERE workspace_id = caller's workspace (forged cross-workspace ids are no-ops). Write-gated (viewer read-only). Mirrors the playlist items reorder. Frontend (the collision): - Card-level dragover/drop: reorder ONLY when target is another card in the SAME section; otherwise no-op so the event bubbles to the section's group-assign handler. stopPropagation on the same-section drop prevents the section handler also firing. Drop indicator (inset box-shadow). Native HTML5 DnD; no library. Validated (headless Chrome, synthetic DnD + a section-level drop spy): - SAME-section reorder: section drop suppressed (sectionDrops=0), POST /devices/reorder fires, NO group call, sort_order persists in DB. - CROSS-section: section drop fires (sectionDrops=1), POST /groups/:id/ devices fires and membership actually changes — group-assign unbroken. - The 0-vs-1 contrast proves stopPropagation disambiguates the shared gesture. - 149 server tests green; migration applies clean on the prod-copy DB. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> |
||
|---|---|---|
| .. | ||
| config | ||
| db | ||
| lib | ||
| middleware | ||
| player | ||
| routes | ||
| scripts | ||
| services | ||
| test | ||
| ws | ||
| .gitignore | ||
| config.js | ||
| package-lock.json | ||
| package.json | ||
| server.js | ||
| version.js | ||