// import { get } from 'lodash' import React from 'react' import ReactDOM from 'react-dom' import { ProseEditorConfigurator as Configurator, EditorSession } from 'substance' import config from './config' import Editor from './Editor' import Importer from './SimpleEditorImporter' import SimpleExporter from './SimpleEditorExporter' import './SimpleEditor.scss' export default class SimpleEditor extends React.Component { constructor (props) { super(props) this.save = this.save.bind(this) this.updateTrackChangesStatus = this.updateTrackChangesStatus.bind(this) this._checkRights = this._checkRights.bind(this) this._releaseLock = this._releaseLock.bind(this) this._acquireLock = this._acquireLock.bind(this) } // TODO -- is this necessary? componentWillMount () { const { fragment } = this.props if (fragment) { this._checkRights() this._acquireLock() } } createSession () { const { fragment } = this.props let source if (fragment) { source = fragment.source } const configurator = new Configurator().import(config) configurator.addImporter('html', Importer) const importer = configurator.createImporter('html') const doc = importer.importDocument(source) const editorSession = new EditorSession(doc, { configurator: configurator }) editorSession.setSaveHandler({ saveDocument: this.save, uploadFile: this.props.fileUpload }) return { configurator: configurator, editorSession: editorSession } } updateTrackChangesStatus () { const { fragment, update } = this.props const patch = { id: fragment.id, trackChanges: !fragment.trackChanges } update(patch) } save (source, changes, callback) { const { onSave } = this.props const config = this.state.config const exporter = new SimpleExporter(config) const convertedSource = exporter.exportDocument(source) return onSave(convertedSource) } // NOTE -- Theoretically, we shouldn't lock when the editor is in read only // mode. This gets complicated however, as the user will be able to be add // comments, which will in turn affect the fragment. So, it is better to // avoid any possible data corruption until collaboration is added. _acquireLock () { const { fragment, update, user } = this.props fragment.lock = { editor: { username: user.username }, timestamp: new Date() } update(fragment) } _releaseLock () { const { fragment, update } = this.props // TODO -- maybe this is causing the lock problems? // if (get(fragment, 'lock.editor.username') === user.username) { // fragment.lock = null // } fragment.lock = null update(fragment) } // TODO -- rewrite cleaner, and as isDisabled (returns boolean) _checkRights () { const { fragment, user } = this.props if (user.admin) return this.setState({ canEdit: true }) if ((fragment.progress['review'] === 1 && user.teams[0].teamType.name === 'Author') || (fragment.progress['edit'] === 1 && user.teams[0].teamType.name === 'Copy Editor')) { this.setState({ canEdit: true }) } else { this.setState({ canEdit: false }) } if (user.teams[0].teamType.name === 'Production Editor') { this.setState({ canEdit: true }) } } // TODO -- remove when reloading works correctly (by refreshing props) componentWillReceiveProps (nextProps) { const { fragment } = this.props if (fragment) return var self = this if (nextProps.fragment) { setTimeout(function () { self._checkRights() self.componentDidMount() }, 0) } } componentDidMount () { const el = ReactDOM.findDOMNode(this) const { book, fragment, history, onSave, update, user } = this.props const { configurator, editorSession } = this.createSession() if (!fragment) return const containerId = 'body' // TODO -- delete const trackChanges = fragment.trackChanges const updateTrackChangesStatus = this.updateTrackChangesStatus const disabled = !this.state.canEdit // TODO -- justify this.setState({ config: configurator.config }) this.editor = Editor.mount({ book, configurator, containerId, disabled, editorSession, fragment, history, onSave, trackChanges, update, updateTrackChangesStatus, user }, el) // TODO -- pull all above into its own function window.addEventListener('beforeunload', this._releaseLock) } componentWillUnmount () { this._releaseLock() window.removeEventListener('beforeunload', this._releaseLock) this.editor.dispose() } // TODO -- use this for correctly refreshing props when the fragment arrives // this.writer does not exist, you have to make it in componentDidMount // this.writer = Editor.mount( .... // New props arrived, update the editor // componentDidUpdate () { // console.log('did update') // // var session = this.createSession() // var documentSession = session.documentSession // var configurator = session.configurator // // this.writer.extendProps({ // documentSession: documentSession, // configurator: configurator // }) // // console.log(this.writer) // } // // componentWillUnmount () { // this.writer.dispose() // } // TODO -- do I even need a render here? render () { return ( <div className='editor-wrapper' /> ) } } SimpleEditor.propTypes = { book: React.PropTypes.object, // canEdit: React.PropTypes.bool, // needed? fragment: React.PropTypes.object, history: React.PropTypes.object.isRequired, onSave: React.PropTypes.func.isRequired, update: React.PropTypes.func.isRequired, fileUpload: React.PropTypes.func.isRequired, user: React.PropTypes.object.isRequired }