bug: fix panel bugs #507, #515, #607, #608, #609, #610, #617, #618, #619 - #576
Merged
Merged
Conversation
Specs live in tests/ and run inside the real Nuxt app; yarn test runs them and CI runs them on pull requests.
<component :is="'NuxtLink'"> resolves NuxtLink from the component registry, which this app never populates, so it rendered an unknown <nuxtlink> element. Fixes 5stackgg/5stack-panel#608
Mirrors the api: an odd field's bye is a free win, so a 15-team Valve Swiss sends 8 teams on.
The form offered up to 256 teams in a single round robin group. Every pairing is a bracket row rebuilt on each stage edit, so 256 teams meant 32,640 rows. Each group now takes up to 32 teams, the old limit, and more groups still reach 256.
Mirrors the api guard: once the bracket is seeded, turning substitutes off strands a team at its minimum. The switch can still turn them back on.
The event page rendered its member tournaments as a bordered div with a status badge and the name, in both the Tournaments tab and the Overview section, because the event subscription only selected id/name/status/start for the nested tournament. It now spreads simpleTournamentFields and uses TournamentCard, stacked like /tournaments, /watch and /play. A mixed-status list has no section header to hoist the status variant onto, so tournamentStatusVariant() derives it per card from the same groupings the /tournaments status filter uses. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The readout is built for a fifteen-minute match check-in, where H:MM:SS always reads as a clock. Reused for a tournament check-in window that can open weeks out, it degenerated into "1390:29:38". Past a day it now shows days and hours, ticks once a minute instead of once a second, and follows the hour rather than the minute for the rollover. Under a day it is the exact clock as before, and the ticker goes back to 1s on the crossing. The heading had the same problem: "Check-in opens at 04:00 PM" for a window two months out reads as today. It now carries the date when the window is not today, and the year when it is not this year. required_window keeps the clock -- "between X and Y on the day" is describing the window's shape. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The outlined echo behind the hero name was held to one line, so a title that wrapped left it running out across the banner. It already takes the title's own width from left-5/right-[-5px], so dropping the nowrap breaks it at the same points and echoes each line. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The region section only ever offered online regions, so a stage could not be pointed at a LAN region. A LAN switch -- shown to match_organizer and above, and only when a LAN region exists -- swaps the region list to the LAN ones and turns region veto off, since there is nothing to veto on a single hall. The switch is inferred back from the stage's saved regions, so reopening a LAN stage shows it on with its region named in the select rather than an empty placeholder. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This was referenced Sep 18, 2026
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.
This fixes the open
[BUG]issues from 5stack-panel #507 onward that need web changes. It pairs with 5stackgg/api#408.It also adds a vitest test setup, since web had no automated tests. Every fix below began with a failing test that reproduced the bug.
Deploy notes
tournaments.substitutes_enabled(feature: import a Valve match from a pasted share code #619). If web ships before the api migration andhasura metadata apply, Hasura rejects the whole subscription and tournament pages go blank.yarn codegenagainst the migrated stack so the zeus types includesubstitutes_enabled. It works at runtime without codegen; only the editor types lag.validation_extras.min_max_teams_min_valuekey is removed (16/16 locales match en.json).Test infrastructure (vitest)
@nuxt/test-utils3.23 in thenuxtenvironment, with happy-dom and@vue/test-utils. Every spec runs inside the real Nuxt app: auto-imports, i18n, pinia, the router and NuxtLink.nuxt.config.tsis unchanged..nuxt/vitest, so it never overwrites the dev server's.nuxt.yarn testruns the suite,yarn test:watchwatches.tests/, mirroring the source path.mountSuspended.// @vitest-environment node.nuxtenvironment. Splitting into projects boots two Nuxt instances in one process and randomly loses auto-imports.resolutionspin stops yarn from nesting test-utils 4 and a second copy of Vue.tests/setup.tswaits out vaul-vue's and the preloader's real 200–300ms timers before the environment removesdocument; otherwise the run fails on an unhandleddocument is not defined.testTimeoutis 30s because the first test in a file pays for the Nuxt boot..github/workflows/tests.ymlruns on pull requests and on pushes to main/beta.#608 Teams participating in an Event are not clickable
Problem. Team cards on the event page look clickable (hover styles) but go nowhere. The same happens with:
Root cause.
<component :is="team.id ? 'NuxtLink' : 'div'">passes NuxtLink as a string, which Vue resolves at runtime from the component registry. Nuxt only rewrites literal<NuxtLink>tags into imports, and this app registers no global components. So Vue rendered an unknown<nuxtlink>element instead of an<a>.Fix.
import { NuxtLink } from "#components"and bind the component itself, the patternTournamentDetail.vuealready uses. That covers 9 sites:Tests.
<a href="/teams/<id>">for real teams and no link for ad-hoc teams.#607 Events page displays past events big, upcoming events small
Problem.
/eventsshowed past events as large full-width heroes and upcoming events as small tiles.Root cause.
EventSquarerow and Finished usedEventHeroin a 2-column grid.starts_at descwith limit/offset and only then split it into Live/Upcoming/Past. Page 1 held the furthest-future events, while live, soonest-upcoming and recent past events spilled onto later pages, and every page repeated all three sections.Fix.
eventPhaseWhere, which matches the client-sideeventPhase. All three share one$now.EventSquare's phase chip is coloured by phase and shows start–end dates.?pageare gone.Tests.
EventSquarespec covers the chip colour and date range.EventHerospec covers lazy images and videos that only play on screen.eventPhaseWhere≡eventPhase, including edge cases.#609 Manual awards can't be granted to the user granting them
Problem. In Grant Award (on /awards, /awards/:id, seasons and events), searching for yourself never finds you.
Root cause.
AwardComposerusedPlayerSearchwithout:self="true", so PlayerSearch:exclude(becoming a Typesensesteam_id:!=filter)The api already allows self-grants.
Fix. Pass
:self="true", as the other pickers that allow selecting yourself do.Tests.
AwardComposer.spec.ts:#610 Manually granted awards don't show up for teams
Problem. A manual team grant shows in the award log and on every roster player, but not on the team page or in the /teams list.
Root cause.
team_idand notournament_team_id.tournament_team.team_id.tournament_team?.team_idand never selectedteam_id.TeamsTableassumed every award had a tournament, so it showed "#null" and "Tournament", and clicking went nowhere.Fix.
team_id. Calculated tournament rows set it too.source = 'tournament'.TeamsTablenames manual grants by the award, labels them "Granted" with the grant date, and links them to/awards/:id, including manual grants made inside a tournament.AwardCaseandAwardModalalso title and date a manual grant by the award rather than its tournament.Tests.
tests/pages/teams/teamAwards.spec.tsruns the pages' real subscriptions over stored rows.TeamsTable.spec.tscovers the label, the click target and the tooltip.AwardCase.spec.tsandAwardModal.spec.tscover manual grants made inside a tournament.#515 Android PWA does not show install
Problem. On Android phones there was no way to install the app. On Android, the Settings → Notifications card said "Already installed?" even when the app wasn't installed.
Root cause.
TopNav, which has hiddenInstallPWAat ≤ 768px since chore: refactor menus #157, with nothing in its place.beforeinstallprompthad been captured.preventDefault()on that event, which also suppresses Chrome's own install banner.The manifest and service worker were verified installable on 5stack.gg.
Fix.
usePwaInstallhas a manual-install state (ios,androidorin_app) for when there's no install dialog and the app isn't running standalone.install()opens Chrome's dialog when it's available, and otherwise shows platform-specific steps.InstallPWADrawer, with Android and in-app-browser steps added. The iOS steps are unchanged.Tests. Vitest specs cover
usePwaInstall,InstallPWA,ProfileMenu,TopNavat 412px, and the notification-preferences page.On-device QA needed.
#507 / #617 / #618 Tournament stage form
Problem. The stage form enforced the old rules the api has now relaxed:
Fix. The new
utilities/tournamentStageTeams.tsmirrors the api'svalidate_tournament_stagerules, andTournamentStageFormuses it for both options and validation:Validation messages show the actual counts.
Tests.
tests/utilities/tournamentStageTeams.spec.ts#619 Tournament substitutes setting
test/tournament-substitutes.spec.ts).