* Show tied ranks with T prefix across standings and Discord notifications, fixes #197 - Add buildTiedRankChecker() utility to standings-display.ts; replaces four copies of inline rank-count logic spread across components, the league home route, and the Discord service - Prefix shared ranks with "T" (e.g. "T3") in StandingsTable (league panel), StandingsTable (full standings), the league home preview, and Discord webhook notifications - Add useMemo wrapping in StandingsTable components so tie detection does not recompute on every render - Fix compareTeamsForRanking to round total points to hundredths before comparing, preventing floating-point noise from producing spurious non-ties in the standings Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * Fix discord test to expect escaped period in rank display Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
37 lines
1.5 KiB
TypeScript
37 lines
1.5 KiB
TypeScript
/**
|
|
* Returns a function that reports whether a given rank is shared by more than
|
|
* one team. Pass an array of all the rank values in the standings.
|
|
*
|
|
* @example
|
|
* const isTied = buildTiedRankChecker(standings.map(s => s.currentRank));
|
|
* isTied(3); // true if two or more teams share rank 3
|
|
*/
|
|
export function buildTiedRankChecker(ranks: number[]): (rank: number) => boolean {
|
|
const counts = new Map<number, number>();
|
|
for (const rank of ranks) counts.set(rank, (counts.get(rank) ?? 0) + 1);
|
|
return (rank) => (counts.get(rank) ?? 1) > 1;
|
|
}
|
|
|
|
/**
|
|
* Returns the display rank for a team on the league home standings preview.
|
|
*
|
|
* Rules:
|
|
* - If the team has a standing, return its numeric rank, prefixed with "T" if
|
|
* the rank is shared by more than one team.
|
|
* - If the team has no standing, it is tied at the position just after all
|
|
* ranked teams. For example, if 3 teams have standings the unranked teams
|
|
* show "T4". If no team has standings yet (scores haven't been calculated)
|
|
* every team is genuinely tied at zero and shows "T1".
|
|
*
|
|
* @param standing - The team's standing record, or undefined if none exists.
|
|
* @param standingsCount - Total number of teams that have a standing record.
|
|
* @param isTied - Whether this team's rank is shared with another team.
|
|
*/
|
|
export function getDisplayRank(
|
|
standing: { currentRank: number } | undefined,
|
|
standingsCount: number,
|
|
isTied?: boolean
|
|
): number | string {
|
|
if (standing) return isTied ? `T${standing.currentRank}` : standing.currentRank;
|
|
return `T${standingsCount + 1}`;
|
|
}
|