Skip to content

Commit 723f915

Browse files
committed
CourseFilter: улучшение UI
1 parent 6ee3f27 commit 723f915

File tree

2 files changed

+93
-101
lines changed

2 files changed

+93
-101
lines changed

hwproj.front/src/components/Courses/CourseFilter.tsx

Lines changed: 47 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import React, {FC, useEffect, useState} from 'react';
22
import {HomeworkViewModel, AccountDataDto, MentorToAssignedStudentsDTO} from '../../api';
33
import Grid from "@material-ui/core/Grid";
4-
import {Autocomplete, Chip} from "@mui/material";
4+
import {Autocomplete, Chip, Stack, Typography} from "@mui/material";
55
import TextField from "@material-ui/core/TextField";
66
import ApiSingleton from "../../api/ApiSingleton";
77
import ErrorsHandler from "../Utils/ErrorsHandler";
@@ -107,6 +107,12 @@ const CourseFilter: FC<ICourseFilterProps> = (props) => {
107107
.filter(x => x !== undefined)
108108
.map(x => x.name + ' ' + x.surname)
109109

110+
const studentsWithMultipleReviewers = new Set(
111+
state.selectedStudents
112+
.map(x => x.userId!)
113+
.filter(x => getAssignedMentors(x).length > 0)
114+
)
115+
110116
return (
111117
<div>
112118
{isLoading ? (
@@ -138,7 +144,7 @@ const CourseFilter: FC<ICourseFilterProps> = (props) => {
138144
placeholder={state.selectedHomeworks.length === 0 ? "Все задания" : ""}
139145
/>
140146
)}
141-
noOptionsText={'На курсе больше нет заданий'}
147+
noOptionsText={'Больше нет заданий для выбора'}
142148
value={state.selectedHomeworks}
143149
onChange={(_, values) => {
144150
setState((prevState) => ({
@@ -159,46 +165,48 @@ const CourseFilter: FC<ICourseFilterProps> = (props) => {
159165
) : (
160166
<Grid container spacing={2} style={{marginTop: '12px'}}>
161167
<Grid item xs={12} sm={12}>
162-
<Autocomplete
163-
multiple
164-
fullWidth
165-
options={state.courseStudents}
166-
getOptionLabel={(option: AccountDataDto) => {
167-
const assignedMentors = getAssignedMentors(option.userId!)
168-
const suffix = assignedMentors.length > 0 ? " — преподаватель " + assignedMentors[0] + "" : ""
169-
return option.surname + ' ' + option.name + suffix;
170-
}}
171-
getOptionKey={(option: AccountDataDto) => option.userId ?? ""}
172-
filterSelectedOptions
173-
isOptionEqualToValue={(option, value) => option.userId === value.userId}
174-
renderInput={(params) => (
175-
<TextField
176-
{...params}
177-
variant="outlined"
178-
label={state.selectedStudents.length === 0 ? "" : `Студенты (${state.selectedStudents.length})`}
179-
placeholder={state.selectedStudents.length === 0 ? "Все студенты" : ""}
180-
/>)}
181-
renderTags={(value, getTagProps) =>
182-
value.map((option, index) => {
183-
const hasAssignedStudents = getAssignedMentors(option.userId!).length > 0
184-
return (
168+
<Stack direction={"column"}>
169+
<Autocomplete
170+
multiple
171+
fullWidth
172+
options={state.courseStudents}
173+
getOptionLabel={(option: AccountDataDto) => {
174+
const assignedMentors = getAssignedMentors(option.userId!)
175+
const suffix = assignedMentors.length > 0 ? " — преподаватель " + assignedMentors[0] + "" : ""
176+
return option.surname + ' ' + option.name + suffix;
177+
}}
178+
getOptionKey={(option: AccountDataDto) => option.userId ?? ""}
179+
filterSelectedOptions
180+
isOptionEqualToValue={(option, value) => option.userId === value.userId}
181+
renderInput={(params) => (
182+
<TextField
183+
{...params}
184+
variant="outlined"
185+
label={state.selectedStudents.length === 0 ? "" : `Студенты (${state.selectedStudents.length})`}
186+
placeholder={state.selectedStudents.length === 0 ? "Все студенты" : ""}
187+
/>)}
188+
renderTags={(value, getTagProps) =>
189+
value.map((option, index) =>
185190
<Chip
186191
label={option.surname + ' ' + option.name}
187192
{...getTagProps({index})}
188-
color={hasAssignedStudents ? "info" : "default"}
189-
/>
190-
);
191-
})
192-
}
193-
noOptionsText={'На курсе нет студентов'}
194-
value={state.selectedStudents}
195-
onChange={(_, values) => {
196-
setState((prevState) => ({
197-
...prevState,
198-
selectedStudents: values
199-
}));
200-
}}
201-
/>
193+
style={studentsWithMultipleReviewers.has(option.userId!) ? {color: "#3f51b5"} : undefined}
194+
/>)
195+
}
196+
noOptionsText={'Больше нет студентов для выбора'}
197+
value={state.selectedStudents}
198+
onChange={(_, values) => {
199+
setState((prevState) => ({
200+
...prevState,
201+
selectedStudents: values
202+
}));
203+
}}
204+
/>
205+
{studentsWithMultipleReviewers.size > 0 &&
206+
<Typography align="center" variant={"caption"} color={"#3f51b5"}>
207+
Синим выделены студенты, закрепленные за несколькими преподавателями
208+
</Typography>}
209+
</Stack>
202210
</Grid>
203211
</Grid>
204212

hwproj.front/src/components/Courses/MentorWorkspaceModal.tsx

Lines changed: 46 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -74,73 +74,57 @@ const MentorWorkspaceModal: FC<MentorWorkspaceProps> = (props) => {
7474
</Typography>
7575
</DialogTitle>
7676
<DialogContent>
77-
<div>
78-
<Grid item container direction={"row"} justifyContent={"center"}>
79-
{state.errors.length > 0 && (
80-
<p style={{color: "red", marginBottom: "5px"}}>{state.errors}</p>
81-
)}
82-
</Grid>
83-
{!isWorkspaceLoading &&
84-
<Typography>
85-
Здесь Вы можете изменить область работы преподавателя
86-
</Typography>}
87-
<CourseFilter courseId={props.courseId}
88-
mentorId={props.mentorId}
89-
isStudentsSelectionHidden={false}
90-
onSelectedHomeworksChange={(homeworks) =>
77+
<Grid item container direction={"row"} justifyContent={"center"}>
78+
{state.errors.length > 0 && (
79+
<p style={{color: "red", marginBottom: "5px"}}>{state.errors}</p>
80+
)}
81+
</Grid>
82+
{!isWorkspaceLoading &&
83+
<Typography>
84+
Здесь Вы можете изменить область работы преподавателя
85+
</Typography>}
86+
<CourseFilter courseId={props.courseId}
87+
mentorId={props.mentorId}
88+
isStudentsSelectionHidden={false}
89+
onSelectedHomeworksChange={(homeworks) =>
90+
setState(prevState => ({
91+
...prevState,
92+
selectedHomeworks: homeworks
93+
}))
94+
}
95+
onSelectedStudentsChange={(students) =>
96+
setState(prevState => ({
97+
...prevState,
98+
selectedStudents: students
99+
}))
100+
}
101+
onWorkspaceInitialize={(success, errors) => {
102+
if (!success) {
91103
setState(prevState => ({
92104
...prevState,
93-
selectedHomeworks: homeworks
105+
errors: errors ?? ['Сервис недоступен']
94106
}))
95107
}
96-
onSelectedStudentsChange={(students) =>
97-
setState(prevState => ({
98-
...prevState,
99-
selectedStudents: students
100-
}))
101-
}
102-
onWorkspaceInitialize={(success, errors) => {
103-
if (!success) {
104-
setState(prevState => ({
105-
...prevState,
106-
errors: errors ?? ['Сервис недоступен']
107-
}))
108-
}
109-
setIsWorkspaceLoading(false)
110-
}}
111-
/>
112-
{!isWorkspaceLoading &&
113-
<Grid
114-
direction="row"
115-
justifyContent="flex-end"
116-
alignItems="flex-end"
117-
container
118-
style={{marginTop: '15px'}}
119-
>
120-
<Grid item>
121-
<Button
122-
onClick={props.onClose}
123-
color="primary"
124-
variant="contained"
125-
style={{marginRight: '10px'}}
126-
>
127-
Закрыть
128-
</Button>
129-
</Grid>
130-
<Grid item>
131-
<Button
132-
variant="contained"
133-
color="primary"
134-
onClick={handleWorkspaceChanges}
135-
>
136-
Изменить
137-
</Button>
138-
</Grid>
139-
</Grid>}
140-
</div>
108+
setIsWorkspaceLoading(false)
109+
}}
110+
/>
141111
</DialogContent>
142-
<DialogActions>
143-
</DialogActions>
112+
{!isWorkspaceLoading && <DialogActions style={{marginTop: 10}}>
113+
<Button
114+
variant="contained"
115+
color="primary"
116+
onClick={handleWorkspaceChanges}
117+
>
118+
Изменить
119+
</Button>
120+
<Button
121+
onClick={props.onClose}
122+
color="primary"
123+
variant="text"
124+
>
125+
Закрыть
126+
</Button>
127+
</DialogActions>}
144128
<Snackbar
145129
anchorOrigin={{vertical: 'top', horizontal: 'center'}}
146130
open={isWorkspaceUpdated}

0 commit comments

Comments
 (0)