Skip to content
Snippets Groups Projects
SimpleEditor.jsx 6.06 KiB
Newer Older
// import { get } from 'lodash'
import React from 'react'
import ReactDOM from 'react-dom'
import { Alert } from 'react-bootstrap'

john's avatar
john committed
import {
  ProseEditorConfigurator as Configurator,
  DocumentSession
} from 'substance'
john's avatar
john committed
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 -- delete, along with Alert
    this.state = {
      canEdit: false
    }
  }

  // TODO -- is this necessary?
  componentWillMount () {
    const { fragment } = this.props
    if (fragment) {
      console.log('fragment? yes!', fragment)
      this._checkRights()
      this._acquireLock()
  }

  createSession () {
    const { fragment } = this.props
    let source
    if (fragment) { source = fragment.source }

john's avatar
john committed
    const configurator = new Configurator().import(config)
    configurator.addImporter('html', Importer)

    const importer = configurator.createImporter('html')
    const doc = importer.importDocument(source)
    const documentSession = new DocumentSession(doc)

    documentSession.setSaveHandler({
      saveDocument: this.save
    })
john's avatar
john committed
      configurator: configurator,
      documentSession: documentSession
  updateTrackChangesStatus () {
    const { fragment, update } = this.props
    fragment.trackChanges = !fragment.trackChanges
    update(fragment)
  }

  save (source, changes, callback) {
    const { onSave } = this.props
john's avatar
john committed
    const config = this.state.config

    const exporter = new SimpleExporter(config)
    const convertedSource = exporter.exportDocument(source)

    onSave(convertedSource, callback)
  // TODO -- for release and acquire use a generic update
  _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)
  }

  _acquireLock () {
    const { fragment, update, user } = this.props
    // const { updateFragment } = this.props.actions

    fragment.lock = {
      editor: { username: user.username },
      timestamp: new Date()
    }

    console.log('locked!')

    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 () {
john's avatar
john committed
    const { onSave } = this.props
    const el = ReactDOM.findDOMNode(this)
    const { fragment } = this.props
john's avatar
john committed
    const session = this.createSession()
    const documentSession = session.documentSession
    const configurator = session.configurator

    if (!fragment) return

john's avatar
john committed
    this.setState({
      config: configurator.config
    })
john's avatar
john committed
    Editor.mount({
      book: this.props.book,
      configurator: configurator,
      containerId: 'body',
      disabled: !this.state.canEdit, // set to true read only mode
      documentSession: documentSession,
      fileUpload: this.props.fileUpload,
      fragment: this.props.fragment,
john's avatar
john committed
      history: this.props.history,
      onSave: onSave,
      trackChanges: this.props.fragment.trackChanges,
      updateComments: this.props.updateComments,
      updateTrackChangesStatus: this.updateTrackChangesStatus,
      user: this.props.user
    }, el)

    window.addEventListener('beforeunload', this._releaseLock)
  }

  componentWillUnmount () {
    this._releaseLock()
    window.removeEventListener('beforeunload', this._releaseLock)
  // 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?
    // TODO -- DELETE THIS !!!!!
    let viewMode = !this.state.canEdit
      <Alert bsStyle='warning' className='view-mode'>
        <span>Editor is in Read-Only Mode</span>
      <div className='editor-wrapper'>
      </div>
    )
  }
}

SimpleEditor.propTypes = {
  book: React.PropTypes.object.isRequired,
  canEdit: React.PropTypes.bool,
  fragment: React.PropTypes.object,
john's avatar
john committed
  history: React.PropTypes.object.isRequired,
  onSave: React.PropTypes.func.isRequired,
  update: React.PropTypes.func.isRequired,
  updateComments: React.PropTypes.func.isRequired,
  fileUpload: React.PropTypes.func.isRequired,
  user: React.PropTypes.object.isRequired
}