Skip to content

Commit 1ce8610

Browse files
committed
Fix rating selection and alignment
1 parent e0740f6 commit 1ce8610

2 files changed

Lines changed: 52 additions & 44 deletions

File tree

frontend/src/components/pages/rating-form.tsx

Lines changed: 25 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,15 @@ import {
55
RadioGroup,
66
FormControlLabel,
77
Radio,
8-
Alert,
98
Typography,
109
Tooltip,
1110
} from "@mui/material";
1211
import { api } from "../../hooks/use-api";
1312
import { useLoginContext } from "../../contexts/login-context";
1413
import { Button } from "../base/button";
1514
import { CriterionDTO, ProjectDTO, RatingDTO } from "../../api/types/dto";
15+
import { useNotificationContext } from "../../contexts/notification-context";
16+
1617
interface IRatingFormProps {
1718
rating?: RatingDTO;
1819
criterion: CriterionDTO;
@@ -31,30 +32,30 @@ export const RatingForm = ({
3132
const loginState = useLoginContext();
3233
const { user } = loginState;
3334

34-
const [ratingValue, setRatingValue] = useState<string | undefined>(
35-
rating?.rating?.toString(),
36-
);
35+
const { showNotification } = useNotificationContext();
36+
37+
const [ratingValue, setRatingValue] = useState<number>(rating?.rating || 3);
3738
const [isSubmitting, setIsSubmitting] = useState(false);
38-
const [error, setError] = useState<string | null>(null);
3939

4040
React.useEffect(() => {
4141
if (rating) {
42-
setRatingValue(rating.rating.toString());
42+
setRatingValue(rating.rating);
4343
}
4444
}, [rating]);
4545

4646
const handleSubmit = async () => {
4747
setIsSubmitting(true);
48-
setError(null);
4948

5049
await api.createRating({
5150
criterion,
52-
rating: parseInt(ratingValue ?? "0", 10),
51+
rating: ratingValue,
5352
user: user!,
5453
project,
5554
} as unknown as RatingDTO);
5655

5756
setIsSubmitting(false);
57+
58+
showNotification(`Submitted ${ratingValue} for "${criterion.title}"`);
5859
};
5960

6061
return (
@@ -73,38 +74,39 @@ export const RatingForm = ({
7374
justifyContent="center"
7475
>
7576
<Tooltip title={criterion.description}>
76-
<Typography variant="h6" sx={{ cursor: "help" }}>
77+
<Typography
78+
style={{ flex: 1, textAlign: "right" }}
79+
sx={{ cursor: "help" }}
80+
>
7781
{criterion.title}
7882
</Typography>
7983
</Tooltip>
80-
8184
<FormControl component="fieldset">
8285
<RadioGroup
8386
row
84-
value={ratingValue}
85-
onChange={(e) => setRatingValue(e.target.value)}
87+
value={ratingValue?.toString()}
88+
onChange={(e) => setRatingValue(parseInt(e.target.value, 10))}
8689
>
8790
{[1, 2, 3, 4, 5].map((value) => (
8891
<FormControlLabel
89-
key={value}
92+
key={value.toString()}
9093
value={value.toString()}
9194
control={<Radio disabled={isSubmitting} />}
9295
label={value.toString()}
9396
/>
9497
))}
9598
</RadioGroup>
9699
</FormControl>
97-
98-
<Button
99-
onClick={handleSubmit}
100-
disable={isSubmitting}
101-
loading={isSubmitting}
102-
>
103-
Submit
104-
</Button>
100+
<div style={{ flex: 1 }}>
101+
<Button
102+
onClick={handleSubmit}
103+
disable={isSubmitting}
104+
loading={isSubmitting}
105+
>
106+
Submit
107+
</Button>
108+
</div>
105109
</Stack>
106-
107-
{error && <Alert severity="error">{error}</Alert>}
108110
</div>
109111
);
110112
};

frontend/src/components/settings/project-rating/rating-criteria-settings.tsx

Lines changed: 27 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -4,21 +4,15 @@ import type { CriterionDTO, SettingsDTO } from "../../../api/types/dto";
44
import { Spacer } from "../../base/flex";
55
import { SettingsSection } from "../settings-section";
66
import { Subsubheading } from "../../base/headings";
7-
import {
8-
TextField,
9-
Switch,
10-
FormControlLabel,
11-
Stack,
12-
Button,
13-
} from "@mui/material";
7+
import { Button } from "../../base/button";
8+
import { TextField, Switch, FormControlLabel, Stack } from "@mui/material";
149
import { api } from "../../../hooks/use-api";
10+
import { useNotificationContext } from "../../../contexts/notification-context";
1511

1612
// TODO Seems more maintainable to me if the save button is fine-grained
1713
// and not global. Remove the global Save button and add one individually for
1814
// each SettingsSection component for consistency.
1915

20-
// TODO use our own button style
21-
2216
interface ICriterionEditorProps {
2317
criterion: CriterionDTO;
2418
onSave: (criterion: CriterionDTO) => Promise<void>;
@@ -34,31 +28,41 @@ const CriterionEditor = React.memo(
3428
const [title, setTitle] = useState(criterion.title);
3529
const [description, setDescription] = useState(criterion.description);
3630

31+
const validateAndSave = (changedCriterion: CriterionDTO) => {
32+
if (changedCriterion.title.length === 0) {
33+
return;
34+
}
35+
36+
if (changedCriterion.description.length === 0) {
37+
return;
38+
}
39+
40+
onSave(changedCriterion);
41+
};
42+
3743
return (
3844
<Stack direction={{ sm: "column", md: "row" }} spacing={{ xs: 1, sm: 2 }}>
3945
<TextField
46+
error={title.length === 0}
4047
value={title}
4148
onChange={(event) => setTitle(event.target.value)}
42-
placeholder="title"
49+
placeholder="Title"
4350
rows={1}
4451
/>
4552
<TextField
53+
error={description.length === 0}
4654
value={description}
4755
onChange={(event) => setDescription(event.target.value)}
4856
placeholder="Description"
4957
rows={1}
5058
sx={{ flex: 1 }}
5159
/>
5260
<Button
53-
fullWidth={false}
54-
variant="contained"
55-
onClick={() => onSave({ ...criterion, title, description })}
61+
onClick={() => validateAndSave({ ...criterion, title, description })}
5662
>
5763
Save
5864
</Button>
59-
<Button variant="contained" onClick={() => onDelete(criterion)}>
60-
Delete
61-
</Button>
65+
<Button onClick={() => onDelete(criterion)}>Delete</Button>
6266
</Stack>
6367
);
6468
},
@@ -72,6 +76,8 @@ export const ProjectRatingSettings = () => {
7276
const [allCriteria, setAllCriteria] = useState<CriterionDTO[]>([]);
7377
const [settings, setSettings] = useState<Partial<SettingsDTO>>({});
7478

79+
const { showNotification } = useNotificationContext();
80+
7581
// Do this only on mount
7682
useEffect(() => {
7783
api.getAllCriteria().then((criteria) => {
@@ -92,8 +98,8 @@ export const ProjectRatingSettings = () => {
9298

9399
const addCriterion = useCallback(async (): Promise<void> => {
94100
const newCriterion = await api.createCriterion({
95-
title: "title",
96-
description: "description",
101+
title: "",
102+
description: "",
97103
} as unknown as CriterionDTO);
98104
setAllCriteria((prev) => [...prev, newCriterion]);
99105
}, []);
@@ -108,6 +114,8 @@ export const ProjectRatingSettings = () => {
108114
: criterion;
109115
}),
110116
);
117+
118+
showNotification("Saved criterion");
111119
},
112120
[],
113121
);
@@ -168,9 +176,7 @@ export const ProjectRatingSettings = () => {
168176
))}
169177
</div>
170178
<div>
171-
<Button fullWidth={false} variant="contained" onClick={addCriterion}>
172-
Add
173-
</Button>
179+
<Button onClick={addCriterion}>Add</Button>
174180
<Spacer />
175181
</div>
176182
</SettingsSection>

0 commit comments

Comments
 (0)