Skip to content

Commit 131448a

Browse files
committed
wip
1 parent eb5cd1d commit 131448a

1 file changed

Lines changed: 77 additions & 118 deletions

File tree

Lines changed: 77 additions & 118 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import {FC, useMemo, useState} from "react";
1+
import {FC, useEffect, useMemo, useState} from "react";
22
import {
33
Grid,
44
TextField,
@@ -17,7 +17,7 @@ import {
1717
import EditIcon from "@mui/icons-material/Edit";
1818
import AddIcon from "@mui/icons-material/Add";
1919
import ApiSingleton from "../../api/ApiSingleton";
20-
import { GroupViewModel, AccountDataDto } from "@/api";
20+
import {GroupViewModel, AccountDataDto} from "@/api";
2121

2222

2323
interface GroupSelectorProps {
@@ -31,8 +31,9 @@ interface GroupSelectorProps {
3131
onCreateNewGroup?: () => void,
3232
}
3333

34-
const GroupSelector: FC<GroupSelectorProps> = (props) => {
35-
const groups = props.groups || [];
34+
const GroupSelector: FC<GroupSelectorProps> = (props) => {
35+
const groups = [...(props.groups || []), {id: undefined, name: "Все студенты"}]
36+
3637
const [isDialogOpen, setIsDialogOpen] = useState(false);
3738
const [formState, setFormState] = useState<{
3839
name: string,
@@ -44,11 +45,9 @@ const GroupSelector: FC<GroupSelectorProps> = (props) => {
4445
const [isSubmitting, setIsSubmitting] = useState(false);
4546
const [isError, setIsError] = useState(false);
4647

47-
const selectedGroup = useMemo(() =>
48-
groups.find(g => g.id === props.selectedGroupId),
49-
[groups, props.selectedGroupId]);
48+
const selectedGroup = groups.find(g => g.id === props.selectedGroupId)
5049

51-
const studentsWithousGroup = useMemo(() => {
50+
const studentsWithoutGroup = useMemo(() => {
5251
const studentsInGroups = groups.flatMap(g => g.studentsIds)
5352
return props.courseStudents.filter((cm) => !studentsInGroups.includes(cm.userId))
5453
}, [groups, props.courseStudents]);
@@ -76,7 +75,7 @@ const GroupSelector: FC<GroupSelectorProps> = (props) => {
7675
selectedGroup.id!,
7776
{
7877
name: formState.name,
79-
groupMates: formState.memberIds.map(studentId => ({ studentId })),
78+
groupMates: formState.memberIds.map(studentId => ({studentId})),
8079
}
8180
);
8281
props.onGroupsUpdate();
@@ -103,70 +102,85 @@ const GroupSelector: FC<GroupSelectorProps> = (props) => {
103102
}
104103

105104
return (
106-
<Grid item xs={12} style={{marginBottom: "15px", marginTop: 1}}>
107-
{props.choiceDisabled ? (
108-
<Stack spacing={1}>
109-
<TextField
110-
label="Группа"
111-
value={selectedGroup?.name || "Все студенты"}
112-
variant="outlined"
113-
fullWidth
114-
disabled
115-
/>
116-
{selectedGroup && (
117-
<Button
105+
<Grid container xs={12} spacing={1}>
106+
<Grid item xs={12}>
107+
<Autocomplete
108+
freeSolo
109+
fullWidth
110+
options={[...groups]}
111+
getOptionLabel={(option) => typeof option === 'string' ? option : option?.name || "Все студенты"}
112+
value={groups.find(g => g.id == props.selectedGroupId)}
113+
onChange={(_, newGroup) => {
114+
if (typeof newGroup === 'string') return
115+
props.onGroupIdChange(newGroup?.id)
116+
}}
117+
renderInput={(params) => (
118+
<TextField
119+
{...params}
120+
label="Группа"
121+
placeholder="Выберите группу"
118122
variant="outlined"
119-
startIcon={<EditIcon />}
120-
onClick={handleOpenEditDialog}
121-
fullWidth
122-
>
123-
Изменить состав группы
124-
</Button>
123+
/>
125124
)}
126-
</Stack>
127-
) : (
128-
<Stack spacing={1}>
125+
/>
126+
</Grid>
127+
{selectedGroup && <Grid item xs={12}>
128+
<Stack direction={"column"}>
129129
<Autocomplete
130-
options={[{ id: undefined, name: "Все студенты" }, ...groups]}
131-
getOptionLabel={(option) => option.name || ""}
132-
value={props.selectedGroupId !== undefined
133-
? groups.find(g => g.id === props.selectedGroupId) || null
134-
: { id: undefined, name: "Все студенты" }}
135-
onChange={(_, newGroup) => {
136-
props.onGroupIdChange(newGroup?.id)
130+
multiple
131+
fullWidth
132+
options={studentsWithoutGroup}
133+
value={props.courseStudents?.filter(s => formState.memberIds.includes(s.userId!)) || []}
134+
getOptionLabel={(option) =>
135+
`${option.surname ?? ""} ${option.name ?? ""} / ${option.email ?? ""}`.trim()
136+
}
137+
filterSelectedOptions
138+
onChange={(_, values) => {
139+
if (selectedGroup) {
140+
// При редактировании выбранной группы можно только добавлять студентов
141+
setFormState(prev => ({
142+
...prev,
143+
memberIds: [...formState.memberIds,
144+
...values.map(x => !formState.memberIds.includes(x.userId!) ? x.userId! : "").filter(Boolean)]
145+
}))
146+
} else {
147+
setFormState(prev => ({
148+
...prev,
149+
memberIds: values
150+
.map(x => x.userId!)
151+
.filter(Boolean)
152+
}))
153+
}
137154
}}
155+
disabled={isSubmitting}
156+
renderTags={(tagValue, getTagProps) =>
157+
tagValue.map((option, index) => (
158+
<Chip
159+
{...getTagProps({index})}
160+
label={`${option.surname ?? ""} ${option.name ?? ""} / ${option.email ?? ""}`.trim()}
161+
onDelete={selectedGroup ? undefined : getTagProps({index}).onDelete}
162+
key={option.userId}
163+
/>
164+
))
165+
}
138166
renderInput={(params) => (
139167
<TextField
140168
{...params}
141-
label="Группа (необязательно)"
142-
placeholder="Выберите группу"
143-
variant="outlined"
169+
label="Участники группы"
170+
placeholder="Выберите студентов"
144171
/>
145172
)}
146173
/>
147-
{selectedGroup && (
148-
<Button
149-
variant="outlined"
150-
startIcon={<EditIcon />}
151-
onClick={handleOpenEditDialog}
152-
fullWidth
153-
>
154-
Изменить состав группы
155-
</Button>
156-
)}
157-
{!selectedGroup && (
158-
<Button
159-
variant="outlined"
160-
startIcon={<AddIcon />}
161-
onClick={handleOpenEditDialog}
162-
fullWidth
163-
>
164-
Создать группу
165-
</Button>
166-
)}
174+
<Button
175+
onClick={handleSubmitEdit}
176+
color="primary"
177+
variant="contained"
178+
disabled={isSubmitting || !formState.name.trim() || formState.memberIds.length === 0}
179+
>
180+
{isSubmitting ? <CircularProgress size={24}/> : selectedGroup ? "Сохранить" : "Создать"}
181+
</Button>
167182
</Stack>
168-
)}
169-
183+
</Grid>}
170184
<Dialog
171185
fullWidth
172186
maxWidth="sm"
@@ -199,52 +213,6 @@ const GroupSelector: FC<GroupSelectorProps> = (props) => {
199213
disabled={isSubmitting || props.choiceDisabled}
200214
/>
201215
</Grid>
202-
<Grid item xs={12}>
203-
<Autocomplete
204-
multiple
205-
options={studentsWithousGroup}
206-
value={props.courseStudents?.filter(s => formState.memberIds.includes(s.userId!)) || []}
207-
getOptionLabel={(option) =>
208-
`${option.surname ?? ""} ${option.name ?? ""} / ${option.email ?? ""}`.trim()
209-
}
210-
filterSelectedOptions
211-
onChange={(_, values) => {
212-
if (selectedGroup) {
213-
// При редактировании выбранной группы можно только добавлять студентов
214-
setFormState(prev => ({
215-
...prev,
216-
memberIds: [...formState.memberIds,
217-
...values.map(x => !formState.memberIds.includes(x.userId!) ? x.userId! : "").filter(Boolean)]
218-
}))
219-
} else {
220-
setFormState(prev => ({
221-
...prev,
222-
memberIds: values
223-
.map(x => x.userId!)
224-
.filter(Boolean)
225-
}))
226-
}
227-
}}
228-
disabled={isSubmitting}
229-
renderTags={(tagValue, getTagProps) =>
230-
tagValue.map((option, index) => (
231-
<Chip
232-
{...getTagProps({ index })}
233-
label={`${option.surname ?? ""} ${option.name ?? ""} / ${option.email ?? ""}`.trim()}
234-
onDelete={selectedGroup ? undefined : getTagProps({ index }).onDelete}
235-
key={option.userId}
236-
/>
237-
))
238-
}
239-
renderInput={(params) => (
240-
<TextField
241-
{...params}
242-
label="Участники группы"
243-
placeholder="Выберите студентов"
244-
/>
245-
)}
246-
/>
247-
</Grid>
248216
</Grid>
249217
</DialogContent>
250218
<DialogActions>
@@ -255,18 +223,9 @@ const GroupSelector: FC<GroupSelectorProps> = (props) => {
255223
>
256224
Отменить
257225
</Button>
258-
<Button
259-
onClick={handleSubmitEdit}
260-
color="primary"
261-
variant="contained"
262-
disabled={isSubmitting || !formState.name.trim() || formState.memberIds.length === 0}
263-
>
264-
{isSubmitting ? <CircularProgress size={24} /> : selectedGroup ? "Сохранить" : "Создать"}
265-
</Button>
266226
</DialogActions>
267227
</Dialog>
268-
</Grid>
269-
)
228+
</Grid>)
270229
}
271230

272231
export default GroupSelector

0 commit comments

Comments
 (0)