Skip to content

feat: edit events and shifts in place, sort members per track - #103

Merged
ethnjs merged 56 commits into
mainfrom
feat/event-logistics
Oct 5, 2026
Merged

ethnjs merged 56 commits into
mainfrom
feat/event-logistics

Conversation

@ethnjs

@ethnjs ethnjs commented Oct 5, 2026 •

Copy link
Copy Markdown
Owner

Summary

Follow-up to #102 — everything on feat/event-logistics since it merged.

  1. The events table is edited in place, cell by cell, with spreadsheet-style keyboard navigation.
  2. The shifts table gets date and duration columns, inline editing, saved filters and chained sorting.
  3. The members table gains dietary, event preference and lunch columns, chained sorting (including per-track fields), and bulk removal.
  4. The assignments board sorts its member belt per tab and shows more fields on member cards.

What changed

Backend

Models and migrations

alembic upgrade head required — 1 revision, data only.

  • Renames each simple tournament's only live track to the tournament's short name, else its name; skipped where a pending-delete track already holds that name. (8a438a1a14a3)
  • Destroys data: the old track names aren't recorded, so the downgrade is a no-op.
  • TournamentEventTrack.effective_floor returns the floor override if set, else the first character of the first room; no column change.
  • TournamentEvent.name on a catalog-linked event is now a tournament-level override of the catalog name (comment and docstring only).

Schemas and routes

  • Display config: new shifts_table surface (filters track, events; sorts label, track, date, start, end, duration, events).
  • Display config: new page_header surface holding only collapsed; collapsed on any other surface is a 422.
  • Events table and board share one filter vocabulary, adding track, building, shifts, shift and staffing; both add division as a sort key.
  • Events table defaults to division, type, category, tracks and time; time is one column, and old time:<id> keys stay valid.
  • Members table and assignment cards accept onboarding plus per-track sort fields (track:, availability_track:, event_pref:<track>:<event>, lunch:<track>:<key>).
  • Members columns add dietary_restriction and event preferences; lunch columns appear for published lunch questions before anyone answers.
  • Assignment cards add onboarding, dietary_restriction, lunch and custom_fields, with card_custom:<field_id> to hide one question.
  • PATCH /shifts/{id} rejects a result that ends at or before its start, checked after merging a partial patch.

Logic

  • sync_sole_track_name runs after tournament renames, track edits and track deletes, so a track rename on a simple tournament is put back rather than refused.
  • Zone resolution matches on effective_floor, so a floor derived from rooms resolves to its floor zone.

Frontend

Events

  • Inline editing for every cell, with arrow keys and Tab moving between cells and out of open editors.
  • Location is one keyboard-first text box; empty cells read No location / No staffing instead of dashes.
  • Toolbar collapses to icon buttons when narrow; header sorting by name, division and category.
  • Rows memoized behind stable callbacks, so focusing an event or sliding a panel no longer rebuilds the table.

Shifts

  • Date and duration columns; inline editing for label, track, date and times, checked before saving.
  • Collapsible header and events-style toolbar with search, saved filters and a sort chain.
  • Arrow-key and Tab navigation; failed edits report in a toast instead of under the cell.

Members

  • Dietary restriction, ranked event preference and question-based lunch columns; free-text columns size to fit.
  • Event preferences filter by rank; popovers stay inside the viewport.
  • Roster sorts by a saved chain of rules, picked by category then pills; Display gets a reset.
  • Select toolbar removes selected members, skipping anyone you can't remove (RemoveMembersModal).

Assignments board

  • Member belt sorts per tab, sharing the roster's sort rules.
  • Member cards can show onboarding, dietary, lunch and custom field answers.

Layout and settings

  • Settings section and its pages show in the folded crumb (useSettingsPages, SettingsPageHeader).
  • A clicked crumb dropdown drops its border once the cursor moves away.
  • Folded page header centers on the topbar; the folded state is saved per viewer (useHeaderCollapse).

Shared UI

  • New: OptionList replaces the separate Dropdown, Combobox and suggestion lists; Enter fills in the first match.
  • New: DivisionButtonGroup for every division picker, SortableHeader for chained header sorting, PillInput.
  • New: lib/gridNav.ts for table cell navigation, lib/memberSort.ts and lib/shiftSort.ts for sort chains.
  • Popover checklists and the table's button-group pickers work from the keyboard.
  • Badge uses its own mono font instead of inheriting one.
  • Panel and tab ids are mirrored into the URL with replaceState instead of a router navigation.

Out of scope

  • The buildings page, and the building and zone backend features: they ship with feat/buildings-and-zones.

Test plan

  • pytest passes locally
  • Migration included for every model change
  • Clicked through the UI change in a browser

Automated

  • test_display_config.py: shifts table and page header surfaces, collapsed rejection, per-track member sort fields, new card fields.
  • test_tracks.py: sole track renamed on tournament rename, track edit and delete down to one.
  • test_shifts.py: a patch ending before its start is rejected.
  • test_memberships.py: filtering event preferences by rank.
  • test_zones.py: a floor rule matches the floor derived from the first room, and a typed floor overrides it.

Manual

  • Events table: edit each cell type, move with arrows and Tab, then reload and confirm the saved values.
  • Shifts table: edit a shift's times so it ends before it starts and confirm the error toast.
  • Members table: add a sort chain with a per-track rule, reload, and confirm it persists.
  • Members table: select members including one you can't remove and confirm they're skipped.
  • Assignments: switch tabs and confirm each keeps its own belt sort.
  • Rename a simple tournament and confirm its track is renamed with it.

ethnjs added 30 commits October 4, 2026 21:46
… shared by the events table and assignments board
…nd time, with reset in the Display button and modal
…rom an expand button, and add DivisionButtonGroup for every division picker
…firming before a track takes its shifts with it
… deriving floor from the first room unless overridden
…us restored after edits, and tracks/shifts at rest until opened
…show 'No location'/'No staffing' instead of dashes
…onList, with Enter filling in the first match
…, so a sliding panel stops re-rendering the table
ethnjs added 21 commits October 5, 2026 00:37
…ed table edits in a toast instead of under the cell
…-based lunch columns, chip the per-track groups, and fold the header; sort shifts by date
…mns to fit instead of truncating, and keep roles wide
…ity, lunch and event preference rank, picked by category then pills
…ed crumb, and drop a clicked crumb dropdown's border once you move away
…he tab-scoped board key, and drop the stale staffing-sort test
@vercel

vercel Bot commented Oct 5, 2026 •

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
nexus Ready Ready Preview Oct 5, 2026 8:16pm UTC

@railway-app

railway-app Bot commented Oct 5, 2026 •

Copy link
Copy Markdown

🚅 Deployed to the nexus-pr-103 environment in nexus

Service Status Web Updated
nexus ✅ Success (View Logs) Oct 5, 2026 at 8:15 pm UTC

@railway-app
railway-app Bot temporarily deployed to nexus / nexus-pr-103 October 5, 2026 19:09 Destroyed
@railway-app
railway-app Bot temporarily deployed to nexus / nexus-pr-103 October 5, 2026 20:15 Destroyed
@ethnjs ethnjs changed the title feat(events): edit events and shifts in place, sort members per track, and name sole tracks after the tournament feat(events): edit events and shifts in place, sort members per track Oct 5, 2026
@ethnjs ethnjs changed the title feat(events): edit events and shifts in place, sort members per track feat: edit events and shifts in place, sort members per track Oct 5, 2026
@ethnjs
ethnjs merged commit b58a89d into main Oct 5, 2026
4 of 6 checks passed

This branch was successfully deployed

1 active deployment
Preview — 6b6c3647 Deployed Oct 5, 2026 by vercel[bot]
nexus / nexus-pr-103 — 6b6c3647 Deployed Oct 5, 2026 by railway-app[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant