Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@
"@types/react-dom": "19.2.3",
"@uiw/react-codemirror": "^4.25.4",
"@vitejs/plugin-react": "^5.1.2",
"@wca/helpers": "^1.1.6",
"@wca/helpers": "2.0.0",
"clsx": "^2.1.1",
"country-flag-icons": "^1.6.8",
"date-fns": "^4.1.0",
Expand Down Expand Up @@ -68,7 +68,6 @@
"vite-plugin-pwa": "^1.2.0",
"vite-plugin-svgr": "^4.3.0",
"vite-tsconfig-paths": "^6.0.5",
"wca-group-generators": "^0.1.8",
"web-vitals": "^5.1.0"
},
"devDependencies": {
Expand Down
7 changes: 6 additions & 1 deletion src/components/Errors/renderers/ValidationErrorRenderer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,15 @@ export const ValidationErrorRenderer = ({ error }: ValidationErrorRendererProps)
assignmentCode: string;
activity: Activity;
}) => {
const registrantId = error.data.person?.registrantId;
if (registrantId === null || registrantId === undefined) {
return;
}

dispatch(
bulkRemovePersonAssignments([
{
registrantId: error.data.person?.registrantId,
registrantId,
activityId: activity.id,
assignmentCode,
},
Expand Down
2 changes: 1 addition & 1 deletion src/components/RoundLimitInfo.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ export const RoundLimitInfo = ({
<Typography>Cutoff:</Typography>
<Typography>
{round.cutoff.numberOfAttempts} attempts to get {'< '}
{renderResultByEventId(eventId as EventId, 'average', round.cutoff.attemptResult)}
{renderResultByEventId(eventId as EventId, 'average', round.cutoff.resultValue)}
</Typography>
{personsShouldBeInRound.length > 0 && (
<Typography>
Expand Down
3 changes: 2 additions & 1 deletion src/components/RoundSelector/_tests_/RoundListItem.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
}));

vi.mock('../../../lib/domain/activities', async () => {
const actual = await vi.importActual<typeof import('../../../lib/domain/activities')>(

Check warning on line 24 in src/components/RoundSelector/_tests_/RoundListItem.test.tsx

View workflow job for this annotation

GitHub Actions / lint

`import()` type annotations are forbidden
'../../../lib/domain/activities'
);

Expand All @@ -36,10 +36,11 @@
it('renders group and assignment summaries', () => {
const round: Round = {
id: '333-r1',
linkedRounds: null,
format: 'a',
timeLimit: null,
cutoff: null,
advancementCondition: null,
participationRuleset: null,
results: [],
scrambleSetCount: 1,
extensions: [],
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
import ConfigureAssignmentsDialog from './ConfigureAssignmentsDialog';
import { buildActivity, buildEvent, buildPerson, buildRound } from '../../store/reducers/_tests_/helpers';
import {
buildActivity,
buildEvent,
buildPerson,
buildRound,
} from '../../store/reducers/_tests_/helpers';
import INITIAL_STATE, { type AppState } from '../../store/initialState';
import reducer from '../../store/reducer';
import { renderWithProviders } from '../../test-utils';
Expand Down Expand Up @@ -72,7 +77,7 @@ const buildWcif = (persons: Person[]): Competition => ({
id: 'test-competition',
name: 'Test Competition',
shortName: 'Test',
formatVersion: '1.0',
formatVersion: '2.0',
persons,
events: [
buildEvent({
Expand Down Expand Up @@ -115,11 +120,7 @@ const buildState = (persons: Person[] = [person]): AppState => ({
});

const renderWithStore = (ui: ReactElement, state = buildState()) => {
const store = createStore(
reducer as Reducer<AppState, AnyAction>,
state,
applyMiddleware(thunk)
);
const store = createStore(reducer as Reducer<AppState, AnyAction>, state, applyMiddleware(thunk));

return {
store,
Expand Down
8 changes: 4 additions & 4 deletions src/dialogs/ConfigureAssignmentsDialog/formatSeedResult.ts
Original file line number Diff line number Diff line change
@@ -1,21 +1,21 @@
import {
type AttemptResult,
type ResultValue,
decodeMultiResult,
type EventId,
formatCentiseconds,
formatMultiResult,
type RankingType,
} from '@wca/helpers';

const isValidResult = (result: AttemptResult | null | undefined) =>
const isValidResult = (result: ResultValue | null | undefined) =>
result !== null && result !== undefined && !Number.isNaN(result as number);

const formatFewestMovesAverage = (result: AttemptResult) => ((result as number) / 100).toFixed(2);
const formatFewestMovesAverage = (result: ResultValue) => (result / 100).toFixed(2);

export const formatSeedResult = (
eventId: EventId,
rankingType: RankingType,
result?: AttemptResult
result?: ResultValue
) => {
if (!result) {
return '-';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import {
acceptedRegistration,
byPROrResult,
getSeedResult,
hasRegistrantId,
isOrganizerOrDelegate,
registeredForEvent,
shouldBeInRound,
Expand Down Expand Up @@ -30,6 +31,7 @@ export function usePersonsData(
}

const personsWithSeedResult = wcif.persons
.filter(hasRegistrantId)
.filter((p) => {
// if competitor does not have an accepted registration, do not show them
if (!acceptedRegistration(p)) {
Expand Down
9 changes: 5 additions & 4 deletions src/dialogs/ConfigureAssignmentsDialog/types.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
import type { ActivityWithParent } from '../../lib/domain/activities';
import type { AttemptResult, Person } from '@wca/helpers';
import type { PersonWithRegistrantId } from '../../lib/domain/persons';
import type { ResultValue } from '@wca/helpers';

export type CompetitorSort = 'speed' | 'name';

export interface PersonWithSeedResult extends Person {
export interface PersonWithSeedResult extends PersonWithRegistrantId {
seedResult: {
ranking: number;
average?: AttemptResult;
single?: AttemptResult;
average?: ResultValue;
single?: ResultValue;
};
}

Expand Down
10 changes: 5 additions & 5 deletions src/dialogs/ConfigureAssignmentsDialog/utils/calcRanking.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
import type { AttemptResult, Person } from '@wca/helpers';
import type { Person, ResultValue } from '@wca/helpers';

export function calcRanking(
person: Person & {
seedResult?: {
average?: AttemptResult;
single?: AttemptResult;
average?: ResultValue;
single?: ResultValue;
};
},
lastPerson?: Person & {
seedResult?: {
ranking?: number;
average?: AttemptResult;
single?: AttemptResult;
average?: ResultValue;
single?: ResultValue;
};
}
) {
Expand Down
7 changes: 3 additions & 4 deletions src/dialogs/ConfigureStationNumbersDialog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import {
parseActivityCode,
roomByActivity,
} from '../lib/domain/activities';
import { byPROrResult, getSeedResult } from '../lib/domain/persons';
import { byPROrResult, getSeedResult, type PersonWithRegistrantId } from '../lib/domain/persons';
import { useAppSelector } from '../store';
import { bulkUpsertPersonAssignments, upsertPersonAssignments } from '../store/actions';
import { selectPersonsAssignedForRound } from '../store/selectors';
Expand All @@ -26,7 +26,7 @@ import {
GridToolbarContainer,
} from '@mui/x-data-grid';
import { formatCentiseconds } from '@wca/helpers';
import type { Activity, Assignment, Person, Room } from '@wca/helpers';
import type { Activity, Assignment, Room } from '@wca/helpers';
import { useCallback, useMemo, useRef } from 'react';
import { useDispatch } from 'react-redux';

Expand All @@ -38,7 +38,7 @@ type ExtendedAssignment = Assignment & {

type SeedResult = ReturnType<typeof getSeedResult>;

type PersonWithAssignment = Person & {
type PersonWithAssignment = PersonWithRegistrantId & {
assignment: ExtendedAssignment;
seedResult?: SeedResult;
};
Expand Down Expand Up @@ -129,7 +129,6 @@ const ConfigureStationNumbersDialog = ({
a.push({
...p,
assignment: competitorAssignment,
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
seedResult: getSeedResult(currentWcif, activityCode, p),
});
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { byPROrResult, findRoundActivitiesById, parseActivityCode } from '../domain';
import { isCompetitorAssignment, missingCompetitorAssignments } from '../domain';
import { personsShouldBeInRound } from '../domain';
import { hasRegistrantId, personsShouldBeInRound } from '../domain';
import { type InProgressAssignmment } from '../types';
import { byName } from '../utils';
import { createGroupAssignment } from '../wcif';
Expand Down Expand Up @@ -73,6 +73,7 @@ export const generateAssignmentsForRoundAttempt = (

return (assignments: InProgressAssignmment[]): InProgressAssignmment[] => {
const persons = personsShouldBeInRound(round)(wcif.persons)
.filter(hasRegistrantId)
.filter(missingCompetitorAssignments({ assignments, groupIds: attemptActivityIds }))
.sort(byName)
.sort(byPROrResult(event, roundNumber));
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { type ActivityWithParent, findGroupActivitiesByRound, parseActivityCode } from '../domain';
import { hasStaffAssignment, isStaffAssignment, missingCompetitorAssignments } from '../domain';
import { personsShouldBeInRound } from '../domain';
import { hasRegistrantId, personsShouldBeInRound } from '../domain';
import { type InProgressAssignmment } from '../types';
import { createGroupAssignment, previousGroupForActivity } from '../wcif';
import { type Competition, type Event, type Person } from '@wca/helpers';
Expand Down Expand Up @@ -64,6 +64,7 @@ export const generateCompetingAssignmentsForStaff = (
const groupIds = groups.map((g) => g.id);

const persons = personsShouldBeInRound(round)(wcif.persons)
.filter(hasRegistrantId)
.filter(hasStaffAssignment({ groupIds }))
.filter(missingCompetitorAssignments({ groupIds }));

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { findGroupActivitiesByRound, parseActivityCode } from '../domain';
import { isCompetitorAssignment, missingCompetitorAssignments } from '../domain';
import { byPROrResult, personsShouldBeInRound } from '../domain';
import { byPROrResult, hasRegistrantId, personsShouldBeInRound } from '../domain';
import { type InProgressAssignmment } from '../types';
import { byName } from '../utils';
import { createGroupAssignment } from '../wcif';
Expand Down Expand Up @@ -29,18 +29,21 @@ export const generateCompetingGroupActitivitesForEveryone = (
allExistingCompetiorAssignments[group.id] = 0;
}

personsInRound.reduce((sizes, person) => {
const competingAssignment = person.assignments?.find(
(a) => groupIds.includes(+a.activityId) && isCompetitorAssignment(a)
);
personsInRound.reduce(
(sizes, person) => {
const competingAssignment = person.assignments?.find(
(a) => groupIds.includes(+a.activityId) && isCompetitorAssignment(a)
);

return {
...sizes,
...(competingAssignment
? { [competingAssignment.activityId]: sizes[+competingAssignment.activityId] + 1 }
: {}),
};
}, {} as Record<number, number>);
return {
...sizes,
...(competingAssignment
? { [competingAssignment.activityId]: sizes[+competingAssignment.activityId] + 1 }
: {}),
};
},
{} as Record<number, number>
);

const nextGroupActivityIdToAssign = (assignments: InProgressAssignmment[]) => {
const groupSizes: Record<number, number> = assignments
Expand Down Expand Up @@ -69,6 +72,7 @@ export const generateCompetingGroupActitivitesForEveryone = (

return (assignments: InProgressAssignmment[]): InProgressAssignmment[] => {
const persons = personsShouldBeInRound(round)(wcif.persons)
.filter(hasRegistrantId)
.filter(missingCompetitorAssignments({ assignments, groupIds }))
.sort(byName)
.sort(byPROrResult(event, roundNumber));
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import {
byPROrResult,
findRoundActivitiesById,
hasRegistrantId,
isOrganizerOrDelegate,
missingCompetitorAssignments,
parseActivityCode,
Expand Down Expand Up @@ -38,6 +39,7 @@ export const generateGroupAssignmentsForDelegatesAndOrganizers = (

return (assignments: InProgressAssignmment[]): InProgressAssignmment[] => {
const persons = personsShouldBeInRound(round)(wcif.persons)
.filter(hasRegistrantId)
.filter(missingCompetitorAssignments({ assignments, groupIds }))
.filter(isOrganizerOrDelegate)
.sort(byName)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,11 @@ const roundActivity: Activity = {

const round: Round = {
id: '333-r1',
linkedRounds: null,
format: 'a',
timeLimit: null,
cutoff: null,
advancementCondition: null,
participationRuleset: null,
scrambleSetCount: 1,
results: [],
extensions: [],
Expand Down Expand Up @@ -53,7 +54,7 @@ const buildCompetition = (groupCount: number, persons: Person[]): Competition =>
const groups = createGroupActivities(groupCount);

return {
formatVersion: 'v1.0',
formatVersion: '2.0',
id: 'test-comp',
name: 'Test Competition',
shortName: 'Test',
Expand Down Expand Up @@ -91,7 +92,7 @@ const buildCompetition = (groupCount: number, persons: Person[]): Competition =>
},
],
},
series: [],
series: null,
competitorLimit: null,
extensions: [],
registrationInfo: {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import {
hasCompetitorAssignment,
missingStaffAssignments,
} from '../domain';
import { isOrganizerOrDelegate, personsShouldBeInRound } from '../domain';
import { hasRegistrantId, isOrganizerOrDelegate, personsShouldBeInRound } from '../domain';
import { type InProgressAssignmment } from '../types';
import { createGroupAssignment, nextGroupForActivity } from '../wcif';
import { type Competition, type Event } from '@wca/helpers';
Expand Down Expand Up @@ -34,6 +34,7 @@ export const generateJudgeAssignmentsFromCompetingAssignments = (
const personFilterContext = { assignments, groupIds };

const persons = personsShouldBeInRound(round)(wcif.persons)
.filter(hasRegistrantId)
.filter(hasCompetitorAssignment(personFilterContext))
.filter(missingStaffAssignments(personFilterContext))
.filter((p) => !isOrganizerOrDelegate(p));
Expand Down
Loading
Loading