diff --git a/.all-contributorsrc b/.all-contributorsrc index 84f368a17..91ad4641f 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -222,6 +222,15 @@ "code" ] }, + { + "login": "jaydonkrooss", + "name": "Jaydon Krooss", + "avatar_url": "https://avatars.githubusercontent.com/u/147423601?v=4", + "profile": "https://github.com/jaydonkrooss", + "contributions": [ + "code" + ] + }, { "login": "dependabot", "name": "Dependabot", diff --git a/.gitignore b/.gitignore index 06148a58c..4fb18406d 100644 --- a/.gitignore +++ b/.gitignore @@ -104,6 +104,7 @@ venv/ ENV/ env.bak/ venv.bak/ +venv_* # Spyder project settings .spyderproject @@ -125,3 +126,6 @@ dmypy.json node_modules/ webpack-stats.json + +# VSCode +.history/ diff --git a/assets/src/components/AssignmentGoalInput.js b/assets/src/components/AssignmentGoalInput.js index c800e349f..f5b2a67d8 100644 --- a/assets/src/components/AssignmentGoalInput.js +++ b/assets/src/components/AssignmentGoalInput.js @@ -1,13 +1,19 @@ import React, { useEffect, useState, useRef } from 'react' -import { withStyles } from '@material-ui/core' -import Grid from '@material-ui/core/Grid' -import Button from '@material-ui/core/Button' +import { styled } from '@mui/material/styles' +import Grid from '@mui/material/Grid' +import Button from '@mui/material/Button' import StyledTextField from './StyledTextField' import debounce from 'lodash.debounce' import { eventLogExtra } from '../util/object' -const styles = ({ - goalGradeInput: { +const PREFIX = 'AssignmentGoalInput' + +const classes = { + goalGradeInput: `${PREFIX}-goalGradeInput` +} + +const StyledGrid = styled(Grid)({ + [`& .${classes.goalGradeInput}`]: { marginTop: 0, width: 150 } @@ -22,8 +28,7 @@ function AssignmentGoalInput (props) { setEventLog, eventLog, handleClearGoalGrades, - mathWarning, - classes + mathWarning } = props const [goalGradeInternal, setGoalGradeInternal] = useState(goalGrade) @@ -44,7 +49,7 @@ function AssignmentGoalInput (props) { }, [goalGrade]) return ( - + 100 || mathWarning || goalGradeInternal > maxPossibleGrade} id='standard-number' @@ -84,8 +89,8 @@ function AssignmentGoalInput (props) { > Clear - + ) } -export default withStyles(styles)(AssignmentGoalInput) +export default (AssignmentGoalInput) diff --git a/assets/src/components/AssignmentTable.js b/assets/src/components/AssignmentTable.js index 3f40ba511..ca68fc61d 100644 --- a/assets/src/components/AssignmentTable.js +++ b/assets/src/components/AssignmentTable.js @@ -1,25 +1,25 @@ import React, { useEffect, useRef, useState } from 'react' -import { withStyles } from '@material-ui/core/styles' -import Button from '@material-ui/core/Button' -import Checkbox from '@material-ui/core/Checkbox' -import FormControl from '@material-ui/core/FormControl' -import Grid from '@material-ui/core/Grid' -import InputLabel from '@material-ui/core/InputLabel' -import Input from '@material-ui/core/Input' -import ListItemText from '@material-ui/core/ListItemText' -import MenuItem from '@material-ui/core/MenuItem' -import MTable from '@material-ui/core/Table' -import Popover from '@material-ui/core/Popover' -import Select from '@material-ui/core/Select' -import TableBody from '@material-ui/core/TableBody' -import TableCell from '@material-ui/core/TableCell' -import TableContainer from '@material-ui/core/TableContainer' -import TableHead from '@material-ui/core/TableHead' -import TableRow from '@material-ui/core/TableRow' -import Tooltip from '@material-ui/core/Tooltip' -import GradedIcon from '@material-ui/icons/Done' -import UnsubmittedIcon from '@material-ui/icons/Remove' -import SubmittedIcon from '@material-ui/icons/Textsms' +import { styled } from '@mui/material/styles' +import Button from '@mui/material/Button' +import Checkbox from '@mui/material/Checkbox' +import FormControl from '@mui/material/FormControl' +import Grid from '@mui/material/Grid' +import InputLabel from '@mui/material/InputLabel' +import Input from '@mui/material/Input' +import ListItemText from '@mui/material/ListItemText' +import MenuItem from '@mui/material/MenuItem' +import MTable from '@mui/material/Table' +import Popover from '@mui/material/Popover' +import Select from '@mui/material/Select' +import TableBody from '@mui/material/TableBody' +import TableCell from '@mui/material/TableCell' +import TableContainer from '@mui/material/TableContainer' +import TableHead from '@mui/material/TableHead' +import TableRow from '@mui/material/TableRow' +import Tooltip from '@mui/material/Tooltip' +import GradedIcon from '@mui/icons-material/Done' +import UnsubmittedIcon from '@mui/icons-material/Remove' +import SubmittedIcon from '@mui/icons-material/Textsms' import ProgressBarV2 from './ProgressBarV2' import PopupMessage from './PopupMessage' import StyledTextField from './StyledTextField' @@ -29,80 +29,126 @@ import { calculateWeekOffset } from '../util/date' import { roundToXDecimals, getDecimalPlaceOfFloat } from '../util/math' import { assignmentStatus } from '../util/assignment' -const headerHeight = 105 +const PREFIX = 'AssignmentTable' + +const classes = { + root: `${PREFIX}-root`, + messageWrapper: `${PREFIX}-messageWrapper`, + container: `${PREFIX}-container`, + sliderCell: `${PREFIX}-sliderCell`, + goalGradeInput: `${PREFIX}-goalGradeInput`, + tableCell: `${PREFIX}-tableCell`, + tableHeadCell: `${PREFIX}-tableHeadCell`, + popover: `${PREFIX}-popover`, + narrowCell: `${PREFIX}-narrowCell`, + veryNarrowCell: `${PREFIX}-veryNarrowCell`, + possiblePointsText: `${PREFIX}-possiblePointsText`, + formControl: `${PREFIX}-formControl`, + filterArea: `${PREFIX}-filterArea`, + graded: `${PREFIX}-graded`, + ungraded: `${PREFIX}-ungraded`, + unsubmitted: `${PREFIX}-unsubmitted`, + assignmentName: `${PREFIX}-assignmentName`, + filterButton: `${PREFIX}-filterButton` +} -const styles = theme => ({ - root: { +const Root = styled('div')(( + { + theme + } +) => ({ + [`& .${classes.root}`]: { flexGrow: 1, padding: 8 }, - paper: { - padding: theme.spacing(2), - color: theme.palette.text.secondary - }, - container: { + + [`& .${classes.container}`]: { maxHeight: 500 }, - sliderCell: { + + [`& .${classes.sliderCell}`]: { minWidth: '150px' }, - goalGradeInput: { + + [`& .${classes.goalGradeInput}`]: { marginTop: 0, width: 100, marginBottom: '10px' }, - tableCell: { + + [`& .${classes.tableCell}`]: { border: 'none' }, - tableHeadCell: { + + [`& .${classes.tableHeadCell}`]: { fontSize: '1em', height: headerHeight + 'px' }, - popover: { + + [`& .${classes.popover}`]: { pointerEvents: 'none' }, - narrowCell: { + + [`& .${classes.narrowCell}`]: { width: '120px' }, - veryNarrowCell: { + + [`& .${classes.veryNarrowCell}`]: { width: '60px' }, - possiblePointsText: { + + [`& .${classes.possiblePointsText}`]: { margin: 'auto', display: 'inline-block', paddingTop: '22px', paddingLeft: '5px', verticalAlign: 'middle' }, - formControl: { + + [`& .${classes.formControl}`]: { margin: theme.spacing(1), width: '95%' }, - filterArea: { + + [`& .${classes.filterArea}`]: { alignItems: 'center', marginBottom: '2px', backgroundColor: '#F4F4F4' }, - graded: { + + [`& .${classes.graded}`]: { color: theme.palette.secondary.main }, - ungraded: { + + [`& .${classes.ungraded}`]: { color: theme.palette.info.main }, - unsubmitted: { + + [`& .${classes.unsubmitted}`]: { color: theme.palette.negative.main }, - assignmentName: { + + [`& .${classes.assignmentName}`]: { whiteSpace: 'nowrap ' }, - filterButton: { + + [`& .${classes.filterButton}`]: { textTransform: 'none' } -}) +})) + +// separate styles for child of opened popover +const StyledPopoverMessage = styled('div')(({ theme }) => ({ + [`& .${classes.messageWrapper}`]: { + padding: theme.spacing(2), + color: theme.palette.text.secondary + } +})) + +const headerHeight = 105 function AssignmentTable (props) { const { - classes, courseGoalGradeSet, assignments, assignmentGroups, @@ -174,7 +220,8 @@ function AssignmentTable (props) { // Use decimal place of pointsPossible if it's a decimal; otherwise, round to nearest tenth const placeToRoundTo = pointsPossible => (String(pointsPossible).includes('.')) - ? getDecimalPlaceOfFloat(pointsPossible) : 1 + ? getDecimalPlaceOfFloat(pointsPossible) + : 1 // this effect scrolls to current week of assignments if it exists useEffect(() => { @@ -258,7 +305,7 @@ function AssignmentTable (props) { } return ( -
+ @@ -352,12 +399,8 @@ function AssignmentTable (props) { @@ -371,9 +414,7 @@ function AssignmentTable (props) { @@ -399,83 +440,90 @@ function AssignmentTable (props) { {`${roundToXDecimals(a.percentOfFinalGrade, 1)}%`} - { - a.graded || a.outOf === 0 - ?
{a.outOf === 0 ? '0' : `${a.currentUserSubmission.score}`}
- : ( - 1} - disabled={!courseGoalGradeSet} - id='standard-number' - value={roundToXDecimals(a.goalGrade, placeToRoundTo(a.pointsPossible))} - label={ - !courseGoalGradeSet ? 'Set a goal' - : (a.goalGrade / a.pointsPossible) > 1 - ? 'Over 100%' - : 'Set a goal' - } - onChange={event => { - const assignmentGoalGrade = event.target.value - handleAssignmentGoalGrade(a.id, assignmentGoalGrade, a.goalGrade) - }} - type='number' - className={classes.goalGradeInput} - onFocus={() => handleInputFocus(a.id)} - onBlur={() => handleInputBlur(a.id)} - /> - ) - } - { + <> + { + a.graded || a.outOf === 0 + ?
{a.outOf === 0 ? '0' : `${a.currentUserSubmission.score}`}
+ : ( + 1} + disabled={!courseGoalGradeSet} + id='standard-number' + value={roundToXDecimals(a.goalGrade, placeToRoundTo(a.pointsPossible))} + label={ + !courseGoalGradeSet + ? 'Set a goal' + : (a.goalGrade / a.pointsPossible) > 1 + ? 'Over 100%' + : 'Set a goal' + } + onChange={event => { + const assignmentGoalGrade = event.target.value + handleAssignmentGoalGrade(a.id, assignmentGoalGrade, a.goalGrade) + }} + type='number' + className={classes.goalGradeInput} + onFocus={() => handleInputFocus(a.id)} + onBlur={() => handleInputBlur(a.id)} + /> + ) + }
{` / ${a.outOf}`}
- } -
setPopoverEl(key, event.currentTarget)} - onMouseLeave={clearPopoverEl} - > - setPopoverEl(key, el)} - onBarBlur={clearPopoverEl} - /> - setPopoverEl(key, event.currentTarget)} + onMouseLeave={clearPopoverEl} > - - -
+ setPopoverEl(key, el)} + onBarBlur={clearPopoverEl} + /> + + +
+ +
+
+
+
+ @@ -497,8 +545,8 @@ function AssignmentTable (props) { {assignments.length > 0 && filteredAssignments.length === 0 && No assignments match your filter selections.} - + ) } -export default withStyles(styles)(AssignmentTable) +export default (AssignmentTable) diff --git a/assets/src/components/AvatarModal.js b/assets/src/components/AvatarModal.js index 524539d8f..667957786 100644 --- a/assets/src/components/AvatarModal.js +++ b/assets/src/components/AvatarModal.js @@ -1,48 +1,66 @@ import React, { useState, useEffect } from 'react' -import { withStyles } from '@material-ui/core/styles' -import Grid from '@material-ui/core/Grid' -import Divider from '@material-ui/core/Divider' -import Typography from '@material-ui/core/Typography' -import Avatar from '@material-ui/core/Avatar' -import Link from '@material-ui/core/Link' -import List from '@material-ui/core/List' -import ListItem from '@material-ui/core/ListItem' -import ListItemIcon from '@material-ui/core/ListItemIcon' -import ListItemText from '@material-ui/core/ListItemText' -import DialogTitle from '@material-ui/core/DialogTitle' -import Dialog from '@material-ui/core/Dialog' -import LogoutIcon from '@material-ui/icons/ExitToApp' -import HelpIcon from '@material-ui/icons/HelpOutline' -import Lock from '@material-ui/icons/Lock' -import Launch from '@material-ui/icons/Launch' +import { styled } from '@mui/material/styles' +import Grid from '@mui/material/Grid' +import Divider from '@mui/material/Divider' +import Typography from '@mui/material/Typography' +import Avatar from '@mui/material/Avatar' +import Link from '@mui/material/Link' +import List from '@mui/material/List' +import ListItemButton from '@mui/material/ListItemButton' +import ListItemIcon from '@mui/material/ListItemIcon' +import ListItemText from '@mui/material/ListItemText' +import DialogTitle from '@mui/material/DialogTitle' +import Dialog from '@mui/material/Dialog' +import LogoutIcon from '@mui/icons-material/ExitToApp' +import HelpIcon from '@mui/icons-material/HelpOutline' +import Lock from '@mui/icons-material/Lock' +import Launch from '@mui/icons-material/Launch' import { viewHelpURLs } from '../globals' -const styles = theme => ({ - root: { +const PREFIX = 'AvatarModal' + +const classes = { + root: `${PREFIX}-root`, + typography: `${PREFIX}-typography`, + avatar: `${PREFIX}-avatar`, + link: `${PREFIX}-link`, + text: `${PREFIX}-text` +} + +const Root = styled('div')(( + { + theme + } +) => ({ + [`&.${classes.root}`]: { flexGrow: 1 }, - typography: { + + [`& .${classes.typography}`]: { marginTop: theme.spacing(2) }, - avatar: { + + [`& .${classes.avatar}`]: { padding: '10px', marginTop: '10px', marginBottom: '10px', marginLeft: 'auto', marginRight: 'auto' }, - link: { + + [`& .${classes.link}`]: { textDecoration: 'none', marginLeft: 0 }, - text: { + + [`& .${classes.text}`]: { paddingLeft: 0, color: 'black' } -}) +})) function AvatarModal (props) { - const { classes, user } = props + const { user } = props const url = window.location.href @@ -52,12 +70,12 @@ function AvatarModal (props) { const Admin = () => ( <> - + - + @@ -65,12 +83,12 @@ function AvatarModal (props) { const SwitchCourses = () => ( <> - setOpenChangeCourseDialog(true)}> + setOpenChangeCourseDialog(true)}> - + setOpenChangeCourseDialog(false)} open={openChangeCourseDialog} @@ -83,9 +101,9 @@ function AvatarModal (props) { href={`/courses/${course.course_id}`} key={i} > - + - + ))} @@ -113,7 +131,7 @@ function AvatarModal (props) { }, [url]) return ( -
+ @@ -135,13 +153,13 @@ function AvatarModal (props) { - - + + - + { @@ -158,21 +176,21 @@ function AvatarModal (props) { user.logoutURL !== '' ? ( - + - + - ) + ) : null } -
+ ) } -export default withStyles(styles)(AvatarModal) +export default (AvatarModal) diff --git a/assets/src/components/Banner.js b/assets/src/components/Banner.js index a873a0a7b..8e8cd5a65 100644 --- a/assets/src/components/Banner.js +++ b/assets/src/components/Banner.js @@ -1,15 +1,27 @@ import React from 'react' -import { withStyles } from '@material-ui/core/styles' -import Grid from '@material-ui/core/Grid' -import Paper from '@material-ui/core/Paper' -import Typography from '@material-ui/core/Typography' +import { styled } from '@mui/material/styles' +import Grid from '@mui/material/Grid' +import Paper from '@mui/material/Paper' +import Typography from '@mui/material/Typography' -const styles = theme => ({ - root: { +const PREFIX = 'Banner' + +const classes = { + root: `${PREFIX}-root`, + paper: `${PREFIX}-paper` +} + +const Root = styled('div')(( + { + theme + } +) => ({ + [`&.${classes.root}`]: { flexGrow: 1, padding: 8 }, - paper: { + + [`& .${classes.paper}`]: { align: 'center', padding: theme.spacing(2), opacity: 0.9, @@ -18,10 +30,10 @@ const styles = theme => ({ '0px 4px 5px 0px rgba(0,0,0,0.14), ' + '0px 1px 10px 0px rgba(0,0,0,0.12)' } -}) +})) function Banner (props) { - const { classes, settings, children } = props + const { settings, children } = props const paperStyle = { background: settings.backgroundColor, @@ -35,7 +47,7 @@ function Banner (props) { } return ( -
+ @@ -45,8 +57,8 @@ function Banner (props) { -
+ ) } -export default withStyles(styles)(Banner) +export default (Banner) diff --git a/assets/src/components/CourseListCard/CourseListCard.js b/assets/src/components/CourseListCard.js similarity index 60% rename from assets/src/components/CourseListCard/CourseListCard.js rename to assets/src/components/CourseListCard.js index 534b3b402..a43c00d6e 100644 --- a/assets/src/components/CourseListCard/CourseListCard.js +++ b/assets/src/components/CourseListCard.js @@ -1,50 +1,72 @@ import React from 'react' +import { styled } from '@mui/material/styles' import PropTypes from 'prop-types' -import { withStyles } from '@material-ui/core/styles' -import { Card, CardContent, Typography } from '@material-ui/core' +import { Card, CardContent, Typography } from '@mui/material' import { Link } from 'react-router-dom' -const styles = theme => ({ - root: { +const PREFIX = 'CourseListCard' + +const classes = { + root: `${PREFIX}-root`, + paper: `${PREFIX}-paper`, + container: `${PREFIX}-container`, + grow: `${PREFIX}-grow`, + card: `${PREFIX}-card`, + content: `${PREFIX}-content`, + title: `${PREFIX}-title`, + description: `${PREFIX}-description` +} + +const StyledCard = styled(Card)(( + { + theme + } +) => ({ + [`& .${classes.root}`]: { flexGrow: 1 }, - paper: { + + [`& .${classes.paper}`]: { padding: theme.spacing(2), color: theme.palette.text.secondary, display: 'flex' }, - container: { + + [`& .${classes.container}`]: { display: 'flex', justifyContent: 'center' }, - grow: { + + [`& .${classes.grow}`]: { flexGrow: 1 }, - card: { + + [`&.${classes.card}`]: { margin: theme.spacing(3) }, - content: { + + [`& .${classes.content}`]: { height: 110, padding: 0 }, - title: { + + [`& .${classes.title}`]: { boxSizing: 'border-box', padding: theme.spacing(1), color: 'white', marginBottom: 0, backgroundColor: theme.palette.primary.main }, - description: { + + [`& .${classes.description}`]: { padding: theme.spacing(1), color: 'black' } -}) +})) const CourseListCard = (props) => { - const { classes } = props - return ( - + @@ -55,7 +77,7 @@ const CourseListCard = (props) => { - + ) } @@ -67,4 +89,4 @@ CourseListCard.propTypes = { CourseListCard.defaultProps = {} -export default withStyles(styles)(CourseListCard) +export default (CourseListCard) diff --git a/assets/src/components/CourseListCard/CourseListCard.lazy.js b/assets/src/components/CourseListCard/CourseListCard.lazy.js deleted file mode 100644 index 2325fe74f..000000000 --- a/assets/src/components/CourseListCard/CourseListCard.lazy.js +++ /dev/null @@ -1,11 +0,0 @@ -import React, { lazy, Suspense } from 'react' - -const LazyCourseListCard = lazy(() => import('./CourseListCard')) - -const CourseListCard = props => ( - - - -) - -export default CourseListCard diff --git a/assets/src/components/EmojiFeedback.js b/assets/src/components/EmojiFeedback.js deleted file mode 100644 index 216e63439..000000000 --- a/assets/src/components/EmojiFeedback.js +++ /dev/null @@ -1,36 +0,0 @@ -import React, { useEffect, memo } from 'react' -import emojiFeedback from '@justin0022/emoji-feedback' -import { withStyles } from '@material-ui/core/styles' -import withPopover from './withPopover' -import compose from '../util/compose' - -const styles = ({ - feedback: { - width: '310px', - height: '350px', - padding: '12px' - } -}) - -const EmojiFeedback = memo(props => { - const { - endpoints, - id, - options, - classes - } = props - - useEffect(() => { - const feedback = emojiFeedback() - feedback.init(id, endpoints, options) - }) - - return ( -
- ) -}) - -export default compose( - withStyles(styles), - withPopover -)(EmojiFeedback) diff --git a/assets/src/components/IconLabel.js b/assets/src/components/IconLabel.js index c6b4985d9..69bf6e226 100644 --- a/assets/src/components/IconLabel.js +++ b/assets/src/components/IconLabel.js @@ -1,30 +1,37 @@ import React from 'react' -import { Typography, withStyles } from '@material-ui/core' +import { styled } from '@mui/material/styles' +import { Typography } from '@mui/material' -const styles = () => ({ - typography: { +const PREFIX = 'IconLabel' + +const classes = { + typography: `${PREFIX}-typography`, + icon: `${PREFIX}-icon` +} + +const StyledTypography = styled(Typography)(() => ({ + [`&.${classes.typography}`]: { marginLeft: '5px', marginRight: '5px' }, - icon: { + + [`& .${classes.icon}`]: { fontSize: '16px', paddingRight: '10px' } -}) - +})) function IconLabel (props) { const { - classes, icon, // font-awesome class name label } = props return ( - + {label} - + ) } -export default withStyles(styles)(IconLabel) +export default (IconLabel) diff --git a/assets/src/components/Label.js b/assets/src/components/Label.js index fb2420dae..dd64e46d5 100644 --- a/assets/src/components/Label.js +++ b/assets/src/components/Label.js @@ -5,17 +5,17 @@ const getHorizontalStyles = (value) => { return ( value > alignThreshold ? { - left: '0', - right: value + '%', - width: value + '%', - textAlign: 'right' - } + left: '0', + right: value + '%', + width: value + '%', + textAlign: 'right' + } : { - left: value + '%', - right: '0', - width: '', - textAlign: 'left' - } + left: value + '%', + right: '0', + width: '', + textAlign: 'left' + } ) } diff --git a/assets/src/components/PopupMessage.js b/assets/src/components/PopupMessage.js index 61e74a6d9..0c83e2c91 100644 --- a/assets/src/components/PopupMessage.js +++ b/assets/src/components/PopupMessage.js @@ -1,5 +1,5 @@ import React from 'react' -import { Typography } from '@material-ui/core' +import { Typography } from '@mui/material' import { getDecimalPlaceOfFloat, roundToXDecimals } from '../util/math' function PopupMessage ({ a, assignmentGroups }) { @@ -7,11 +7,11 @@ function PopupMessage ({ a, assignmentGroups }) { const assignmentGroup = assignmentGroups.find(ag => ag.id === a.assignmentGroupId) return assignmentGroup ? ( - { - dropLowest: assignmentGroup.dropLowest, - dropHighest: assignmentGroup.dropHighest - } - ) + { + dropLowest: assignmentGroup.dropLowest, + dropHighest: assignmentGroup.dropHighest + } + ) : false } diff --git a/assets/src/components/ProgressBarV2.js b/assets/src/components/ProgressBarV2.js index 4245bf954..6c033c1d0 100644 --- a/assets/src/components/ProgressBarV2.js +++ b/assets/src/components/ProgressBarV2.js @@ -1,24 +1,35 @@ import React from 'react' +import { styled } from '@mui/material/styles' import Line from './Line' -import { withStyles } from '@material-ui/core/styles' +const PREFIX = 'ProgressBarV2' -const styles = theme => ({ - gradedBar: { +const classes = { + gradedBar: `${PREFIX}-gradedBar`, + ungradedBar: `${PREFIX}-ungradedBar`, + outOfBar: `${PREFIX}-outOfBar` +} + +// TODO jss-to-styled codemod: The Fragment root was replaced by div. Change the tag if needed. +const Root = styled('div')(( + { + theme + } +) => ({ + [`& .${classes.gradedBar}`]: { backgroundColor: theme.palette.secondary.main }, - ungradedBar: { + [`& .${classes.ungradedBar}`]: { backgroundColor: theme.palette.info.main }, - outOfBar: { + [`& .${classes.outOfBar}`]: { backgroundColor: theme.palette.negative.main } -}) +})) function ProgressBarV2 (props) { const { - classes, score, outOf, submitted, @@ -36,7 +47,7 @@ function ProgressBarV2 (props) { : null return ( - <> + {
{ if (onBarFocus) onBarFocus(event.currentTarget) }} onBlur={(event) => { if (onBarBlur) onBarBlur() }} @@ -73,13 +84,13 @@ function ProgressBarV2 (props) { height: `${height}px` }} /> - ) + ) : null }
} - +
) } -export default withStyles(styles)(ProgressBarV2) +export default (ProgressBarV2) diff --git a/assets/src/components/RangeSlider.js b/assets/src/components/RangeSlider.js index 90fbc2d85..7ba486c9b 100644 --- a/assets/src/components/RangeSlider.js +++ b/assets/src/components/RangeSlider.js @@ -1,6 +1,6 @@ import React from 'react' import 'rc-slider/assets/index.css' -import { Range } from 'rc-slider' +import Slider from 'rc-slider' import { siteTheme } from '../globals' const rangeSlider = props => { @@ -31,18 +31,21 @@ const rangeSlider = props => { return (

Select a start and end week

-
) diff --git a/assets/src/components/SelectCard.js b/assets/src/components/SelectCard.js index 87d9793f0..d5f9c0aad 100644 --- a/assets/src/components/SelectCard.js +++ b/assets/src/components/SelectCard.js @@ -1,91 +1,130 @@ /* global fetch */ import React, { useState } from 'react' -import { withStyles } from '@material-ui/core/styles' -import { Card, CardActionArea, CardActions, CardContent, CardMedia, CircularProgress, Divider, Fab, IconButton, Link as MUILink, Snackbar, Tooltip, Typography } from '@material-ui/core' -import CheckBoxIcon from '@material-ui/icons/CheckBox' -import CheckBoxOutlineBlankIcon from '@material-ui/icons/CheckBoxOutlineBlank' -import CloseIcon from '@material-ui/icons/Close' -import InfoIcon from '@material-ui/icons/Info' -import SaveIcon from '@material-ui/icons/Save' +import { styled } from '@mui/material/styles' +import { Card, CardActionArea, CardActions, CardContent, CardMedia, CircularProgress, Divider, Fab, IconButton, Link as MUILink, Snackbar, Tooltip, Typography } from '@mui/material' +import CheckBoxIcon from '@mui/icons-material/CheckBox' +import CheckBoxOutlineBlankIcon from '@mui/icons-material/CheckBoxOutlineBlank' +import CloseIcon from '@mui/icons-material/Close' +import InfoIcon from '@mui/icons-material/Info' +import SaveIcon from '@mui/icons-material/Save' import { Link } from 'react-router-dom' -import Grid from '@material-ui/core/Grid' -import { yellow, grey } from '@material-ui/core/colors' +import Grid from '@mui/material/Grid' +import { yellow, grey } from '@mui/material/colors' import clsx from 'clsx' import { defaultFetchOptions, handleError } from '../util/data' import { isTeacherOrAdmin } from '../util/roles' import PropTypes from 'prop-types' -const styles = theme => ({ - card: { +const PREFIX = 'SelectCard' + +const classes = { + card: `${PREFIX}-card`, + media: `${PREFIX}-media`, + content: `${PREFIX}-content`, + title: `${PREFIX}-title`, + titleArea: `${PREFIX}-titleArea`, + description: `${PREFIX}-description`, + titleLink: `${PREFIX}-titleLink`, + infoLink: `${PREFIX}-infoLink`, + help: `${PREFIX}-help`, + mainCardContainer: `${PREFIX}-mainCardContainer`, + wrapper: `${PREFIX}-wrapper`, + fabProgress: `${PREFIX}-fabProgress`, + buttonEnabled: `${PREFIX}-buttonEnabled`, + buttonDisabled: `${PREFIX}-buttonDisabled`, + checkbox: `${PREFIX}-checkbox` +} + +// TODO jss-to-styled codemod: The Fragment root was replaced by div. Change the tag if needed. +const Root = styled('div')(( + { + theme + } +) => ({ + [`& .${classes.card}`]: { margin: theme.spacing(3) }, - media: { + + [`& .${classes.media}`]: { height: 140, backgroundSize: 'auto', objectFit: 'scale-down' }, - content: { + + [`& .${classes.content}`]: { height: 110, padding: 0 }, - title: { + + [`& .${classes.title}`]: { boxSizing: 'border-box', padding: theme.spacing(1), color: 'white', marginBottom: 0, backgroundColor: theme.palette.primary.main }, - titleArea: { + + [`& .${classes.titleArea}`]: { color: 'white', backgroundColor: theme.palette.primary.main }, - description: { + + [`& .${classes.description}`]: { padding: theme.spacing(1), color: 'black', height: '100%' }, - titleLink: { + + [`& .${classes.titleLink}`]: { color: 'white' }, - infoLink: { + + [`& .${classes.infoLink}`]: { color: 'white' }, - help: { + + [`& .${classes.help}`]: { position: 'absolute', zIndex: 1, bottom: '21%', right: '5.5%' }, - mainCardContainer: { + + [`& .${classes.mainCardContainer}`]: { position: 'relative' }, - wrapper: { + + [`& .${classes.wrapper}`]: { margin: theme.spacing(1), position: 'relative' }, - fabProgress: { + + [`& .${classes.fabProgress}`]: { color: yellow[500], position: 'absolute', top: -6, left: -6, zIndex: 1 }, - buttonEnabled: { + + [`& .${classes.buttonEnabled}`]: { }, - buttonDisabled: { + + [`& .${classes.buttonDisabled}`]: { backgroundColor: grey[500], '&:hover': { backgroundColor: grey[700] } }, - checkbox: { + + [`& .${classes.checkbox}`]: { backgroundColor: 'transparent' } -}) +})) const SelectCard = props => { - const { classes, cardData, courseId } = props + const { cardData, courseId } = props const { viewCode } = cardData const [enabled, setEnabled] = useState(props.courseInfo.course_view_options[viewCode]) const [snackbarMessage, setResponseMessage] = useState('Saved') @@ -200,7 +239,7 @@ const SelectCard = props => { } return ( - <> +
@@ -258,12 +297,13 @@ const SelectCard = props => { aria-label='close' color='inherit' onClick={() => setSnackbarOpen(false)} + size='large' > ]} /> - + ) } @@ -281,4 +321,4 @@ SelectCard.propTypes = { SelectCard.defaultProps = {} -export default withStyles(styles)(SelectCard) +export default (SelectCard) diff --git a/assets/src/components/StyledTextField.js b/assets/src/components/StyledTextField.js index 1e5c8d15c..5e7b48c22 100644 --- a/assets/src/components/StyledTextField.js +++ b/assets/src/components/StyledTextField.js @@ -1,21 +1,19 @@ -import TextField from '@material-ui/core/TextField' -import { withStyles } from '@material-ui/core/styles' +import TextField from '@mui/material/TextField' +import { styled } from '@mui/material/styles' -const StyledTextField = withStyles(theme => ({ - root: { - '& .MuiFormLabel-root.Mui-error': { - color: theme.palette.warning.dark - }, - '& .MuiInput-underline.Mui-error:after': { - borderBottomColor: theme.palette.warning.main - }, - '& .MuiInputBase-input': { - color: 'green' - }, - '& .MuiOutlinedInput-root.Mui-error .MuiOutlinedInput-notchedOutline': { - borderColor: theme.palette.warning.main - } +const StyledTextField = styled(TextField)(({ theme }) => ({ + '& .MuiFormLabel-root.Mui-error': { + color: theme.palette.warning.dark + }, + '& .MuiInput-underline.Mui-error:after': { + borderBottomColor: theme.palette.warning.main + }, + '& .MuiInputBase-input': { + color: 'green' + }, + '& .MuiOutlinedInput-root.Mui-error .MuiOutlinedInput-notchedOutline': { + borderColor: theme.palette.warning.main } -}))(TextField) +})) export default StyledTextField diff --git a/assets/src/components/SurveyModal.js b/assets/src/components/SurveyModal.js index dfc03391c..df0e8f55a 100644 --- a/assets/src/components/SurveyModal.js +++ b/assets/src/components/SurveyModal.js @@ -1,19 +1,33 @@ import React, { useState } from 'react' -import { useLocation } from 'react-router' -import { makeStyles } from '@material-ui/core/styles' -import Button from '@material-ui/core/Button' -import DialogTitle from '@material-ui/core/DialogTitle' -import IconButton from '@material-ui/core/IconButton' -import Modal from '@material-ui/core/Modal' -import CloseIcon from '@material-ui/icons/Close' +import { styled } from '@mui/material/styles' +import { useLocation } from 'react-router-dom' +import Button from '@mui/material/Button' +import DialogTitle from '@mui/material/DialogTitle' +import IconButton from '@mui/material/IconButton' +import Modal from '@mui/material/Modal' +import CloseIcon from '@mui/icons-material/Close' +import Typography from '@mui/material/Typography' -const useStyles = makeStyles((theme) => ({ - modal: { +const PREFIX = 'SurveyModal' + +const classes = { + modal: `${PREFIX}-modal`, + paper: `${PREFIX}-paper`, + dialogTitle: `${PREFIX}-dialogTitle`, + iframeContainer: `${PREFIX}-iframeContainer`, + iframe: `${PREFIX}-iframe`, + surveyButton: `${PREFIX}-surveyButton` +} + +// styling within the modal (root styling doesn't apply to portal elements) +const StyledModalBody = styled('div')(({ theme }) => ({ + [`& .${classes.modal}`]: { top: '10%', left: '50%', transform: 'translate(-50%)' }, - paper: { + + [`& .${classes.paper}`]: { position: 'absolute', width: 400, backgroundColor: theme.palette.background.paper, @@ -21,20 +35,23 @@ const useStyles = makeStyles((theme) => ({ boxShadow: theme.shadows[5], padding: theme.spacing(2, 4, 3) }, - dialogTitle: { + + [`& .${classes.dialogTitle}`]: { display: 'flex', justifyContent: 'space-between', alignItems: 'center', padding: '0px' }, - iframeContainer: { + + [`& .${classes.iframeContainer}`]: { position: 'relative', overflow: 'hidden', width: '100%', paddingTop: '150%' }, + /* Then style the iframe to fit in the container div with full height and width */ - iframe: { + [`& .${classes.iframe}`]: { position: 'absolute', top: 0, left: 0, @@ -42,15 +59,18 @@ const useStyles = makeStyles((theme) => ({ right: 0, width: '100%', height: '100%' - }, - surveyButton: { - color: theme.palette.primary.main, - background: theme.palette.getContrastText(theme.palette.primary.main) + } +})) + +const ColoredButton = styled(Button)(({ theme }) => ({ + backgroundColor: theme.palette.getContrastText(theme.palette.primary.main), + color: theme.palette.primary.main, + '&:hover': { + backgroundColor: '#D5D5D5' } })) export default function SurveyModal (props) { - const classes = useStyles() const location = useLocation() const [open, setOpen] = useState(false) @@ -74,9 +94,9 @@ export default function SurveyModal (props) { const body = (
- -

{props.surveyLink.text}

- + + {props.surveyLink.text} + @@ -90,16 +110,16 @@ export default function SurveyModal (props) { ) return ( -
- + <> + {props.surveyLink.text} - {body} + {body} -
+ ) } diff --git a/assets/src/components/Table.js b/assets/src/components/Table.js index f19a8ad33..2194b1bd9 100644 --- a/assets/src/components/Table.js +++ b/assets/src/components/Table.js @@ -1,15 +1,28 @@ // modified from https://demos.creative-tim.com/material-dashboard-react/?_ga=2.12819711.913135977.1549993496-494583875.1549993496#/table import React from 'react' -import withStyles from '@material-ui/core/styles/withStyles' -import Table from '@material-ui/core/Table' -import TableHead from '@material-ui/core/TableHead' -import TableRow from '@material-ui/core/TableRow' -import TableBody from '@material-ui/core/TableBody' -import TableCell from '@material-ui/core/TableCell' +import { styled } from '@mui/material/styles' +import Table from '@mui/material/Table' +import TableHead from '@mui/material/TableHead' +import TableRow from '@mui/material/TableRow' +import TableBody from '@mui/material/TableBody' +import TableCell from '@mui/material/TableCell' -const tableStyle = theme => ({ - table: { +const PREFIX = 'Table' + +const classes = { + table: `${PREFIX}-table`, + tableHeadCell: `${PREFIX}-tableHeadCell`, + tableCell: `${PREFIX}-tableCell`, + tableResponsive: `${PREFIX}-tableResponsive` +} + +const Root = styled('div')(( + { + theme + } +) => ({ + [`& .${classes.table}`]: { marginBottom: '0', width: '100%', maxWidth: '100%', @@ -17,43 +30,48 @@ const tableStyle = theme => ({ borderSpacing: '0', borderCollapse: 'collapse' }, - tableHeadCell: { + + [`& .${classes.tableHeadCell}`]: { color: 'inherit', fontSize: '1em' }, - tableCell: { + + [`& .${classes.tableCell}`]: { lineHeight: '1.42857143', padding: '12px 8px', verticalAlign: 'middle' }, - tableResponsive: { + + [`&.${classes.tableResponsive}`]: { width: '100%', overflowX: 'auto' } -}) +})) function CustomTable (props) { - const { classes, tableHead, tableData, noBorder } = props + const { tableHead, tableData, noBorder } = props return ( -
+ - {tableHead !== undefined ? ( - - - {tableHead.map((prop, key) => { - return ( - - {prop} - - ) - })} - - - ) : null} + {tableHead !== undefined + ? ( + + + {tableHead.map((prop, key) => { + return ( + + {prop} + + ) + })} + + + ) + : null} {tableData.map((prop, key) => { return ( @@ -74,8 +92,8 @@ function CustomTable (props) { })}
-
+ ) } -export default withStyles(tableStyle)(CustomTable) +export default (CustomTable) diff --git a/assets/src/components/TestThemeProvider.js b/assets/src/components/TestThemeProvider.js index 13b38be0d..35a6663fe 100644 --- a/assets/src/components/TestThemeProvider.js +++ b/assets/src/components/TestThemeProvider.js @@ -1,5 +1,5 @@ import * as React from 'react' -import { ThemeProvider } from '@material-ui/core/styles' +import { ThemeProvider } from '@mui/material/styles' import { siteTheme } from '../globals' diff --git a/assets/src/components/UserSettingSnackbar.js b/assets/src/components/UserSettingSnackbar.js index 94d3fd64b..85c4a0e74 100644 --- a/assets/src/components/UserSettingSnackbar.js +++ b/assets/src/components/UserSettingSnackbar.js @@ -1,8 +1,8 @@ import React, { useState, useEffect } from 'react' -import Snackbar from '@material-ui/core/Snackbar' -import IconButton from '@material-ui/core/IconButton' -import CloseIcon from '@material-ui/icons/Close' -import Slide from '@material-ui/core/Slide' +import Snackbar from '@mui/material/Snackbar' +import IconButton from '@mui/material/IconButton' +import CloseIcon from '@mui/icons-material/Close' +import Slide from '@mui/material/Slide' function SlideTransition (props) { return @@ -53,6 +53,7 @@ function UserSettingSnackbar (props) { aria-label='close' color='inherit' onClick={() => setSavedSnackbarOpen(false)} + size='large' >
diff --git a/assets/src/components/ViewHeader.js b/assets/src/components/ViewHeader.js index 47e640fb8..99a54a970 100644 --- a/assets/src/components/ViewHeader.js +++ b/assets/src/components/ViewHeader.js @@ -1,5 +1,5 @@ import React, { useEffect, useState } from 'react' -import Typography from '@material-ui/core/Typography' +import Typography from '@mui/material/Typography' function ViewHeader (props) { const [domElement, setDomElement] = useState(null) diff --git a/assets/src/components/d3/createResourceAccessChart.js b/assets/src/components/d3/createResourceAccessChart.js index 30fd268f8..e60852cdf 100644 --- a/assets/src/components/d3/createResourceAccessChart.js +++ b/assets/src/components/d3/createResourceAccessChart.js @@ -215,7 +215,7 @@ function createResourceAccessChart ({ data, width, height, domElement }) { .attr('dx', -10) .attr('dy', '.35em') .attr('font-size', '12px') - .style('fill', d => d.self_access_count > 0 ? 'white' : 'black') + .style('fill', 'black') .attr('text-anchor', 'end') .text(d => ( ((mainYScale(d.resource_name) + mainYScale.bandwidth() / 2) < mainHeight) && @@ -256,8 +256,8 @@ function createResourceAccessChart ({ data, width, height, domElement }) { const fullRange = mainYZoom.range() const selection = event ? event.selection[1] === 0 // prevents [0, 0] from being returned, which causes bug - ? [0, 0.1] - : event.selection + ? [0, 0.1] + : event.selection : defaultSelection // Update the axes diff --git a/assets/src/components/withPopover.js b/assets/src/components/withPopover.js index 9be645826..ec4e24de7 100644 --- a/assets/src/components/withPopover.js +++ b/assets/src/components/withPopover.js @@ -1,6 +1,6 @@ import React, { useState } from 'react' -import Button from '@material-ui/core/Button' -import Popover from '@material-ui/core/Popover' +import Button from '@mui/material/Button' +import Popover from '@mui/material/Popover' const withPopover = Component => props => { const { popoverText } = props diff --git a/assets/src/containers/App.js b/assets/src/containers/App.js index 82524e63b..2a131928d 100755 --- a/assets/src/containers/App.js +++ b/assets/src/containers/App.js @@ -1,14 +1,13 @@ import React from 'react' -import { Route, Switch, useLocation } from 'react-router-dom' -import { matchPath } from 'react-router' +import { Route, Routes, useMatch } from 'react-router-dom' import GoogleAnalyticsTracking from '../components/GoogleAnalyticsTracking' import CourseList from './CourseList' import Course from './Course' import WarningBanner from '../components/WarningBanner' +import AlertBanner from '../components/AlertBanner' import { Helmet } from 'react-helmet' function App (props) { - const location = useLocation() const { user, gaId, cspNonce } = props if (!user.isLoggedIn) { @@ -17,24 +16,20 @@ function App (props) { } return (window.location.href = user.loginURL) } - const coursePageMatch = matchPath(location.pathname, '/courses/:courseId/') + const coursePageMatch = useMatch('/courses/:courseId/*') const courseId = coursePageMatch ? coursePageMatch.params.courseId : null - return ( <> - - - - - - - - - {courseId ? : null} - - + + } /> + } /> + : Application Launch did not happened properely} + /> + ) } diff --git a/assets/src/containers/AssignmentPlanningV2.js b/assets/src/containers/AssignmentPlanningV2.js index a38dfe7ae..bd835cb92 100644 --- a/assets/src/containers/AssignmentPlanningV2.js +++ b/assets/src/containers/AssignmentPlanningV2.js @@ -1,8 +1,8 @@ import React, { useState } from 'react' -import { withStyles } from '@material-ui/core/styles' -import Grid from '@material-ui/core/Grid' -import Paper from '@material-ui/core/Paper' -import Typography from '@material-ui/core/Typography' +import { styled } from '@mui/material/styles' +import Grid from '@mui/material/Grid' +import Paper from '@mui/material/Paper' +import Typography from '@mui/material/Typography' import AlertBanner from '../components/AlertBanner' import AssignmentGoalInput from '../components/AssignmentGoalInput' import AssignmentTable from '../components/AssignmentTable' @@ -30,48 +30,77 @@ import { setAssigmentGoalInputState } from '../util/assignment' -const styles = theme => ({ - root: { +const PREFIX = 'AssignmentPlanningV2' + +const classes = { + root: `${PREFIX}-root`, + paper: `${PREFIX}-paper`, + section: `${PREFIX}-section`, + mainProgressBar: `${PREFIX}-mainProgressBar`, + assignStatus: `${PREFIX}-assignStatus`, + legendItem: `${PREFIX}-legendItem`, + legendItemLabel: `${PREFIX}-legendItemLabel`, + graded: `${PREFIX}-graded`, + ungraded: `${PREFIX}-ungraded`, + unsubmitted: `${PREFIX}-unsubmitted` +} + +// TODO jss-to-styled codemod: The Fragment root was replaced by div. Change the tag if needed. +const Root = styled('div')(( + { + theme + } +) => ({ + [`& .${classes.root}`]: { flexGrow: 1, padding: 8 }, - paper: { + + [`& .${classes.paper}`]: { padding: theme.spacing(2), color: theme.palette.text.secondary }, - section: { + + [`& .${classes.section}`]: { paddingBottom: 10, paddingTop: 10 }, - mainProgressBar: { + + [`& .${classes.mainProgressBar}`]: { marginBottom: '2.5rem' }, - assignStatus: { + + [`& .${classes.assignStatus}`]: { width: '10px', height: '10px', display: 'inline-block' }, - legendItem: { + + [`& .${classes.legendItem}`]: { display: 'inline-block', marginRight: '14px' }, - legendItemLabel: { + + [`& .${classes.legendItemLabel}`]: { display: 'inline', marginLeft: '6px' }, - graded: { + + [`& .${classes.graded}`]: { background: theme.palette.secondary.main }, - ungraded: { + + [`& .${classes.ungraded}`]: { background: theme.palette.info.main }, - unsubmitted: { + + [`& .${classes.unsubmitted}`]: { background: theme.palette.negative.main } -}) +})) function AssignmentPlanningV2 (props) { - const { classes, disabled, courseId, isAdmin, enrollmentTypes } = props + const { disabled, courseId, isAdmin, enrollmentTypes } = props if (disabled && !isTeacherOrAdmin(isAdmin, enrollmentTypes)) return (The Assignment Planning view is hidden for this course.) const [assignments, setAssignments] = useState([]) @@ -165,7 +194,7 @@ function AssignmentPlanningV2 (props) { if (error) return () return ( - <> + {disabled ? Preview Mode: This view is currently disabled for students. : undefined}
@@ -267,8 +296,8 @@ function AssignmentPlanningV2 (props) {
- +
) } -export default withStyles(styles)(AssignmentPlanningV2) +export default (AssignmentPlanningV2) diff --git a/assets/src/containers/Course.js b/assets/src/containers/Course.js index 25b3ac26e..ee7e2a429 100644 --- a/assets/src/containers/Course.js +++ b/assets/src/containers/Course.js @@ -1,5 +1,6 @@ import React, { useState } from 'react' -import { BrowserRouter as Router, Route, Switch } from 'react-router-dom' +import { styled } from '@mui/material/styles' +import { Route, Routes } from 'react-router-dom' import DashboardAppBar from './DashboardAppBar' import SideDrawer from './SideDrawer' import GradeDistribution from './GradeDistribution' @@ -10,25 +11,37 @@ import Spinner from '../components/Spinner' import { isObjectEmpty } from '../util/object' import { useCourseInfo } from '../service/api' import WarningBanner from '../components/WarningBanner' -import { CardMedia, Card } from '@material-ui/core' -import { withStyles } from '@material-ui/core/styles' +import { CardMedia, Card } from '@mui/material' import { Helmet } from 'react-helmet' -const styles = theme => ({ - card: { +const PREFIX = 'Course' + +const classes = { + card: `${PREFIX}-card`, + notLoadedMedia: `${PREFIX}-notLoadedMedia` +} + +// TODO jss-to-styled codemod: The Fragment root was replaced by div. Change the tag if needed. +const Root = styled('div')(( + { + theme + } +) => ({ + [`& .${classes.card}`]: { margin: theme.spacing(3) }, - notLoadedMedia: { + + [`& .${classes.notLoadedMedia}`]: { maxWidth: '50%', marginLeft: 'auto', marginRight: 'auto', marginTop: theme.spacing(2), marginBottom: theme.spacing(2) } -}) +})) function Course (props) { - const { courseId, user, classes } = props + const { courseId, user } = props const [loaded, error, courseInfo] = useCourseInfo(courseId) const [sideDrawerState, setSideDrawerState] = useState(false) @@ -50,7 +63,7 @@ function Course (props) { const notLoadedAltMessage = 'Mouse running on wheel with text "Course Data Being Processed, Try Back in 24 Hours"' return ( - <> + {loaded ? ( <> @@ -81,48 +94,54 @@ function Course (props) { alt={notLoadedAltMessage} /> - ) : ( - - - + - - - } + /> + - - - } + /> + - - - } + /> + - - - )} + />} + /> + + )} - ) : } - + ) + : } + ) } -export default withStyles(styles)(Course) +export default (Course) diff --git a/assets/src/containers/CourseList.js b/assets/src/containers/CourseList.js index e7fd235a3..d2db6e04b 100644 --- a/assets/src/containers/CourseList.js +++ b/assets/src/containers/CourseList.js @@ -1,48 +1,67 @@ import React, { useState } from 'react' -import { withStyles } from '@material-ui/core/styles' -import AppBar from '@material-ui/core/AppBar' -import Avatar from '@material-ui/core/Avatar' -import Grid from '@material-ui/core/Grid' -import IconButton from '@material-ui/core/IconButton' -import MuiLink from '@material-ui/core/Link' -import Popover from '@material-ui/core/Popover' -import Toolbar from '@material-ui/core/Toolbar' -import Typography from '@material-ui/core/Typography' +import { styled } from '@mui/material/styles' +import AppBar from '@mui/material/AppBar' +import Avatar from '@mui/material/Avatar' +import Grid from '@mui/material/Grid' +import IconButton from '@mui/material/IconButton' +import MuiLink from '@mui/material/Link' +import Popover from '@mui/material/Popover' +import Toolbar from '@mui/material/Toolbar' +import Typography from '@mui/material/Typography' import { siteTheme } from '../globals' import AlertBanner from '../components/AlertBanner' import AvatarModal from '../components/AvatarModal' -import CourseListCard from '../components/CourseListCard/CourseListCard' +import CourseListCard from '../components/CourseListCard' -const styles = theme => ({ - root: { +const PREFIX = 'CourseList' + +const classes = { + root: `${PREFIX}-root`, + paper: `${PREFIX}-paper`, + content: `${PREFIX}-content`, + container: `${PREFIX}-container`, + grow: `${PREFIX}-grow` +} + +// TODO jss-to-styled codemod: The Fragment root was replaced by div. Change the tag if needed. +const Root = styled('div')(( + { + theme + } +) => ({ + [`& .${classes.root}`]: { flexGrow: 1 }, - paper: { + + [`& .${classes.paper}`]: { padding: theme.spacing(2), color: theme.palette.text.secondary, display: 'flex' }, - content: { + + [`& .${classes.content}`]: { flexGrow: 1, padding: 8 }, - container: { + + [`& .${classes.container}`]: { display: 'flex', justifyContent: 'center' }, - grow: { + + [`& .${classes.grow}`]: { flexGrow: 1 } -}) +})) function CourseList (props) { - const { classes, user } = props + const { user } = props const [avatarEl, setAvatarEl] = useState(null) const avatarOpen = Boolean(avatarEl) return ( - <> + @@ -84,7 +103,7 @@ function CourseList (props) { Visit the Help site for more information about this tool. - ) + ) : ( @@ -96,11 +115,11 @@ function CourseList (props) { )) } - ) + ) }
- + ) } -export default withStyles(styles)(CourseList) +export default (CourseList) diff --git a/assets/src/containers/DashboardAppBar.js b/assets/src/containers/DashboardAppBar.js index b94d6d877..c378311ed 100644 --- a/assets/src/containers/DashboardAppBar.js +++ b/assets/src/containers/DashboardAppBar.js @@ -1,47 +1,67 @@ import React, { useState } from 'react' -import { withStyles } from '@material-ui/core/styles' -import { withRouter, Link } from 'react-router-dom' -import AppBar from '@material-ui/core/AppBar' -import Toolbar from '@material-ui/core/Toolbar' -import IconButton from '@material-ui/core/IconButton' -import MenuIcon from '@material-ui/icons/Menu' -import Avatar from '@material-ui/core/Avatar' -import Popover from '@material-ui/core/Popover' +import { styled } from '@mui/material/styles' +import { Link } from 'react-router-dom' +import AppBar from '@mui/material/AppBar' +import Toolbar from '@mui/material/Toolbar' +import IconButton from '@mui/material/IconButton' +import MenuIcon from '@mui/icons-material/Menu' +import Avatar from '@mui/material/Avatar' +import Popover from '@mui/material/Popover' import AvatarModal from '../components/AvatarModal' import SurveyModal from '../components/SurveyModal' import { surveyLink } from '../globals' +import withRouter from './WithRouter' -const styles = theme => ({ - root: { +const PREFIX = 'DashboardAppBar' + +const classes = { + root: `${PREFIX}-root`, + button: `${PREFIX}-button`, + grow: `${PREFIX}-grow`, + menuButton: `${PREFIX}-menuButton`, + homeButton: `${PREFIX}-homeButton`, + roundButton: `${PREFIX}-roundButton` +} + +const Root = styled('div')(( + { + theme + } +) => ({ + [`& .${classes.root}`]: { flexGrow: 1 }, - button: { + + [`& .${classes.button}`]: { margin: theme.spacing(1) }, - grow: { + + [`& .${classes.grow}`]: { flexGrow: 1 }, - menuButton: { + + [`& .${classes.menuButton}`]: { marginLeft: -12, marginRight: 20 }, - homeButton: { + + [`& .${classes.homeButton}`]: { textDecoration: 'none', color: 'white', textTransform: 'capitalize', padding: 4, fontSize: '1.25rem' }, - roundButton: { + + [`& .${classes.roundButton}`]: { borderRadius: '50%', padding: '12px', color: 'white' } -}) +})) function DashboardAppBar (props) { const { - classes, onMenuBarClick, user, courseId, @@ -54,7 +74,7 @@ function DashboardAppBar (props) { const showSurveyLink = Boolean(surveyLink.text.length && surveyLink.url.length) return ( -
+ @@ -79,6 +100,7 @@ function DashboardAppBar (props) { color='inherit' aria-haspopup='true' variant='contained' + size='large' > {user.initials} @@ -100,8 +122,8 @@ function DashboardAppBar (props) { -
+ ) } -export default withRouter(withStyles(styles)(DashboardAppBar)) +export default withRouter(DashboardAppBar) diff --git a/assets/src/containers/GradeDistribution.js b/assets/src/containers/GradeDistribution.js index 1cd3d530a..a49e3bd79 100644 --- a/assets/src/containers/GradeDistribution.js +++ b/assets/src/containers/GradeDistribution.js @@ -1,9 +1,9 @@ import React, { useState, useEffect } from 'react' -import { withStyles } from '@material-ui/core/styles' -import Paper from '@material-ui/core/Paper' -import Grid from '@material-ui/core/Grid' -import Typography from '@material-ui/core/Typography' -import Checkbox from '@material-ui/core/Checkbox' +import { styled } from '@mui/material/styles' +import Paper from '@mui/material/Paper' +import Grid from '@mui/material/Grid' +import Typography from '@mui/material/Typography' +import Checkbox from '@mui/material/Checkbox' import AlertBanner from '../components/AlertBanner' import WarningBanner from '../components/WarningBanner' import Histogram from '../components/Histogram' @@ -19,22 +19,37 @@ import useUserSetting from '../hooks/useUserSetting' import { isTeacherOrAdmin } from '../util/roles' import { Helmet } from 'react-helmet' -const styles = theme => ({ - root: { +const PREFIX = 'GradeDistribution' + +const classes = { + root: `${PREFIX}-root`, + paper: `${PREFIX}-paper`, + table: `${PREFIX}-table` +} + +// TODO jss-to-styled codemod: The Fragment root was replaced by div. Change the tag if needed. +const Root = styled('div')(( + { + theme + } +) => ({ + [`& .${classes.root}`]: { flexGrow: 1, padding: 8 }, - paper: { + + [`& .${classes.paper}`]: { padding: theme.spacing(2), color: theme.palette.text.secondary }, - table: { + + [`& .${classes.table}`]: { width: '300px' } -}) +})) function GradeDistribution (props) { - const { classes, disabled, courseId, user, isAdmin, enrollmentTypes } = props + const { disabled, courseId, user, isAdmin, enrollmentTypes } = props if (disabled && !isTeacherOrAdmin(isAdmin, enrollmentTypes)) return (The Grade Distribution view is hidden for this course.) const [gradeLoaded, gradeError, gradeData] = useGradeData(courseId) @@ -70,7 +85,7 @@ function GradeDistribution (props) { ['Class Size', {gradeData.summary.tot_students}], !user.admin && showGrade ? ([ - 'My grade', + 'My grade', { gradeData.summary.current_user_grade @@ -78,14 +93,14 @@ function GradeDistribution (props) { : 'There are no grades yet for you in this course' } - ]) + ]) : [] ] const gradeCheckbox = !user.admin ? userSettingLoaded ? ( - {'Show my grade'} + Show my grade - ) + ) : : null @@ -131,7 +146,7 @@ function GradeDistribution (props) { } return ( - <> + {disabled ? Preview Mode: This view is currently disabled for students. : undefined}
@@ -148,8 +163,8 @@ function GradeDistribution (props) {
- +
) } -export default withStyles(styles)(GradeDistribution) +export default (GradeDistribution) diff --git a/assets/src/containers/IndexPage.js b/assets/src/containers/IndexPage.js index f55286e0a..8ae6e7fd4 100644 --- a/assets/src/containers/IndexPage.js +++ b/assets/src/containers/IndexPage.js @@ -1,5 +1,5 @@ import React from 'react' -import Grid from '@material-ui/core/Grid' +import Grid from '@mui/material/Grid' import SelectCard from '../components/SelectCard' import { isObjectEmpty, getObjectValues } from '../util/object' import WarningBanner from '../components/WarningBanner' @@ -22,7 +22,7 @@ function IndexPage (props) { } return ( - + { routes(courseId, views, !teacherOrAdmin).map((p, key) => ( diff --git a/assets/src/containers/ResourcesAccessed.js b/assets/src/containers/ResourcesAccessed.js index 64a251997..9476aace5 100644 --- a/assets/src/containers/ResourcesAccessed.js +++ b/assets/src/containers/ResourcesAccessed.js @@ -1,16 +1,16 @@ /* global fetch */ import React, { useEffect, useState } from 'react' -import { withStyles } from '@material-ui/core/styles' -import Checkbox from '@material-ui/core/Checkbox' -import FormControl from '@material-ui/core/FormControl' -import FormControlLabel from '@material-ui/core/FormControlLabel' -import FormGroup from '@material-ui/core/FormGroup' -import Grid from '@material-ui/core/Grid' -import MenuItem from '@material-ui/core/MenuItem' -import Paper from '@material-ui/core/Paper' -import Select from '@material-ui/core/Select' -import Typography from '@material-ui/core/Typography' +import { styled } from '@mui/material/styles' +import Checkbox from '@mui/material/Checkbox' +import FormControl from '@mui/material/FormControl' +import FormControlLabel from '@mui/material/FormControlLabel' +import FormGroup from '@mui/material/FormGroup' +import Grid from '@mui/material/Grid' +import MenuItem from '@mui/material/MenuItem' +import Paper from '@mui/material/Paper' +import Select from '@mui/material/Select' +import Typography from '@mui/material/Typography' import AlertBanner from '../components/AlertBanner' import IconLabel from '../components/IconLabel' import RangeSlider from '../components/RangeSlider' @@ -26,32 +26,49 @@ import { handleError, defaultFetchOptions } from '../util/data' import { isTeacherOrAdmin } from '../util/roles' import { Helmet } from 'react-helmet' -const styles = theme => ({ - root: { +const PREFIX = 'ResourcesAccessed' + +const classes = { + root: `${PREFIX}-root`, + paper: `${PREFIX}-paper`, + formController: `${PREFIX}-formController`, + controlText: `${PREFIX}-controlText` +} + +// TODO jss-to-styled codemod: The Fragment root was replaced by div. Change the tag if needed. +const Root = styled('div')(( + { + theme + } +) => ({ + [`& .${classes.root}`]: { flexGrow: 1, padding: 8 }, - paper: { + + [`& .${classes.paper}`]: { color: theme.palette.text.secondary, padding: theme.spacing(2) }, - formController: { + + [`& .${classes.formController}`]: { alignItems: 'center', display: 'flex', justifyContent: 'center', marginTop: theme.spacing(2) }, - controlText: { + + [`& .${classes.controlText}`]: { marginRight: 16 } -}) +})) const currentSetting = 'My current setting' const rememberSetting = 'Remember my setting' const settingNotUpdated = 'Setting not updated' function ResourcesAccessed (props) { - const { classes, courseInfo, courseId, disabled, isAdmin, enrollmentTypes } = props + const { courseInfo, courseId, disabled, isAdmin, enrollmentTypes } = props if (disabled && !isTeacherOrAdmin(isAdmin, enrollmentTypes)) return (The Resources Accessed view is hidden for this course.) const resourceTypes = courseInfo.resource_types.length === 0 ? [{ label: 'Files', icon: 'fas fa-file fa-lg' }] @@ -256,7 +273,7 @@ function ResourcesAccessed (props) { } } return ( - <> + {disabled ? Preview Mode: This view is currently disabled for students. : undefined}
@@ -280,7 +297,7 @@ function ResourcesAccessed (props) { }

Resources accessed from week {weekRange[0]} {weekRange[0] === curWeek ? ' (Now)' : ''} to {weekRange[1]}{weekRange[1] === curWeek ? ' (Now) ' : ''} by students with these grades:

- +