Skip to content

Commit 781d77d

Browse files
committed
Added recipe to generate 1 group finals
1 parent 8cdf70d commit 781d77d

14 files changed

Lines changed: 161 additions & 78 deletions

File tree

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@
4646
"redux-thunk": "^2.4.1",
4747
"reselect": "^4.1.6",
4848
"typescript": "^4.8.4",
49-
"wca-group-generators": "^0.1.0",
49+
"wca-group-generators": "^0.1.1",
5050
"web-vitals": "^2.1.4"
5151
},
5252
"scripts": {

src/components/RecipeEditor/EditRecipeDialog.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ import {
1515
ListItemIcon,
1616
ListItemText,
1717
} from '@mui/material';
18-
import { RecipeConfig, Step, StepLibrary } from '../../lib/recipes';
18+
import { AssignmentStep, RecipeConfig, Step, StepLibrary } from '../../lib/recipes';
1919
import { EditStepDialog } from './EditStepDialog';
2020

2121
interface EditRecipeDialogProps {
@@ -68,7 +68,7 @@ export const EditRecipeDialog = ({ open, onClose, recipeConfig, round }: EditRec
6868
</DialogContent>
6969
</Dialog>
7070
<EditStepDialog
71-
step={selectedStep}
71+
step={selectedStep as AssignmentStep}
7272
onClose={() => setSelectedStep(undefined)}
7373
round={round}
7474
/>

src/components/RecipeEditor/EditStepDialog.tsx

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ import {
5555
GridRowModesModel,
5656
} from '@mui/x-data-grid';
5757
import Assignments from '../../config/assignments';
58-
import { ConstraintProps, Filters, Step, StepLibrary } from '../../lib/recipes';
58+
import { AssignmentStep, ConstraintProps, Filters, StepLibrary } from '../../lib/recipes';
5959
import { useAppSelector } from '../../store';
6060
import { updateStep } from '../../store/actions';
6161

@@ -93,7 +93,7 @@ const AccordionDetails = styled(MuiAccordionDetails)(() => ({
9393

9494
interface EditStepDialogProps {
9595
onClose: () => void;
96-
step?: Step;
96+
step?: AssignmentStep;
9797
round: Round;
9898
}
9999

@@ -102,30 +102,30 @@ export const EditStepDialog = ({ onClose, step, round }: EditStepDialogProps) =>
102102
const dataGridRef = useRef(null);
103103
const [rowModesModel, setRowModesModel] = useState<GridRowModesModel>({});
104104

105-
const [assignmentCode, setAssignmentCode] = useState<Step['props']['assignmentCode'] | undefined>(
106-
step?.props?.assignmentCode
107-
);
108-
const [selectedGenerator, setSelectedGenerator] = useState<Step['generator'] | undefined>(
109-
step?.generator
110-
);
111-
const [generatorOptions, setGeneratorOptions] = useState<Step['props']['options']>(
105+
const [assignmentCode, setAssignmentCode] = useState<
106+
AssignmentStep['props']['assignmentCode'] | undefined
107+
>(step?.props?.assignmentCode);
108+
const [selectedGenerator, setSelectedGenerator] = useState<
109+
AssignmentStep['props']['generator'] | undefined
110+
>(step?.props?.generator);
111+
const [generatorOptions, setGeneratorOptions] = useState<AssignmentStep['props']['options']>(
112112
step?.props?.options ?? {}
113113
);
114-
const [editingCluster, setEditingCluster] = useState<Step['props']['cluster']>(
114+
const [editingCluster, setEditingCluster] = useState<AssignmentStep['props']['cluster']>(
115115
step?.props?.cluster || {
116116
base: 'personsInRound',
117117
filters: [],
118118
}
119119
);
120120

121-
const [constraints, setConstraints] = useState<Step['props']['constraints']>(
121+
const [constraints, setConstraints] = useState<AssignmentStep['props']['constraints']>(
122122
step?.props?.constraints ?? []
123123
);
124124

125125
const dirty = useMemo(() => {
126126
return (
127127
step?.props?.assignmentCode !== assignmentCode ||
128-
step?.generator !== selectedGenerator ||
128+
step?.props?.generator !== selectedGenerator ||
129129
JSON.stringify(step?.props?.options) !== JSON.stringify(generatorOptions) ||
130130
step?.props?.cluster.base !== editingCluster.base ||
131131
step?.props?.cluster.filters.some(
@@ -140,7 +140,7 @@ export const EditStepDialog = ({ onClose, step, round }: EditStepDialogProps) =>
140140
editingCluster.filters,
141141
generatorOptions,
142142
selectedGenerator,
143-
step?.generator,
143+
step?.props?.generator,
144144
step?.props?.assignmentCode,
145145
step?.props?.cluster.base,
146146
step?.props?.cluster.filters,
@@ -150,7 +150,7 @@ export const EditStepDialog = ({ onClose, step, round }: EditStepDialogProps) =>
150150
const wcif = useAppSelector((state) => state.wcif);
151151

152152
useEffect(() => {
153-
setSelectedGenerator(step?.generator);
153+
setSelectedGenerator(step?.props?.generator);
154154
setAssignmentCode(step?.props?.assignmentCode);
155155
setEditingCluster(step?.props?.cluster ?? { base: 'personsInRound', filters: [] });
156156
setGeneratorOptions(step?.props?.options ?? {});
@@ -393,7 +393,7 @@ export const EditStepDialog = ({ onClose, step, round }: EditStepDialogProps) =>
393393
onChange={(e) => {
394394
setEditingCluster((prev) => ({
395395
...prev,
396-
base: e.target.value as Step['props']['cluster']['base'],
396+
base: e.target.value as AssignmentStep['props']['cluster']['base'],
397397
}));
398398
}}
399399
value={editingCluster?.base}>

src/lib/recipes/activities.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
import { Competition, parseActivityCode } from '@wca/helpers';
22
import { findAllActivities } from 'wca-group-generators';
33
import { activityCodeIsChild } from '../activities';
4-
import { Step } from './types';
4+
import { AssignmentStep } from './types';
55

66
const getBaseActivities = (
77
wcif: Competition,
8-
base: Step['props']['activities']['base'],
8+
base: AssignmentStep['props']['activities']['base'],
99
roundId: string
1010
) => {
1111
const allActivities = findAllActivities(wcif);
@@ -34,7 +34,7 @@ const getBaseActivities = (
3434

3535
export const getActivities = (
3636
wcif: Competition,
37-
{ base, options = {} }: Step['props']['activities'],
37+
{ base, options = {} }: AssignmentStep['props']['activities'],
3838
roundId: string
3939
) => {
4040
const baseActivities = getBaseActivities(wcif, base, roundId);

src/lib/recipes/clusters.ts

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import { Competition, Person, Round } from '@wca/helpers';
22
import { Assignments } from '../../config/assignments';
33
import { findGroupActivitiesByRound } from '../activities';
44
import { acceptedRegistrations, personsShouldBeInRound } from '../persons';
5-
import { Step } from './types';
5+
import { ClusterDefinition } from './types';
66

77
export const Filters = [
88
{
@@ -89,7 +89,7 @@ export const Filters = [
8989

9090
export const getBaseCluster = (
9191
wcif: Competition,
92-
base: Step['props']['cluster']['base'],
92+
base: ClusterDefinition['base'],
9393
roundId: string
9494
) => {
9595
switch (base) {
@@ -101,11 +101,7 @@ export const getBaseCluster = (
101101
}
102102
};
103103

104-
export const getCluster = (
105-
wcif: Competition,
106-
cluster: Step['props']['cluster'],
107-
roundId: string
108-
) => {
104+
export const getCluster = (wcif: Competition, cluster: ClusterDefinition, roundId: string) => {
109105
const activityIds = findGroupActivitiesByRound(wcif, roundId).map((a) => a.id);
110106

111107
const baseCluster = getBaseCluster(wcif, cluster.base, roundId);

src/lib/recipes/recipes.ts

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { StepLibrary, fromDefaults } from './steps';
2-
import { RecipeConfig, RecipeDefinition } from './types';
2+
import { RecipeConfig, RecipeDefinition, Step } from './types';
33

44
export const Recipes: RecipeDefinition[] = [
55
{
@@ -13,11 +13,17 @@ export const Recipes: RecipeDefinition[] = [
1313
StepLibrary.GenerateJudgeAssignmentsForCompetitors,
1414
],
1515
},
16+
{
17+
id: 'pnw-1-group-finals',
18+
name: 'PNW 1 group final',
19+
description: 'Makes a single group of competitors for finals',
20+
defaultSteps: [StepLibrary.GenerateSingleGroup, StepLibrary.GenerateCompetitorAssignments],
21+
},
1622
];
1723

1824
export const fromRecipeDefinition = (recipe: RecipeDefinition): RecipeConfig => ({
1925
id: recipe.id,
2026
name: recipe.name,
2127
description: recipe.description,
22-
steps: recipe.defaultSteps.map(fromDefaults),
28+
steps: recipe.defaultSteps.map(fromDefaults) as Step[],
2329
});

src/lib/recipes/steps.ts

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { Competition } from '@wca/helpers';
22
import { getActivities } from './activities';
33
import { getCluster } from './clusters';
4-
import { Step, StepDefinition } from './types';
4+
import { AssignmentStep, StepDefinition } from './types';
55

66
export const StepLibrary: Record<string, StepDefinition> = {
77
GenerateCompetitorAssignmentsForStaff: {
@@ -10,8 +10,9 @@ export const StepLibrary: Record<string, StepDefinition> = {
1010
description:
1111
'Generates competitor assignments for staff members based on their staff assignments',
1212
defaults: {
13-
generator: 'assignEveryone',
13+
type: 'assignments',
1414
props: {
15+
generator: 'assignEveryone',
1516
cluster: {
1617
base: 'personsInRound',
1718
filters: [
@@ -60,8 +61,9 @@ export const StepLibrary: Record<string, StepDefinition> = {
6061
name: 'Generate Competitor Assignments For First Timers',
6162
description: 'Generates competitor assignments for first timers',
6263
defaults: {
63-
generator: 'assignEveryone',
64+
type: 'assignments',
6465
props: {
66+
generator: 'assignEveryone',
6567
cluster: {
6668
base: 'personsInRound',
6769
filters: [
@@ -102,8 +104,9 @@ export const StepLibrary: Record<string, StepDefinition> = {
102104
name: 'Generate Competitor Assignments',
103105
description: 'Generates competitor assignments for everyone else',
104106
defaults: {
105-
generator: 'assignEveryone',
107+
type: 'assignments',
106108
props: {
109+
generator: 'assignEveryone',
107110
cluster: {
108111
base: 'personsInRound',
109112
filters: [
@@ -149,8 +152,9 @@ export const StepLibrary: Record<string, StepDefinition> = {
149152
description:
150153
'Creates judge assignments for competitors based on their competitor assignments. Judge assignments are generally assigned for the group directly following the competitor assignment.',
151154
defaults: {
152-
generator: 'assignEveryone',
155+
type: 'assignments',
153156
props: {
157+
generator: 'assignEveryone',
154158
assignmentCode: 'staff-judge',
155159
cluster: {
156160
base: 'personsInRound',
@@ -194,6 +198,17 @@ export const StepLibrary: Record<string, StepDefinition> = {
194198
},
195199
},
196200
},
201+
GenerateSingleGroup: {
202+
id: 'GenerateSingleGroup',
203+
name: 'Generate Single Group',
204+
description: 'Generates a single group of competitors',
205+
defaults: {
206+
type: 'groups',
207+
props: {
208+
count: 1,
209+
},
210+
},
211+
},
197212
};
198213

199214
export const Steps = Object.keys(StepLibrary).reduce((acc, key) => {
@@ -205,7 +220,7 @@ export const fromDefaults = (step: StepDefinition) => ({
205220
...step.defaults,
206221
});
207222

208-
export const hydrateStep = (wcif: Competition, roundId: string, step: Step) => {
223+
export const hydrateStep = (wcif: Competition, roundId: string, step: AssignmentStep) => {
209224
return {
210225
...step,
211226
props: {

src/lib/recipes/types.ts

Lines changed: 20 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,3 @@
1-
export interface StepDefinition {
2-
id: string;
3-
name: string;
4-
description: string;
5-
defaults: Omit<Step, 'id'>;
6-
}
7-
81
export interface ClusterFilter {
92
key: string;
103
value: string | string[] | number | boolean;
@@ -21,10 +14,11 @@ export interface ConstraintProps {
2114
options?: any;
2215
}
2316

24-
export interface Step {
17+
export interface AssignmentStep {
2518
id: string;
26-
generator: string;
19+
type: 'assignments';
2720
props: {
21+
generator: string;
2822
assignmentCode: string;
2923
cluster: ClusterDefinition;
3024
activities: {
@@ -37,6 +31,23 @@ export interface Step {
3731
};
3832
}
3933

34+
export interface GroupStep {
35+
id: string;
36+
type: 'groups';
37+
props: {
38+
count: number;
39+
};
40+
}
41+
42+
export type Step = GroupStep | AssignmentStep;
43+
44+
export interface StepDefinition {
45+
id: string;
46+
name: string;
47+
description: string;
48+
defaults: Omit<Step, 'id'>;
49+
}
50+
4051
export interface RecipeDefinition {
4152
id: string;
4253
name: string;

src/pages/Competition/Round/ConfigureGroupCountsDialog.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ const ConfigureGroupCountsDialog = ({ open, onClose, activityCode, round, roundA
5656
return;
5757
}
5858

59-
dispatch(updateRoundExtensionData(round.id, groupsData));
59+
dispatch(updateRoundExtensionData(round.id, 'groups', groupsData));
6060

6161
const newRoundActivities = createGroupsAcrossStages(wcif, roundActivities, groupsData);
6262
console.log(newRoundActivities);

src/pages/Competition/Round/index.js

Lines changed: 30 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,15 @@ import {
1111
CardActions,
1212
CardHeader,
1313
Divider,
14+
FormControl,
1415
IconButton,
16+
InputLabel,
1517
List,
1618
ListItemButton,
1719
ListSubheader,
20+
MenuItem,
1821
Paper,
22+
Select,
1923
Table,
2024
TableBody,
2125
TableCell,
@@ -48,6 +52,7 @@ import {
4852
bulkRemovePersonAssignments,
4953
generateAssignments,
5054
updateRoundChildActivities,
55+
updateRoundExtensionData,
5156
} from '../../../store/actions';
5257
import {
5358
selectPersonsAssignedForRound,
@@ -169,6 +174,10 @@ const RoundPage = () => {
169174
dispatch(generateAssignments(round.id, recipeConfig));
170175
};
171176

177+
const onSwitchRecipes = (id) => {
178+
dispatch(updateRoundExtensionData(round.id, 'recipe', { id }));
179+
};
180+
172181
const onResetGroupActitivites = () => {
173182
confirm({
174183
description: 'Do you really want to reset all group activities in this round?',
@@ -401,8 +410,27 @@ const RoundPage = () => {
401410

402411
<Grid item>
403412
<AppBar position="sticky" color="secondary" sx={{ top: '480px' }}>
404-
<Toolbar component={Paper}>
405-
<Typography>Recipe: {recipeConfig.name}</Typography>
413+
<Toolbar component={Paper} sx={{ p: 1 }}>
414+
<FormControl>
415+
<InputLabel id="recipe-select-label">Recipe</InputLabel>
416+
<Select
417+
label="Recipe"
418+
labelId="recipe-select-label"
419+
variant="outlined"
420+
value={recipeConfig.id}
421+
onChange={(e) => onSwitchRecipes(e.target.value)}
422+
autoWidth
423+
sx={{
424+
minWidth: 200,
425+
}}
426+
renderValue={(value) => recipeConfig.name}>
427+
{Recipes.map((recipe) => (
428+
<MenuItem key={recipe.id} value={recipe.id}>
429+
{recipe.name}
430+
</MenuItem>
431+
))}
432+
</Select>
433+
</FormControl>
406434
<div style={{ display: 'flex', flex: 1 }} />
407435
<Button onClick={onGenerateGroupActitivites}>Run Recipe</Button>
408436
<IconButton edge="end" onClick={() => setConfigureRecipeDialog(true)}>

0 commit comments

Comments
 (0)