2016-06-16 22:47:45 -03:00
|
|
|
import React, { PropTypes } from 'react';
|
|
|
|
import ImmutablePropTypes from 'react-immutable-proptypes';
|
2016-02-25 20:40:35 -08:00
|
|
|
import { connect } from 'react-redux';
|
2017-03-15 10:47:03 -07:00
|
|
|
import history from '../routing/history';
|
2016-06-08 04:42:24 -03:00
|
|
|
import {
|
|
|
|
loadEntry,
|
2016-07-19 17:11:22 -03:00
|
|
|
createDraftFromEntry,
|
2016-08-24 21:36:44 -03:00
|
|
|
createEmptyDraft,
|
2016-06-08 04:42:24 -03:00
|
|
|
discardDraft,
|
2016-12-29 17:18:24 -02:00
|
|
|
changeDraftField,
|
2017-01-13 19:30:40 -02:00
|
|
|
changeDraftFieldValidation,
|
2016-10-11 18:24:55 +02:00
|
|
|
persistEntry,
|
2017-07-21 23:40:33 -07:00
|
|
|
deleteEntry,
|
2016-06-08 04:42:24 -03:00
|
|
|
} from '../actions/entries';
|
2017-01-11 20:58:15 -02:00
|
|
|
import { closeEntry } from '../actions/editor';
|
2017-07-18 19:14:40 -04:00
|
|
|
import { deserializeValues } from '../lib/serializeEntryValues';
|
2017-01-10 22:23:22 -02:00
|
|
|
import { addAsset, removeAsset } from '../actions/media';
|
2016-11-11 17:54:58 -02:00
|
|
|
import { openSidebar } from '../actions/globalUI';
|
2017-01-10 22:23:22 -02:00
|
|
|
import { selectEntry, getAsset } from '../reducers';
|
2016-11-11 17:54:58 -02:00
|
|
|
import { selectFields } from '../reducers/collections';
|
2016-09-29 19:02:28 +02:00
|
|
|
import EntryEditor from '../components/EntryEditor/EntryEditor';
|
2016-10-11 18:24:55 +02:00
|
|
|
import entryPageHOC from './editorialWorkflow/EntryPageHOC';
|
2016-10-14 13:42:58 +02:00
|
|
|
import { Loader } from '../components/UI';
|
2016-02-25 20:40:35 -08:00
|
|
|
|
2016-05-30 17:08:30 -07:00
|
|
|
class EntryPage extends React.Component {
|
2016-10-03 14:33:48 +02:00
|
|
|
static propTypes = {
|
2017-01-10 22:23:22 -02:00
|
|
|
addAsset: PropTypes.func.isRequired,
|
|
|
|
boundGetAsset: PropTypes.func.isRequired,
|
2016-12-29 17:18:24 -02:00
|
|
|
changeDraftField: PropTypes.func.isRequired,
|
2017-01-13 19:30:40 -02:00
|
|
|
changeDraftFieldValidation: PropTypes.func.isRequired,
|
2016-10-03 14:33:48 +02:00
|
|
|
collection: ImmutablePropTypes.map.isRequired,
|
|
|
|
createDraftFromEntry: PropTypes.func.isRequired,
|
|
|
|
createEmptyDraft: PropTypes.func.isRequired,
|
|
|
|
discardDraft: PropTypes.func.isRequired,
|
|
|
|
entry: ImmutablePropTypes.map,
|
|
|
|
entryDraft: ImmutablePropTypes.map.isRequired,
|
|
|
|
loadEntry: PropTypes.func.isRequired,
|
|
|
|
persistEntry: PropTypes.func.isRequired,
|
2017-07-21 23:40:33 -07:00
|
|
|
deleteEntry: PropTypes.func.isRequired,
|
|
|
|
showDelete: PropTypes.bool.isRequired,
|
2017-01-10 22:23:22 -02:00
|
|
|
removeAsset: PropTypes.func.isRequired,
|
2017-01-11 20:58:15 -02:00
|
|
|
closeEntry: PropTypes.func.isRequired,
|
2016-11-11 17:54:58 -02:00
|
|
|
openSidebar: PropTypes.func.isRequired,
|
2016-10-21 20:42:14 -02:00
|
|
|
fields: ImmutablePropTypes.list.isRequired,
|
2016-10-03 14:33:48 +02:00
|
|
|
slug: PropTypes.string,
|
|
|
|
newEntry: PropTypes.bool.isRequired,
|
|
|
|
};
|
2016-06-06 21:53:22 -03:00
|
|
|
|
2016-06-08 04:42:24 -03:00
|
|
|
componentDidMount() {
|
2016-11-15 17:21:33 -08:00
|
|
|
const { entry, newEntry, collection, slug, loadEntry, createEmptyDraft } = this.props;
|
2016-11-11 17:54:58 -02:00
|
|
|
this.props.openSidebar();
|
2016-10-13 14:30:11 +02:00
|
|
|
if (newEntry) {
|
|
|
|
createEmptyDraft(collection);
|
2016-10-10 15:34:21 -03:00
|
|
|
} else {
|
2017-01-11 20:58:15 -02:00
|
|
|
loadEntry(collection, slug);
|
2016-06-08 04:42:24 -03:00
|
|
|
}
|
2017-03-15 10:47:03 -07:00
|
|
|
|
|
|
|
this.unlisten = history.listenBefore((location) => {
|
|
|
|
if (this.props.entryDraft.get('hasChanged')) {
|
|
|
|
return "Are you sure you want to leave this page?";
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
});
|
2016-06-08 04:42:24 -03:00
|
|
|
}
|
|
|
|
|
|
|
|
componentWillReceiveProps(nextProps) {
|
2016-08-24 21:36:44 -03:00
|
|
|
if (this.props.entry === nextProps.entry) return;
|
2017-07-18 19:14:40 -04:00
|
|
|
const { entry, newEntry, fields, collection } = nextProps;
|
2016-11-01 14:31:04 -02:00
|
|
|
|
2017-07-18 19:14:40 -04:00
|
|
|
if (entry && !entry.get('isFetching') && !entry.get('error')) {
|
2017-08-02 13:11:43 -04:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Deserialize entry values for widgets with registered serializers before
|
|
|
|
* creating the entry draft.
|
|
|
|
*/
|
2017-07-18 19:14:40 -04:00
|
|
|
const values = deserializeValues(entry.get('data'), fields);
|
|
|
|
const deserializedEntry = entry.set('data', values);
|
|
|
|
this.createDraft(deserializedEntry);
|
|
|
|
} else if (newEntry) {
|
|
|
|
this.props.createEmptyDraft(collection);
|
2016-06-08 04:42:24 -03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
componentWillUnmount() {
|
|
|
|
this.props.discardDraft();
|
2017-03-15 10:47:03 -07:00
|
|
|
this.unlisten();
|
2016-06-08 04:42:24 -03:00
|
|
|
}
|
|
|
|
|
2016-10-11 18:24:55 +02:00
|
|
|
createDraft = (entry) => {
|
2016-08-24 21:36:44 -03:00
|
|
|
if (entry) this.props.createDraftFromEntry(entry);
|
2016-10-03 14:25:27 +02:00
|
|
|
};
|
2016-08-24 21:36:44 -03:00
|
|
|
|
2017-01-11 20:58:15 -02:00
|
|
|
handleCloseEntry = () => {
|
2017-07-21 23:40:33 -07:00
|
|
|
return this.props.closeEntry();
|
2017-01-11 20:58:15 -02:00
|
|
|
};
|
|
|
|
|
2016-10-03 14:25:27 +02:00
|
|
|
handlePersistEntry = () => {
|
2017-01-13 19:30:40 -02:00
|
|
|
const { persistEntry, collection } = this.props;
|
2017-01-13 19:46:49 -02:00
|
|
|
setTimeout(() => {
|
2017-07-21 23:40:33 -07:00
|
|
|
persistEntry(collection).then(() => this.handleCloseEntry());
|
2017-01-13 19:46:49 -02:00
|
|
|
}, 0);
|
2016-10-03 14:25:27 +02:00
|
|
|
};
|
2016-06-05 01:52:18 -07:00
|
|
|
|
2017-07-21 23:40:33 -07:00
|
|
|
handleDeleteEntry = () => {
|
|
|
|
if (!window.confirm('Are you sure you want to delete this entry?')) { return; }
|
|
|
|
if (this.props.newEntry) {
|
|
|
|
return this.handleCloseEntry();
|
|
|
|
}
|
|
|
|
|
|
|
|
const { deleteEntry, entry, collection } = this.props;
|
|
|
|
const slug = entry.get('slug');
|
|
|
|
setTimeout(() => {
|
|
|
|
deleteEntry(collection, slug).then(() => this.handleCloseEntry());
|
|
|
|
}, 0);
|
|
|
|
}
|
|
|
|
|
2016-02-25 20:40:35 -08:00
|
|
|
render() {
|
2016-06-10 00:16:01 -03:00
|
|
|
const {
|
2016-10-11 18:24:55 +02:00
|
|
|
entry,
|
|
|
|
entryDraft,
|
2016-10-21 20:42:14 -02:00
|
|
|
fields,
|
2017-01-10 22:23:22 -02:00
|
|
|
boundGetAsset,
|
2016-10-11 18:24:55 +02:00
|
|
|
collection,
|
2016-12-29 17:18:24 -02:00
|
|
|
changeDraftField,
|
2017-01-13 19:30:40 -02:00
|
|
|
changeDraftFieldValidation,
|
2017-01-10 22:23:22 -02:00
|
|
|
addAsset,
|
|
|
|
removeAsset,
|
2017-01-11 20:58:15 -02:00
|
|
|
closeEntry,
|
2016-06-10 00:16:01 -03:00
|
|
|
} = this.props;
|
2016-09-13 15:30:58 +02:00
|
|
|
|
2017-01-10 22:23:22 -02:00
|
|
|
if (entry && entry.get('error')) {
|
|
|
|
return <div><h3>{ entry.get('error') }</h3></div>;
|
|
|
|
} else if (entryDraft == null
|
2016-10-11 18:24:55 +02:00
|
|
|
|| entryDraft.get('entry') === undefined
|
|
|
|
|| (entry && entry.get('isFetching'))) {
|
2016-10-14 13:42:58 +02:00
|
|
|
return <Loader active>Loading entry...</Loader>;
|
2016-06-05 01:52:18 -07:00
|
|
|
}
|
2017-01-10 22:23:22 -02:00
|
|
|
|
2016-06-05 01:52:18 -07:00
|
|
|
return (
|
|
|
|
<EntryEditor
|
2016-09-29 19:02:28 +02:00
|
|
|
entry={entryDraft.get('entry')}
|
2017-01-10 22:23:22 -02:00
|
|
|
getAsset={boundGetAsset}
|
2016-09-29 19:02:28 +02:00
|
|
|
collection={collection}
|
2016-10-21 20:42:14 -02:00
|
|
|
fields={fields}
|
2016-12-29 17:18:24 -02:00
|
|
|
fieldsMetaData={entryDraft.get('fieldsMetaData')}
|
2017-01-13 19:30:40 -02:00
|
|
|
fieldsErrors={entryDraft.get('fieldsErrors')}
|
2016-12-29 17:18:24 -02:00
|
|
|
onChange={changeDraftField}
|
2017-01-13 19:30:40 -02:00
|
|
|
onValidate={changeDraftFieldValidation}
|
2017-01-10 22:23:22 -02:00
|
|
|
onAddAsset={addAsset}
|
|
|
|
onRemoveAsset={removeAsset}
|
2016-09-29 19:02:28 +02:00
|
|
|
onPersist={this.handlePersistEntry}
|
2017-07-21 23:40:33 -07:00
|
|
|
onDelete={this.handleDeleteEntry}
|
|
|
|
showDelete={this.props.showDelete}
|
2017-09-02 19:24:37 -06:00
|
|
|
hasChanged={entryDraft.get('hasChanged')}
|
2017-01-11 20:58:15 -02:00
|
|
|
onCancelEdit={this.handleCloseEntry}
|
2016-06-05 01:52:18 -07:00
|
|
|
/>
|
|
|
|
);
|
2016-02-25 20:40:35 -08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
function mapStateToProps(state, ownProps) {
|
2016-06-08 04:42:24 -03:00
|
|
|
const { collections, entryDraft } = state;
|
2016-10-21 20:42:14 -02:00
|
|
|
const slug = ownProps.params.slug;
|
2016-05-30 16:55:32 -07:00
|
|
|
const collection = collections.get(ownProps.params.name);
|
2016-08-24 21:36:44 -03:00
|
|
|
const newEntry = ownProps.route && ownProps.route.newRecord === true;
|
2016-11-11 17:54:58 -02:00
|
|
|
const fields = selectFields(collection, slug);
|
2016-08-24 21:36:44 -03:00
|
|
|
const entry = newEntry ? null : selectEntry(state, collection.get('name'), slug);
|
2017-01-10 22:23:22 -02:00
|
|
|
const boundGetAsset = getAsset.bind(null, state);
|
2016-10-13 14:30:11 +02:00
|
|
|
return {
|
|
|
|
collection,
|
|
|
|
collections,
|
|
|
|
newEntry,
|
|
|
|
entryDraft,
|
2017-01-10 22:23:22 -02:00
|
|
|
boundGetAsset,
|
2016-11-11 17:54:58 -02:00
|
|
|
fields,
|
2016-10-13 14:30:11 +02:00
|
|
|
slug,
|
|
|
|
entry,
|
|
|
|
};
|
2016-02-25 20:40:35 -08:00
|
|
|
}
|
|
|
|
|
2016-06-08 04:42:24 -03:00
|
|
|
export default connect(
|
|
|
|
mapStateToProps,
|
|
|
|
{
|
2016-12-29 17:18:24 -02:00
|
|
|
changeDraftField,
|
2017-01-13 19:30:40 -02:00
|
|
|
changeDraftFieldValidation,
|
2017-01-10 22:23:22 -02:00
|
|
|
addAsset,
|
|
|
|
removeAsset,
|
2016-06-08 04:42:24 -03:00
|
|
|
loadEntry,
|
2016-07-19 17:11:22 -03:00
|
|
|
createDraftFromEntry,
|
2016-08-24 21:36:44 -03:00
|
|
|
createEmptyDraft,
|
2016-06-08 04:42:24 -03:00
|
|
|
discardDraft,
|
2016-10-11 18:24:55 +02:00
|
|
|
persistEntry,
|
2017-07-21 23:40:33 -07:00
|
|
|
deleteEntry,
|
2017-01-11 20:58:15 -02:00
|
|
|
closeEntry,
|
2016-11-11 17:54:58 -02:00
|
|
|
openSidebar,
|
2016-06-08 04:42:24 -03:00
|
|
|
}
|
2016-10-11 18:24:55 +02:00
|
|
|
)(entryPageHOC(EntryPage));
|