-
john authored4d814f7e
Code owners
Assign users and groups as approvers for specific file changes. Learn more.
Forked from
Coko Org / Products / ketty / editoria-app
374 commits behind the upstream repository.
SimpleEditor.jsx 5.81 KiB
// 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
}