Commit b4ba0cc0 authored by Florent Chehab's avatar Florent Chehab
Browse files

History component adapted to setup.

parent 5b6f2861
...@@ -76,7 +76,7 @@ class GenericModule extends CustomComponentForAPI { ...@@ -76,7 +76,7 @@ class GenericModule extends CustomComponentForAPI {
this.setState({ alert: { open: false } }); this.setState({ alert: { open: false } });
} }
handleCloseHistory = () => { handleHistoryWasClosed = () => {
this.setState({ historyOpen: false }); this.setState({ historyOpen: false });
}; };
...@@ -116,7 +116,7 @@ class GenericModule extends CustomComponentForAPI { ...@@ -116,7 +116,7 @@ class GenericModule extends CustomComponentForAPI {
rawModelDataForEditor: rawModelData, rawModelDataForEditor: rawModelData,
forceSave: true, forceSave: true,
}); });
this.handleCloseHistory(); this.handleHistoryWasClosed();
this.handleOpenEditor(); this.handleOpenEditor();
} }
...@@ -174,7 +174,7 @@ class GenericModule extends CustomComponentForAPI { ...@@ -174,7 +174,7 @@ class GenericModule extends CustomComponentForAPI {
<History <History
factory={this} factory={this}
open={this.state.historyOpen} open={this.state.historyOpen}
handleCloseHistory={this.handleCloseHistory} handleHistoryWasClosed={this.handleHistoryWasClosed}
handleRestoreVersion={this.handleRestoreVersion} handleRestoreVersion={this.handleRestoreVersion}
/> />
<PendingModeration <PendingModeration
......
import React, {Component} from "react"; import React, { Component } from "react";
import { openFullScreenDialog, closeFullScreenDialog } from "../../../actions/fullScreenDialog";
import PropTypes from "prop-types"; import PropTypes from "prop-types";
import withStyles from "@material-ui/core/styles/withStyles"; import withStyles from "@material-ui/core/styles/withStyles";
import compose from "recompose/compose"; import compose from "recompose/compose";
import { connect } from "react-redux"; import { connect } from "react-redux";
import Button from "@material-ui/core/Button"; import Button from "@material-ui/core/Button";
import Dialog from "@material-ui/core/Dialog";
import Paper from "@material-ui/core/Paper"; import Paper from "@material-ui/core/Paper";
import AppBar from "@material-ui/core/AppBar"; import AppBar from "@material-ui/core/AppBar";
import Toolbar from "@material-ui/core/Toolbar"; import Toolbar from "@material-ui/core/Toolbar";
import IconButton from "@material-ui/core/IconButton"; import IconButton from "@material-ui/core/IconButton";
import Typography from "@material-ui/core/Typography"; import Typography from "@material-ui/core/Typography";
import CloseIcon from "@material-ui/icons/Close"; import CloseIcon from "@material-ui/icons/Close";
import Slide from "@material-ui/core/Slide";
import Divider from "@material-ui/core/Divider"; import Divider from "@material-ui/core/Divider";
import MobileStepper from "@material-ui/core/MobileStepper"; import MobileStepper from "@material-ui/core/MobileStepper";
...@@ -28,71 +28,101 @@ import _cloneDeep from "lodash/cloneDeep"; ...@@ -28,71 +28,101 @@ import _cloneDeep from "lodash/cloneDeep";
import getActions from "../../../api/getActions"; import getActions from "../../../api/getActions";
const styles = theme => ({
...editorStyle(theme),
editButton: {
display: "block",
marginLeft: "auto",
marginRight: "auto",
marginTop: 2 * theme.spacing.unit,
marginBottom: 2 * theme.spacing.unit
}
});
function Transition(props) {
return <Slide direction="up" {...props} />;
}
/**
* Component to display the previous versions of module
*
* TODO: use with CustomComponentForAPI
*
* @class History
* @extends {Component}
*/
class History extends Component { class History extends Component {
// Store the version that is being viewed
state = { state = {
versionInView: 0 versionInView: 0
} }
/**
* Move to next or previous version with step
*
* @param {number} step
* @memberof History
*/
handleGoBy(step) { handleGoBy(step) {
this.setState({ versionInView: this.state.versionInView + step }); this.setState({ versionInView: this.state.versionInView + step });
} }
// TODO remove this
componentWillMount() { componentWillMount() {
let tmp = _pick(this.props.factory, ["props", "renderCore", "renderTitle"]); let tmp = _pick(this.props.factory, ["props", "renderCore", "renderTitle"]);
tmp = _omit(tmp, ["props.children"]); tmp = _omit(tmp, ["props.children"]);
this.newFactory = _cloneDeep(tmp); this.newFactory = _cloneDeep(tmp);
} }
/**
* Returns the versions matching the props.
*
* @returns {Array}
* @memberof History
*/
getVersions() { getVersions() {
if (!this.props.versions.readSucceeded.readAt) { if (!this.props.versions.readSucceeded.readAt) {
return null; return [];
} else { } else {
const h = this.props.versions.readSucceeded.data; return this.props.versions.readSucceeded.data
return h.map((el) => { return el.data; }).slice(1); .map((el) => { return el.data; }) // get the data inside the version
.slice(1); // the first (ie 0) version is the one already displayed
} }
} }
/**
* Get the information about the model from the props.
*
* @returns
* @memberof History
*/
getContentTypeAndId() { getContentTypeAndId() {
// eslint-disable-next-line react/prop-types // eslint-disable-next-line react/prop-types
const { rawModelData } = this.props.factory.props; const { rawModelData } = this.props.factory.props,
const { content_type_id, id } = rawModelData; { content_type_id, id } = rawModelData;
return { content_type_id, id }; return { content_type_id, id };
} }
/**
* Checks whether the versioned data is ready or not.
*
* @returns
* @memberof History
*/
dataIsReady() { dataIsReady() {
if (this.props.versions.isInvalidated) { if (this.props.versions.isInvalidated) {
return false; return false;
} }
const { content_type_id, id } = this.getContentTypeAndId();
const versions = this.getVersions(); const { content_type_id, id } = this.getContentTypeAndId(),
if (!versions) { versions = this.getVersions();
if (versions.length === 0) {
return false; return false;
} }
const lastVersion = versions[0]; const lastVersion = versions[0];
if (versions && lastVersion.content_type_id == content_type_id && lastVersion.id == id) {
return true; return lastVersion.content_type_id == content_type_id
} else { && lastVersion.id == id;
return false;
}
} }
/**
* Extends function to open panel in redux and load Data
*
* @memberof History
*/
componentDidUpdate() { componentDidUpdate() {
if (this.props.open) { if (this.props.open) {
// already open the panel
this.props.openFullScreenDialog(this.renderPanel());
// Load the data as necessary
if (!this.dataIsReady() && !this.props.versions.isLoading) { if (!this.dataIsReady() && !this.props.versions.isLoading) {
const { content_type_id, id } = this.getContentTypeAndId(); const { content_type_id, id } = this.getContentTypeAndId();
this.props.readVersions(content_type_id, id); this.props.readVersions(content_type_id, id);
...@@ -100,42 +130,62 @@ class History extends Component { ...@@ -100,42 +130,62 @@ class History extends Component {
} }
} }
renderVersionInfo(rawModelData) { /**
let dateInfo = (<em>(Information non connue.)</em>); * Function to close history panel
const { updated_on } = rawModelData; *
if (updated_on) { * @memberof History
const data = dateTimeStrToStr(updated_on); */
dateInfo = data.date + " à " + data.time; closeHistory() {
} this.props.handleHistoryWasClosed();
this.props.closeFullScreenDialog();
this.props.resetVersions();
}
/**
* Renders the panel that contain the history data
*
* @returns
* @memberof History
*/
renderPanel() {
const { classes } = this.props;
return ( return (
<div> <div>
<Typography variant='caption' align='center'>Les versions successives d'un même utilisateur ne sont pas enregistrés (dans de tels cas, seul la dernière est conservée).</Typography> <AppBar className={classes.appBar} >
<Typography variant='h6' align='center'>Version n°{this.state.versionInView + 1} du {dateInfo}</Typography> <Toolbar>
<Button <IconButton color="inherit" onClick={() => this.closeHistory()} aria-label="Close">
variant='outlined' <CloseIcon />
color="primary" </IconButton>
className={this.props.classes.editButton} <Typography variant="h6" color="inherit" className={classes.flex}>
onClick={() => this.props.handleRestoreVersion(rawModelData)} Parcours de l'historique
> </Typography>
Éditer à partir de cette version </Toolbar>
</Button> </AppBar>
<Divider /> <Paper className={classes.paper}>
{this.renderHistory()}
</Paper>
</div> </div>
); );
} }
/**
* Renders the versions previewer and steppers
*
* @returns
* @memberof History
*/
renderHistory() { renderHistory() {
if (this.props.versions.readFailed.failed) { if (this.props.versions.readFailed.failed) {
return <p>Sorry! There was an error loading the history</p>; return <p>Nous sommes désolé, une erreur est survenue lors du chargement de l'historique</p>;
} }
if (!this.dataIsReady()) { if (!this.dataIsReady()) {
return <Loading />; return <Loading />;
} }
const theme = this.props; const { theme } = this.props,
const versions = this.getVersions(); versions = this.getVersions(),
const activeStep = this.state.versionInView; activeStep = this.state.versionInView,
const maxSteps = versions.length; maxSteps = versions.length;
Object.assign(this.newFactory.props.rawModelData, versions[activeStep]); Object.assign(this.newFactory.props.rawModelData, versions[activeStep]);
const { rawModelData } = this.newFactory.props; const { rawModelData } = this.newFactory.props;
...@@ -168,32 +218,42 @@ class History extends Component { ...@@ -168,32 +218,42 @@ class History extends Component {
); );
} }
render() {
const { classes } = this.props; /**
* Render a version
*
* @param {object} rawModelData
* @returns
* @memberof History
*/
renderVersionInfo(rawModelData) {
let dateInfo = <em>(Information non connue.)</em>;
const { updated_on } = rawModelData;
if (updated_on) {
const data = dateTimeStrToStr(updated_on);
dateInfo = `${data.date} à ${data.time}`;
}
return ( return (
<div> <div>
<Dialog <Typography variant='caption' align='center'>Les versions successives d'un même utilisateur ne sont pas enregistrés (dans de tels cas, seul la dernière est conservée).</Typography>
fullScreen <Typography variant='h6' align='center'>Version n°{this.state.versionInView + 1} du {dateInfo}</Typography>
open={this.props.open} <Button
TransitionComponent={Transition} variant='outlined'
color="primary"
className={this.props.classes.editButton}
onClick={() => this.props.handleRestoreVersion(rawModelData)}
> >
<AppBar className={classes.appBar} > Éditer à partir de cette version
<Toolbar> </Button>
<IconButton color="inherit" onClick={() => { this.props.handleCloseHistory(); this.props.resetVersions(); }} aria-label="Close"> <Divider />
<CloseIcon />
</IconButton>
<Typography variant="h6" color="inherit" className={classes.flex}>
Parcours de l'historique
</Typography>
</Toolbar>
</AppBar>
<Paper className={classes.paper}>
{this.props.open ? this.renderHistory() : <div></div>}
</Paper>
</Dialog>
</div> </div>
); );
} }
// Dumb render function for the component
render() {
return <div></div>;
}
} }
History.propTypes = { History.propTypes = {
...@@ -201,16 +261,19 @@ History.propTypes = { ...@@ -201,16 +261,19 @@ History.propTypes = {
factory: PropTypes.object.isRequired, factory: PropTypes.object.isRequired,
handleRestoreVersion: PropTypes.func.isRequired, handleRestoreVersion: PropTypes.func.isRequired,
readVersions: PropTypes.func.isRequired, readVersions: PropTypes.func.isRequired,
handleCloseHistory: PropTypes.func.isRequired, handleHistoryWasClosed: PropTypes.func.isRequired,
resetVersions: PropTypes.func.isRequired, resetVersions: PropTypes.func.isRequired,
open: PropTypes.bool.isRequired, open: PropTypes.bool.isRequired,
versions: PropTypes.object.isRequired versions: PropTypes.object.isRequired,
theme: PropTypes.object.isRequired,
openFullScreenDialog: PropTypes.func.isRequired,
closeFullScreenDialog: PropTypes.func.isRequired,
}; };
History.defaultProps = { History.defaultProps = {
open: false, open: false,
// eslint-disable-next-line no-console // eslint-disable-next-line no-console
handleCloseHistory: () => console.error("Dev forgot something...") handleHistoryWasClosed: () => console.error("Dev forgot something..."),
}; };
...@@ -224,10 +287,24 @@ const mapDispatchToProps = (dispatch) => { ...@@ -224,10 +287,24 @@ const mapDispatchToProps = (dispatch) => {
return { return {
readVersions: (content_type_id, id) => dispatch(getActions("versions").readSpecific(content_type_id + "/" + id)), readVersions: (content_type_id, id) => dispatch(getActions("versions").readSpecific(content_type_id + "/" + id)),
resetVersions: () => dispatch(getActions("versions").setInvalidatedSpecific(true)), resetVersions: () => dispatch(getActions("versions").setInvalidatedSpecific(true)),
openFullScreenDialog: (innerNodes) => dispatch(openFullScreenDialog(innerNodes)),
closeFullScreenDialog: () => dispatch(closeFullScreenDialog()),
}; };
}; };
const styles = theme => ({
...editorStyle(theme),
editButton: {
display: "block",
marginLeft: "auto",
marginRight: "auto",
marginTop: 2 * theme.spacing.unit,
marginBottom: 2 * theme.spacing.unit
}
});
export default compose( export default compose(
withStyles(styles, { withTheme: true }), withStyles(styles, { withTheme: true }),
connect(mapStateToProps, mapDispatchToProps) connect(mapStateToProps, mapDispatchToProps)
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment