diff --git a/app/db/tables.ts b/app/db/tables.ts index 2ec212347..88b9fa1fb 100644 --- a/app/db/tables.ts +++ b/app/db/tables.ts @@ -569,6 +569,7 @@ export interface TournamentRound { maps: ColumnType; } +// when updating this also update `defaultBracketSettings` in tournament-utils.ts export interface TournamentStageSettings { // SE thirdPlaceMatch?: boolean; diff --git a/app/features/calendar/actions/calendar.new.server.ts b/app/features/calendar/actions/calendar.new.server.ts index 256ecc469..bb7a68a40 100644 --- a/app/features/calendar/actions/calendar.new.server.ts +++ b/app/features/calendar/actions/calendar.new.server.ts @@ -92,8 +92,6 @@ export const action: ActionFunction = async ({ request }) => { rankedModesShort.find((mode) => mode === data.toToolsMode) ?? null, bracketProgression: data.bracketProgression ?? null, minMembersPerTeam: data.minMembersPerTeam ?? undefined, - teamsPerGroup: data.teamsPerGroup ?? undefined, - thirdPlaceMatch: data.thirdPlaceMatch ?? undefined, isRanked: data.isRanked ?? undefined, isInvitational: data.isInvitational ?? false, deadlines: data.strictDeadline ? ("STRICT" as const) : ("DEFAULT" as const), @@ -101,8 +99,6 @@ export const action: ActionFunction = async ({ request }) => { enableSubs: data.enableSubs ?? undefined, requireInGameNames: data.requireInGameNames ?? undefined, autonomousSubs: data.autonomousSubs ?? undefined, - swissGroupCount: data.swissGroupCount ?? undefined, - swissRoundCount: data.swissRoundCount ?? undefined, tournamentToCopyId: data.tournamentToCopyId, regClosesAt: data.regClosesAt ? dateToDatabaseTimestamp( @@ -283,35 +279,8 @@ export const newCalendarEventActionSchema = z checkboxValueToBoolean, z.boolean().nullish(), ), - // - // tournament format related fields - // - bracketProgression: bracketProgressionSchema.nullish(), minMembersPerTeam: z.coerce.number().int().min(1).max(4).nullish(), - withUndergroundBracket: z.preprocess(checkboxValueToBoolean, z.boolean()), - thirdPlaceMatch: z.preprocess( - checkboxValueToBoolean, - z.boolean().nullish(), - ), - teamsPerGroup: z.coerce - .number() - .min(TOURNAMENT.MIN_GROUP_SIZE) - .max(TOURNAMENT.MAX_GROUP_SIZE) - .nullish(), - swissGroupCount: z.coerce.number().int().positive().nullish(), - swissRoundCount: z.coerce.number().int().positive().nullish(), - followUpBrackets: z.preprocess( - safeJSONParse, - z - .array( - z.object({ - name: z.string(), - placements: z.array(z.number()), - }), - ) - .min(1) - .nullish(), - ), + bracketProgression: bracketProgressionSchema.nullish(), }) .refine( async (schema) => { diff --git a/app/features/calendar/components/BracketProgressionSelector.tsx b/app/features/calendar/components/BracketProgressionSelector.tsx index 9127d9f25..a65d6061d 100644 --- a/app/features/calendar/components/BracketProgressionSelector.tsx +++ b/app/features/calendar/components/BracketProgressionSelector.tsx @@ -10,6 +10,7 @@ import { SendouSwitch } from "~/components/elements/Switch"; import { PlusIcon } from "~/components/icons/Plus"; import { TOURNAMENT } from "~/features/tournament"; import * as Progression from "~/features/tournament-bracket/core/Progression"; +import { defaultBracketSettings } from "../../tournament/tournament-utils"; const defaultBracket = (): Progression.InputBracket => ({ id: nanoid(), @@ -154,7 +155,15 @@ function TournamentFormatBracketSelector({ const isFirstBracket = count === 1; const updateBracket = (newProps: Partial) => { - onChange({ ...bracket, ...newProps }); + const defaultSettings = newProps.type + ? defaultBracketSettings(newProps.type) + : undefined; + + onChange({ + ...bracket, + ...newProps, + settings: newProps.settings ?? defaultSettings ?? bracket.settings, + }); }; return ( diff --git a/app/features/tournament/tournament-utils.ts b/app/features/tournament/tournament-utils.ts index 6ded940ea..d612f69cf 100644 --- a/app/features/tournament/tournament-utils.ts +++ b/app/features/tournament/tournament-utils.ts @@ -5,6 +5,8 @@ import { rankedModesShort } from "~/modules/in-game-lists/modes"; import { weekNumberToDate } from "~/utils/dates"; import invariant from "~/utils/invariant"; import { tournamentLogoUrl } from "~/utils/urls"; +import type { Tables, TournamentStageSettings } from "../../db/tables"; +import { assertUnreachable } from "../../utils/types"; import { MapPool } from "../map-list-generator/core/map-pool"; import { currentSeason } from "../mmr/season"; import { BANNED_MAPS } from "../sendouq-settings/banned-maps"; @@ -307,3 +309,32 @@ export function resolveLeagueRoundStartDate( return date; } + +export function defaultBracketSettings( + type: Tables["TournamentStage"]["type"], +): TournamentStageSettings { + switch (type) { + case "single_elimination": { + return { + thirdPlaceMatch: true, + }; + } + case "double_elimination": { + return {}; + } + case "round_robin": { + return { + teamsPerGroup: 4, + }; + } + case "swiss": { + return { + roundCount: 5, + groupCount: 1, + }; + } + default: { + assertUnreachable(type); + } + } +}