diff --git a/packages/component-sortable-list/src/components/SortableList.js b/packages/component-sortable-list/src/components/SortableList.js index 0858630f0aa568f250de046bc4270b0a6e0666f6..bfb94cb78600d5685fdaad18c3564deccd148bbe 100644 --- a/packages/component-sortable-list/src/components/SortableList.js +++ b/packages/component-sortable-list/src/components/SortableList.js @@ -102,7 +102,7 @@ const SortableList = ({ <DecoratedItem dragHandle={dragHandle} index={i} - key={item[itemKey]} + key={getKey(item, 'id')} listItem={listItem} moveItem={moveItem} {...item} @@ -112,6 +112,14 @@ const SortableList = ({ </div> ) +const getKey = (item, itemKey) => { + if (item[itemKey]) { + return item[itemKey] + } + + return Object.values(item)[0] +} + // helper function for sortable lists SortableList.moveItem = (items, dragIndex, hoverIndex) => { if (dragIndex <= hoverIndex) { diff --git a/packages/component-wizard/src/components/Wizard.js b/packages/component-wizard/src/components/Wizard.js index 97edfa95a1bf67e3482a73e392454823e1b8a821..3a05e1944bd8e0d3f8b31990f0d3a250601ff1cb 100644 --- a/packages/component-wizard/src/components/Wizard.js +++ b/packages/component-wizard/src/components/Wizard.js @@ -1,6 +1,6 @@ import React from 'react' import styled from 'styled-components' -import { Steps } from 'pubsweet-components-faraday/src/components' +import { Steps, AuthorList } from 'pubsweet-components-faraday/src/components' // import { Steps } from '@pubsweet/ui' import WizardFormStep from './WizardFormStep' @@ -20,6 +20,7 @@ export default ({ ))} </Steps> )} + <AuthorList /> <WizardFormStep {...steps[step]} nextStep={nextStep} prevStep={prevStep} /> </Root> ) diff --git a/packages/components-faraday/src/components/AuthorList/Author.js b/packages/components-faraday/src/components/AuthorList/Author.js index d8e7bb8e467336b7420e40cd65883da5b52cb096..0bc1540af854eef4bb0a351e10258c5dbb243610 100644 --- a/packages/components-faraday/src/components/AuthorList/Author.js +++ b/packages/components-faraday/src/components/AuthorList/Author.js @@ -1,9 +1,8 @@ import React from 'react' -import classnames from 'classnames' import { Icon } from '@pubsweet/ui' +import styled from 'styled-components' import { Label } from './FormItems' -import classes from './AuthorList.local.scss' export default ({ firstName, @@ -18,67 +17,94 @@ export default ({ removeAuthor, isSubmitting, isCorresponding, - setAsCorresponding, parseAuthorType, editedAuthor, setAuthorEdit, index, }) => ( - <div - className={classnames({ - [classes.author]: true, - [classes.dashed]: isOver, - })} - > + <Root isOver={isOver}> {!isOver && dragHandle} - <div - className={classnames({ - [classes.container]: true, - [classes.hide]: isOver, - })} - > - <span className={classnames(classes.title)}> - {parseAuthorType(isSubmitting, isCorresponding, index)} - </span> - <div className={classnames(classes.row)}> + <AuthorContainer isOver={isOver}> + <Header> + <Title>{parseAuthorType(isSubmitting, isCorresponding, index)}</Title> + <ButtonContainer> + {!isSubmitting && ( + <ClickableIcon onClick={removeAuthor(email)} title="Delete author"> + <Icon size={18}>trash</Icon> + </ClickableIcon> + )} + {editedAuthor < 0 && ( + <ClickableIcon onClick={setAuthorEdit(index)} title="Edit author"> + <Icon size={18}>edit-2</Icon> + </ClickableIcon> + )} + </ButtonContainer> + </Header> + <Row> <Label label="First name" value={firstName} /> <Label label="Middle name" value={middleName} /> <Label label="Last name" value={lastName} /> - </div> - <div className={classnames(classes.row)}> + </Row> + <Row> <Label label="Email" value={email} /> <Label label="Affiliation" value={affiliation} /> <Label label="Country" value={countryParser(country)} /> - </div> - </div> - <div className={classnames(classes['button-container'])}> - {editedAuthor < 0 && ( - <div - className={classnames(classes.corresponding)} - onClick={setAuthorEdit(index)} - title="Edit author" - > - <Icon>edit-2</Icon> - </div> - )} - {!isCorresponding && ( - <div - className={classnames(classes.corresponding)} - onClick={setAsCorresponding(email)} - title="Set as corresponding author" - > - <Icon>mail</Icon> - </div> - )} - {!isSubmitting && ( - <div - className={classnames(classes['delete-button'])} - onClick={removeAuthor(email)} - title="Delete author" - > - <Icon>trash</Icon> - </div> - )} - </div> - </div> + </Row> + </AuthorContainer> + </Root> ) + +// #region styled-components +const Header = styled.div` + align-items: center; + display: flex; + flex-direction: row; + justify-content: space-between; +` + +const Title = styled.span` + font-family: Helvetica; + font-size: 14px; + font-weight: 600; +` + +const ButtonContainer = styled.div` + align-items: center; + display: flex; + flex-direction: row; + justify-content: flex-end; +` + +const ClickableIcon = styled.div` + align-items: center; + cursor: pointer; + display: flex; + flex: 1; + flex-direction: column; + justify-content: center; + margin: 0 12px; +` + +const Row = styled.div` + display: flex; + flex-direction: row; + margin: 10px 0; +` + +const AuthorContainer = styled.div` + display: flex; + flex-direction: column; + flex: 1; + padding: 10px; + opacity: ${({ isOver }) => (isOver ? 0 : 1)}; +` + +const Root = styled.div` + border: 1px solid #444; + display: flex; + flex-direction: row; + margin-bottom: 10px; + border: ${({ isOver }) => + isOver ? '1px dashed #444 !important' : '1px solid #444'}; +` +// #endregion diff --git a/packages/components-faraday/src/components/AuthorList/AuthorEditor.js b/packages/components-faraday/src/components/AuthorList/AuthorEditor.js index 72ea87fc3315b0bf4035f4603368727b68b51a1d..a229db588ca6dff1839081c6c2d0536b466a613f 100644 --- a/packages/components-faraday/src/components/AuthorList/AuthorEditor.js +++ b/packages/components-faraday/src/components/AuthorList/AuthorEditor.js @@ -1,8 +1,8 @@ import React from 'react' -import classnames from 'classnames' import { compose } from 'recompose' -import { Button } from '@pubsweet/ui' +import { Icon } from '@pubsweet/ui' import { connect } from 'react-redux' +import styled from 'styled-components' import { reduxForm } from 'redux-form' import countries from './countries' @@ -10,22 +10,55 @@ import { Spinner } from '../UIComponents' import { getAuthorFetching } from '../../redux/authors' import { ValidatedTextField, MenuItem } from './FormItems' -import classes from './AuthorList.local.scss' - const emailRegex = new RegExp(/^\w+([.-]?\w+)*@\w+([.-]?\w+)*(\.\w{2,3})+$/) const emailValidator = value => emailRegex.test(value) ? undefined : 'Invalid email' -const AuthorEdit = ({ isFetching, setAuthorEdit, handleSubmit }) => ( - <div className={classnames(classes['editor-body'])}> - <div className={classnames(classes.row)}> +const AuthorEdit = ({ + isFetching, + setAuthorEdit, + handleSubmit, + parseAuthorType, + index, + isSubmitting, + isCorresponding, + setAsCorresponding, + email, +}) => ( + <Root> + <Header> + <TitleContainer> + <span>{parseAuthorType(isSubmitting, isCorresponding, index)}</span> + <input + checked={isCorresponding} + onChange={setAsCorresponding(email)} + type="checkbox" + /> + <label>Corresponding</label> + </TitleContainer> + + <ButtonsContainer> + <ClickableIcon onClick={setAuthorEdit(-1)}> + <Icon size={18}>x-circle</Icon> + </ClickableIcon> + {!isFetching ? ( + <ClickableIcon onClick={handleSubmit}> + <Icon size={18}>check-circle</Icon> + </ClickableIcon> + ) : ( + <Spinner /> + )} + </ButtonsContainer> + </Header> + + <Row> <ValidatedTextField isRequired label="First name" name="edit.firstName" /> <ValidatedTextField label="Middle name" name="edit.middleName" /> <ValidatedTextField isRequired label="Last name" name="edit.lastName" /> - </div> + </Row> - <div className={classnames(classes.row)}> + <Row> <ValidatedTextField isRequired label="Email" @@ -38,19 +71,8 @@ const AuthorEdit = ({ isFetching, setAuthorEdit, handleSubmit }) => ( name="edit.affiliation" /> <MenuItem label="Country" name="edit.country" options={countries} /> - </div> - - <div className={classnames(classes['form-buttons'])}> - <Button onClick={setAuthorEdit(-1)}>Cancel</Button> - {!isFetching ? ( - <Button onClick={handleSubmit} primary> - Save - </Button> - ) : ( - <Spinner /> - )} - </div> - </div> + </Row> + </Root> ) export default compose( @@ -74,3 +96,63 @@ export default compose( }, }), )(AuthorEdit) + +// #region styled-components +const Row = styled.div` + display: flex; + flex-direction: row; + margin: 10px 0; +` + +const TitleContainer = styled.div` + align-items: center; + display: flex; + flex-direction: row; + + > span { + font-family: Helvetica; + font-size: 14px; + font-weight: 600; + margin-right: 20px; + text-align: left; + } + + label { + font-family: Helvetica; + font-size: 12px; + text-align: left; + } +` + +const ButtonsContainer = styled.div` + align-items: center; + display: flex; + flex-direction: row; + justify-content: flex-end; +` + +const ClickableIcon = styled.div` + align-items: center; + cursor: pointer; + display: flex; + flex: 1; + flex-direction: column; + justify-content: center; + margin: 0 12px; +` + +const Header = styled.div` + align-items: center; + display: flex; + flex-direction: row; + justify-content: space-between; +` + +const Root = styled.div` + border: 1px solid #444; + margin: 10px 0; + padding: 10px; + display: flex; + flex-direction: column; +` +// #endregion diff --git a/packages/components-faraday/src/components/AuthorList/AuthorList.js b/packages/components-faraday/src/components/AuthorList/AuthorList.js index 60c8b41a5678b6d464694986149cdf62ed2bb791..cb70a7af07386608e5d61b0a53c68fdfd2e3fea2 100644 --- a/packages/components-faraday/src/components/AuthorList/AuthorList.js +++ b/packages/components-faraday/src/components/AuthorList/AuthorList.js @@ -1,7 +1,8 @@ import React from 'react' +import { get } from 'lodash' import PropTypes from 'prop-types' import { connect } from 'react-redux' -import { get } from 'lodash' +import styled from 'styled-components' import { withRouter } from 'react-router-dom' import { compose, @@ -36,7 +37,7 @@ const Authors = ({ setFormAuthors, ...rest }) => ( - <div> + <Root> <AuthorAdder addAuthor={addAuthor} authors={authors} @@ -66,7 +67,7 @@ const Authors = ({ {...rest} /> )} - </div> + </Root> ) export default compose( @@ -137,3 +138,10 @@ export default compose( }, }), )(Authors) + +// #region styled-components +const Root = styled.div` + border: 1px solid #667080; + padding: 0 10px; +` +// #endregion diff --git a/packages/components-faraday/src/components/AuthorList/FormItems.js b/packages/components-faraday/src/components/AuthorList/FormItems.js index 96b8a93c4cb4ff0f6b68e0e6ddc19df02d26500b..183fcebcf18d6532ee00a0096fd98de30aee3bec 100644 --- a/packages/components-faraday/src/components/AuthorList/FormItems.js +++ b/packages/components-faraday/src/components/AuthorList/FormItems.js @@ -1,5 +1,6 @@ import React from 'react' import classnames from 'classnames' +import styled from 'styled-components' import { required } from 'xpub-validators' import { TextField, Menu, ValidatedField, Icon } from '@pubsweet/ui' @@ -32,10 +33,10 @@ export const MenuItem = ({ label, name, options }) => ( ) export const Label = ({ label, value }) => ( - <div className={classnames(classes['label-container'])}> - <span className={classnames(classes.label)}>{label}</span> - <span className={classnames(classes.value)}>{value}</span> - </div> + <LabelContainer> + <span>{label}</span> + <span>{value}</span> + </LabelContainer> ) export const DragHandle = () => ( @@ -45,3 +46,29 @@ export const DragHandle = () => ( <Icon>chevron_down</Icon> </div> ) + +// #region styled-components +const LabelContainer = styled.div` + display: flex; + flex-direction: column; + margin: 5px; + width: ${({ width }) => `${width || 225}px`}; + + span:first-child { + font-size: 14px; + font-weight: 300; + overflow: hidden; + text-transform: uppercase; + text-overflow: ellipsis; + white-space: nowrap; + } + + span:last-child { + font-size: 16px; + font-weight: 600; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + } +` +// #endregion diff --git a/packages/components-faraday/src/components/AuthorList/StaticList.js b/packages/components-faraday/src/components/AuthorList/StaticList.js index 7fe49d1efc1aaf9be939954d8a86ea62b1027430..b8b45d89a865d9630f649127414076bb66c8284d 100644 --- a/packages/components-faraday/src/components/AuthorList/StaticList.js +++ b/packages/components-faraday/src/components/AuthorList/StaticList.js @@ -11,6 +11,7 @@ export default ({ editComponent, setAuthorEdit, parseAuthorType, + setAsCorresponding, ...rest }) => ( <div> @@ -28,6 +29,8 @@ export default ({ setAuthorEdit, countryParser, parseAuthorType, + setAsCorresponding, + ...author, }) ) : ( <Author @@ -37,6 +40,7 @@ export default ({ index={index} parseAuthorType={parseAuthorType} removeAuthor={removeAuthor} + setAsCorresponding={setAsCorresponding} {...rest} /> ),