Commit 9caa1a59 authored by Florent Chehab's avatar Florent Chehab

bumped(material-ui version) & Enhance(previous departure front)

* Bumped material-UI to v4.0.0
* Fixed braking changes,
* Moved some components to React Hook along the way
* Fixed some bugs
* v0.4.0 of the frontend image,

---

Enhanced frontend of previous departure, still a WIP
parent 59c8c491
Pipeline #40501 passed with stages
in 4 minutes and 31 seconds
...@@ -34,7 +34,7 @@ check_back: ...@@ -34,7 +34,7 @@ check_back:
check_front: check_front:
<<: *only-default <<: *only-default
stage: check stage: check
image: registry.gitlab.utc.fr/rex-dri/rex-dri/frontend:v0.3.0 image: registry.gitlab.utc.fr/rex-dri/rex-dri/frontend:v0.4.0
before_script: before_script:
- cd frontend && cp -R /usr/src/deps/node_modules . - cd frontend && cp -R /usr/src/deps/node_modules .
script: script:
...@@ -70,7 +70,7 @@ test_back: ...@@ -70,7 +70,7 @@ test_back:
test_frontend: test_frontend:
<<: *only-default <<: *only-default
stage: test stage: test
image: registry.gitlab.utc.fr/rex-dri/rex-dri/frontend:v0.3.0 image: registry.gitlab.utc.fr/rex-dri/rex-dri/frontend:v0.4.0
before_script: before_script:
- cd frontend && cp -R /usr/src/deps/node_modules . - cd frontend && cp -R /usr/src/deps/node_modules .
script: script:
...@@ -90,7 +90,7 @@ flake8: ...@@ -90,7 +90,7 @@ flake8:
eslint: eslint:
<<: *only-default <<: *only-default
stage: lint stage: lint
image: registry.gitlab.utc.fr/rex-dri/rex-dri/frontend:v0.3.0 image: registry.gitlab.utc.fr/rex-dri/rex-dri/frontend:v0.4.0
before_script: before_script:
- cd frontend && cp -R /usr/src/deps/node_modules . - cd frontend && cp -R /usr/src/deps/node_modules .
script: script:
......
...@@ -15,11 +15,11 @@ class CourseFeedback(EssentialModule): ...@@ -15,11 +15,11 @@ class CourseFeedback(EssentialModule):
) )
comment = models.TextField(null=True, max_length=1500) comment = models.TextField(null=True, max_length=1500)
adequation = models.IntegerField( adequation = models.IntegerField(
default=0, validators=[MaxValueValidator(5), MinValueValidator(-5)] default=0, validators=[MinValueValidator(-5), MaxValueValidator(5)]
) )
working_dose = models.IntegerField( working_dose = models.IntegerField(
default=0, validators=[MaxValueValidator(5), MinValueValidator(-5)] default=0, validators=[MinValueValidator(-5), MaxValueValidator(5)]
) )
language_following_ease = models.IntegerField( language_following_ease = models.IntegerField(
default=0, validators=[MaxValueValidator(5), MinValueValidator(-5)] default=0, validators=[MinValueValidator(-5), MaxValueValidator(5)]
) )
...@@ -23,7 +23,7 @@ class ExchangeFeedback(EssentialModule): ...@@ -23,7 +23,7 @@ class ExchangeFeedback(EssentialModule):
) )
general_comment = models.TextField(null=True, max_length=1500) general_comment = models.TextField(null=True, max_length=1500)
academical_level_appreciation = models.IntegerField( academical_level_appreciation = models.IntegerField(
validators=[MaxValueValidator(5), MinValueValidator(-5)] validators=[MinValueValidator(-5), MaxValueValidator(5)]
) )
foreign_student_welcome = models.PositiveIntegerField( foreign_student_welcome = models.PositiveIntegerField(
validators=[MaxValueValidator(10)] validators=[MaxValueValidator(10)]
......
...@@ -63,7 +63,7 @@ services: ...@@ -63,7 +63,7 @@ services:
# Service to handle frontend live developpments and building # Service to handle frontend live developpments and building
frontend: frontend:
# Get the image from the registry # Get the image from the registry
image: registry.gitlab.utc.fr/rex-dri/rex-dri/frontend:v0.3.0 image: registry.gitlab.utc.fr/rex-dri/rex-dri/frontend:v0.4.0
# To use a locally built one, comment above, uncomment bellow. # To use a locally built one, comment above, uncomment bellow.
# build: ./frontend # build: ./frontend
# On startup, we retrieve the dependencies from the image and start the developpement server # On startup, we retrieve the dependencies from the image and start the developpement server
......
This diff is collapsed.
...@@ -20,19 +20,19 @@ ...@@ -20,19 +20,19 @@
"license": "BSD-2-Clause", "license": "BSD-2-Clause",
"private": true, "private": true,
"dependencies": { "dependencies": {
"@date-io/date-fns": "^1.1.0", "@date-io/date-fns": "^1.3.6",
"@date-io/luxon": "^1.1.0", "@material-ui/core": "^4.0.0",
"@material-ui/core": "^3.9.2", "@material-ui/styles": "^4.0.0",
"@material-ui/icons": "^3.0.2", "@material-ui/icons": "^4.0.0",
"@material-ui/lab": "^3.0.0-alpha.30", "@material-ui/lab": "^4.0.0-alpha.13",
"@material-ui/pickers": "^3.0.0",
"axios": "^0.18.0", "axios": "^0.18.0",
"date-fns": "^2.0.0-alpha.25", "date-fns": "^2.0.0-alpha.27",
"downshift": "^3.2.3", "downshift": "^3.2.3",
"fuzzysort": "^1.1.4", "fuzzysort": "^1.1.4",
"keycode": "^2.2.0", "keycode": "^2.2.0",
"lodash": "^4.17.11", "lodash": "^4.17.11",
"mapbox-gl": "^0.54.0", "mapbox-gl": "^0.54.0",
"material-ui-pickers": "^2.2.1",
"notistack": "^0.4.3", "notistack": "^0.4.3",
"react": "^16.8.6", "react": "^16.8.6",
"react-awesome-slider": "^0.5.2", "react-awesome-slider": "^0.5.2",
......
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
import React from "react"; import React from "react";
import PropTypes from "prop-types"; import PropTypes from "prop-types";
import withStyles from "@material-ui/core/styles/withStyles"; import {withStyles} from "@material-ui/styles";
import FullScreenDialog from "./FullScreenDialog"; import FullScreenDialog from "./FullScreenDialog";
import {connect} from "react-redux"; import {connect} from "react-redux";
...@@ -85,7 +85,7 @@ const mapDispatchToProps = (dispatch) => { ...@@ -85,7 +85,7 @@ const mapDispatchToProps = (dispatch) => {
const styles = theme => ({ const styles = theme => ({
content: { content: {
[theme.breakpoints.up("md")]: { [theme.breakpoints.up("md")]: {
padding: theme.spacing.unit * 3, padding: theme.spacing(3),
}, },
[theme.breakpoints.down("sm")]: { [theme.breakpoints.down("sm")]: {
padding: 0, padding: 0,
......
...@@ -83,12 +83,12 @@ const styles = theme => ({ ...@@ -83,12 +83,12 @@ const styles = theme => ({
display: "none" display: "none"
}, },
[theme.breakpoints.up("lg")]: { [theme.breakpoints.up("lg")]: {
marginLeft: theme.spacing.unit, marginLeft: theme.spacing(1),
marginRight: theme.spacing.unit, marginRight: theme.spacing(1),
} }
}, },
mainMenuButtonIcon: { mainMenuButtonIcon: {
marginLeft: theme.spacing.unit, marginLeft: theme.spacing(1),
fontSize: "1.2em", fontSize: "1.2em",
[theme.breakpoints.down("md")]: { [theme.breakpoints.down("md")]: {
display: "none" display: "none"
...@@ -102,8 +102,8 @@ const styles = theme => ({ ...@@ -102,8 +102,8 @@ const styles = theme => ({
}, },
mobileIcon: {}, mobileIcon: {},
mobileIconContainer: { mobileIconContainer: {
marginLeft: theme.spacing.unit, marginLeft: theme.spacing(1),
marginRight: theme.spacing.unit, marginRight: theme.spacing(1),
}, },
primaryDark: { primaryDark: {
backgroundColor: theme.palette.primary.dark, backgroundColor: theme.palette.primary.dark,
......
...@@ -13,7 +13,6 @@ import InfoIcon from "@material-ui/icons/Info"; ...@@ -13,7 +13,6 @@ import InfoIcon from "@material-ui/icons/Info";
class DrawerMenu extends React.Component { class DrawerMenu extends React.Component {
toListItem(items, inset = false) { toListItem(items, inset = false) {
return items.map(({label, route, Icon}, idx) => ( return items.map(({label, route, Icon}, idx) => (
<CustomNavLink key={idx} to={route} onClick={() => this.props.closeDrawer()}> <CustomNavLink key={idx} to={route} onClick={() => this.props.closeDrawer()}>
...@@ -46,7 +45,7 @@ class DrawerMenu extends React.Component { ...@@ -46,7 +45,7 @@ class DrawerMenu extends React.Component {
render() { render() {
return ( return (
<div> <div style={{zIndex: 200000}}>
<Drawer open={this.props.open} onClose={() => this.props.closeDrawer()}> <Drawer open={this.props.open} onClose={() => this.props.closeDrawer()}>
<List>{this.toListItem([mainMenuHome])}</List> <List>{this.toListItem([mainMenuHome])}</List>
<Divider/> <Divider/>
......
...@@ -9,9 +9,9 @@ import { connect } from "react-redux"; ...@@ -9,9 +9,9 @@ import { connect } from "react-redux";
* Component to enable the FullScreenDialog to have nice transitions * Component to enable the FullScreenDialog to have nice transitions
* @returns * @returns
*/ */
function Transition(props) { const Transition = React.forwardRef(function Transition(props, ref) {
return <Slide direction="up" {...props} />; return <Slide direction="up" ref={ref} {...props} />;
} });
/** /**
......
import {NavLink} from "react-router-dom"; import {NavLink} from "react-router-dom";
import React from "react"; import React from "react";
import PropTypes from "prop-types"; import PropTypes from "prop-types";
import {makeStyles} from "@material-ui/styles";
const useStyles = makeStyles(theme => {
return {
link: {
color: theme.palette.text.primary,
textDecoration: "none"
},
};
});
/** /**
* Renders a NavLink (internal app link) with no decoration * Renders a NavLink (internal app link) with no decoration
*/ */
class CustomNavLink extends React.Component { function CustomNavLink(props) {
render() { const {to, children} = props;
const {to, children} = this.props; return (
return ( <NavLink to={to} className={useStyles().link}>
<NavLink to={to} style={{textDecoration: "none"}}> {children}
{children} </NavLink>
</NavLink> );
);
}
} }
CustomNavLink.propTypes = { CustomNavLink.propTypes = {
......
...@@ -79,9 +79,13 @@ const ConnectedErrorBoundary = compose( ...@@ -79,9 +79,13 @@ const ConnectedErrorBoundary = compose(
* @returns {function(*): function(*): *} * @returns {function(*): function(*): *}
*/ */
export function withErrorBoundary() { export function withErrorBoundary() {
return Component => setDisplayName("Error boundary")(props => ( return Component => setDisplayName("error-boundary")(
<ConnectedErrorBoundary> // We need to forward the ref otherwise the styles are not correctly applied.
<Component {...props}/> // eslint-disable-next-line react/display-name
</ConnectedErrorBoundary> React.forwardRef((props, ref) =>
)); <ConnectedErrorBoundary>
<Component {...props} ref={ref}/>
</ConnectedErrorBoundary>
)
);
} }
...@@ -5,6 +5,12 @@ import Fab from "@material-ui/core/Fab"; ...@@ -5,6 +5,12 @@ import Fab from "@material-ui/core/Fab";
import {MenuItem} from "@material-ui/core"; import {MenuItem} from "@material-ui/core";
import {NavLink} from "react-router-dom"; import {NavLink} from "react-router-dom";
/**
* There were errors during migrations to material-ui v4 as Navlink couldn't hold a ref...
*/
// eslint-disable-next-line react/display-name
const ForwardedNavLink = React.forwardRef((props, ref)=> <div ref={ref}><NavLink {...props}/></div>);
class IconWithMenu extends React.Component { class IconWithMenu extends React.Component {
state = { state = {
anchorEl: null, anchorEl: null,
...@@ -48,7 +54,7 @@ class IconWithMenu extends React.Component { ...@@ -48,7 +54,7 @@ class IconWithMenu extends React.Component {
</MenuItem> </MenuItem>
: :
<MenuItem key={idx} <MenuItem key={idx}
component={NavLink} component={ForwardedNavLink}
to={route} to={route}
onClick={this.handleCloseMenu}> onClick={this.handleCloseMenu}>
{label} {label}
...@@ -67,7 +73,7 @@ IconWithMenu.defaultProps = { ...@@ -67,7 +73,7 @@ IconWithMenu.defaultProps = {
}; };
IconWithMenu.propTypes = { IconWithMenu.propTypes = {
Icon: PropTypes.func.isRequired, // should be a react component Icon: PropTypes.object.isRequired, // should be a react component
menuItems: PropTypes.array.isRequired, // should be an array of menu items menuItems: PropTypes.array.isRequired, // should be an array of menu items
fabProps: PropTypes.object, fabProps: PropTypes.object,
iconProps: PropTypes.object, iconProps: PropTypes.object,
......
...@@ -65,7 +65,7 @@ Loading.defaultProps = { ...@@ -65,7 +65,7 @@ Loading.defaultProps = {
const styles = theme => ({ const styles = theme => ({
progress: { progress: {
margin: theme.spacing.unit * 2, margin: theme.spacing(2),
} }
}); });
......
...@@ -2,14 +2,12 @@ ...@@ -2,14 +2,12 @@
/* eslint-disable react/display-name */ /* eslint-disable react/display-name */
// Inspired by : https://github.com/mui-org/material-ui/blob/master/docs/src/pages/page-layout-examples/blog/Markdown.js // Inspired by : https://github.com/mui-org/material-ui/blob/master/docs/src/pages/page-layout-examples/blog/Markdown.js
import React, { Component } from "react"; import React, {Component} from "react";
import PropTypes from "prop-types"; import PropTypes from "prop-types";
import ReactMarkdown from "react-markdown"; import ReactMarkdown from "react-markdown";
import parseMoney from "../../utils/parseMoney"; import parseMoney from "../../utils/parseMoney";
import convertAmountToEur from "../../utils/convertAmountToEur"; import convertAmountToEur from "../../utils/convertAmountToEur";
import withStyles from "@material-ui/core/styles/withStyles";
import Typography from "@material-ui/core/Typography"; import Typography from "@material-ui/core/Typography";
import Table from "@material-ui/core/Table"; import Table from "@material-ui/core/Table";
import TableBody from "@material-ui/core/TableBody"; import TableBody from "@material-ui/core/TableBody";
...@@ -18,13 +16,15 @@ import TableHead from "@material-ui/core/TableHead"; ...@@ -18,13 +16,15 @@ import TableHead from "@material-ui/core/TableHead";
import TableRow from "@material-ui/core/TableRow"; import TableRow from "@material-ui/core/TableRow";
import Paper from "@material-ui/core/Paper"; import Paper from "@material-ui/core/Paper";
import { lighten, darken } from "@material-ui/core/styles/colorManipulator"; import {darken, lighten} from "@material-ui/core/styles/colorManipulator";
import Divider from "@material-ui/core/Divider"; import Divider from "@material-ui/core/Divider";
import TextLink, {getLinkColor} from "../common/TextLink"; import TextLink, {getLinkColor} from "../common/TextLink";
import {makeStyles} from "@material-ui/styles";
// Custom styling for the rendered markdown // Custom styling for the rendered markdown
const styles = theme => { // To be used in hooks based components only
const { palette } = theme, const useStyles = makeStyles(theme => {
const {palette} = theme,
backgroundTable = palette.type === "dark" ? lighten(palette.background.paper, 0.07) : darken(palette.background.paper, 0.02), backgroundTable = palette.type === "dark" ? lighten(palette.background.paper, 0.07) : darken(palette.background.paper, 0.02),
headerTable = palette.type === "dark" ? lighten(palette.background.paper, 0.13) : darken(palette.background.paper, 0.07); headerTable = palette.type === "dark" ? lighten(palette.background.paper, 0.13) : darken(palette.background.paper, 0.07);
...@@ -36,7 +36,7 @@ const styles = theme => { ...@@ -36,7 +36,7 @@ const styles = theme => {
fontFamily: "monospace" fontFamily: "monospace"
}, },
listItem: { listItem: {
marginTop: theme.spacing.unit, marginTop: theme.spacing(1),
}, },
blockquote: { blockquote: {
color: palette.text.secondary, color: palette.text.secondary,
...@@ -64,14 +64,14 @@ const styles = theme => { ...@@ -64,14 +64,14 @@ const styles = theme => {
fontWeight: 700 fontWeight: 700
} }
}; };
}; });
///////////////////////////////////////// /////////////////////////////////////////
/// Renderers definition /// Renderers definition
//////////////////////////////////////// ////////////////////////////////////////
const HeadingRenderer = (props) => { const HeadingRenderer = (props) => {
const { level } = props; const {level} = props;
let variant = "body2", let variant = "body2",
paragraph = false; paragraph = false;
...@@ -96,59 +96,59 @@ const HeadingRenderer = (props) => { ...@@ -96,59 +96,59 @@ const HeadingRenderer = (props) => {
} }
return ( return (
<Typography gutterBottom variant={variant} paragraph={paragraph} > <Typography gutterBottom variant={variant} paragraph={paragraph}>
{props.children} {props.children}
</Typography> </Typography>
); );
}; };
const ListRenderer = (props, classes) => ( const ListRenderer = (props) => (
<ul className={classes.list}> <ul className={useStyles().list}>
{props.children} {props.children}
</ul> </ul>
); );
const ListItemRenderer = (props, classes) => ( const ListItemRenderer = (props) => (
<li className={classes.listItem}> <li className={useStyles().listItem}>
<Typography component="span"> <Typography component="span">
{props.children} {props.children}
</Typography > </Typography>
</li> </li>
); );
const CodeRenderer = (props) => ( const CodeRenderer = (props) => (
// className={classes.code} would be override by typography variant // className={classes.code} would be override by typography variant
<Typography variant={"body2"} component='code' style={{ fontFamily: "monospace" }}> <Typography variant={"body2"} component='code' style={{fontFamily: "monospace"}}>
{props.value} {props.value}
</Typography> </Typography>
); );
const InlineCodeRenderer = (props, classes) => ( const InlineCodeRenderer = (props) => (
<code className={classes.code}> <code className={useStyles().code}>
{props.children} {props.children}
</code> </code>
); );
const BlockquoteRenderer = (props, classes) => ( const BlockquoteRenderer = (props) => (
<blockquote className={classes.blockquote}> <blockquote className={useStyles().blockquote}>
<em> <em>
{props.children} {props.children}
</em> </em>
</blockquote> </blockquote>
); );
const TableRenderer = (props, classes) => ( const TableRenderer = (props) => (
<Paper className={classes.backgroundTable}> <Paper className={useStyles().backgroundTable}>
<Table className={classes.table}>{props.children}</Table> <Table className={useStyles().table}>{props.children}</Table>
</Paper> </Paper>
); );
const TableHeadRenderer = (props, classes) => ( const TableHeadRenderer = (props) => (
<TableHead <TableHead
classes={{ root: classes.bold }} classes={{root: useStyles().bold}}
className={classes.tableHead} className={useStyles().tableHead}
> >
{props.children} {props.children}
</TableHead> </TableHead>
...@@ -158,23 +158,22 @@ const TableHeadRenderer = (props, classes) => ( ...@@ -158,23 +158,22 @@ const TableHeadRenderer = (props, classes) => (
const renderers = { const renderers = {
heading: HeadingRenderer, heading: HeadingRenderer,
list: withStyles(styles, { withTheme: true })(ListRenderer), list: ListRenderer,
listItem: withStyles(styles, { withTheme: true })(ListItemRenderer), listItem: ListItemRenderer,
paragraph: (props) => <Typography paragraph >{props.children}</Typography>, paragraph: (props) => <Typography paragraph>{props.children}</Typography>,
link: props => <TextLink {...props} />, link: props => <TextLink {...props} />,
code: withStyles(styles, { withTheme: true })(CodeRenderer), code: CodeRenderer,
inlineCode: withStyles(styles, { withTheme: true })(InlineCodeRenderer), inlineCode: InlineCodeRenderer,
blockquote: withStyles(styles, { withTheme: true })(BlockquoteRenderer), blockquote: BlockquoteRenderer,
table: withStyles(styles, { withTheme: true })(TableRenderer), table: TableRenderer,
tableHead: withStyles(styles, { withTheme: true })(TableHeadRenderer), tableHead: TableHeadRenderer,
tableBody: props => (<TableBody>{props.children}</TableBody>), tableBody: props => (<TableBody>{props.children}</TableBody>),
tableRow: props => (<TableRow hover={true}>{props.children}</TableRow>), tableRow: props => (<TableRow hover={true}>{props.children}</TableRow>),
tableCell: props => (<TableCell>{props.children}</TableCell>), tableCell: props => (<TableCell>{props.children}</TableCell>),
thematicBreak: () => (<Divider />), thematicBreak: () => (<Divider/>),
}; };
/** /**
* Custom Markdown component renderer to make use of material UI * Custom Markdown component renderer to make use of material UI
* *
...@@ -202,7 +201,7 @@ class Markdown extends Component { ...@@ -202,7 +201,7 @@ class Markdown extends Component {
if (!el.isMoney) { if (!el.isMoney) {
compiled += el.text; compiled += el.text;
} else { } else {
const { amount, currency } = el; const {amount, currency} = el;
if (currency === "EUR") { if (currency === "EUR") {
compiled += `${amount}€`; compiled += `${amount}€`;
......
import React from "react";
import {getGradient, Spectral, viridis} from "../../utils/colormaps";
import PropTypes from "prop-types";
import {classNames} from "../../utils/classNames";
import ThumbsUp from "@material-ui/icons/ThumbUp";
import ThumbsDown from "@material-ui/icons/ThumbDown";
import Close from "@material-ui/icons/Close";
import Warning from "@material-ui/icons/Warning";
import Done from "@material-ui/icons/Done";
import DoneAll from "@material-ui/icons/DoneAll";
import Favorite from "@material-ui/icons/Favorite";
import {makeStyles} from "@material-ui/styles";
const possibleIcons = [Close, Warning, Done, DoneAll, Favorite];
const breakPoints = [20, 40, 60, 80, 100];
const indicatorWidth = 14,
indicatorExtraHeight = 10;
const useStyles = makeStyles(theme => ({
barContainer: {
flexWrap: "nowrap",
display: "flex",
alignItems: "center",
paddingTop: 25,
paddingBottom: 10,
},
barContent: {},
linearBackground: {
background: getGradient([...viridis].reverse())
},
divergentBackground: {
background: getGradient(Spectral)
},
colorBar: {
height: props => props.height,
borderRadius: props => props.height / 2,
marginLeft: 10,
marginRight: 10,
},
indicator: {
height: props => props.height + indicatorExtraHeight,
width: indicatorWidth,
top: -(indicatorExtraHeight / 2),
borderRadius: indicatorExtraHeight,
position: "relative",
background: theme.palette.background.default,
borderStyle: "solid",
borderColor: theme.palette.text.primary,
},
indicatorIcon: {
left: "50%",
transform: "translateX(-50%)",
position: "relative",
top: -29
}