|  | 
| 1 |  | -import React, {useEffect, useState} from "react"; | 
|  | 1 | +import React, {FC, useEffect, useState} from "react"; | 
| 2 | 2 | import {CourseViewModel, HomeworkViewModel, StatisticsCourseMatesModel} from "../../api/"; | 
| 3 | 3 | import {useNavigate, useParams} from 'react-router-dom'; | 
| 4 | 4 | import {Table, TableBody, TableCell, TableContainer, TableHead, TableRow} from "@material-ui/core"; | 
| 5 | 5 | import StudentStatsCell from "../Tasks/StudentStatsCell"; | 
| 6 |  | -import {Alert, Button, Chip, Typography} from "@mui/material"; | 
|  | 6 | +import {Alert, Button, Chip, Typography, Menu, MenuItem, ListItemIcon, ListItemText, Popover} from "@mui/material"; | 
| 7 | 7 | import {grey} from "@material-ui/core/colors"; | 
| 8 | 8 | import StudentStatsUtils from "../../services/StudentStatsUtils"; | 
| 9 |  | -import ShowChartIcon from "@mui/icons-material/ShowChart"; | 
|  | 9 | +import {MoreVert, Download, ShowChart} from "@mui/icons-material"; | 
| 10 | 10 | import {BonusTag, DefaultTags, TestTag} from "../Common/HomeworkTags"; | 
| 11 | 11 | import Lodash from "lodash" | 
| 12 | 12 | import SaveStats from "components/Solutions/SaveStats"; | 
| @@ -34,7 +34,7 @@ const StudentStats:  React.FC<IStudentStatsProps> = (props) => { | 
| 34 | 34 |     }); | 
| 35 | 35 |     const {courseId} = useParams(); | 
| 36 | 36 |     const navigate = useNavigate(); | 
| 37 |  | -    const handleClick = () => { | 
|  | 37 | +    const goToCharts = () => { | 
| 38 | 38 |         navigate(`/statistics/${courseId}/charts`) | 
| 39 | 39 |     } | 
| 40 | 40 | 
 | 
| @@ -103,6 +103,92 @@ const StudentStats:  React.FC<IStudentStatsProps> = (props) => { | 
| 103 | 103 |     const hasHomeworks = homeworksMaxSum > 0 | 
| 104 | 104 |     const hasTests = testsMaxSum > 0 | 
| 105 | 105 | 
 | 
|  | 106 | +    const StatsMenu: FC = () => { | 
|  | 107 | +        const [menuState, setMenuState] = useState<{ | 
|  | 108 | +            anchorEl: null | HTMLElement; | 
|  | 109 | +            popoverAnchorEl: null | HTMLElement; | 
|  | 110 | +        }>({anchorEl: null, popoverAnchorEl: null}) | 
|  | 111 | + | 
|  | 112 | +        const {anchorEl, popoverAnchorEl} = menuState | 
|  | 113 | +        const openMenu = Boolean(anchorEl) | 
|  | 114 | +        const openPopover = Boolean(popoverAnchorEl) | 
|  | 115 | + | 
|  | 116 | +        const handleOpenMenu = (event: React.MouseEvent<HTMLElement>) => { | 
|  | 117 | +            setMenuState ({ | 
|  | 118 | +                anchorEl: event.currentTarget, | 
|  | 119 | +                popoverAnchorEl: null, | 
|  | 120 | +            }) | 
|  | 121 | +        } | 
|  | 122 | + | 
|  | 123 | +        const handleClose = () => { | 
|  | 124 | +            setMenuState ({ | 
|  | 125 | +                anchorEl: null, | 
|  | 126 | +                popoverAnchorEl: null, | 
|  | 127 | +            }) | 
|  | 128 | +        } | 
|  | 129 | + | 
|  | 130 | +        const handleOpenPopover = (event: React.MouseEvent<HTMLElement>) => { | 
|  | 131 | +            setMenuState (prevState => ({ | 
|  | 132 | +                ...prevState, | 
|  | 133 | +                popoverAnchorEl: event.currentTarget, | 
|  | 134 | +            })) | 
|  | 135 | +        } | 
|  | 136 | + | 
|  | 137 | +        return ( | 
|  | 138 | +            <div style={{paddingTop: 4}}> | 
|  | 139 | +                <Button size="medium" | 
|  | 140 | +                        color="primary" | 
|  | 141 | +                        onClick={handleOpenMenu} | 
|  | 142 | +                > | 
|  | 143 | +                    Меню | 
|  | 144 | +                    <MoreVert fontSize="small"/> | 
|  | 145 | +                </Button> | 
|  | 146 | +                <Menu | 
|  | 147 | +                    id="long-menu" | 
|  | 148 | +                    MenuListProps={{ | 
|  | 149 | +                        'aria-labelledby': 'long-button', | 
|  | 150 | +                    }} | 
|  | 151 | +                    anchorEl={anchorEl} | 
|  | 152 | +                    open={openMenu} | 
|  | 153 | +                    onClose={handleClose} | 
|  | 154 | +                > | 
|  | 155 | +                    <MenuItem onClick={goToCharts}> | 
|  | 156 | +                        <ListItemIcon> | 
|  | 157 | +                            <ShowChart fontSize="small"/> | 
|  | 158 | +                        </ListItemIcon> | 
|  | 159 | +                        <ListItemText> | 
|  | 160 | +                            Графики успеваемости | 
|  | 161 | +                        </ListItemText> | 
|  | 162 | +                    </MenuItem> | 
|  | 163 | +                    <MenuItem onClick={handleOpenPopover}> | 
|  | 164 | +                        <ListItemIcon> | 
|  | 165 | +                            <Download fontSize="small"/> | 
|  | 166 | +                        </ListItemIcon> | 
|  | 167 | +                        <ListItemText> | 
|  | 168 | +                            Выгрузить таблицу | 
|  | 169 | +                        </ListItemText> | 
|  | 170 | +                        <Popover open={openPopover} | 
|  | 171 | +                                 onClose={handleClose} | 
|  | 172 | +                                 anchorEl={popoverAnchorEl} | 
|  | 173 | +                                 anchorOrigin={{ | 
|  | 174 | +                                    vertical: 'bottom', | 
|  | 175 | +                                    horizontal: 'left', | 
|  | 176 | +                                  }} | 
|  | 177 | +                        > | 
|  | 178 | +                            <SaveStats | 
|  | 179 | +                                courseId={props.course.id} | 
|  | 180 | +                                userId={props.userId} | 
|  | 181 | +                                yandexCode={props.yandexCode} | 
|  | 182 | +                                onActionOpening={() => setSearched({searched, isSaveStatsActionOpened: true})} | 
|  | 183 | +                                onActionClosing={() => setSearched({searched, isSaveStatsActionOpened: false})} | 
|  | 184 | +                            /> | 
|  | 185 | +                        </Popover> | 
|  | 186 | +                    </MenuItem> | 
|  | 187 | +                </Menu> | 
|  | 188 | +            </div> | 
|  | 189 | +        ) | 
|  | 190 | +    } | 
|  | 191 | + | 
| 106 | 192 |     return ( | 
| 107 | 193 |         <div> | 
| 108 | 194 |             {searched && | 
| @@ -146,15 +232,8 @@ const StudentStats:  React.FC<IStudentStatsProps> = (props) => { | 
| 146 | 232 |                                 </TableCell>)} | 
| 147 | 233 |                         </TableRow> | 
| 148 | 234 |                         <TableRow> | 
| 149 |  | -                            <TableCell style={{zIndex: 10}} | 
| 150 |  | -                                       component="td"> | 
| 151 |  | -                                {solutions.length > 0 && | 
| 152 |  | -                                    <Button startIcon={<ShowChartIcon/>} color="primary" | 
| 153 |  | -                                            style={{backgroundColor: 'transparent'}} size='medium' | 
| 154 |  | -                                            onClick={handleClick}> | 
| 155 |  | -                                        Графики | 
| 156 |  | -                                    </Button> | 
| 157 |  | -                                } | 
|  | 235 | +                            <TableCell style={{zIndex: 10}} component="td"> | 
|  | 236 | +                                {solutions.length > 0 && <StatsMenu/>} | 
| 158 | 237 |                             </TableCell> | 
| 159 | 238 |                             {hasHomeworks && <TableCell padding="checkbox" component="td" align="center" | 
| 160 | 239 |                                                         style={{ | 
| @@ -300,15 +379,6 @@ const StudentStats:  React.FC<IStudentStatsProps> = (props) => { | 
| 300 | 379 |                     </TableBody> | 
| 301 | 380 |                 </Table> | 
| 302 | 381 |             </TableContainer> | 
| 303 |  | -            <div style={{marginTop: 15}}> | 
| 304 |  | -                <SaveStats | 
| 305 |  | -                    courseId={props.course.id} | 
| 306 |  | -                    userId={props.userId} | 
| 307 |  | -                    yandexCode={props.yandexCode} | 
| 308 |  | -                    onActionOpening={() => setSearched({searched, isSaveStatsActionOpened: true})} | 
| 309 |  | -                    onActionClosing={() => setSearched({searched, isSaveStatsActionOpened: false})} | 
| 310 |  | -                /> | 
| 311 |  | -            </div> | 
| 312 | 382 |         </div> | 
| 313 | 383 |     ); | 
| 314 | 384 | } | 
|  | 
0 commit comments