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 {
this.setState({ alert: { open: false } });
}
handleCloseHistory = () => {
handleHistoryWasClosed = () => {
this.setState({ historyOpen: false });
};
......@@ -116,7 +116,7 @@ class GenericModule extends CustomComponentForAPI {
rawModelDataForEditor: rawModelData,
forceSave: true,
});
this.handleCloseHistory();
this.handleHistoryWasClosed();
this.handleOpenEditor();
}
......@@ -174,7 +174,7 @@ class GenericModule extends CustomComponentForAPI {
<History
factory={this}
open={this.state.historyOpen}
handleCloseHistory={this.handleCloseHistory}
handleHistoryWasClosed={this.handleHistoryWasClosed}
handleRestoreVersion={this.handleRestoreVersion}
/>
<PendingModeration
......
import React, {Component} from "react";
import React, { Component } from "react";
import { openFullScreenDialog, closeFullScreenDialog } from "../../../actions/fullScreenDialog";
import PropTypes from "prop-types";
import withStyles from "@material-ui/core/styles/withStyles";
import compose from "recompose/compose";
import { connect } from "react-redux";
import Button from "@material-ui/core/Button";
import Dialog from "@material-ui/core/Dialog";
import Paper from "@material-ui/core/Paper";
import AppBar from "@material-ui/core/AppBar";
import Toolbar from "@material-ui/core/Toolbar";
import IconButton from "@material-ui/core/IconButton";
import Typography from "@material-ui/core/Typography";
import CloseIcon from "@material-ui/icons/Close";
import Slide from "@material-ui/core/Slide";
import Divider from "@material-ui/core/Divider";
import MobileStepper from "@material-ui/core/MobileStepper";
......@@ -28,71 +28,101 @@ import _cloneDeep from "lodash/cloneDeep";
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 {
// Store the version that is being viewed
state = {
versionInView: 0
}
/**
* Move to next or previous version with step
*
* @param {number} step
* @memberof History
*/
handleGoBy(step) {
this.setState({ versionInView: this.state.versionInView + step });
}
// TODO remove this
componentWillMount() {
let tmp = _pick(this.props.factory, ["props", "renderCore", "renderTitle"]);
tmp = _omit(tmp, ["props.children"]);
this.newFactory = _cloneDeep(tmp);
}
/**
* Returns the versions matching the props.
*
* @returns {Array}
* @memberof History
*/
getVersions() {
if (!this.props.versions.readSucceeded.readAt) {
return null;
return [];
} else {
const h = this.props.versions.readSucceeded.data;
return h.map((el) => { return el.data; }).slice(1);
return this.props.versions.readSucceeded.data
.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() {
// eslint-disable-next-line react/prop-types
const { rawModelData } = this.props.factory.props;
const { content_type_id, id } = rawModelData;
const { rawModelData } = this.props.factory.props,
{ content_type_id, id } = rawModelData;
return { content_type_id, id };
}
/**
* Checks whether the versioned data is ready or not.
*
* @returns
* @memberof History
*/
dataIsReady() {
if (this.props.versions.isInvalidated) {
return false;
}
const { content_type_id, id } = this.getContentTypeAndId();
const versions = this.getVersions();
if (!versions) {
const { content_type_id, id } = this.getContentTypeAndId(),
versions = this.getVersions();
if (versions.length === 0) {
return false;
}
const lastVersion = versions[0];
if (versions && lastVersion.content_type_id == content_type_id && lastVersion.id == id) {
return true;
} else {
return false;
}
return lastVersion.content_type_id == content_type_id
&& lastVersion.id == id;
}
/**
* Extends function to open panel in redux and load Data
*
* @memberof History
*/
componentDidUpdate() {
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) {
const { content_type_id, id } = this.getContentTypeAndId();
this.props.readVersions(content_type_id, id);
......@@ -100,42 +130,62 @@ class History extends Component {
}
}
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;
/**
* Function to close history panel
*
* @memberof History
*/
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 (
<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>
<Typography variant='h6' align='center'>Version n°{this.state.versionInView + 1} du {dateInfo}</Typography>
<Button
variant='outlined'
color="primary"
className={this.props.classes.editButton}
onClick={() => this.props.handleRestoreVersion(rawModelData)}
>
Éditer à partir de cette version
</Button>
<Divider />
<AppBar className={classes.appBar} >
<Toolbar>
<IconButton color="inherit" onClick={() => this.closeHistory()} aria-label="Close">
<CloseIcon />
</IconButton>
<Typography variant="h6" color="inherit" className={classes.flex}>
Parcours de l'historique
</Typography>
</Toolbar>
</AppBar>
<Paper className={classes.paper}>
{this.renderHistory()}
</Paper>
</div>
);
}
/**
* Renders the versions previewer and steppers
*
* @returns
* @memberof History
*/
renderHistory() {
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()) {
return <Loading />;
}
const theme = this.props;
const versions = this.getVersions();
const activeStep = this.state.versionInView;
const maxSteps = versions.length;
const { theme } = this.props,
versions = this.getVersions(),
activeStep = this.state.versionInView,
maxSteps = versions.length;
Object.assign(this.newFactory.props.rawModelData, versions[activeStep]);
const { rawModelData } = this.newFactory.props;
......@@ -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 (
<div>
<Dialog
fullScreen
open={this.props.open}
TransitionComponent={Transition}
<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>
<Typography variant='h6' align='center'>Version n°{this.state.versionInView + 1} du {dateInfo}</Typography>
<Button
variant='outlined'
color="primary"
className={this.props.classes.editButton}
onClick={() => this.props.handleRestoreVersion(rawModelData)}
>
<AppBar className={classes.appBar} >
<Toolbar>
<IconButton color="inherit" onClick={() => { this.props.handleCloseHistory(); this.props.resetVersions(); }} aria-label="Close">
<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>
Éditer à partir de cette version
</Button>
<Divider />
</div>
);
}
// Dumb render function for the component
render() {
return <div></div>;
}
}
History.propTypes = {
......@@ -201,16 +261,19 @@ History.propTypes = {
factory: PropTypes.object.isRequired,
handleRestoreVersion: PropTypes.func.isRequired,
readVersions: PropTypes.func.isRequired,
handleCloseHistory: PropTypes.func.isRequired,
handleHistoryWasClosed: PropTypes.func.isRequired,
resetVersions: PropTypes.func.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 = {
open: false,
// 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) => {
return {
readVersions: (content_type_id, id) => dispatch(getActions("versions").readSpecific(content_type_id + "/" + id)),
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(
withStyles(styles, { withTheme: true }),
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