screentinker/frontend/js
ScreenTinker 5d24c30ea1 feat(displays): drag-to-reorder display tiles within a section (#106)
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>
2026-06-15 15:15:21 -05:00
..
components feat(admin): Delete Organization + Workspace with cascade (#36) 2026-06-09 09:22:21 -05:00
i18n feat(ui): surface the agency portal handoff at token creation (#73) 2026-06-14 17:54:23 -05:00
views feat(displays): drag-to-reorder display tiles within a section (#106) 2026-06-15 15:15:21 -05:00
agency-portal.js feat: agency zone-grant issuance UI + reactive placement card (#73) 2026-06-14 15:12:55 -05:00
api.js feat(displays): drag-to-reorder display tiles within a section (#106) 2026-06-15 15:15:21 -05:00
app.js feat(signup): optional org-on-create for self-service signups (#12) 2026-06-05 11:16:27 -05:00
brand-prime.js fix(branding): inject instance branding into the app shell, no default flash (#76) 2026-06-11 09:30:23 -05:00
branding.js fix(branding): no ScreenTinker default flash on load/switch (#38) 2026-06-09 11:43:42 -05:00
i18n.js i18n: register Italian locale in language registry (followup to PR #2) 2026-05-11 20:05:09 -05:00
socket.js feat(debug): live per-device debug logging toggle on the device screen 2026-06-08 21:49:03 -05:00
utils.js Phase 2.1: tenancy middleware, permission helpers, JWT workspace context, frontend + backend role-rename compat 2026-05-11 20:02:00 -05:00