Commit 7768f71e authored by Florent Chehab's avatar Florent Chehab
Browse files

userData handling changed followning the change in the backend

UniversitySemestersDates partially connected
parent 32e2b6bb
Pipeline #27167 passed with stages
in 2 minutes and 44 seconds
...@@ -38,7 +38,7 @@ class UserDataSerializer(MyModelSerializer): ...@@ -38,7 +38,7 @@ class UserDataSerializer(MyModelSerializer):
class UserDataViewSet(MyModelViewSet): class UserDataViewSet(MyModelViewSet):
permission_classes = get_viewset_permissions("UserDataViewSet") permission_classes = get_viewset_permissions("UserDataViewSet")
serializer_class = UserDataSerializer serializer_class = UserDataSerializer
BYPASS_DICT_MODE = True LIST_SHOULD_BE_DETAIL = True
def get_queryset(self): def get_queryset(self):
return UserData.objects.filter(owner=self.request.user) # pylint: disable=E1101 return UserData.objects.filter(owner=self.request.user) # pylint: disable=E1101
...@@ -139,9 +139,9 @@ export function {{obj.name}}FetchDataSuccess({{obj.name}}) { ...@@ -139,9 +139,9 @@ export function {{obj.name}}FetchDataSuccess({{obj.name}}) {
} }
export function {{obj.name}}FetchData() { export function {{obj.name}}FetchData(pk="") {
return _FetchData( return _FetchData(
"", pk,
"{{obj.api_end_point}}", "{{obj.api_end_point}}",
{{obj.name}}IsLoading, {{obj.name}}IsLoading,
{{obj.name}}FetchDataSuccess, {{obj.name}}FetchDataSuccess,
......
...@@ -3,28 +3,7 @@ import Loading from './other/Loading'; ...@@ -3,28 +3,7 @@ import Loading from './other/Loading';
class MyComponent extends Component { class MyComponent extends Component {
customErrorHandlers = {} customErrorHandlers = {}
requireUserData = false; idToUse = null;
// If true,
// You need to import
// userDataElFetchData,
// userDataElSaveData,
//your mapStateToProps should contain:
// const mapStateToProps = (state) => {
// return {
// userDataEl: state.userDataEl
// }
// };
//
// And your mapDispatchToProps should have:
// const mapDispatchToProps = (dispatch) => {
// return {
// fetchUserDataSingle: (id) => dispatch(userDataElFetchData(id)),
// fetchData: {
// userDataEl: () => dispatch(userDataElFetchData("")),
// },
// createUserData: () => dispatch(userDataElSaveData(Object()))
// };
// };
getFetchedData(prop) { getFetchedData(prop) {
return this.props[prop].fetched.data; return this.props[prop].fetched.data;
...@@ -79,6 +58,7 @@ class MyComponent extends Component { ...@@ -79,6 +58,7 @@ class MyComponent extends Component {
if (prop.fetchHasError.status) { if (prop.fetchHasError.status) {
if (prop_key in this.customErrorHandlers) { if (prop_key in this.customErrorHandlers) {
console.log("icicicicici"); console.log("icicicicici");
return this.customErrorHandlers[prop_key](prop.fetchHasError.error);
} else { } else {
return true; return true;
} }
...@@ -113,13 +93,25 @@ class MyComponent extends Component { ...@@ -113,13 +93,25 @@ class MyComponent extends Component {
if (prop === Object(prop) && 'fetched' in prop) { if (prop === Object(prop) && 'fetched' in prop) {
if ((!prop.fetched.fetchedAt) || prop.invalidated) { if ((!prop.fetched.fetchedAt) || prop.invalidated) {
if (!prop.isLoading) { if (!prop.isLoading) {
props.fetchData[prop_key](); if (this.idToUse) {
props.fetchData[prop_key](this.props[this.idToUse]);
} else {
props.fetchData[prop_key]();
}
} }
} }
} }
} }
} }
allFetchedDataReady(){
if (this.checkPropsHasError() ||this.checkPropsIsLoading() || this.checkPropsInvalidated() || this.checkPropsIsSaving()) {
return false;
} else {
return true;
}
}
componentDidMount() { componentDidMount() {
this.loadPropsIfNeeded(); this.loadPropsIfNeeded();
this.myComponentDidMount(); this.myComponentDidMount();
...@@ -129,27 +121,6 @@ class MyComponent extends Component { ...@@ -129,27 +121,6 @@ class MyComponent extends Component {
componentDidUpdate() { componentDidUpdate() {
// TODO ajouter expire date // TODO ajouter expire date
this.loadPropsIfNeeded(); this.loadPropsIfNeeded();
if (this.requireUserData) {
//TODO cleaner too many loads
// load the correct user data
const { userDataEl } = this.props;
if (userDataEl.isLoading || userDataEl.isSaving) {
return;
}
const userData = this.getFetchedData("userDataEl");
if (userData instanceof Array) {
if (userData.length == 0) {
if (!this.props.userDataEl.isSaving) {
this.props.createUserData();
}
} else if (userData.length == 1) {
this.props.fetchUserDataSingle(userData[0].id)
} else {
throw Error("We shouldn't have more thant one here !")
}
}
}
this.myComponentDidUpdate(); this.myComponentDidUpdate();
} }
myComponentDidUpdate() { }; myComponentDidUpdate() { };
...@@ -159,7 +130,7 @@ class MyComponent extends Component { ...@@ -159,7 +130,7 @@ class MyComponent extends Component {
return <p>Sorry! There was an error loading the items</p>; return <p>Sorry! There was an error loading the items</p>;
} }
if (this.checkPropsIsLoading() || this.checkPropsInvalidated() || this.checkPropsIsSaving()) { if (!this.allFetchedDataReady()) {
return <Loading />; return <Loading />;
} }
......
...@@ -17,40 +17,45 @@ import { saveAppTheme } from '../actions/theme'; ...@@ -17,40 +17,45 @@ import { saveAppTheme } from '../actions/theme';
class ThemeProvider extends MyComponent { class ThemeProvider extends MyComponent {
requireUserData = true;
state = { theme: this.props.themeSavedInTheApp.theme }; state = { theme: this.props.themeSavedInTheApp.theme };
myComponentDidUpdate() { myComponentDidUpdate() {
if (!this.allFetchedDataReady()) {
return;
}
const currentTheme = this.state.theme; const currentTheme = this.state.theme;
const themeSavedInTheApp = this.props.themeSavedInTheApp.theme; const themeSavedInTheApp = this.props.themeSavedInTheApp.theme;
const themeSavedInTheAppAt = this.props.themeSavedInTheApp.savedAt; const themeSavedInTheAppAt = this.props.themeSavedInTheApp.savedAt;
let themeOnServer = Object(); const themeOnServer = this.props.userDataEl.fetched.data.config.theme;
let themeOnServerRetrievedAt = 0; const themeOnServerRetrievedAt = this.props.userDataEl.fetched.fetchedAt;
try { if (!themeOnServer) {
themeOnServer = this.props.userDataEl.fetched.data.config.theme; // config on server is raw, we need to add the default one.
themeOnServerRetrievedAt = this.props.userDataEl.fetched.fetchedAt; const userData = this.getFetchedData('userDataEl');
} catch (e) { let newUserData = Object.assign({}, userData);
if (!e instanceof TypeError) { newUserData.config.theme = this.state.theme;
throw e; this.props.saveUserData(newUserData);
} return;
} }
const themeToRender = themeSavedInTheAppAt > themeOnServerRetrievedAt ? themeSavedInTheApp : themeOnServer; const themeToRender = themeSavedInTheAppAt > themeOnServerRetrievedAt ? themeSavedInTheApp : themeOnServer;
if ((!areSameThemes(themeToRender, currentTheme)) && typeof themeToRender != 'undefined') { if ((!areSameThemes(themeToRender, currentTheme)) && typeof themeToRender != 'undefined') {
this.setState({ theme: themeToRender }); this.setState({ theme: themeToRender });
if (!areSameThemes(themeToRender, themeSavedInTheApp)){ if (!areSameThemes(themeToRender, themeSavedInTheApp)) {
this.props.saveTheme(themeToRender); this.props.saveTheme(themeToRender);
} }
} }
} }
myRender() { myRender() {
const font = {typography: { const font = {
fontSize: 14, typography: {
htmlFontSize: 14 fontSize: 14,
}} htmlFontSize: 14
}
}
const theme = Object.assign({}, this.state.theme, font) const theme = Object.assign({}, this.state.theme, font)
return ( return (
<div> <div>
...@@ -74,11 +79,10 @@ const mapStateToProps = (state) => { ...@@ -74,11 +79,10 @@ const mapStateToProps = (state) => {
const mapDispatchToProps = (dispatch) => { const mapDispatchToProps = (dispatch) => {
return { return {
saveTheme: (theme) => dispatch(saveAppTheme(theme)), saveTheme: (theme) => dispatch(saveAppTheme(theme)),
fetchUserDataSingle: (id) => dispatch(userDataElFetchData(id)), saveUserData: (data) => dispatch(userDataElSaveData(data)),
fetchData: { fetchData: {
userDataEl: () => dispatch(userDataElFetchData("")), userDataEl: () => dispatch(userDataElFetchData("")),
}, },
createUserData: () => dispatch(userDataElSaveData(Object()))
}; };
}; };
......
...@@ -76,7 +76,6 @@ const styles = theme => ({ ...@@ -76,7 +76,6 @@ const styles = theme => ({
// TODO switch to my component // TODO switch to my component
class ColorTool extends MyComponent { class ColorTool extends MyComponent {
requireUserData = true;
state = this.props.state state = this.props.state
componentWillUnmount() { componentWillUnmount() {
...@@ -90,29 +89,41 @@ class ColorTool extends MyComponent { ...@@ -90,29 +89,41 @@ class ColorTool extends MyComponent {
} }
myComponentDidUpdate() { myComponentDidUpdate() {
if (!this.allFetchedDataReady()) {
return
}
try { const configOnServer = this.props.userDataEl.fetched.data.config;
const themeOnServerRetrievedAt = this.props.userDataEl.fetched.fetchedAt; const themeOnServer = configOnServer.theme;
if (themeOnServerRetrievedAt > this.state.updatedAt) { const colorPickerConfigOnServer = configOnServer.colorPicker;
const configOnServer = this.props.userDataEl.fetched.data.config; const serverDataRetrievedAt = this.props.userDataEl.fetched.fetchedAt;
const colorPickerConfigOnServer = configOnServer.colorPicker;
const themeOnServer = configOnServer.theme; if (!themeOnServer) {
// we need to set the color picker colors from server color // we need to initialize it
const primary = themeOnServer.palette.primary.main; this.handleSendToServer(true, false);
const secondary = themeOnServer.palette.secondary.main; return;
this.setState({ }
updatedAt: Date.now(),
primary, if (!colorPickerConfigOnServer) {
secondary, this.handleSendToServer(false, true);
primaryHue: colorPickerConfigOnServer.primaryHue, return;
secondaryHue: colorPickerConfigOnServer.secondaryHue, }
primaryShade: colorPickerConfigOnServer.primaryShade,
secondaryShade: colorPickerConfigOnServer.secondaryShade,
darkModeActivated: themeOnServer.palette.type == 'light' ? false : true
});
}
} catch (e) { if (!(e instanceof TypeError)) { throw e; } }
if (serverDataRetrievedAt > this.state.updatedAt) {
// we need to set the color picker colors from server color
const primary = themeOnServer.palette.primary.main;
const secondary = themeOnServer.palette.secondary.main;
this.setState({
updatedAt: Date.now(),
primary,
secondary,
primaryHue: colorPickerConfigOnServer.primaryHue,
secondaryHue: colorPickerConfigOnServer.secondaryHue,
primaryShade: colorPickerConfigOnServer.primaryShade,
secondaryShade: colorPickerConfigOnServer.secondaryShade,
darkModeActivated: themeOnServer.palette.type == 'light' ? false : true
});
}
} }
handleChangeHue = name => event => { handleChangeHue = name => event => {
...@@ -174,16 +185,20 @@ class ColorTool extends MyComponent { ...@@ -174,16 +185,20 @@ class ColorTool extends MyComponent {
return currentTheme; return currentTheme;
} }
handleSendToServer = () => { handleSendToServer = (saveTheme = true, saveColorPicker = true) => {
const userData = this.props.userDataEl.fetched.data; const userData = this.props.userDataEl.fetched.data;
let newUserData = Object.assign({}, userData); let newUserData = Object.assign({}, userData);
newUserData.config.theme = this.getThemeFromProps(); if (saveTheme) {
newUserData.config.colorPicker = { newUserData.config.theme = this.getThemeFromProps();
primaryHue: this.state.primaryHue, }
secondaryHue: this.state.secondaryHue, if (saveColorPicker) {
primaryShade: this.state.primaryShade, newUserData.config.colorPicker = {
secondaryShade: this.state.secondaryShade, primaryHue: this.state.primaryHue,
}; secondaryHue: this.state.secondaryHue,
primaryShade: this.state.primaryShade,
secondaryShade: this.state.secondaryShade,
};
}
this.props.saveToServer(newUserData); this.props.saveToServer(newUserData);
} }
...@@ -340,11 +355,9 @@ const mapDispatchToProps = (dispatch) => { ...@@ -340,11 +355,9 @@ const mapDispatchToProps = (dispatch) => {
saveTheme: (theme) => dispatch(saveAppTheme(theme)), saveTheme: (theme) => dispatch(saveAppTheme(theme)),
saveColorPicker: (partialState) => dispatch(saveAppColorPicker(partialState)), saveColorPicker: (partialState) => dispatch(saveAppColorPicker(partialState)),
saveToServer: (data) => dispatch(userDataElSaveData(data)), saveToServer: (data) => dispatch(userDataElSaveData(data)),
fetchUserDataSingle: (id) => dispatch(userDataElFetchData(id)),
fetchData: { fetchData: {
userDataEl: () => dispatch(userDataElFetchData("")), userDataEl: () => dispatch(userDataElFetchData("")),
}, },
createUserData: () => dispatch(userDataElSaveData(Object()))
}; };
}; };
export default connect(mapStateToProps, mapDispatchToProps)(withStyles(styles, { withTheme: true })(ColorTool)); export default connect(mapStateToProps, mapDispatchToProps)(withStyles(styles, { withTheme: true })(ColorTool));
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'; import { withStyles } from '@material-ui/core/styles';
import { compose } from 'recompose';
import { connect } from "react-redux";
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';
...@@ -15,12 +17,18 @@ import Typography from '@material-ui/core/Typography'; ...@@ -15,12 +17,18 @@ import Typography from '@material-ui/core/Typography';
import CloudQueueIcon from '@material-ui/icons/CloudQueue'; import CloudQueueIcon from '@material-ui/icons/CloudQueue';
import LocalFloristIcon from '@material-ui/icons/LocalFlorist'; import LocalFloristIcon from '@material-ui/icons/LocalFlorist';
import MyComponent from '../../MyComponent';
import TextLink from '../../other/TextLink'; import TextLink from '../../other/TextLink';
import GenericModule from './GenericModule'; import GenericModule from './GenericModule';
import Grid from '@material-ui/core/Grid'; import Grid from '@material-ui/core/Grid';
import Divider from '@material-ui/core/Divider'; import Divider from '@material-ui/core/Divider';
import MyComponent from '../../MyComponent';
import {
universitiesSemestersDatesElFetchData,
} from '../../../generated/actions';
const styles = theme => ({ const styles = theme => ({
root: { root: {
...@@ -39,11 +47,39 @@ const styles = theme => ({ ...@@ -39,11 +47,39 @@ const styles = theme => ({
} }
}); });
const comment = "**Attention certaines activités commencent avant cette période**"; function convertDate(date) {
if (date) {
const d = new Date(date);
let dd = d.getDate();
let mm = d.getMonth() + 1;
dd = dd < 10 ? '0' + dd : dd;
mm = mm < 10 ? '0' + mm : mm;
const yyyy = d.getFullYear();
return dd + '/' + mm + '/' + yyyy;
} else {
return "Non connue."
}
}
class UniversitySemestersDates extends MyComponent {
idToUse = "univId";
customErrorHandlers = {
universitiesSemestersDatesEl: (e) => {
console.log(e);
return true;
}
}
myRender() {
const { classes } = this.props;
console.log("props", this.props)
const semestersDates = this.getFetchedData('universitiesSemestersDatesEl');
let { autumn_begin, autumn_end, spring_begin, spring_end, comment } = semestersDates;
autumn_begin = convertDate(autumn_begin);
autumn_end = convertDate(autumn_end);
spring_begin = convertDate(spring_begin);
spring_end = convertDate(spring_end);
class UniversitySemestersDates extends React.Component {
render() {
const { classes, theme } = this.props;
return ( return (
<GenericModule title={"Date des semestres"} usefulLinks={[{ description: "Site de l'EPFL", url: "https://epfl.ch" }]}> <GenericModule title={"Date des semestres"} usefulLinks={[{ description: "Site de l'EPFL", url: "https://epfl.ch" }]}>
<div className={classes.root}> <div className={classes.root}>
...@@ -64,8 +100,8 @@ class UniversitySemestersDates extends React.Component { ...@@ -64,8 +100,8 @@ class UniversitySemestersDates extends React.Component {
<div>Automne</div> <div>Automne</div>
</div> </div>
</TableCell> </TableCell>
<TableCell className={classes.tableCell} component="td" >12/03/2018</TableCell> <TableCell className={classes.tableCell} component="td" >{autumn_begin}</TableCell>
<TableCell className={classes.tableCell} component="td" >12/03/2018</TableCell> <TableCell className={classes.tableCell} component="td" >{autumn_end}</TableCell>
</TableRow> </TableRow>
<TableRow key={2}> <TableRow key={2}>
...@@ -75,8 +111,8 @@ class UniversitySemestersDates extends React.Component { ...@@ -75,8 +111,8 @@ class UniversitySemestersDates extends React.Component {
<div>Printemps</div> <div>Printemps</div>
</div> </div>
</TableCell> </TableCell>
<TableCell className={classes.tableCell} component="td" >12/03/2018</TableCell> <TableCell className={classes.tableCell} component="td" >{spring_begin}</TableCell>
<TableCell className={classes.tableCell} component="td" >12/03/2018</TableCell> <TableCell className={classes.tableCell} component="td" >{spring_end}</TableCell>
</TableRow> </TableRow>
</TableBody> </TableBody>
...@@ -88,4 +124,30 @@ class UniversitySemestersDates extends React.Component { ...@@ -88,4 +124,30 @@ class UniversitySemestersDates extends React.Component {
} }
} }
export default withStyles(styles, { withTheme: true })(UniversitySemestersDates);
UniversitySemestersDates.propTypes = {
classes: PropTypes.object.isRequired,
theme: PropTypes.object.isRequired,
univId: PropTypes.string.isRequired
};
const mapStateToProps = (state) => {
return {
universitiesSemestersDatesEl: state.universitiesSemestersDatesEl,
};
};
const mapDispatchToProps = (dispatch) => {
return {
fetchData: {
universitiesSemestersDatesEl: (univId) => dispatch(universitiesSemestersDatesElFetchData(univId)),
}
};
};
export default compose(
withStyles(styles, { withTheme: true }),
connect(mapStateToProps, mapDispatchToProps)
)(UniversitySemestersDates);
\ No newline at end of file
...@@ -7,8 +7,6 @@ import { compose } from 'recompose'; ...@@ -7,8 +7,6 @@ import { compose } from 'recompose';
import GenericModule from '../modules/GenericModule'; import GenericModule from '../modules/GenericModule';
import Grid from '@material-ui/core/Grid'; import Grid from '@material-ui/core/Grid';
import Typography from '@material-ui/core/Typography';
import Lorem from 'react-lorem-component';
import UniversityGeneral from '../modules/UniversityGeneral'; import UniversityGeneral from '../modules/UniversityGeneral';
import UniversitySemestersDates from '../modules/UniversitySemestersDates'; import UniversitySemestersDates from '../modules/UniversitySemestersDates';
...@@ -28,7 +26,9 @@ const styles = theme => ({ ...@@ -28,7 +26,9 @@ const styles = theme => ({
}, },
}); });
class GeneralInfo extends MyComponent {
class GeneralInfoTab extends MyComponent {
myRender() { myRender() {
const { classes, theme } = this.props; const { classes, theme } = this.props;
// Resizing with the grid was causing weird gaps so we rerender depending on the width // Resizing with the grid was causing weird gaps so we rerender depending on the width
...@@ -39,17 +39,17 @@ class GeneralInfo extends MyComponent { ...@@ -39,17 +39,17 @@ class GeneralInfo extends MyComponent {
<div style={{ flexGrow: 8, paddingRight: 2 * theme.spacing.unit }}> <div style={{ flexGrow: 8, paddingRight: 2 * theme.spacing.unit }}>
<Grid container direction='column' > <Grid container direction='column' >
<Grid item xs style={{ paddingBottom: 2 * theme.spacing.unit }} >