171 lines
5.4 KiB
JavaScript
Raw Normal View History

import React, { Component, PropTypes } from 'react';
import ImmutablePropTypes from 'react-immutable-proptypes';
import SplitPane from 'react-split-pane';
2017-03-17 15:12:15 -04:00
import Button from 'react-toolbox/lib/button';
import { ScrollSync, ScrollSyncPane } from '../ScrollSync';
import ControlPane from '../ControlPanel/ControlPane';
import PreviewPane from '../PreviewPane/PreviewPane';
import Toolbar from './EntryEditorToolbar';
2016-09-11 23:08:18 +02:00
import styles from './EntryEditor.css';
import stickyStyles from '../UI/Sticky/Sticky.css';
2016-05-30 16:55:32 -07:00
2017-04-05 12:06:12 -04:00
const PREVIEW_VISIBLE = 'cms.preview-visible';
2017-03-17 15:12:15 -04:00
class EntryEditor extends Component {
state = {
showEventBlocker: false,
2017-04-05 12:06:12 -04:00
previewVisible: localStorage.getItem(PREVIEW_VISIBLE) !== "false",
};
handleSplitPaneDragStart = () => {
this.setState({ showEventBlocker: true });
};
handleSplitPaneDragFinished = () => {
this.setState({ showEventBlocker: false });
};
handleOnPersist = () => {
this.controlPaneRef.validate();
this.props.onPersist();
};
2017-03-17 15:12:15 -04:00
handleTogglePreview = () => {
2017-04-05 12:06:12 -04:00
const newPreviewVisible = !this.state.previewVisible;
this.setState({ previewVisible: newPreviewVisible });
localStorage.setItem(PREVIEW_VISIBLE, newPreviewVisible);
2017-03-17 15:12:15 -04:00
};
setSticky = (contextTop, containerRect, sticky) => {
if (contextTop >= containerRect.top) {
if (contextTop < containerRect.bottom - 60) {
sticky.classList.add(stickyStyles.top);
sticky.classList.remove(stickyStyles.bottom);
} else if (contextTop >= containerRect.bottom - 60) {
sticky.classList.remove(stickyStyles.top);
sticky.classList.add(stickyStyles.bottom);
}
} else {
sticky.classList.remove(stickyStyles.top);
sticky.classList.remove(stickyStyles.bottom);
}
};
handleControlPaneRef = (ref) => {
const sticky = ref.querySelector('.cms__index__editorControlBar');
const stickyContainer = ref.querySelector('.stickyContainer');
stickyContainer.style.paddingTop = `${ sticky.offsetHeight }px`;
sticky.style.position = 'absolute';
sticky.style.top = `${ -sticky.offsetHeight }px`;
sticky.style.width = `${ stickyContainer.getBoundingClientRect().width }px`;
ref && ref.addEventListener('scroll', (e) => {
const contextTop = e.target.getBoundingClientRect().top;
this.setSticky(contextTop, stickyContainer.getBoundingClientRect(), sticky);
});
};
render() {
const {
collection,
entry,
fields,
fieldsMetaData,
fieldsErrors,
2017-01-10 22:23:22 -02:00
getAsset,
onChange,
onValidate,
2017-01-10 22:23:22 -02:00
onAddAsset,
onRemoveAsset,
onCancelEdit,
} = this.props;
const controlClassName = `${ styles.controlPane } ${ this.state.showEventBlocker && styles.blocker }`;
const previewClassName = `${ styles.previewPane } ${ this.state.showEventBlocker && styles.blocker }`;
const collectionPreviewEnabled = collection.getIn(['editor', 'preview'], true);
const togglePreviewButton = (
<Button className={styles.previewToggle} onClick={this.handleTogglePreview}>Toggle Preview</Button>
);
2017-03-17 15:12:15 -04:00
const editor = (
<div className={controlClassName} ref={this.handleControlPaneRef}>
{ collectionPreviewEnabled ? togglePreviewButton : null }
2017-03-17 15:12:15 -04:00
<ControlPane
collection={collection}
entry={entry}
fields={fields}
fieldsMetaData={fieldsMetaData}
fieldsErrors={fieldsErrors}
getAsset={getAsset}
onChange={onChange}
onValidate={onValidate}
onAddAsset={onAddAsset}
onRemoveAsset={onRemoveAsset}
ref={c => this.controlPaneRef = c} // eslint-disable-line
/>
</div>
);
const editorWithPreview = (
2017-03-17 15:12:15 -04:00
<ScrollSync>
<div className={styles.container}>
<SplitPane
defaultSize="50%"
onDragStarted={this.handleSplitPaneDragStart}
onDragFinished={this.handleSplitPaneDragFinished}
>
2017-04-05 12:06:12 -04:00
<ScrollSyncPane>{editor}</ScrollSyncPane>
2017-03-17 15:12:15 -04:00
<div className={previewClassName}>
<PreviewPane
collection={collection}
entry={entry}
fields={fields}
fieldsMetaData={fieldsMetaData}
getAsset={getAsset}
/>
</div>
</SplitPane>
</div>
</ScrollSync>
);
2017-04-05 12:06:12 -04:00
2017-04-14 21:30:49 +01:00
const editorWithoutPreview = (
<div className={styles.noPreviewEditorContainer}>
{editor}
</div>
);
2017-03-17 15:12:15 -04:00
return (
<div className={styles.root}>
2017-04-14 21:30:49 +01:00
{ collectionPreviewEnabled && this.state.previewVisible ? editorWithPreview : editorWithoutPreview }
<div className={styles.footer}>
<Toolbar
isPersisting={entry.get('isPersisting')}
onPersist={this.handleOnPersist}
onCancelEdit={onCancelEdit}
/>
</div>
2016-05-30 16:55:32 -07:00
</div>
);
}
2016-05-30 16:55:32 -07:00
}
EntryEditor.propTypes = {
collection: ImmutablePropTypes.map.isRequired,
entry: ImmutablePropTypes.map.isRequired,
fields: ImmutablePropTypes.list.isRequired,
fieldsMetaData: ImmutablePropTypes.map.isRequired,
fieldsErrors: ImmutablePropTypes.map.isRequired,
2017-01-10 22:23:22 -02:00
getAsset: PropTypes.func.isRequired,
onAddAsset: PropTypes.func.isRequired,
onChange: PropTypes.func.isRequired,
onValidate: PropTypes.func.isRequired,
onPersist: PropTypes.func.isRequired,
2017-01-10 22:23:22 -02:00
onRemoveAsset: PropTypes.func.isRequired,
onCancelEdit: PropTypes.func.isRequired,
};
export default EntryEditor;