Commit 8938d686 authored by Alexandros Georgantas's avatar Alexandros Georgantas

Merge branch 'staging' into 'master'

Staging

See merge request !113
parents ab527771 b560894f
**/_build
**/node_modules
**/coverage
packages/ui/styleguide
**/node_modules
packages/vivliostyle/vivliostyle-viewer
packages/paged-viewer/lib
{
"linters": {
"*.{js,jsx}": ["prettier --write", "eslint --fix", "stylelint", "git add"]
},
ignore: ["**/CHANGELOG.md"]
}
package.json
.config/configstore/update-notifier-npm.json
**/_build
**/node_modules
**/coverage
{
"extends": [
"stylelint-config-recommended",
"stylelint-config-styled-components"
],
"plugins": ["stylelint-order"],
"processors": ["stylelint-processor-styled-components"],
"rules": {
"order/order": ["declarations", "rules", "at-rules"],
"order/properties-alphabetical-order": true
}
}
module.exports = { extends: ['@commitlint/config-conventional'] }
......@@ -3,5 +3,11 @@
"packages": [
"packages/*"
],
"command": {
"publish": {
"conventionalCommits": true,
"message": "chore(release): publish"
}
},
"version": "independent"
}
......@@ -4,6 +4,10 @@
"devDependencies": {
"babel-eslint": "^8.0.3",
"babel-preset-es2015": "^6.24.1",
"@commitlint/cli": "^6.0.5",
"@commitlint/config-conventional": "^6.0.4",
"commitizen": "^2.9.6",
"cz-conventional-changelog": "^2.1.0",
"eslint": "^4.13.1",
"eslint-config-pubsweet": "^0.0.6",
"eslint-plugin-import": "^2.8.0",
......@@ -18,8 +22,9 @@
"lint-staged": "^6.0.0",
"prettier": "^1.8.2",
"stylelint": "^8.2.0",
"stylelint-config-prettier": "^2.0.0",
"stylelint-config-pubsweet": "^0.0.3",
"stylelint-config-recommended": "^2.1.0",
"stylelint-config-styled-components": "^0.1.1",
"stylelint-processor-styled-components": "^1.3.1",
"standard-version": "^4.4.0"
},
"license": "MIT",
......@@ -35,9 +40,20 @@
"publish": "lerna publish",
"updated": "lerna updated",
"test": "lerna run test",
"lint": "npm run lint:js && npm run lint:style",
"lint:js": "eslint 'packages/**/*.{js,jsx}'",
"lint:style": "stylelint 'packages/**/*.{js,jsx}'",
"precommit": "lint-staged",
"cz": "git-cz",
"commitmsg": "commitlint -e $GIT_PARAMS",
"release": "standard-version"
},
"version": "1.0.0",
"version": "0.0.0",
"config": {
"commitizen": {
"path": "./node_modules/cz-conventional-changelog"
}
},
"dependencies": {
"babel-preset-stage-0": "^6.24.1"
},
......
module.exports = {
frontend: {
components: [
() => require('./src/BookBuilder')
]
}
}
\ No newline at end of file
components: [() => require('./src/BookBuilder')],
},
}
......@@ -64,7 +64,8 @@ export class BookBuilder extends React.Component {
// I'm using the ref inside the render function it was created in
// So it won't be available until didMount
// Pass it to the state and use it safely (no undefined scenarios)
this.setState({ outerContainer: this.refs.outerContainer })
this.setState({ outerContainer: this.refs.outerContainer }) // eslint-disable-line
}
// setProductionEditor() {
......@@ -280,6 +281,7 @@ export class BookBuilder extends React.Component {
return (
<div className="bootstrap modal pubsweet-component pubsweet-component-scroll">
<div className={styles.bookBuilder}>
{/* eslint-disable-next-line react/no-string-refs */}
<div className={styles.universe} ref="outerContainer">
<div className={`${styles.productionEditorContainer}`}>
<span>{this.renderProductionEditors()}</span>
......
......@@ -5,24 +5,16 @@ import React from 'react'
import classes from './AlignmentBox.local.scss'
const AlignmentBox = ({ active, id, noBorder, onClick }) => {
const styles = classNames(
classes.root,
{
[classes.active]: active,
[classes.borderTop]: noBorder.top,
[classes.borderRight]: noBorder.right,
[classes.borderBottom]: noBorder.bottom,
[classes.borderLeft]: noBorder.left
}
)
const styles = classNames(classes.root, {
[classes.active]: active,
[classes.borderTop]: noBorder.top,
[classes.borderRight]: noBorder.right,
[classes.borderBottom]: noBorder.bottom,
[classes.borderLeft]: noBorder.left,
})
return (
<div
className={styles}
id={id}
onClick={onClick}
role='presentation'
/>
<div className={styles} id={id} onClick={onClick} role="presentation" />
)
}
......
......@@ -11,17 +11,15 @@ const AlignmentBoxWithLabel = ({
labelPositionRight,
labelText,
noBorder,
onClick
onClick,
}) => {
const styles = classNames(classes.root, {
[classes.reverseOrder]: labelPositionRight
[classes.reverseOrder]: labelPositionRight,
})
return (
<div className={styles}>
<span className={classes.label}>
{labelText}
</span>
<span className={classes.label}>{labelText}</span>
<AlignmentBox
active={active}
id={id}
......
......@@ -6,7 +6,8 @@ import classes from './AlignmentTool.local.scss'
const AlignmentTool = ({ data, onClickAlignmentBox }) => {
const onClick = event => {
const id = event.currentTarget.id
const { currentTarget } = event
const { id } = currentTarget
onClickAlignmentBox(id)
}
......
......@@ -45,14 +45,14 @@ class ChapterTitle extends React.Component {
return (
<Title
isRenaming={isRenaming}
isLocked={chapter.lock !== null}
goToEditor={this.goToEditor}
isLocked={chapter.lock !== null}
isRenaming={isRenaming}
number={chapter.number || null}
onSaveRename={onSaveRename}
// ref={node => (this.title = node)}
title={title}
showNumber={showNumber}
number={chapter.number || null}
title={title}
/>
)
......
......@@ -18,7 +18,7 @@ class DeleteModal extends React.Component {
render() {
const { chapter, container, show, toggle } = this.props
const type = chapter.type
const { type } = chapter
return (
<Modal
......
......@@ -34,9 +34,17 @@ class DropdownTitle extends React.Component {
this.width = 180
}
componentDidMount() {
window.addEventListener('click', this.handleClickOutside)
}
componentWillUnmount() {
window.removeEventListener('click', this.handleClickOutside)
}
breakIntoColumns(items) {
const max = this.maxItemsInColumn
const width = this.width
const { width } = this
const columns = []
let loopIt = 1
......@@ -67,14 +75,14 @@ class DropdownTitle extends React.Component {
getDropdownOptions() {
const { chapter } = this.props
const division = chapter.division
const { division } = chapter
return config.bookBuilder.chapter.dropdownValues[division]
}
getMenuItems() {
const dropdownOptions = this.getDropdownOptions()
const onClickOption = this.onClickOption
const { onClickOption } = this
const menuItems = map(dropdownOptions, (item, i) => (
<MenuItem className={styles.menuItem} key={i} onClick={onClickOption}>
......@@ -85,12 +93,6 @@ class DropdownTitle extends React.Component {
return menuItems
}
onClickOption(event) {
const value = event.target.innerHTML.trim()
this.update(value)
this.close()
}
setCustomTitle(e) {
const value = get(this.dropDownInput, 'state.value', null)
this.update(value)
......@@ -116,8 +118,8 @@ class DropdownTitle extends React.Component {
}
handleClickOutside(event) {
const domNode = findDOMNode(this)
const input = findDOMNode(this.dropDownInput)
const domNode = findDOMNode(this) // eslint-disable-line react/no-find-dom-node
const input = findDOMNode(this.dropDownInput) // eslint-disable-line react/no-find-dom-node
if (input) input.focus()
......@@ -128,17 +130,15 @@ class DropdownTitle extends React.Component {
}
}
componentDidMount() {
window.addEventListener('click', this.handleClickOutside)
}
componentWillUnmount() {
window.removeEventListener('click', this.handleClickOutside)
onClickOption(event) {
const value = event.target.innerHTML.trim()
this.update(value)
this.close()
}
renderInput() {
return (
<div className={styles.dropDownInputContairer}>
<div className={styles.dropDownInputContainer}>
<TextInput
className={`drop-input ${styles.dropDownInput}`}
onSave={this.setCustomTitle}
......@@ -157,7 +157,7 @@ class DropdownTitle extends React.Component {
const columnCount = this.getColumnCount()
const menuItems = this.getMenuItems()
const input = this.renderInput()
const width = this.width
const { width } = this
let columns = menuItems
if (columnCount > 1) columns = this.breakIntoColumns(menuItems)
......
import { includes } from 'lodash'
import React from 'react'
import PropTypes from 'prop-types'
......@@ -28,6 +27,7 @@ class EditingNotification extends React.Component {
const { user } = this.props
return user.admin
}
/* eslint-disable */
formatDate(timestamp) {
const date = new Date(timestamp)
......@@ -52,11 +52,14 @@ class EditingNotification extends React.Component {
return formatted
}
/* eslint-enable */
render() {
const { chapter, modalContainer, update } = this.props
const { showModal } = this.state
const username = chapter.lock.editor.username
const { lock } = chapter
const { editor } = lock
const username = editor
const isAdmin = this.isAdmin()
const message = `${username} is editing`
......
......@@ -25,6 +25,7 @@ class ChapterFirstRow extends React.Component {
})
}
/* eslint-disable consistent-return */
onSaveRename(title) {
const { chapter, update } = this.props
title = title.trim()
......@@ -45,6 +46,7 @@ class ChapterFirstRow extends React.Component {
this.setState({ isRenamingTitle: false })
}
/* eslint-enable */
// follow a chain of refs to call the save function of the input
// this is done to facilitate sibling-sibling component communication
......@@ -90,9 +92,9 @@ class ChapterFirstRow extends React.Component {
onClickRename={this.onClickRename}
// onClickSave={this.onClickSave}
remove={remove}
user={user}
type={type}
update={update}
user={user}
/>
</div>
)
......
......@@ -85,6 +85,7 @@ export class ProgressItem extends React.Component {
return false
}
/* eslint-disable consistent-return */
onClick() {
const { roles } = this.props
......@@ -103,6 +104,7 @@ export class ProgressItem extends React.Component {
this.toggleModal()
}
/* eslint-enable */
renderModal() {
const { chapter, modalContainer, type } = this.props
......@@ -135,7 +137,7 @@ export class ProgressItem extends React.Component {
return (
<Alert bsStyle="warning" className={styles.noWritesError}>
You don't have access to perfom this action. Please contact your
You don&apos;t have access to perform this action. Please contact your
Production Editor.
</Alert>
)
......@@ -157,7 +159,7 @@ export class ProgressItem extends React.Component {
return (
<span>
{errorMessage}
{/* eslint-disable-next-line */}
<li className={`progress${currentStateValue}`} onClick={this.onClick}>
{currentStateText} &nbsp;
{icon}
......
/* DEPRECATED */
/* eslint-disable */
import React from 'react'
import PropTypes from 'prop-types'
......
/* DEPRECATED */
/* eslint-disable */
import React from 'react'
import PropTypes from 'prop-types'
......@@ -7,7 +7,14 @@ import Modal from 'editoria-common/src/Modal'
class ProgressModal extends React.Component {
render() {
const { changeProgressState, chapter, container, show, toggle, modalType } = this.props
const {
changeProgressState,
chapter,
container,
show,
toggle,
modalType,
} = this.props
const type = chapter.type
return (
......
/* eslint-disable */
import React from 'react'
import PropTypes from 'prop-types'
......
......@@ -351,6 +351,12 @@ class ChapterSecondRow extends React.Component {
})
}
toggleModal() {
this.setState({
showModal: !this.state.showModal,
})
}
onClickAlignmentBox(id) {
const { chapter, update } = this.props
......@@ -363,12 +369,6 @@ class ChapterSecondRow extends React.Component {
update(patch)
}
toggleModal() {
this.setState({
showModal: !this.state.showModal,
})
}
renderModal() {
const { chapter, outerContainer } = this.props
const { modalType, showModal } = this.state
......
......@@ -4,12 +4,12 @@ import PropTypes from 'prop-types'
import Modal from 'editoria-common/src/Modal'
class UnlockModal extends React.Component {
constructor (props) {
constructor(props) {
super(props)
this.onUnlock = this.onUnlock.bind(this)
}
onUnlock () {
onUnlock() {
const { chapter, toggle, update } = this.props
chapter.lock = null
......@@ -17,21 +17,21 @@ class UnlockModal extends React.Component {
toggle()
}
render () {
render() {
const { chapter, container, show, toggle } = this.props
const type = chapter.type
const { type } = chapter
return (
<Modal
title={'Unlock ' + type}
action="unlock"
chapter={chapter}
action='unlock'
successText='Unlock'
type={type}
successAction={this.onUnlock}
container={container}
show={show}
successAction={this.onUnlock}
successText="Unlock"
title={`Unlock ${type}`}
toggle={toggle}
container={container}
type={type}
/>
)
}
......
......@@ -17,13 +17,6 @@ export class UploadButton extends React.Component {
}
}
renderUploadIndicator() {
const { isUploadInProgress } = this.props
if (isUploadInProgress) return true
return false
}
handleFileUpload(event) {
event.preventDefault()
......@@ -94,16 +87,23 @@ export class UploadButton extends React.Component {
})
}
isLocked() {
const { chapter } = this.props
if (chapter.lock === null) return false
return true
}
onClick() {
if (!this.isLocked()) return
this.toggleModal()
}
isLocked() {
const { chapter } = this.props
renderUploadIndicator() {
const { isUploadInProgress } = this.props
if (isUploadInProgress) return true
if (chapter.lock === null) return false
return true
return false
}
renderInput() {
......
......@@ -7,22 +7,18 @@ import AlignmentBox from '../AlignmentBox'
const { data } = global.mock
const type = 'front'
const chapters = data.chapters.filter((chapter) => {
return chapter.division === type
})
const chapters = data.chapters.filter(chapter => chapter.division === type)
let props = {
const props = {
chapter: chapters[0],
position: 'left',
update: sinon.spy()
update: sinon.spy(),
}
const getWrapper = () => {
return shallow(<AlignmentBox {...props} />)
}
const getWrapper = () => shallow(<AlignmentBox {...props} />)
test('should render correctly', () => {
const wrapper = getWrapper()
const tree = shallowToJson(wrapper)
expect(tree).toMatchSnapshot()
})
\ No newline at end of file
})
......@@ -7,18 +7,14 @@ import AlignmentTool from '../AlignmentTool'
const { data } = global.mock
const type = 'front'
const chapters = data.chapters.filter((chapter) => {
return chapter.division === type
})
const chapters = data.chapters.filter(chapter => chapter.division === type)
let props = {
const props = {
chapter: chapters[0],
update: sinon.spy()
update: sinon.spy(),
}
const getWrapper = () => {
return shallow(<AlignmentTool {...props} />)
}
const getWrapper = () => shallow(<AlignmentTool {...props} />)
test('should render correctly', () => {
const wrapper = getWrapper()
......
......@@ -7,21 +7,17 @@ import ProgressItem from '../ProgressItem'
const { data } = global.mock
const type = 'front'
const chapters = data.chapters.filter((chapter) => {
return chapter.division === type
})
const chapters = data.chapters.filter(chapter => chapter.division === type)
let props = {
const props = {
chapter: chapters[0],
type: 'edit',
modalContainer: {},
update: sinon.spy(),
roles: []
roles: [],
}
const getWrapper = () => {
return shallow(<ProgressItem {...props} />)
}
const getWrapper = () => shallow(<ProgressItem {...props} />)
test('should render correctly', () => {
const wrapper = getWrapper()
......
......@@ -21,7 +21,10 @@ const DownloadEpub = ({ book, showModal, showModalToggle, outerContainer }) => {
.then(res => {
window.location.replace(res.request.responseURL)
})
.catch(error => showModalToggle())
.catch(error => {
showModalToggle()
console.error(error)
})
}
const toggleModal = () => {
......@@ -40,7 +43,7 @@ const DownloadEpub = ({ book, showModal, showModalToggle, outerContainer }) => {
return (
<div className={`${classes.exportBookContainer}`} onClick={handleDownload}>
<i className={classes.exportToBookIcon} />
<label className={classes.donwloadEpubText}>Download Epub</label>
<label className={classes.downloadEpubText}>Download Epub</label>
{modal}
</div>
)
......
......@@ -24,7 +24,7 @@ $black: #000;
width: 24px;
}
label.donwloadEpubText {
label.downloadEpubText {
color: $upload-multiple;
margin-bottom: 0;
cursor: pointer;
......
......@@ -4,18 +4,20 @@ import PropTypes from 'prop-types'
import AbstractModal from 'editoria-common/src/AbstractModal'
class ErrorModal extends React.Component {
/* eslint-disable */
renderBody() {
return (
<div>
An error occured during the conversion to epub. Please try again later.
An error occurred during the conversion to epub. Please try again later.
</div>
)
}
/* eslint-enabled */
render() {
const { container, show, toggle } = this.props
const body = this.renderBody()
const title = 'An error occured'
const title = 'An error occurred'
return (
<AbstractModal
......
......@@ -4,18 +4,20 @@ import PropTypes from 'prop-types'
import AbstractModal from 'editoria-common/src/AbstractModal'
class ErrorModal extends React.Component {
/* eslint-disable */
renderBody() {
return (
<div>
An error occured during the conversion to epub. Please try again later.
An error occurred during the conversion to epub. Please try again later.
</div>
)
}