Skip to content
Snippets Groups Projects
ProgressItem.jsx 4.14 KiB
Newer Older
import { includes } from 'lodash'
john's avatar
john committed
import React from 'react'
import { Alert } from 'react-bootstrap'
john's avatar
john committed

import ProgressModal from './ProgressModal'
john's avatar
john committed
import styles from '../styles/bookBuilder.local.scss'
john's avatar
john committed
export class ProgressItem extends React.Component {
  constructor (props) {
    super(props)

john's avatar
john committed
    this.canChange = this.canChange.bind(this)
john's avatar
john committed
    this.changeProgressState = this.changeProgressState.bind(this)
    this.onClick = this.onClick.bind(this)
    this.renderErrorMessage = this.renderErrorMessage.bind(this)
    this.renderIcon = this.renderIcon.bind(this)
    this.renderModal = this.renderModal.bind(this)
    this.toggleModal = this.toggleModal.bind(this)
john's avatar
john committed
    // TODO -- move to config
    this.progressValues = {
      style: ['To Style', 'Styling', 'Styled'],
      edit: ['To Edit', 'Editing', 'Edited'],
      review: ['To Review', 'Reviewing', 'Reviewed'],
      clean: ['To Clean', 'Cleaning', 'Cleaned']
    }

    this.state = {
john's avatar
john committed
      showModal: false,
john's avatar
john committed
  toggleModal () {
    this.setState({
      showModal: !this.state.showModal
    })
  }

  changeProgressState () {
    const { chapter, update, type } = this.props
    const { progressValues } = this

    const list = progressValues[type]
    const len = list.length

    let position = chapter.progress[type]
    position += 1                      // move up a level
    if (position >= len) position = 0  // or cycle back to the beginning

    chapter.progress[type] = position
    update(chapter)

john's avatar
john committed
    this.setState({ showModal: false })
john's avatar
john committed
  canChange () {
    const { type, roles, chapter } = this.props

john's avatar
john committed
    if (includes(roles, 'admin') || includes(roles, 'production-editor')) return true
john's avatar
john committed
    const isActive = (chapter.progress[type] === 1)
john's avatar
john committed
    if (isActive) {
      if (type === 'edit') {
        if (includes(roles, 'copy-editor')) return true
      }
      if (type === 'review') {
        if (includes(roles, 'author')) return true
      }
    }
john's avatar
john committed
  onClick () {
    const { roles } = this.props
john's avatar
john committed

    if (!this.canChange()) {
      this.setState({ showError: true })
john's avatar
john committed

      return setTimeout(() => {
        this.setState({ showError: false })
      }, 3000)
john's avatar
john committed
    if (includes(roles, 'production-editor')) {
      return this.changeProgressState()
    }

    this.toggleModal()
john's avatar
john committed
  renderModal () {
    const { chapter, modalContainer, type } = this.props
    const { showModal } = this.state
john's avatar
john committed
    const typesWithModal = ['edit', 'review']
    if (!includes(typesWithModal, type)) return null
john's avatar
john committed
    return (
      <ProgressModal
        changeProgressState={this.changeProgressState}
        chapter={chapter}
        container={modalContainer}
        show={showModal}
        toggle={this.toggleModal}
      />
    )
  }
john's avatar
john committed
  renderIcon () {
    const { hasIcon } = this.props
    if (!hasIcon) return null
john's avatar
john committed
    return (<i className='fa fa-angle-right' />)
  }
john's avatar
john committed
  renderErrorMessage () {
    const { showError } = this.state
    if (!showError) return null

    return (
      <Alert
        bsStyle='warning'
        className={styles.noWritesError}
      >
        You don't have access to perfom this action.
        Please contact your Production Editor.
      </Alert>
    )
john's avatar
john committed
    const { type, chapter } = this.props
    const { progressValues } = this

john's avatar
john committed
    const currentStateValue = chapter.progress[type]
    const currentStateText = progressValues[type][currentStateValue]
john's avatar
john committed
    const errorMessage = this.renderErrorMessage()
    const icon = this.renderIcon()
    const warningModal = this.renderModal()
john's avatar
john committed
    // TODO -- find a nicer way to display the error message
john's avatar
john committed
        { errorMessage }

        <li
          className={'progress' + currentStateValue}
          onClick={this.onClick}
        >
john's avatar
john committed
          { currentStateText } &nbsp;
john's avatar
john committed
ProgressItem.propTypes = {
  chapter: React.PropTypes.object.isRequired,
  hasIcon: React.PropTypes.bool,
john's avatar
john committed
  modalContainer: React.PropTypes.object,
  roles: React.PropTypes.array.isRequired,
john's avatar
john committed
  type: React.PropTypes.string.isRequired,
  update: React.PropTypes.func.isRequired
john's avatar
john committed
export default ProgressItem