Repository navigation
feat(frontend): team assignment page - #323
Merged
Merged
Conversation
Teams are now built from the downloaded spreadsheet or by dragging, so the automatic suggestion only competed with that for attention. Drop the button, its handler, and the distribution algorithm nothing else used. PlannedTeam and initialsOf stay; the CSV import and "+ Add Team" still need them.
The upload rules lived in a tooltip on "Upload CSV", where nobody found them. Group Download, Upload and a new "How the file works" toggle under a Spreadsheet label; the panel lists the three steps and what each kind of edit does on upload, mirroring applyAssignmentCsv's rules. An upload that reports problems links straight to it.
Only multiple-choice questions reached the Manage Teams legend. Letter all of them: a tick-box codes as Yes/No like a two-option list, and a free-text answer is carried whole under the question's letter and shown as a truncated line under the name, full text on hover. The panel becomes one row per question with its codes and a "Show on cards" toggle.
Clicking an answer in the questions panel narrows the Unassigned column to the people who gave it; a free-text question gets a "contains" box. Answers to one question widen the filter, different questions narrow it. Each answer shows how many unassigned people gave it. Active filters show as removable tags above the pool with a count and "Reset filters", and are kept per hackathon in the browser, keyed by question id and answer text so a shifted letter cannot redirect them.
Matching, toggling, restoring saved filters and answer counts move from the Manage Teams page into $lib/utils/teamPoolFilter with unit tests. Behaviour is unchanged.
… rest A filter on Unassigned now reorders rather than hides: matches come first, everyone else follows greyed out under "Not matching" and stays draggable. Someone dragged back into the pool no longer disappears, and a filter left on from an earlier visit cannot hide people.
"N want in" on each project row becomes a toggle that brings the unassigned people who picked that project to the top, shown as a "Prefers 3" tag beside the answer filters. Projects widen among themselves and narrow against answers, like a question. Saved project filters for projects that no longer have a row are dropped on restore.
The spreadsheet is now where teams are planned, so every registration question gets a column, free text included. Long answers stay in their cell; the writer already quotes line breaks. Values are written as stored, matching csvRow's existing choice for names.
The intro paragraph, the questions panel hint and the organizer's "you are not here" note go; the page's controls speak for themselves and the spreadsheet rules stay in "How the file works". The loader's ownerMissingFromPool flag existed only for that note and goes with it.
A "Project preferences" box below the registration questions holds one pill per approved project with how many unassigned people picked it, so every filter on the page lives in one place and works one way. The "N want in" toggles on the project rows go back to plain text. The box also gets a "Show on cards" toggle for the "Prefers …" line, on by default and remembered per hackathon like the question ticks.
Codes like "A5" sent the reader to the legend to find out what they meant. Cards now show the question's letter with the answer itself — "A: XL", "B: No" — in a small tag, the full question on hover, and a free-text answer as a "C: …" line of its own. Filter tags read the same way. The questions box keeps its letters, and its answer pills drop the codes since the letter is already on the row. Project numbers stay as they were.
A question's letter in the questions box becomes a button that sets a short name, so cards and filter tags read "size: S" instead of "B: S". A yes/no question instead gets its own words for Yes and No, and then shows "remote" or "on site" alone, falling back to its letter for a side left unnamed. Names are kept per hackathon in the browser like the "Show on cards" ticks, and are display-only: filters still match the stored answer.
A yes/no answer reads "Yes" or "No" on a card, or the organizer's own words for them, so the letter in front added nothing. Tick-boxes no longer take a letter in answerLegend, keeping A, B, C gap-free for the questions that use one, and their naming button in the questions box is just a pencil.
…ignment The upload now treats the file as the complete assignment: a row with a project and a team assigns, a row with neither unassigns, and a team the file leaves empty is removed. Anything wrong — one of the two columns missing, an unknown project or person, a duplicate, or no row for someone on a team — cancels the whole file, so it applies completely or not at all. Someone unassigned with no row, likely new since the download, only warns. The page asks before an upload takes people off teams, and "How the file works" describes the new rules.
An upload now replaces all teams with the ones the file names, each a new team. A row assigns a person when it has a project from the page and a team name of at least three characters; any other row, a duplicate, or a person with no row leaves that person unassigned with a warning. Only a file without the needed columns is refused. The info box is rewritten around these rules and keeps only what an organizer needs to know.
…are published Changing teams after a submission or after publishing them would either delete a submission or reshuffle people who have been told their team. The page now says why it is locked and disables Clear all, Upload, Discard and Save, and the team cards go read-only; download and the participant filters still work. The save action re-checks, and a failed submission check locks rather than guesses open. A backend check follows in a separate pull request.
A team with nobody in it is not part of the assignment, so Save no longer creates an empty new team and deletes an emptied saved one. The unsaved changes summary counts empty teams the same way, and an empty team card says it will be removed.
sabinem
force-pushed
the
feat/team-assignment-page
branch
from
October 8, 2026 11:13
3fb6b21 to
eed5764
Compare
macOS hides scrollbars until hover, so a long Unassigned list looked like it ended at the bottom of its box. A new theme class, .scroll-visible, styles the scrollbar, which keeps it visible in Chrome, Edge and Safari; Firefox gets a thin themed one and still follows the system setting.
…heet The download writes each project as the number the page shows, in the project and prefers columns, with a project_title column beside it; the upload reads numbers (titles still work) and warns about a row whose title no longer matches its number, which catches a file from before the numbering moved. Page and file share one numbering helper. Team names may be anything non-empty, down to a single character.
Once a team has a submission or teams are published, only what would rebuild the teams is off: upload, Clear all, adding and deleting teams. People can still be moved between teams or to Unassigned and teams renamed, so a late dropout can be handled; an emptied team is kept. The save action refuses a plan that adds or deletes a team in that state.
The project_title column goes from the download and the upload: the on-screen number is what organizers work with. A row whose project is not one of the page's numbers — a title, a typo, an unknown number — is no longer an assignment; that person is warned about and left unassigned.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Manage Teams: plan in a spreadsheet, filter by answers and preferences, lock once teams are in use
As an organizer assigning 100+ participants to teams, I can now see what everyone answered at registration and which projects they want, bring the right people to the top of the Unassigned list, and plan the whole assignment in a spreadsheet. Once teams are in use, the page protects them.
Before: the page opened with a "Suggest teams" button nobody should use. The upload rules were hidden in a tooltip. Only multiple-choice registration questions showed up, as codes like "B2" that needed a legend. Finding "beginners who want project 3" meant scrolling through every card. Nothing stopped an organizer from reshuffling teams that already had submissions.
Now:
projectandpreferscolumns, with aproject_titlecolumn beside the number. The download now includes free-text answers.project_titleno longer matches its number gets a warning too. That catches a file downloaded before a project was approved or rejected.Deliberately left out
TeamServicestill accepts adding or deleting teams in that state from other callers. A backend check is planned for a follow-up PR, markedTODO(backend: team-assignment-lock).=could be run as a formula by a spreadsheet. This matches how names were already exported.