diff --git a/packages/component-faraday-ui/src/AppBarMenu.js b/packages/component-faraday-ui/src/AppBarMenu.js index 7ab755a7b02041442ae354e5e3f0cb260daf2dfa..dc418f6d7c884928c60c0a6641e5945127bd0ab0 100644 --- a/packages/component-faraday-ui/src/AppBarMenu.js +++ b/packages/component-faraday-ui/src/AppBarMenu.js @@ -11,7 +11,7 @@ import { withStateHandlers, } from 'recompose' -import Text from './Text' +import { Text } from './' const AppBarMenu = ({ goTo, diff --git a/packages/component-faraday-ui/src/AuthorCard.js b/packages/component-faraday-ui/src/AuthorCard.js index 8f627001d6beef0cfc09ad8d80b0bc2a57362d25..985084779395eb627c34d92c1b2270a02b692aee 100644 --- a/packages/component-faraday-ui/src/AuthorCard.js +++ b/packages/component-faraday-ui/src/AuthorCard.js @@ -1,9 +1,9 @@ import React, { Fragment } from 'react' import { isNumber } from 'lodash' import styled from 'styled-components' -import { reduxForm, Field } from 'redux-form' import { th } from '@pubsweet/ui-toolkit' import { required } from 'xpub-validators' +import { reduxForm, Field } from 'redux-form' import { H3, ValidatedField, TextField, Checkbox } from '@pubsweet/ui' import { compose, diff --git a/packages/component-faraday-ui/src/ManuscriptCard.js b/packages/component-faraday-ui/src/ManuscriptCard.js index 4fbaf55e081576ed335a99d45fe22e0627f81242..9f77bdce73bd1b74f7497f6442df8d1964cbabfb 100644 --- a/packages/component-faraday-ui/src/ManuscriptCard.js +++ b/packages/component-faraday-ui/src/ManuscriptCard.js @@ -1,9 +1,10 @@ import React from 'react' import { get } from 'lodash' -import { H3, H4, DateParser } from '@pubsweet/ui' +import { H3, H4 } from '@pubsweet/ui' import styled from 'styled-components' import { th } from '@pubsweet/ui-toolkit' import { withJournal } from 'xpub-journal' +import { DateParser } from 'pubsweet-components-faraday/src/components' import { compose, withHandlers, setDisplayName, withProps } from 'recompose' import { @@ -27,7 +28,12 @@ const ManuscriptCard = ({ manuscriptType = {}, collection: { visibleStatus = 'Draft', handlingEditor, customId }, }) => { - const { authors = [], id: fragmentId, metadata = {} } = fragment + const { + authors = [], + id: fragmentId, + metadata = {}, + submitted = null, + } = fragment const { title = 'No title', journal = '', type = '' } = metadata return ( <Root data-test-id={`fragment-${fragmentId}`} onClick={onCardClick}> @@ -45,16 +51,15 @@ const ManuscriptCard = ({ )} <Row alignItems="center" justify="flex-start" mb={1}> <Text customId mr={1}>{`ID ${customId}`}</Text> - <DateParser - durationThreshold={0} - timestamp={fragment.submitted || ''} - > - {timestamp => ( - <Text mr={3} secondary> - Submitted on {timestamp} - </Text> - )} - </DateParser> + {submitted && ( + <DateParser durationThreshold={0} timestamp={submitted}> + {timestamp => ( + <Text mr={3} secondary> + Submitted on {timestamp} + </Text> + )} + </DateParser> + )} <H4>{manuscriptType.label || type}</H4> <Text ml={1} secondary> {journal} diff --git a/packages/component-faraday-ui/src/ReviewerBreakdown.js b/packages/component-faraday-ui/src/ReviewerBreakdown.js index 5c0d5a9e52864acd01cf5f48c01e50cfd96fbd6c..a1e37f53fe81ab0ef330155d7d4941c4af324cb8 100644 --- a/packages/component-faraday-ui/src/ReviewerBreakdown.js +++ b/packages/component-faraday-ui/src/ReviewerBreakdown.js @@ -20,6 +20,7 @@ const reviewerReduce = (acc, r) => ({ submitted: submittedFilter(r) ? acc.submitted + 1 : acc.submitted, }) +/** @component */ export default compose( withProps(({ fragment }) => ({ invitations: get(fragment, 'invitations', []), diff --git a/packages/component-manuscript/src/components/ReviewerReportForm.js b/packages/component-manuscript/src/components/ReviewerReportForm.js index ab0e9a496e9c747512eb4431cbd3e1f6e07cf3c8..3dcbcc4fc1419e3bd92fc8574c4178edba54ba25 100644 --- a/packages/component-manuscript/src/components/ReviewerReportForm.js +++ b/packages/component-manuscript/src/components/ReviewerReportForm.js @@ -1,26 +1,18 @@ import React, { Fragment } from 'react' import { connect } from 'react-redux' import { isEmpty, merge } from 'lodash' +import { th } from '@pubsweet/ui-toolkit' import { withJournal } from 'xpub-journal' import { required } from 'xpub-validators' import styled, { css } from 'styled-components' -import { - Menu, - Icon, - Button, - Spinner, - ErrorText, - ValidatedField, -} from '@pubsweet/ui' -import { th } from '@pubsweet/ui-toolkit' import { compose, withHandlers, withProps } from 'recompose' +import { Menu, Icon, Button, ErrorText, ValidatedField } from '@pubsweet/ui' import { reduxForm, isSubmitting, getFormValues, change as changeForm, } from 'redux-form' -import AutosaveIndicator from 'pubsweet-component-wizard/src/components/AutosaveIndicator' import { uploadFile, @@ -28,10 +20,6 @@ import { getSignedUrl, getRequestStatus, } from 'pubsweet-components-faraday/src/redux/files' -import { - FileItem, - FilePicker, -} from 'pubsweet-components-faraday/src/components/Files' import { withModal, @@ -88,24 +76,9 @@ const ReviewerReportForm = ({ validate={[required]} /> </Row> + <Spacing /> - <Row left> - <Label>Report</Label> - {!fileFetching.review ? ( - <Fragment> - {isEmpty(formValues.files) && ( - <FilePicker - allowedFileExtensions={['pdf', 'doc', 'docx']} - onUpload={addFile} - > - <ActionText left={12}>Upload file</ActionText> - </FilePicker> - )} - </Fragment> - ) : ( - <Spinner size={2} /> - )} - </Row> + <Row> <FullWidth className="full-width"> <ValidatedField @@ -115,21 +88,7 @@ const ReviewerReportForm = ({ /> </FullWidth> </Row> - {formValues.files && ( - <Fragment> - <Row left> - {formValues.files.map(file => ( - <FileItem - compact - id={file.id} - key={file.id} - {...file} - removeFile={removeFile} - /> - ))} - </Row> - </Fragment> - )} + {formValues.hasConfidential ? ( <Fragment> <Spacing /> @@ -170,10 +129,6 @@ const ReviewerReportForm = ({ )} <Row> <ActionButton onClick={handleSubmit}>Submit report</ActionButton> - <AutosaveIndicator - formName="reviewerReport" - lastUpdated={review.updatedOn} - /> </Row> </Root> ) diff --git a/packages/component-manuscript/src/components/SubmitRevision.js b/packages/component-manuscript/src/components/SubmitRevision.js index afaf7697ebebc111d39a773e01ccf69e594c5e48..0fa81380877fdf5ff9c2be286c62971c01139fe8 100644 --- a/packages/component-manuscript/src/components/SubmitRevision.js +++ b/packages/component-manuscript/src/components/SubmitRevision.js @@ -23,7 +23,6 @@ import { } from 'pubsweet-component-modal/src/components' import { AuthorList, Files } from 'pubsweet-components-faraday/src/components' import { submitRevision } from 'pubsweet-component-wizard/src/redux/conversion' -import AutosaveIndicator from 'pubsweet-component-wizard/src/components/AutosaveIndicator' import { selectReviewRecommendations } from 'pubsweet-components-faraday/src/redux/recommendations' import { toClass, @@ -32,10 +31,6 @@ import { withContext, withHandlers, } from 'recompose' -import { - FileItem, - FilePicker, -} from 'pubsweet-components-faraday/src/components/Files' import { uploadFile, deleteFile, @@ -126,29 +121,11 @@ const SubmitRevision = ({ /> </FullWidth> </Row> - <Row left> - {responseFiles.map(file => ( - <FileItem - compact - id={file.id} - key={file.id} - {...file} - removeFile={removeFile} - /> - ))} - </Row> - <FilePicker - allowedFileExtensions={['pdf', 'doc', 'docx']} - onUpload={addFile} - > - <ActionText left={12}>Upload file</ActionText> - </FilePicker> </Expandable> )} <SubmitContainer> {submitFailed && formError && <Error>There are some errors above.</Error>} - <AutosaveIndicator formName="revision" /> <Button onClick={handleSubmit} primary> SUBMIT REVISION </Button> @@ -295,13 +272,6 @@ const Row = styled.div` } ` -const ActionText = styled.span` - ${defaultText}; - cursor: pointer; - margin-left: ${({ left }) => left || 0}px; - text-decoration: underline; -` - const Root = styled.div` background-color: ${th('colorBackground')}; ` diff --git a/packages/component-wizard/src/components/AutosaveIndicator.js b/packages/component-wizard/src/components/AutosaveIndicator.js deleted file mode 100644 index 8f3f0949be7843dc7187eb35ec481998405cd0c3..0000000000000000000000000000000000000000 --- a/packages/component-wizard/src/components/AutosaveIndicator.js +++ /dev/null @@ -1,96 +0,0 @@ -import React from 'react' -import moment from 'moment' -import { connect } from 'react-redux' -import { Icon } from '@pubsweet/ui' -import { getFormValues } from 'redux-form' -import { compose, withProps } from 'recompose' -import styled, { withTheme } from 'styled-components' -import Spinner from 'pubsweet-components-faraday/src/components/UIComponents/Spinner' - -import { getAutosave } from '../redux/autosave' - -const durationParser = lastUpdate => { - const today = moment() - const last = moment(lastUpdate) - const duration = moment.duration(today.diff(last)) - return `Progress saved ${duration.humanize()} ago.` -} - -const Indicator = ({ - isVisibile, - progressText = 'Saving changes...', - errorText = 'Changes not saved', - successText, - autosave: { isFetching, error, lastUpdate }, - theme, - lastUpdated, -}) => - isVisibile ? ( - <Root className="autosave-indicator"> - {isFetching && ( - <AutoSaveContainer> - <Spinner icon="loader" size={3} /> - <Info>{progressText}</Info> - </AutoSaveContainer> - )} - - {!isFetching && - lastUpdate && ( - <AutoSaveContainer> - <IconContainer> - <Icon size={3}>check-circle</Icon> - </IconContainer> - <Info>{successText || durationParser(lastUpdate)}</Info> - </AutoSaveContainer> - )} - {!isFetching && - error && ( - <AutoSaveContainer> - <IconContainer> - <Icon color={theme.colorError} size={3}> - alert-triangle - </Icon> - </IconContainer> - <Info error={theme.colorError} title={error}> - {errorText} - </Info> - </AutoSaveContainer> - )} - </Root> - ) : ( - <div>{lastUpdated ? durationParser(lastUpdated) : ''}</div> - ) - -export default compose( - connect((state, { formName = 'wizard' }) => ({ - autosave: getAutosave(state), - form: !!getFormValues(formName)(state), - })), - withProps(({ autosave: { isFetching, error, lastUpdate }, form }) => ({ - isVisibile: form && Boolean(isFetching || lastUpdate || error), - })), - withTheme, -)(Indicator) - -// #region styles -const Root = styled.div` - align-items: center; - display: flex; - justify-content: flex-end; -` -const AutoSaveContainer = styled.div` - align-items: center; - display: flex; - padding: 5px; -` -const IconContainer = styled.div` - align-items: center; - display: flex; - justify-content: center; -` -const Info = styled.span` - font-size: 12px; - margin-left: 5px; - color: ${({ error }) => error || ''}; -` -// #endregion diff --git a/packages/component-wizard/src/components/AutosaveIndicator.md b/packages/component-wizard/src/components/AutosaveIndicator.md deleted file mode 100644 index d83ba4fbda481d696db7e5c3ca2a0f6efe632f77..0000000000000000000000000000000000000000 --- a/packages/component-wizard/src/components/AutosaveIndicator.md +++ /dev/null @@ -1,22 +0,0 @@ -# AutoSave indicator - -Display the status of the form (Saving in progress, Saved or Error while saving) - -## Props - -| Prop | Description | Required | Default | Type | -| :---: | :--------------------------------------------------------------------------: | :------: | :------: | :----: | -| formName | Redux Form name | false | 'wizard' | string | -| progressText | Text to show while API returns | false | 'Saving changes... ' | string | -| errorText | Text to show on error | false | 'Changes not saved ' | string | -| successText | Text to show on success | false | 'Progress saved ${duration.humanize()} ago.' | string | -| lastUpdated | Show last updated timestamp from the beginning | false | 'Progress saved ${duration.humanize()} ago.' | date | -## Examples - -```js -<AutosaveIndicator /> -``` - -```js -<AutosaveIndicator formName="authors" progressText='Saving...' successText='Saved' errorText='Something went wrong!' /> -``` \ No newline at end of file diff --git a/packages/component-wizard/src/components/SubmissionWizard.js b/packages/component-wizard/src/components/SubmissionWizard.js index 5431e9fb6293a7e894cdcf86b8345844fac374cd..fa83662dc92e5328269e49d7f21c73a79c553bf7 100644 --- a/packages/component-wizard/src/components/SubmissionWizard.js +++ b/packages/component-wizard/src/components/SubmissionWizard.js @@ -36,13 +36,8 @@ import { } from 'pubsweet-components-faraday/src/redux/files' import { wizardSteps } from './' -import { - autosaveRequest, - autosaveSuccess, - autosaveFailure, - getAutosaveFetching, -} from '../redux/autosave' import { submitManuscript } from '../redux/conversion' +import { getAutosaveFetching } from '../redux/autosave' import { onChange, onSubmit, setInitialValues, validate } from './utils' // #region wizard @@ -115,15 +110,12 @@ export default compose( uploadFile, deleteFile, getSignedUrl, - autosaveRequest, - autosaveSuccess, - autosaveFailure, submitManuscript, updateFragment: actions.updateFragment, }, ), withStateHandlers( - { step: 2 }, + { step: 1 }, { nextStep: ({ step }) => () => ({ step: Math.min(wizardSteps.length - 1, step + 1), diff --git a/packages/component-wizard/src/components/utils.js b/packages/component-wizard/src/components/utils.js index 9c35ccd5057b2e25d5fc8f552e0dd213a7db1559..b5ddee1d0c7a024233fbe86af5cea134d328f8be 100644 --- a/packages/component-wizard/src/components/utils.js +++ b/packages/component-wizard/src/components/utils.js @@ -8,6 +8,11 @@ import { debounce, isBoolean, } from 'lodash' +import { + autosaveRequest, + autosaveSuccess, + autosaveFailure, +} from '../redux/autosave' import { SubmissionStatement } from './' export const setInitialValues = ({ version }) => ({ @@ -50,11 +55,7 @@ export const validate = (values, props) => { return errors } -const _onChange = ( - values, - dispatch, - { project, version, autosaveRequest, updateFragment }, -) => { +const _onChange = (values, dispatch, { project, version, updateFragment }) => { const previousValues = pick(version, [ 'files', 'authors', @@ -64,11 +65,14 @@ const _onChange = ( ]) const newValues = omit(values, ['agree', 'authorForm']) if (!isEqual(newValues, previousValues)) { - autosaveRequest() + dispatch(autosaveRequest()) updateFragment(project, { ...version, ...newValues, - }) + }).then( + () => dispatch(autosaveSuccess()), + () => dispatch(autosaveFailure()), + ) } } diff --git a/packages/component-wizard/src/redux/autosave.js b/packages/component-wizard/src/redux/autosave.js index 74a88b092075b11f661fe5b099b94521e8835b2c..7372e112409b4a1b23468c24ed76432a62ac24b7 100644 --- a/packages/component-wizard/src/redux/autosave.js +++ b/packages/component-wizard/src/redux/autosave.js @@ -36,13 +36,11 @@ export default (state = initialState, action) => { isFetching: true, } case AUTOSAVE_FAILURE: - case 'UPDATE_FRAGMENT_FAILURE': return { ...initialState, error: action.error, } case AUTOSAVE_SUCCESS: - case 'UPDATE_FRAGMENT_SUCCESS': return { ...initialState, lastUpdate: action.receivedAt || action.lastUpdate, diff --git a/packages/components-faraday/src/components/AppBar/AppBar.js b/packages/components-faraday/src/components/AppBar/AppBar.js deleted file mode 100644 index 0edd233bd500f5eb986cd30d64c7bd313851a45f..0000000000000000000000000000000000000000 --- a/packages/components-faraday/src/components/AppBar/AppBar.js +++ /dev/null @@ -1,174 +0,0 @@ -import React from 'react' -import { get } from 'lodash' -import { Icon } from '@pubsweet/ui' -import { connect } from 'react-redux' -import styled from 'styled-components' -import { th } from '@pubsweet/ui-toolkit' -import { withRouter } from 'react-router-dom' -import { withState, withHandlers, compose } from 'recompose' - -import { userNotConfirmed } from 'pubsweet-component-faraday-selectors' - -const AppBar = ({ - goTo, - user, - brand, - expanded, - toggleMenu, - currentUser, - onLogoutClick, - shouldShowConfirmation, -}) => ( - <Root className="appbar"> - <Row bordered className="row"> - <Brand> - {React.cloneElement(brand, { - onClick: goTo('/'), - })} - </Brand> - {user && ( - <User> - <div onClick={toggleMenu}> - <Icon secondary>user</Icon> - <span> - {get(user, 'firstName') || get(user, 'username') || 'User'} - </span> - <Icon secondary>chevron-down</Icon> - </div> - {expanded && ( - <Dropdown> - <DropdownOption onClick={goTo('/profile')}> - My profile - </DropdownOption> - {currentUser.admin && ( - <DropdownOption onClick={goTo('/admin')}> - Admin dashboard - </DropdownOption> - )} - <DropdownOption onClick={onLogoutClick}>Logout</DropdownOption> - </Dropdown> - )} - </User> - )} - </Row> - {shouldShowConfirmation && ( - <Row bgColor="salmon" centered className="row"> - <ConfirmationText> - Your author account is not confirmed. Check your email. - </ConfirmationText> - </Row> - )} - {expanded && <ToggleOverlay onClick={toggleMenu} />} - </Root> -) - -export default compose( - withRouter, - connect(state => ({ - currentUser: get(state, 'currentUser.user'), - shouldShowConfirmation: userNotConfirmed(state), - })), - withState('expanded', 'setExpanded', false), - withHandlers({ - toggleMenu: ({ setExpanded }) => () => { - setExpanded(v => !v) - }, - goTo: ({ setExpanded, history }) => path => () => { - setExpanded(v => false) - history.push(path) - }, - }), -)(AppBar) - -// #region styled-components -const Root = styled.div` - align-items: center; - background-color: #ffffff; - font-family: ${th('fontInterface')}; - display: flex; - flex-direction: column; - flex-grow: 1; - - position: fixed; - top: 0; - right: 0; - left: 0; - z-index: 10; -` - -const Row = styled.div` - align-items: center; - align-self: stretch; - background-color: ${({ bgColor }) => bgColor || 'transparent'}; - box-shadow: ${({ bordered }) => (bordered ? th('dropShadow') : 'none')}; - display: flex; - justify-content: ${({ centered }) => - centered ? 'center' : 'space-between;'}; -` - -const ConfirmationText = styled.span` - font-size: ${th('fontSizeBaseSmall')}; -` -const Brand = styled.div` - padding: 10px 20px; - cursor: pointer; -` - -const User = styled.div` - align-items: center; - display: flex; - justify-content: space-between; - height: 60px; - position: relative; - padding: 10px 20px; - - > div:first-child { - align-items: center; - cursor: pointer; - display: flex; - } - - & span { - color: ${th('colorText')}; - font-family: ${th('fontHeading')}; - font-size: ${th('fontSizeBase')}; - margin-left: 10px; - } -` - -const Dropdown = styled.div` - background-color: ${th('colorBackground')}; - position: absolute; - right: 20px; - top: 60px; - width: calc(${th('gridUnit')} * 8); - z-index: 10; - border: ${th('borderWidth')} ${th('borderStyle')} ${th('colorBorder')}; -` - -const DropdownOption = styled.div` - align-items: center; - color: ${th('colorText')}; - cursor: pointer; - display: flex; - justify-content: flex-start; - height: calc(${th('gridUnit')} * 2); - font-family: ${th('fontInterface')}; - font-size: ${th('fontSizeBase')}; - line-height: ${th('fontLineHeight')}; - padding: 0 15px; - - &:hover { - background-color: ${th('backgroundColor')}; - } -` - -const ToggleOverlay = styled.div` - position: fixed; - top: 0; - bottom: 0; - left: 0; - right: 0; - opacity: 0; -` -// #endregion diff --git a/packages/components-faraday/src/components/AuthorList/Author.js b/packages/components-faraday/src/components/AuthorList/Author.js deleted file mode 100644 index b05e2040e73f7c05bd6cdfc8b5e9391c2dc39548..0000000000000000000000000000000000000000 --- a/packages/components-faraday/src/components/AuthorList/Author.js +++ /dev/null @@ -1,115 +0,0 @@ -import React from 'react' -import { Icon } from '@pubsweet/ui' -import styled from 'styled-components' -import { th } from '@pubsweet/ui-toolkit' - -import { Label } from './FormItems' - -export default ({ - id, - email, - index, - isOver, - lastName, - firstName, - dragHandle, - affiliation, - removeAuthor, - isSubmitting, - editedAuthor, - setAuthorEdit, - isCorresponding, - parseAuthorType, - ...rest -}) => ( - <Root isOver={isOver}> - {!isOver && dragHandle} - <AuthorContainer isOver={isOver}> - <Header> - <Title>{parseAuthorType(isSubmitting, isCorresponding, index)}</Title> - <ButtonContainer> - {!isSubmitting && ( - <ClickableIcon - data-test={`delete-author-${id}`} - onClick={removeAuthor(id)} - title="Delete author" - > - <Icon size={3}>trash</Icon> - </ClickableIcon> - )} - {editedAuthor < 0 && ( - <ClickableIcon - data-test={`edit-author-${id}`} - onClick={setAuthorEdit(index)} - title="Edit author" - > - <Icon size={3}>edit-2</Icon> - </ClickableIcon> - )} - </ButtonContainer> - </Header> - <Row> - <Label label="First name" value={firstName} /> - <Label label="Last name" value={lastName} /> - </Row> - <Row> - <Label label="Email" value={email} /> - <Label label="Affiliation" value={affiliation} /> - </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: ${th('fontHeading')}; - font-size: ${th('fontSizeBaseSmall')}; - 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` - display: flex; - flex-direction: row; - margin-bottom: 10px; - border: ${({ isOver, theme }) => - isOver ? '1px dashed #444 !important' : theme.borderDefault}; -` -// #endregion diff --git a/packages/components-faraday/src/components/AuthorList/AuthorAdder.js b/packages/components-faraday/src/components/AuthorList/AuthorAdder.js deleted file mode 100644 index 4d0282274de8e79809e3679cecbd013f0d278c09..0000000000000000000000000000000000000000 --- a/packages/components-faraday/src/components/AuthorList/AuthorAdder.js +++ /dev/null @@ -1,168 +0,0 @@ -import React from 'react' -import { get } from 'lodash' -import { Button } from '@pubsweet/ui' -import { connect } from 'react-redux' -import styled from 'styled-components' -import { th } from '@pubsweet/ui-toolkit' -import { selectCurrentUser } from 'xpub-selectors' -import { reduxForm, change as changeForm } from 'redux-form' -import { compose, withProps, setDisplayName } from 'recompose' - -import { emailValidator } from '../utils' -import { Spinner } from '../UIComponents/' -import { - authorSuccess, - authorFailure, - getAuthorFetching, -} from '../../redux/authors' -import { ValidatedTextField } from './FormItems' - -const AuthorAdder = ({ - editMode, - isFetching, - setEditMode, - authors = [], - handleSubmit, -}) => ( - <Root> - <Button data-test="button-add-author" onClick={setEditMode(true)} primary> - {authors.length === 0 ? '+ Add submitting author' : '+ Add author'} - </Button> - {editMode && ( - <FormBody> - <Title>{authors.length === 0 ? 'Submitting author' : 'Author'}</Title> - <Row> - <ValidatedTextField isRequired label="First name*" name="firstName" /> - <ValidatedTextField isRequired label="Last name*" name="lastName" /> - </Row> - - <Row> - <ValidatedTextField - isRequired - label="Email*" - name="email" - validators={[emailValidator]} - /> - <ValidatedTextField - isRequired - label="Affiliation*" - name="affiliation" - /> - </Row> - <ButtonsContainer> - <Button data-test="button-cancel-author" onClick={setEditMode(false)}> - Cancel - </Button> - {!isFetching ? ( - <Button - data-test="button-save-author" - onClick={handleSubmit} - primary - > - Save - </Button> - ) : ( - <Spinner size={3} /> - )} - </ButtonsContainer> - </FormBody> - )} - </Root> -) - -export default compose( - connect( - state => ({ - isFetching: getAuthorFetching(state), - currentUser: selectCurrentUser(state), - }), - { - changeForm, - authorSuccess, - authorFailure, - }, - ), - withProps( - ({ - currentUser: { admin, affiliation, firstName, lastName, email }, - authors, - }) => { - if (!admin && authors.length === 0) { - return { - initialValues: { - email, - lastName, - firstName, - affiliation, - }, - } - } - }, - ), - reduxForm({ - form: 'author', - enableReinitialize: true, - destroyOnUnmount: false, - onSubmit: ( - values, - dispatch, - { - reset, - match, - changeForm, - addAuthor, - setEditMode, - authors = [], - parentForm, - }, - ) => { - const collectionId = get(match, 'params.project') - const fragmentId = get(match, 'params.version') - const isFirstAuthor = authors.length === 0 - const newAuthor = { - ...values, - isSubmitting: isFirstAuthor, - isCorresponding: isFirstAuthor, - } - addAuthor(newAuthor, collectionId, fragmentId).then(author => { - changeForm(parentForm, 'authors', [...authors, author]) - setEditMode(false)() - reset() - }) - }, - }), - setDisplayName('AuthorAdder'), -)(AuthorAdder) - -// #region styled-components -const ButtonsContainer = styled.div` - display: flex; - justify-content: space-around; - margin: calc(${th('subGridUnit')} * 2) 0 0 0; -` - -const Row = styled.div` - display: flex; - flex-direction: row; - margin: ${th('subGridUnit')} 0; -` - -const Title = styled.span` - font-size: ${th('fontSizeBase')}; - font-weight: 500; - margin: ${th('subGridUnit')} 0; - text-transform: uppercase; -` - -const FormBody = styled.div` - border: ${th('borderDefault')}; - margin-top: ${th('subGridUnit')}; - padding: ${th('subGridUnit')}; -` - -const Root = styled.div` - display: flex; - flex-direction: column; - margin: ${th('subGridUnit')} 0; -` -// #endregion diff --git a/packages/components-faraday/src/components/AuthorList/AuthorEditor.js b/packages/components-faraday/src/components/AuthorList/AuthorEditor.js deleted file mode 100644 index 7ec4fb86523b67164805ac3cc095fa96729f8f1f..0000000000000000000000000000000000000000 --- a/packages/components-faraday/src/components/AuthorList/AuthorEditor.js +++ /dev/null @@ -1,193 +0,0 @@ -import React, { Fragment } from 'react' -import { pick } from 'lodash' -import { connect } from 'react-redux' -import { th } from '@pubsweet/ui-toolkit' -import { required } from 'xpub-validators' -import { compose, withProps } from 'recompose' -import styled, { css } from 'styled-components' -import { Icon, Checkbox, ValidatedField } from '@pubsweet/ui' -import { reduxForm, Field, change as changeForm } from 'redux-form' -import { FormItems } from 'pubsweet-components-faraday/src/components' - -import { Spinner } from '../UIComponents' - -import { - authorSuccess, - authorFailure, - getAuthorFetching, -} from '../../redux/authors' - -import { authorKeys, parseEditedAuthors } from './utils' - -const { Row, Label, RowItem, TextField, DefaultText } = FormItems - -const renderCheckbox = ({ input }) => ( - <Checkbox checked={input.value} type="checkbox" {...input} /> -) - -const AuthorEdit = ({ - id, - index, - email, - isFetching, - handleSubmit, - isSubmitting, - setAuthorEdit, - parseAuthorType, - isCorresponding, -}) => ( - <Root> - <Header> - <TitleContainer> - <span>{parseAuthorType(isSubmitting, isCorresponding, index)}</span> - {!isSubmitting && ( - <Fragment> - <Field component={renderCheckbox} name="edit.isCorresponding" /> - <label>Corresponding</label> - </Fragment> - )} - </TitleContainer> - - <ButtonsContainer> - <ClickableIcon - data-test="author-edit-close" - onClick={setAuthorEdit(-1)} - > - <Icon size={3}>x-circle</Icon> - </ClickableIcon> - {!isFetching ? ( - <ClickableIcon data-test="author-edit-save" onClick={handleSubmit}> - <Icon size={3}>check-circle</Icon> - </ClickableIcon> - ) : ( - <Spinner size={3} /> - )} - </ButtonsContainer> - </Header> - - <Row> - <RowItem data-test="edit-author-firstname" vertical withRightMargin> - <Label>First name*</Label> - <ValidatedField - component={TextField} - name="edit.firstName" - validate={[required]} - /> - </RowItem> - <RowItem data-test="edit-author-lastname" vertical> - <Label>Last name*</Label> - <ValidatedField - component={TextField} - name="edit.lastName" - validate={[required]} - /> - </RowItem> - </Row> - - <Row> - <RowItem vertical withRightMargin> - <Label>Email</Label> - <DefaultText>{email}</DefaultText> - </RowItem> - <RowItem data-test="edit-author-affiliation" vertical> - <Label>Affiliation*</Label> - <ValidatedField - component={TextField} - name="edit.affiliation" - validate={[required]} - /> - </RowItem> - </Row> - </Root> -) - -export default compose( - connect( - state => ({ - isFetching: getAuthorFetching(state), - }), - { changeForm, authorSuccess, authorFailure }, - ), - withProps(props => ({ - initialValues: { - edit: pick(props, authorKeys), - }, - })), - reduxForm({ - form: 'edit', - onSubmit: ( - { edit: newAuthor }, - dispatch, - { authors, changeForm, setAuthorEdit, parentForm }, - ) => { - const newAuthors = parseEditedAuthors(newAuthor, authors) - changeForm(parentForm, 'authors', newAuthors) - setAuthorEdit(-1)() - }, - }), -)(AuthorEdit) - -// #region styled-components -const defaultText = css` - color: ${th('colorText')}; - font-size: ${th('fontSizeBaseSmall')}; - font-family: ${th('fontReading')}; -` - -// const Row = styled.div` -// display: flex; -// flex-direction: row; -// margin: ${th('subGridUnit')} 0; -// ` - -const TitleContainer = styled.div` - align-items: center; - display: flex; - flex-direction: row; - - > span { - ${defaultText}; - font-size: ${th('fontSizeHeading6')}; - margin-right: ${th('subGridUnit')}; - font-weight: 600; - text-align: left; - } - - label { - ${defaultText}; - 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 calc(${th('subGridUnit')} * 2); -` - -const Header = styled.div` - align-items: center; - display: flex; - flex-direction: row; - justify-content: space-between; -` - -const Root = styled.div` - border: ${th('borderDefault')}; - display: flex; - flex-direction: column; - margin: ${th('subGridUnit')} 0; - padding: ${th('subGridUnit')}; -` -// #endregion diff --git a/packages/components-faraday/src/components/AuthorList/AuthorList.js b/packages/components-faraday/src/components/AuthorList/AuthorList.js deleted file mode 100644 index b822775bf42e2a47ef65868e744061538f927e11..0000000000000000000000000000000000000000 --- a/packages/components-faraday/src/components/AuthorList/AuthorList.js +++ /dev/null @@ -1,156 +0,0 @@ -import React from 'react' -import { get, isBoolean, isNumber } from 'lodash' -import { connect } from 'react-redux' -import styled from 'styled-components' -import { th } from '@pubsweet/ui-toolkit' -import { withRouter } from 'react-router-dom' -import { selectCurrentVersion } from 'xpub-selectors' -import { - compose, - withState, - withProps, - withHandlers, - setDisplayName, -} from 'recompose' -import { change as changeForm, formValueSelector } from 'redux-form' -import { SortableList } from 'pubsweet-component-sortable-list/src/components' - -import { - addAuthor, - deleteAuthor, - authorFailure, - getAuthorError, -} from '../../redux/authors' - -import { DragHandle } from './FormItems' -import { Author, StaticList, AuthorAdder, AuthorEditor } from './' - -const Authors = ({ - match, - error, - authors, - version, - addMode, - editMode, - dropItem, - addAuthor, - moveAuthor, - editAuthor, - setEditMode, - editedAuthor, - setFormAuthors, - parentForm = 'wizard', - ...rest -}) => ( - <Root> - <AuthorAdder - addAuthor={addAuthor} - authors={authors} - editAuthor={editAuthor} - editMode={addMode} - match={match} - parentForm={parentForm} - setEditMode={setEditMode} - setFormAuthors={setFormAuthors} - /> - {isNumber(editMode) && editMode > -1 ? ( - <StaticList - authors={authors} - editComponent={AuthorEditor} - editIndex={editMode} - parentForm={parentForm} - setFormAuthors={setFormAuthors} - version={version} - {...rest} - /> - ) : ( - <SortableList - beginDragProps={['index', 'lastName']} - dragHandle={DragHandle} - editedAuthor={editMode} - items={authors || []} - listItem={Author} - moveItem={moveAuthor} - {...rest} - /> - )} - {error && <ErrorMessage>{error}</ErrorMessage>} - </Root> -) - -export default compose( - withRouter, - connect( - (state, { project, parentForm = 'wizard' }) => ({ - error: getAuthorError(state), - currentUser: get(state, 'currentUser.user'), - version: selectCurrentVersion(state, project), - authorForm: formValueSelector(parentForm)(state, 'authorForm'), - }), - { - addAuthor, - changeForm, - deleteAuthor, - authorFailure, - }, - ), - withState('authors', 'setAuthors', []), - withProps(({ version, authorPath = 'authors', authorForm }) => ({ - authors: get(version, authorPath, []), - addMode: isBoolean(authorForm) && authorForm, - editMode: isNumber(authorForm) ? authorForm : -1, - })), - withHandlers({ - setFormAuthors: ({ setAuthors, changeForm, parentForm = 'wizard' }) => ( - authors = [], - ) => { - setAuthors(authors) - changeForm(parentForm, 'authors', authors) - }, - }), - withHandlers({ - setAuthorEdit: ({ - changeForm, - parentForm = 'wizard', - }) => authorIndex => e => { - e && e.preventDefault && e.preventDefault() - changeForm(parentForm, 'authorForm', authorIndex) - }, - setEditMode: ({ changeForm, parentForm = 'wizard' }) => mode => e => { - e && e.preventDefault() - changeForm(parentForm, 'authorForm', mode) - }, - parseAuthorType: () => (isSubmitting, isCorresponding, index) => { - if (isSubmitting) return `#${index + 1} Submitting author` - if (isCorresponding) return `#${index + 1} Corresponding author` - return `#${index + 1} Author` - }, - moveAuthor: ({ authors, setFormAuthors }) => (dragIndex, hoverIndex) => { - const newAuthors = SortableList.moveItem(authors, dragIndex, hoverIndex) - setFormAuthors(newAuthors) - }, - removeAuthor: ({ - authors, - version, - project, - deleteAuthor, - setFormAuthors, - }) => id => () => { - deleteAuthor(project.id, version.id, id).then(() => { - const newAuthors = authors.filter(a => a.id !== id) - setFormAuthors(newAuthors) - }) - }, - }), - setDisplayName('AuthorList'), -)(Authors) - -// #region styled-components -const Root = styled.div` - border: ${th('borderDefault')}; - padding: ${th('subGridUnit')}; -` -const ErrorMessage = styled.div` - color: ${th('colorError')}; -` -// #endregion diff --git a/packages/components-faraday/src/components/AuthorList/FormItems.js b/packages/components-faraday/src/components/AuthorList/FormItems.js deleted file mode 100644 index d1c6fdb52614eebfc28dd3e8103b74d570d59560..0000000000000000000000000000000000000000 --- a/packages/components-faraday/src/components/AuthorList/FormItems.js +++ /dev/null @@ -1,105 +0,0 @@ -import React from 'react' -import { th } from '@pubsweet/ui-toolkit' -import { required } from 'xpub-validators' -import styled, { css } from 'styled-components' -import { TextField, Menu, ValidatedField, Icon } from '@pubsweet/ui' - -export const ValidatedTextField = ({ - label, - name, - isRequired, - validators = [], -}) => { - const v = [isRequired && required, ...validators].filter(Boolean) - return ( - <ValidatedTextFieldRoot> - <StyledLabel>{label}</StyledLabel> - <ValidatedField component={TextField} name={name} validate={v} /> - </ValidatedTextFieldRoot> - ) -} - -export const MenuItem = ({ label, name, options }) => ( - <MenuItemRoot data-test="country-selector-author"> - <StyledLabel>{label}</StyledLabel> - <ValidatedField - component={input => <Menu {...input} options={options} />} - name={name} - validate={[required]} - /> - </MenuItemRoot> -) - -export const Label = ({ label, value }) => ( - <LabelRoot> - <span>{label}</span> - <span>{value}</span> - </LabelRoot> -) - -export const DragHandle = () => ( - <DragHandleRoot> - <Icon primary>chevron_up</Icon> - <Icon primary size={3}> - menu - </Icon> - <Icon primary>chevron_down</Icon> - </DragHandleRoot> -) - -// #region styled-components -const defaultText = css` - color: ${th('colorText')}; - font-size: ${th('fontSizeBaseSmall')}; - font-family: ${th('fontReading')}; -` - -const ValidatedTextFieldRoot = styled.div` - flex: 1; - margin-right: 5px; -` - -const MenuItemRoot = styled.div` - flex: 1; -` - -const StyledLabel = styled.span` - ${defaultText}; - font-weight: 300; - text-transform: uppercase; -` - -const DragHandleRoot = styled.div` - align-items: center; - border-right: ${th('borderDefault')}; - cursor: move; - display: flex; - flex-direction: column; - justify-content: center; -` - -const LabelRoot = styled.div` - display: flex; - flex: 1; - flex-direction: column; - margin: ${th('subGridUnit')}; - width: ${({ width }) => `${width || 150}px`}; - - span:first-child { - ${defaultText}; - font-weight: 300; - overflow: hidden; - text-transform: uppercase; - text-overflow: ellipsis; - white-space: nowrap; - } - - span:last-child { - ${defaultText}; - 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 deleted file mode 100644 index c9e6fc756411e091cb0ef48b726fe993008ef1b2..0000000000000000000000000000000000000000 --- a/packages/components-faraday/src/components/AuthorList/StaticList.js +++ /dev/null @@ -1,49 +0,0 @@ -import React from 'react' - -import Author from './Author' - -export default ({ - version, - project, - authors, - editIndex, - parentForm, - removeAuthor, - editComponent, - setAuthorEdit, - setFormAuthors, - parseAuthorType, - ...rest -}) => ( - <div> - {authors.map( - (author, index) => - index === editIndex ? ( - React.createElement(editComponent, { - key: 'author-editor', - index, - initialValues: { - edit: author, - }, - authors, - setAuthors: setFormAuthors, - setAuthorEdit, - parseAuthorType, - parentForm, - project, - version, - ...author, - }) - ) : ( - <Author - key={author.id} - {...author} - index={index} - parseAuthorType={parseAuthorType} - removeAuthor={removeAuthor} - {...rest} - /> - ), - )} - </div> -) diff --git a/packages/components-faraday/src/components/AuthorList/countries.js b/packages/components-faraday/src/components/AuthorList/countries.js deleted file mode 100644 index b746f4355554d22abea3ffa439d17881c8863d3e..0000000000000000000000000000000000000000 --- a/packages/components-faraday/src/components/AuthorList/countries.js +++ /dev/null @@ -1,245 +0,0 @@ -export default [ - { label: 'Afghanistan', value: 'AF' }, - { label: 'Åland Islands', value: 'AX' }, - { label: 'Albania', value: 'AL' }, - { label: 'Algeria', value: 'DZ' }, - { label: 'American Samoa', value: 'AS' }, - { label: 'Andorra', value: 'AD' }, - { label: 'Angola', value: 'AO' }, - { label: 'Anguilla', value: 'AI' }, - { label: 'Antarctica', value: 'AQ' }, - { label: 'Antigua and Barbuda', value: 'AG' }, - { label: 'Argentina', value: 'AR' }, - { label: 'Armenia', value: 'AM' }, - { label: 'Aruba', value: 'AW' }, - { label: 'Australia', value: 'AU' }, - { label: 'Austria', value: 'AT' }, - { label: 'Azerbaijan', value: 'AZ' }, - { label: 'Bahamas', value: 'BS' }, - { label: 'Bahrain', value: 'BH' }, - { label: 'Bangladesh', value: 'BD' }, - { label: 'Barbados', value: 'BB' }, - { label: 'Belarus', value: 'BY' }, - { label: 'Belgium', value: 'BE' }, - { label: 'Belize', value: 'BZ' }, - { label: 'Benin', value: 'BJ' }, - { label: 'Bermuda', value: 'BM' }, - { label: 'Bhutan', value: 'BT' }, - { label: 'Bolivia', value: 'BO' }, - { label: 'Bosnia and Herzegovina', value: 'BA' }, - { label: 'Botswana', value: 'BW' }, - { label: 'Bouvet Island', value: 'BV' }, - { label: 'Brazil', value: 'BR' }, - { label: 'British Indian Ocean Territory', value: 'IO' }, - { label: 'Brunei Darussalam', value: 'BN' }, - { label: 'Bulgaria', value: 'BG' }, - { label: 'Burkina Faso', value: 'BF' }, - { label: 'Burundi', value: 'BI' }, - { label: 'Cambodia', value: 'KH' }, - { label: 'Cameroon', value: 'CM' }, - { label: 'Canada', value: 'CA' }, - { label: 'Cape Verde', value: 'CV' }, - { label: 'Cayman Islands', value: 'KY' }, - { label: 'Central African Republic', value: 'CF' }, - { label: 'Chad', value: 'TD' }, - { label: 'Chile', value: 'CL' }, - { label: 'China', value: 'CN' }, - { label: 'Christmas Island', value: 'CX' }, - { label: 'Cocos (Keeling) Islands', value: 'CC' }, - { label: 'Colombia', value: 'CO' }, - { label: 'Comoros', value: 'KM' }, - { label: 'Congo', value: 'CG' }, - { label: 'Congo, The Democratic Republic of the', value: 'CD' }, - { label: 'Cook Islands', value: 'CK' }, - { label: 'Costa Rica', value: 'CR' }, - { label: "Cote D'Ivoire", value: 'CI' }, - { label: 'Croatia', value: 'HR' }, - { label: 'Cuba', value: 'CU' }, - { label: 'Cyprus', value: 'CY' }, - { label: 'Czech Republic', value: 'CZ' }, - { label: 'Denmark', value: 'DK' }, - { label: 'Djibouti', value: 'DJ' }, - { label: 'Dominica', value: 'DM' }, - { label: 'Dominican Republic', value: 'DO' }, - { label: 'Ecuador', value: 'EC' }, - { label: 'Egypt', value: 'EG' }, - { label: 'El Salvador', value: 'SV' }, - { label: 'Equatorial Guinea', value: 'GQ' }, - { label: 'Eritrea', value: 'ER' }, - { label: 'Estonia', value: 'EE' }, - { label: 'Ethiopia', value: 'ET' }, - { label: 'Falkland Islands (Malvinas)', value: 'FK' }, - { label: 'Faroe Islands', value: 'FO' }, - { label: 'Fiji', value: 'FJ' }, - { label: 'Finland', value: 'FI' }, - { label: 'France', value: 'FR' }, - { label: 'French Guiana', value: 'GF' }, - { label: 'French Polynesia', value: 'PF' }, - { label: 'French Southern Territories', value: 'TF' }, - { label: 'Gabon', value: 'GA' }, - { label: 'Gambia', value: 'GM' }, - { label: 'Georgia', value: 'GE' }, - { label: 'Germany', value: 'DE' }, - { label: 'Ghana', value: 'GH' }, - { label: 'Gibraltar', value: 'GI' }, - { label: 'Greece', value: 'GR' }, - { label: 'Greenland', value: 'GL' }, - { label: 'Grenada', value: 'GD' }, - { label: 'Guadeloupe', value: 'GP' }, - { label: 'Guam', value: 'GU' }, - { label: 'Guatemala', value: 'GT' }, - { label: 'Guernsey', value: 'GG' }, - { label: 'Guinea', value: 'GN' }, - { label: 'Guinea-Bissau', value: 'GW' }, - { label: 'Guyana', value: 'GY' }, - { label: 'Haiti', value: 'HT' }, - { label: 'Heard Island and Mcdonald Islands', value: 'HM' }, - { label: 'Holy See (Vatican City State)', value: 'VA' }, - { label: 'Honduras', value: 'HN' }, - { label: 'Hong Kong', value: 'HK' }, - { label: 'Hungary', value: 'HU' }, - { label: 'Iceland', value: 'IS' }, - { label: 'India', value: 'IN' }, - { label: 'Indonesia', value: 'ID' }, - { label: 'Iran, Islamic Republic Of', value: 'IR' }, - { label: 'Iraq', value: 'IQ' }, - { label: 'Ireland', value: 'IE' }, - { label: 'Isle of Man', value: 'IM' }, - { label: 'Israel', value: 'IL' }, - { label: 'Italy', value: 'IT' }, - { label: 'Jamaica', value: 'JM' }, - { label: 'Japan', value: 'JP' }, - { label: 'Jersey', value: 'JE' }, - { label: 'Jordan', value: 'JO' }, - { label: 'Kazakhstan', value: 'KZ' }, - { label: 'Kenya', value: 'KE' }, - { label: 'Kiribati', value: 'KI' }, - { label: "Korea, Democratic People's Republic of", value: 'KP' }, - { label: 'Korea, Republic of', value: 'KR' }, - { label: 'Kuwait', value: 'KW' }, - { label: 'Kyrgyzstan', value: 'KG' }, - { label: "Lao People'S Democratic Republic", value: 'LA' }, - { label: 'Latvia', value: 'LV' }, - { label: 'Lebanon', value: 'LB' }, - { label: 'Lesotho', value: 'LS' }, - { label: 'Liberia', value: 'LR' }, - { label: 'Libyan Arab Jamahiriya', value: 'LY' }, - { label: 'Liechtenstein', value: 'LI' }, - { label: 'Lithuania', value: 'LT' }, - { label: 'Luxembourg', value: 'LU' }, - { label: 'Macao', value: 'MO' }, - { label: 'Macedonia, The Former Yugoslav Republic of', value: 'MK' }, - { label: 'Madagascar', value: 'MG' }, - { label: 'Malawi', value: 'MW' }, - { label: 'Malaysia', value: 'MY' }, - { label: 'Maldives', value: 'MV' }, - { label: 'Mali', value: 'ML' }, - { label: 'Malta', value: 'MT' }, - { label: 'Marshall Islands', value: 'MH' }, - { label: 'Martinique', value: 'MQ' }, - { label: 'Mauritania', value: 'MR' }, - { label: 'Mauritius', value: 'MU' }, - { label: 'Mayotte', value: 'YT' }, - { label: 'Mexico', value: 'MX' }, - { label: 'Micronesia, Federated States of', value: 'FM' }, - { label: 'Moldova, Republic of', value: 'MD' }, - { label: 'Monaco', value: 'MC' }, - { label: 'Mongolia', value: 'MN' }, - { label: 'Montserrat', value: 'MS' }, - { label: 'Morocco', value: 'MA' }, - { label: 'Mozambique', value: 'MZ' }, - { label: 'Myanmar', value: 'MM' }, - { label: 'Namibia', value: 'NA' }, - { label: 'Nauru', value: 'NR' }, - { label: 'Nepal', value: 'NP' }, - { label: 'Netherlands', value: 'NL' }, - { label: 'Netherlands Antilles', value: 'AN' }, - { label: 'New Caledonia', value: 'NC' }, - { label: 'New Zealand', value: 'NZ' }, - { label: 'Nicaragua', value: 'NI' }, - { label: 'Niger', value: 'NE' }, - { label: 'Nigeria', value: 'NG' }, - { label: 'Niue', value: 'NU' }, - { label: 'Norfolk Island', value: 'NF' }, - { label: 'Northern Mariana Islands', value: 'MP' }, - { label: 'Norway', value: 'NO' }, - { label: 'Oman', value: 'OM' }, - { label: 'Pakistan', value: 'PK' }, - { label: 'Palau', value: 'PW' }, - { label: 'Palestinian Territory, Occupied', value: 'PS' }, - { label: 'Panama', value: 'PA' }, - { label: 'Papua New Guinea', value: 'PG' }, - { label: 'Paraguay', value: 'PY' }, - { label: 'Peru', value: 'PE' }, - { label: 'Philippines', value: 'PH' }, - { label: 'Pitcairn', value: 'PN' }, - { label: 'Poland', value: 'PL' }, - { label: 'Portugal', value: 'PT' }, - { label: 'Puerto Rico', value: 'PR' }, - { label: 'Qatar', value: 'QA' }, - { label: 'Reunion', value: 'RE' }, - { label: 'Romania', value: 'RO' }, - { label: 'Russian Federation', value: 'RU' }, - { label: 'RWANDA', value: 'RW' }, - { label: 'Saint Helena', value: 'SH' }, - { label: 'Saint Kitts and Nevis', value: 'KN' }, - { label: 'Saint Lucia', value: 'LC' }, - { label: 'Saint Pierre and Miquelon', value: 'PM' }, - { label: 'Saint Vincent and the Grenadines', value: 'VC' }, - { label: 'Samoa', value: 'WS' }, - { label: 'San Marino', value: 'SM' }, - { label: 'Sao Tome and Principe', value: 'ST' }, - { label: 'Saudi Arabia', value: 'SA' }, - { label: 'Senegal', value: 'SN' }, - { label: 'Serbia and Montenegro', value: 'CS' }, - { label: 'Seychelles', value: 'SC' }, - { label: 'Sierra Leone', value: 'SL' }, - { label: 'Singapore', value: 'SG' }, - { label: 'Slovakia', value: 'SK' }, - { label: 'Slovenia', value: 'SI' }, - { label: 'Solomon Islands', value: 'SB' }, - { label: 'Somalia', value: 'SO' }, - { label: 'South Africa', value: 'ZA' }, - { label: 'South Georgia and the South Sandwich Islands', value: 'GS' }, - { label: 'Spain', value: 'ES' }, - { label: 'Sri Lanka', value: 'LK' }, - { label: 'Sudan', value: 'SD' }, - { label: 'Suriname', value: 'SR' }, - { label: 'Svalbard and Jan Mayen', value: 'SJ' }, - { label: 'Swaziland', value: 'SZ' }, - { label: 'Sweden', value: 'SE' }, - { label: 'Switzerland', value: 'CH' }, - { label: 'Syrian Arab Republic', value: 'SY' }, - { label: 'Taiwan, Province of China', value: 'TW' }, - { label: 'Tajikistan', value: 'TJ' }, - { label: 'Tanzania, United Republic of', value: 'TZ' }, - { label: 'Thailand', value: 'TH' }, - { label: 'Timor-Leste', value: 'TL' }, - { label: 'Togo', value: 'TG' }, - { label: 'Tokelau', value: 'TK' }, - { label: 'Tonga', value: 'TO' }, - { label: 'Trinidad and Tobago', value: 'TT' }, - { label: 'Tunisia', value: 'TN' }, - { label: 'Turkey', value: 'TR' }, - { label: 'Turkmenistan', value: 'TM' }, - { label: 'Turks and Caicos Islands', value: 'TC' }, - { label: 'Tuvalu', value: 'TV' }, - { label: 'Uganda', value: 'UG' }, - { label: 'Ukraine', value: 'UA' }, - { label: 'United Arab Emirates', value: 'AE' }, - { label: 'United Kingdom', value: 'GB' }, - { label: 'United States', value: 'US' }, - { label: 'United States Minor Outlying Islands', value: 'UM' }, - { label: 'Uruguay', value: 'UY' }, - { label: 'Uzbekistan', value: 'UZ' }, - { label: 'Vanuatu', value: 'VU' }, - { label: 'Venezuela', value: 'VE' }, - { label: 'Vietnam', value: 'VN' }, - { label: 'Virgin Islands, British', value: 'VG' }, - { label: 'Virgin Islands, U.S.', value: 'VI' }, - { label: 'Wallis and Futuna', value: 'WF' }, - { label: 'Western Sahara', value: 'EH' }, - { label: 'Yemen', value: 'YE' }, - { label: 'Zambia', value: 'ZM' }, - { label: 'Zimbabwe', value: 'ZW' }, -] diff --git a/packages/components-faraday/src/components/AuthorList/index.js b/packages/components-faraday/src/components/AuthorList/index.js deleted file mode 100644 index 1ff2016c20ac9622dde7315255596cff24fea844..0000000000000000000000000000000000000000 --- a/packages/components-faraday/src/components/AuthorList/index.js +++ /dev/null @@ -1,9 +0,0 @@ -import * as utils from './utils' - -export { default as Author } from './Author' -export { default as AuthorList } from './AuthorList' -export { default as StaticList } from './StaticList' -export { default as AuthorAdder } from './AuthorAdder' -export { default as AuthorEditor } from './AuthorEditor' - -export { utils } diff --git a/packages/components-faraday/src/components/AuthorList/utils.js b/packages/components-faraday/src/components/AuthorList/utils.js deleted file mode 100644 index e58c4abec7befcf31d2d74dc9c4ecf0ceb324ab0..0000000000000000000000000000000000000000 --- a/packages/components-faraday/src/components/AuthorList/utils.js +++ /dev/null @@ -1,40 +0,0 @@ -import { isBoolean } from 'lodash' - -export const authorKeys = [ - 'id', - 'email', - 'lastName', - 'firstName', - 'affiliation', - 'isSubmitting', - 'isCorresponding', -] - -export const setCorresponding = id => author => - author.id === id - ? { - ...author, - isCorresponding: true, - } - : { ...author, isCorresponding: false } - -export const castToBool = author => ({ - ...author, - isCorresponding: isBoolean(author.isCorresponding) && author.isCorresponding, -}) - -export const parseEditedAuthors = (editedAuthor, authors) => { - const newAuthor = castToBool(editedAuthor) - - return authors.map( - a => - a.id === newAuthor.id - ? newAuthor - : { - ...a, - isCorresponding: newAuthor.isCorresponding - ? false - : a.isCorresponding, - }, - ) -} diff --git a/packages/components-faraday/src/components/Dashboard/AssignHEModal.js b/packages/components-faraday/src/components/Dashboard/AssignHEModal.js deleted file mode 100644 index 100678c1cb55c5538b36c51960dfecc4f2278fd3..0000000000000000000000000000000000000000 --- a/packages/components-faraday/src/components/Dashboard/AssignHEModal.js +++ /dev/null @@ -1,239 +0,0 @@ -/* eslint react/prefer-stateless-function: 0 */ - -import React from 'react' -import { get } from 'lodash' -import { compose } from 'recompose' -import { connect } from 'react-redux' -import styled from 'styled-components' -import { actions } from 'pubsweet-client' -import { th } from '@pubsweet/ui-toolkit' -import { Icon, ErrorText, Spinner } from '@pubsweet/ui' - -import { - selectFetching, - assignHandlingEditor, - selectHandlingEditors, -} from '../../redux/editors' - -class AssignHEModal extends React.Component { - state = { - searchInput: '', - } - - changeInput = e => { - this.setState({ searchInput: e.target.value }) - } - - filterEditors = editors => { - const { searchInput } = this.state - return editors.filter(({ firstName, lastName, email }) => - `${firstName} ${lastName} ${email}` - .toLowerCase() - .includes(searchInput.trim()), - ) - } - - assignEditor = email => () => { - const { - showModal, - hideModal, - collectionId, - setModalError, - getCollections, - assignHandlingEditor, - } = this.props - assignHandlingEditor(email, collectionId).then( - () => { - getCollections() - hideModal() - showModal({ - cancelText: 'OK', - type: 'confirmation', - title: 'Assignation Sent', - }) - }, - e => { - setModalError( - get(JSON.parse(e.response), 'error', 'Oops! Something went wrong!'), - ) - }, - ) - } - - render() { - const { searchInput } = this.state - const { editors, hideModal, isFetching, modalError } = this.props - const filteredEditors = this.filterEditors(editors) - return ( - <RootModal> - <CloseIcon data-test="icon-modal-hide" onClick={hideModal}> - <Icon primary>x</Icon> - </CloseIcon> - <ModalTitle>Assign Handling Editor</ModalTitle> - <ModalHeader> - <SubtitleRow> - <span>HANDLING EDITORS</span> - {isFetching && <Spinner size={3} />} - </SubtitleRow> - <SearchInput - data-test="he-search" - onChange={this.changeInput} - placeholder="Search by name or email" - type="text" - value={searchInput} - /> - </ModalHeader> - <ScrollContainer> - <ModalContent> - {filteredEditors.map(({ firstName, lastName, email }, index) => ( - <SuggestedEditor - isLast={index === filteredEditors.length - 1} - key={email} - > - <EditorDetails> - <span>{`${firstName} ${lastName}`}</span> - <span>{email}</span> - </EditorDetails> - {!isFetching && ( - <AssignButton - data-test={`assign-${email}`} - onClick={this.assignEditor(email)} - > - ASSIGN - </AssignButton> - )} - </SuggestedEditor> - ))} - </ModalContent> - </ScrollContainer> - <CustomError>{modalError}</CustomError> - </RootModal> - ) - } -} - -export default compose( - connect( - state => ({ - isFetching: selectFetching(state), - editors: selectHandlingEditors(state), - }), - { - assignHandlingEditor, - getCollections: actions.getCollections, - updateCollection: actions.updateCollection, - }, - ), -)(AssignHEModal) - -// #region styled-components -const CustomError = ErrorText.extend` - font-family: ${th('fontReading')}; - margin: ${th('subGridUnit')} 0; -` - -const SubtitleRow = styled.div` - display: flex; - justify-content: space-between; - - & span { - color: ${th('colorPrimary')}; - font-size: ${th('fontSizeBase')}; - font-family: ${th('fontReading')}; - margin-bottom: ${th('subGridUnit')}; - } -` - -const CloseIcon = styled.div` - cursor: pointer; - position: absolute; - top: ${th('subGridUnit')}; - right: ${th('subGridUnit')}; -` - -const EditorDetails = styled.div` - display: flex; - flex-direction: column; -` -const SuggestedEditor = styled.div` - align-items: center; - border: ${th('borderDefault')}; - border-bottom: ${({ isLast }) => (isLast ? th('borderDefault') : 'none')}; - display: flex; - justify-content: space-between; - padding: ${th('subGridUnit')}; - height: calc(${th('gridUnit')} * 2); - - &:hover { - background-color: ${th('colorSecondary')}; - } -` - -const AssignButton = styled.button` - align-items: center; - background-color: ${th('colorPrimary')}; - cursor: pointer; - color: ${th('colorTextReverse')}; - display: flex; - justify-content: center; - font-size: ${th('fontSizeBaseSmall')}; - font-family: ${th('fontReading')}; - height: ${th('gridUnit')}; - opacity: 0; - width: calc(${th('gridUnit')} * 4); - - ${SuggestedEditor}:hover & { - opacity: 1; - } -` - -const RootModal = styled.div` - align-items: center; - background-color: ${th('colorBackgroundHue')}; - display: flex; - flex-direction: column; - justify-content: flex-start; - height: calc(${th('gridUnit')} * 18); - padding: calc(${th('subGridUnit')} * 8) calc(${th('subGridUnit')} * 6); - position: relative; - width: calc(${th('gridUnit')} * 24); -` - -const ModalTitle = styled.span` - color: ${th('colorPrimary')}; - font-size: ${th('fontSizeHeading4')}; - font-family: ${th('fontHeading')}; - margin-bottom: calc(${th('subGridUnit')} * 5); -` - -const ModalHeader = styled.div` - align-self: stretch; - display: flex; - flex-direction: column; -` - -const SearchInput = styled.input` - border: 4px solid gray; - height: calc(${th('subGridUnit')} * 5); - padding: ${th('subGridUnit')}; - - &:focus, - &:active { - outline: none; - } -` - -const ScrollContainer = styled.div` - align-self: stretch; - flex: 1; - overflow: auto; - border: ${th('borderDefault')}; -` - -const ModalContent = styled.div` - display: flex; - flex-direction: column; - overflow: auto; - padding: calc(${th('subGridUnit')} * 2) calc(${th('subGridUnit')} * 3); -` -// #endregion diff --git a/packages/components-faraday/src/components/Dashboard/AuthorTooltip.js b/packages/components-faraday/src/components/Dashboard/AuthorTooltip.js deleted file mode 100644 index 9af3963903ca0c5662c955493aa5cada0a1e49be..0000000000000000000000000000000000000000 --- a/packages/components-faraday/src/components/Dashboard/AuthorTooltip.js +++ /dev/null @@ -1,78 +0,0 @@ -import React from 'react' -import { Tooltip } from 'react-tippy' -import { th } from '@pubsweet/ui-toolkit' -import styled, { ThemeProvider, withTheme } from 'styled-components' - -const AuthorTooltip = ({ - authorName, - email, - affiliation, - isSubmitting, - isCorresponding, - theme, -}) => ( - <ThemeProvider theme={theme}> - <TooltipRoot> - <TooltipRow> - <AuthorName>{authorName}</AuthorName> - {isSubmitting && <SpecialAuthor>Submitting Author</SpecialAuthor>} - {isCorresponding && - !isSubmitting && <SpecialAuthor>Corresponding Author</SpecialAuthor>} - </TooltipRow> - <TooltipRow> - <AuthorDetails>{email}</AuthorDetails> - </TooltipRow> - <TooltipRow> - <AuthorDetails>{affiliation}</AuthorDetails> - </TooltipRow> - </TooltipRoot> - </ThemeProvider> -) - -const TooltipComponent = ({ children, ...rest }) => ( - <Tooltip arrow html={<AuthorTooltip {...rest} />} position="bottom"> - {children} - </Tooltip> -) - -export default withTheme(TooltipComponent) - -// #region styled-components -const TooltipRoot = styled.div` - align-items: flex-start; - display: flex; - flex-direction: column; - justify-content: center; - padding: calc(${th('subGridUnit')}*2); -` - -const TooltipRow = styled.div` - align-items: center; - display: flex; - justify-content: flex-start; - margin: ${th('subGridUnit')} 0; -` - -const AuthorName = styled.span` - color: ${th('colorSecondary')}; - font-family: ${th('fontHeading')}; - font-size: ${th('fontSizeBase')}; -` - -const AuthorDetails = styled.span` - color: ${th('colorSecondary')}; - font-family: ${th('fontReading')}; - font-size: ${th('fontSizeBaseSmall')}; -` - -const SpecialAuthor = styled.span` - background-color: ${th('colorBackground')}; - color: ${th('colorTextPlaceholder')}; - font-family: ${th('fontInterface')}; - font-size: ${th('fontSizeBaseSmall')}; - font-weight: bold; - margin-left: ${th('subGridUnit')}; - padding: 0 ${th('subGridUnit')}; -` - -// #endregion diff --git a/packages/components-faraday/src/components/Dashboard/DeleteManuscript.js b/packages/components-faraday/src/components/Dashboard/DeleteManuscript.js deleted file mode 100644 index 55bd0d640c8274bea44ba74c12d056fc3c7d6e7e..0000000000000000000000000000000000000000 --- a/packages/components-faraday/src/components/Dashboard/DeleteManuscript.js +++ /dev/null @@ -1,53 +0,0 @@ -import React from 'react' -import styled from 'styled-components' -import { th } from '@pubsweet/ui-toolkit' -import { compose, withHandlers, setDisplayName } from 'recompose' -import { - withModal, - ConfirmationModal, -} from 'pubsweet-component-modal/src/components' - -import { handleError } from '../utils' - -const DeleteManuscript = ({ confirmDelete }) => ( - <Details onClick={confirmDelete}>Delete</Details> -) - -export default compose( - setDisplayName('DeleteManuscript'), - withModal(() => ({ - modalComponent: ConfirmationModal, - })), - withHandlers({ - confirmDelete: ({ - showModal, - hideModal, - deleteProject, - setModalError, - }) => () => { - showModal({ - confirmText: 'Delete', - title: 'Are you sure you want to delete this submission?', - onConfirm: () => { - deleteProject().then(hideModal, handleError(setModalError)) - }, - }) - }, - }), -)(DeleteManuscript) - -// #region styled-components -const Details = styled.div` - align-items: center; - cursor: pointer; - color: ${th('colorText')}; - display: flex; - font-family: ${th('fontReading')}; - font-size: ${th('fontSizeBaseSmall')}; - margin-left: calc(${th('subGridUnit')} * 2); - text-decoration: underline; - text-align: center; - text-transform: uppercase; - white-space: nowrap; -` -// #endregion diff --git a/packages/components-faraday/src/components/Dashboard/EditorInChiefActions.js b/packages/components-faraday/src/components/Dashboard/EditorInChiefActions.js deleted file mode 100644 index 0095f685b776f573ff370bb2b2f6d882c4ad68b5..0000000000000000000000000000000000000000 --- a/packages/components-faraday/src/components/Dashboard/EditorInChiefActions.js +++ /dev/null @@ -1,179 +0,0 @@ -import React from 'react' -import { get } from 'lodash' -import { connect } from 'react-redux' -import { actions } from 'pubsweet-client' -import { th } from '@pubsweet/ui-toolkit' -import { Icon, Button } from '@pubsweet/ui' -import styled, { css } from 'styled-components' -import { compose, withHandlers } from 'recompose' -import { - withModal, - SuccessModal, - ConfirmationModal, -} from 'pubsweet-component-modal/src/components' - -import { handleError } from './../utils' -import { - selectFetching, - revokeHandlingEditor, - assignHandlingEditor, -} from '../../redux/editors' - -import HEModal from './AssignHEModal' - -const EditorInChiefActions = ({ - project, - showHEModal, - showConfirmModal, - getHandlingEditor, -}) => { - const handlingEditor = getHandlingEditor() - const isAccepted = get(handlingEditor, 'isAccepted') - const hasAnswer = get(handlingEditor, 'hasAnswer') - return ( - <Root> - <HEActions data-test="eic-assign"> - {!handlingEditor || (hasAnswer && !isAccepted) ? ( - <AssignButton onClick={showHEModal}>Assign</AssignButton> - ) : ( - <HEActions> - <HEName>{get(handlingEditor, 'name')}</HEName> - <HEActions data-test="eic-after-assign"> - <div onClick={showConfirmModal('resend')}> - <Icon primary>refresh-cw</Icon> - </div> - <div onClick={showConfirmModal('cancel')}> - <Icon primary>x-circle</Icon> - </div> - </HEActions> - </HEActions> - )} - </HEActions> - </Root> - ) -} - -const CardModal = connect(state => ({ - isFetching: selectFetching(state), -}))(({ type, isFetching, ...rest }) => { - switch (type) { - case 'confirmation': - return <ConfirmationModal {...rest} isFetching={isFetching} /> - case 'success': - return <SuccessModal {...rest} /> - case 'he-modal': - default: - return <HEModal {...rest} /> - } -}) - -export default compose( - connect(null, { - revokeHandlingEditor, - assignHandlingEditor, - getCollections: actions.getCollections, - }), - withModal(() => ({ - modalComponent: CardModal, - })), - withHandlers({ - getHandlingEditor: ({ project }) => () => get(project, 'handlingEditor'), - }), - withHandlers({ - showConfirmModal: ({ - project, - showModal, - hideModal, - setModalError, - getCollections, - getHandlingEditor, - revokeHandlingEditor, - assignHandlingEditor, - }) => actionType => { - const editor = get(project, 'handlingEditor') - const invitation = project.invitations.find(i => i.userId === editor.id) - const resendConfig = { - title: 'Resend Invitation?', - subtitle: '', - confirmText: 'Resend', - onConfirm: () => - assignHandlingEditor(get(editor, 'email'), project.id, true).then( - () => { - getCollections() - hideModal() - showModal({ - type: 'success', - title: 'Invite resent', - }) - }, - handleError(setModalError), - ), - } - const revokeConfig = { - title: 'Revoke Handling Editor Assignation?', - subtitle: `Clicking 'Revoke' will allow you to invite a different person.`, - confirmText: 'Revoke invite', - onConfirm: () => - revokeHandlingEditor(invitation.id, project.id).then(() => { - getCollections() - hideModal() - showModal({ - type: 'success', - title: 'Handling Editor Assignation Revoked', - }) - }, handleError(setModalError)), - } - - return () => { - const cfg = actionType === 'resend' ? resendConfig : revokeConfig - showModal({ ...cfg, type: 'confirmation' }) - } - }, - showHEModal: ({ showModal, project }) => () => { - showModal({ type: 'he-modal', collectionId: project.id, showModal }) - }, - }), -)(EditorInChiefActions) - -// #region styled-components -const defaultText = css` - color: ${th('colorText')}; - font-family: ${th('fontReading')}; - font-size: ${th('fontSizeBaseSmall')}; -` - -const Root = styled.div` - margin-left: ${th('gridUnit')}; -` - -const HEName = styled.div` - text-decoration: underline; -` - -const HEActions = styled.div` - ${defaultText}; - display: flex; - align-items: center; - cursor: pointer; - margin-left: ${th('subGridUnit')}; - span { - margin-left: ${th('subGridUnit')}; - &:hover { - svg { - opacity: 0.8; - } - } - } -` - -const AssignButton = styled(Button)` - ${defaultText}; - align-items: center; - background-color: ${th('colorPrimary')}; - color: ${th('colorTextReverse')}; - height: calc(${th('subGridUnit')} * 5); - padding: 0; - text-align: center; - text-transform: uppercase; -` -// #endregion diff --git a/packages/components-faraday/src/components/Dashboard/HandlingEditorActions.js b/packages/components-faraday/src/components/Dashboard/HandlingEditorActions.js deleted file mode 100644 index bdb2ecb7d4d91c1d853af5da4bf03b07ac8c4192..0000000000000000000000000000000000000000 --- a/packages/components-faraday/src/components/Dashboard/HandlingEditorActions.js +++ /dev/null @@ -1,165 +0,0 @@ -import React from 'react' -import { connect } from 'react-redux' -import { Button } from '@pubsweet/ui' -import { actions } from 'pubsweet-client' -import { th } from '@pubsweet/ui-toolkit' -import styled, { css } from 'styled-components' -import { withHandlers, compose, withState } from 'recompose' -import { - withModal, - ConfirmationModal, -} from 'pubsweet-component-modal/src/components' - -import { handleError } from './../utils' -import { handlingEditorDecision } from '../../redux/editors' - -const DeclineModal = compose( - withState('reason', 'setReason', ''), - withHandlers({ - changeReason: ({ setReason }) => e => { - setReason(e.target.value) - }, - }), -)(({ reason, changeReason, hideModal, onConfirm }) => ( - <DeclineRoot> - <span>Decline handling editor role</span> - <textarea - onChange={changeReason} - placeholder="Decline reason (optional)" - value={reason} - /> - <div data-test="he-buttons"> - <DecisionButton onClick={hideModal}>Cancel</DecisionButton> - <DecisionButton onClick={onConfirm(reason)} primary> - Decline - </DecisionButton> - </div> - </DeclineRoot> -)) - -const ModalComponent = ({ type, ...rest }) => - type === 'decline' ? ( - <DeclineModal {...rest} /> - ) : ( - <ConfirmationModal {...rest} /> - ) - -const HandlingEditorActions = ({ showHEModal }) => ( - <Root> - <DecisionButton onClick={showHEModal('decline')}>DECLINE</DecisionButton> - <DecisionButton onClick={showHEModal()} primary> - AGREE - </DecisionButton> - </Root> -) - -export default compose( - connect(null, { - getCollections: actions.getCollections, - }), - withModal(() => ({ - modalComponent: ModalComponent, - })), - withHandlers({ - showHEModal: ({ - project, - showModal, - hideModal, - currentUser, - setModalError, - getCollections, - }) => modalType => { - const invitation = project.invitations.find( - i => i.userId === currentUser.id, - ) - const agreeConfig = { - type: modalType, - title: 'Agree to handling editor assignment', - subtitle: `Clicking "Agree" will assign you as Handling Editor for this Manuscript.`, - confirmText: 'Agree', - onConfirm: () => { - handlingEditorDecision(invitation.id, project.id, true).then(() => { - getCollections() - hideModal() - }, handleError(setModalError)) - }, - } - const declineConfig = { - type: modalType, - title: 'Decline handling editor role', - subtitle: `Clicking "Agree" will assign you as Handling Editor for this Manuscript.`, - onConfirm: reason => () => { - handlingEditorDecision(invitation.id, project.id, false, reason).then( - () => { - getCollections() - hideModal() - }, - handleError(setModalError), - ) - }, - } - return () => { - const cfg = modalType === 'decline' ? declineConfig : agreeConfig - showModal(cfg) - } - }, - }), -)(HandlingEditorActions) - -// #region styled-components -const defaultText = css` - font-family: ${th('fontReading')}; - font-size: ${th('fontSizeBaseSmall')}; -` - -const DecisionButton = styled(Button)` - ${defaultText}; - align-items: center; - color: ${({ primary }) => - primary ? th('colorTextReverse') : th('colorPrimary')}; - background-color: ${({ primary }) => - primary ? th('colorPrimary') : th('backgroundColorReverse')}; - height: calc(${th('subGridUnit')} * 5); - margin-left: ${th('gridUnit')}; - padding: 0; - text-align: center; -` - -const DeclineRoot = styled.div` - align-items: center; - background-color: ${th('backgroundColor')}; - display: flex; - flex-direction: column; - height: calc(${th('gridUnit')} * 13); - justify-content: space-between; - padding: calc(${th('subGridUnit')} * 7); - width: calc(${th('gridUnit')} * 24); - - & span { - color: ${th('colorPrimary')}; - font-size: ${th('fontSizeHeading5')}; - font-family: ${th('fontHeading')}; - margin-bottom: ${th('gridUnit')}; - } - - & textarea { - height: 100%; - padding: calc(${th('subGridUnit')} * 2); - width: 100%; - } - - & textarea:focus, - & textarea:active { - outline: none; - } - - & div { - display: flex; - justify-content: space-evenly; - margin: ${th('gridUnit')} auto 0; - width: 100%; - } -` - -const Root = styled.div`` -// #endregion diff --git a/packages/components-faraday/src/components/Dashboard/HandlingEditorSection.js b/packages/components-faraday/src/components/Dashboard/HandlingEditorSection.js deleted file mode 100644 index 6fcf4bff380ec7a10db0bde1704a07114aeec88c..0000000000000000000000000000000000000000 --- a/packages/components-faraday/src/components/Dashboard/HandlingEditorSection.js +++ /dev/null @@ -1,69 +0,0 @@ -import React from 'react' -import { get } from 'lodash' -import { th } from '@pubsweet/ui-toolkit' -import styled, { css } from 'styled-components' -import { EditorInChiefActions, HandlingEditorActions } from './' - -const renderHE = (currentUser, isHE, project) => { - const status = get(project, 'status', 'draft') - const isAdmin = get(currentUser, 'admin') - const isEic = get(currentUser, 'editorInChief') - - const handlingEditor = get(project, 'handlingEditor') - const eicActionsStatuses = ['submitted', 'heInvited'] - const heActionsStatuses = ['heInvited'] - - if ((isAdmin || isEic) && eicActionsStatuses.includes(status)) { - return ( - <EditorInChiefActions - modalKey={`eicActions-${project.id}`} - project={project} - /> - ) - } - - if (isHE && heActionsStatuses.includes(status)) { - return ( - <HandlingEditorActions - currentUser={currentUser} - modalKey={`heActions-${project.id}`} - project={project} - /> - ) - } - - return <AssignedHE>{get(handlingEditor, 'name', 'N/A')}</AssignedHE> -} - -const HandlingEditorSection = ({ isHE, currentUser, project }) => ( - <Root> - <HEText>Handling Editor</HEText> - {renderHE(currentUser, isHE, project)} - </Root> -) - -export default HandlingEditorSection - -// #region styled-components -const defaultText = css` - color: ${th('colorText')}; - font-family: ${th('fontReading')}; - font-size: ${th('fontSizeBaseSmall')}; -` -const Root = styled.div` - display: flex; - flex-wrap: wrap; - flex: 1; -` - -const HEText = styled.div` - ${defaultText}; - text-transform: uppercase; -` - -const AssignedHE = styled.span` - ${defaultText}; - margin-left: calc(${th('subGridUnit')} * 3); - text-decoration: underline; -` -// #endregion diff --git a/packages/components-faraday/src/components/Dashboard/ReviewerDecision.js b/packages/components-faraday/src/components/Dashboard/ReviewerDecision.js deleted file mode 100644 index 415d871c26a55df6248b4937c1d476109d3bb3e2..0000000000000000000000000000000000000000 --- a/packages/components-faraday/src/components/Dashboard/ReviewerDecision.js +++ /dev/null @@ -1,107 +0,0 @@ -import React from 'react' -import { connect } from 'react-redux' -import { Button } from '@pubsweet/ui' -import { th } from '@pubsweet/ui-toolkit' -import { actions } from 'pubsweet-client' -import styled, { css } from 'styled-components' -import { compose, withHandlers } from 'recompose' -import { - withModal, - ConfirmationModal, -} from 'pubsweet-component-modal/src/components' - -import { handleError } from '../utils' -import { selectFetchingDecision, reviewerDecision } from '../../redux/reviewers' - -const ReviewerDecision = ({ showAcceptModal, showDeclineModal, ...rest }) => ( - <div> - <DecisionButton onClick={showDeclineModal}>Decline</DecisionButton> - <DecisionButton onClick={showAcceptModal} primary> - Agree - </DecisionButton> - </div> -) - -const ModalComponent = connect(state => ({ - isFetching: selectFetchingDecision(state), -}))(({ isFetching, ...rest }) => ( - <ConfirmationModal {...rest} isFetching={isFetching} /> -)) - -export default compose( - connect(null, { - reviewerDecision, - getCollection: actions.getCollection, - }), - withModal(props => ({ - modalComponent: ModalComponent, - })), - withHandlers({ - decisionSuccess: ({ project, hideModal, getCollection }) => () => { - getCollection(project) - hideModal() - }, - }), - withHandlers({ - showAcceptModal: ({ - project, - version, - showModal, - invitation, - setModalError, - decisionSuccess, - reviewerDecision, - }) => () => { - showModal({ - title: 'Agree to review Manuscript?', - confirmText: 'Agree', - onConfirm: () => { - reviewerDecision(invitation.id, project.id, version.id, true).then( - decisionSuccess, - handleError(setModalError), - ) - }, - }) - }, - showDeclineModal: ({ - project, - version, - showModal, - invitation, - setModalError, - decisionSuccess, - reviewerDecision, - }) => () => { - showModal({ - title: 'Decline to review Manuscript?', - confirmText: 'Decline', - onConfirm: () => { - reviewerDecision(invitation.id, project.id, version.id, false).then( - decisionSuccess, - handleError(setModalError), - ) - }, - }) - }, - }), -)(ReviewerDecision) - -// #region styled-components -const defaultText = css` - font-family: ${th('fontReading')}; - font-size: ${th('fontSizeBaseSmall')}; -` - -const DecisionButton = styled(Button)` - ${defaultText}; - align-items: center; - background-color: ${({ primary }) => - primary ? th('colorPrimary') : th('backgroundColorReverse')}; - color: ${({ primary }) => - primary ? th('colorTextReverse') : th('colorPrimary')}; - height: calc(${th('subGridUnit')} * 5); - margin-left: ${th('gridUnit')}; - padding: 0; - text-align: center; -` -// #endregion diff --git a/packages/components-faraday/src/components/Dashboard/index.js b/packages/components-faraday/src/components/Dashboard/index.js index 0352a0743410c6b7a8fe3ed953278ac984296632..fdadaa5bc667f522d45c6661b967811bce585d65 100644 --- a/packages/components-faraday/src/components/Dashboard/index.js +++ b/packages/components-faraday/src/components/Dashboard/index.js @@ -1,13 +1,7 @@ import DashboardPage from './DashboardPage' export { default as Dashboard } from './Dashboard' -export { default as AuthorTooltip } from './AuthorTooltip' export { default as DashboardItems } from './DashboardItems' -export { default as DeleteManuscript } from './DeleteManuscript' -export { default as ReviewerDecision } from './ReviewerDecision' export { default as DashboardFilters } from './DashboardFilters' -export { default as EditorInChiefActions } from './EditorInChiefActions' -export { default as HandlingEditorActions } from './HandlingEditorActions' -export { default as HandlingEditorSection } from './HandlingEditorSection' export default DashboardPage diff --git a/packages/components-faraday/src/components/Files/Components.js b/packages/components-faraday/src/components/Files/Components.js deleted file mode 100644 index 45cd65d3898b1c3efdf1e5884b04acc0932006b3..0000000000000000000000000000000000000000 --- a/packages/components-faraday/src/components/Files/Components.js +++ /dev/null @@ -1,13 +0,0 @@ -import styled from 'styled-components' -import { th } from '@pubsweet/ui-toolkit' - -export const IconButton = styled.div` - align-items: center; - cursor: pointer; - display: flex; - justify-content: center; - margin: 0 ${th('subGridUnit')}; - &:hover { - opacity: 0.7; - } -` diff --git a/packages/components-faraday/src/components/Files/FileDownload.js b/packages/components-faraday/src/components/Files/FileDownload.js deleted file mode 100644 index 3f73bf42e53d67879ab61c5b46316dd6ae8e0147..0000000000000000000000000000000000000000 --- a/packages/components-faraday/src/components/Files/FileDownload.js +++ /dev/null @@ -1,49 +0,0 @@ -import React from 'react' -import qs from 'querystring' -import { Icon } from '@pubsweet/ui' -import { connect } from 'react-redux' -import { compose, withHandlers } from 'recompose' - -import { Components } from './' -import { createAnchorElement, removeAnchorElement } from './utils' -import { getUserToken } from '../../../../component-faraday-selectors' - -const FileDownload = ({ downloadFile }) => ( - <Components.IconButton onClick={downloadFile}> - <Icon primary size={3}> - download - </Icon> - </Components.IconButton> -) - -export default compose( - connect(state => ({ - token: getUserToken(state), - })), - withHandlers({ - downloadFile: ({ fileId, token, fileName = 'file' }) => () => { - const fileURL = `${ - window.location.origin - }/api/files/${fileId}?${qs.stringify({ - download: true, - })}` - - const xhr = new XMLHttpRequest() - xhr.onreadystatechange = function onXhrStateChange() { - if (this.readyState === 4) { - if (this.status >= 200 && this.status < 300) { - const f = new File([this.response], fileName) - - const { a, url } = createAnchorElement(f, fileName) - a.click() - removeAnchorElement(a, url) - } - } - } - xhr.open('GET', fileURL) - xhr.responseType = 'blob' - xhr.setRequestHeader('Authorization', `Bearer ${token}`) - xhr.send() - }, - }), -)(FileDownload) diff --git a/packages/components-faraday/src/components/Files/FileItem.js b/packages/components-faraday/src/components/Files/FileItem.js deleted file mode 100644 index 5b933d3bb8bf5cbaefb3abc339c0f889d4c87c4d..0000000000000000000000000000000000000000 --- a/packages/components-faraday/src/components/Files/FileItem.js +++ /dev/null @@ -1,139 +0,0 @@ -import React, { Fragment } from 'react' -import { last } from 'lodash' -import { Icon } from '@pubsweet/ui' -import { th } from '@pubsweet/ui-toolkit' -import styled, { css } from 'styled-components' - -import { FilePreview, FileDownload, Components } from './' - -const parseFileSize = size => { - const kbSize = size / 1000 - const mbSize = kbSize / 1000 - const gbSize = mbSize / 1000 - - if (Math.floor(gbSize)) { - return `${Math.floor(gbSize)} GB` - } else if (Math.floor(mbSize)) { - return `${Math.floor(mbSize)} MB` - } else if (Math.floor(kbSize)) { - return `${Math.floor(kbSize)} kB` - } - return `${size} bytes` -} - -const hasPreview = (name = '') => { - const extension = last(name.split('.')) - return ['pdf', 'png', 'jpg'].includes(extension) -} - -const FileItem = ({ - id, - name, - size, - theme, - dragHandle, - removeFile, - compact = false, -}) => ( - <Fragment> - {compact ? ( - <FileRoot data-test={`file-${id}`}> - {hasPreview(name) && <FilePreview fileId={id} />} - <FileDownload fileId={id} fileName={name} /> - <FileName>{name}</FileName> - <FileSize>{parseFileSize(size)}</FileSize> - {removeFile && ( - <Components.IconButton onClick={removeFile(id)}> - <Icon primary size={3}> - x - </Icon> - </Components.IconButton> - )} - </FileRoot> - ) : ( - <Root data-test={`file-${id}`}> - {dragHandle} - <Info> - <span>{name}</span> - <span>{parseFileSize(size)}</span> - </Info> - <Buttons> - {hasPreview(name) && <FilePreview fileId={id} />} - {removeFile && ( - <button onClick={removeFile(id)} title="Delete"> - <Icon primary size={3}> - trash-2 - </Icon> - </button> - )} - </Buttons> - </Root> - )} - </Fragment> -) - -export default FileItem - -// #region styles -const defaultText = css` - color: ${th('colorPrimary')}; - font-family: ${th('fontHeading')}; - font-size: ${th('fontSizeBaseSmall')}; -` - -const Root = styled.div` - align-items: center; - border: ${th('borderDefault')}; - display: flex; - margin: ${th('subGridUnit')}; -` - -const Info = styled.div` - border-right: ${th('borderDefault')}; - display: flex; - flex: 1; - justify-content: space-between; - padding: calc(${th('subGridUnit')} / 2) ${th('subGridUnit')} - ${th('subGridUnit')} 0; -` - -const Buttons = styled.div` - align-items: center; - display: flex; - justify-content: center; - margin: 0 calc(${th('subGridUnit')} * 2); - - a { - align-items: center; - display: flex; - } - - button { - background-color: transparent; - border: none; - cursor: pointer; - - &:active, - &:focus { - outline: none; - } - } -` -const FileName = styled.span` - ${defaultText}; - margin: 0 ${th('subGridUnit')}; -` -const FileSize = FileName.extend` - margin-left: ${th('subGridUnit')}; -` - -const FileRoot = styled.div` - align-items: center; - border: ${th('borderDefault')}; - display: flex; - flex-direction: row; - margin-bottom: ${th('subGridUnit')}; - margin-right: ${th('subGridUnit')}; - padding: ${th('subGridUnit')}; -` -// #endregion diff --git a/packages/components-faraday/src/components/Files/FilePicker.js b/packages/components-faraday/src/components/Files/FilePicker.js deleted file mode 100644 index 779c42ec7535994bf253f512dd6c6a87167c2673..0000000000000000000000000000000000000000 --- a/packages/components-faraday/src/components/Files/FilePicker.js +++ /dev/null @@ -1,43 +0,0 @@ -import React, { Component } from 'react' - -class FilePicker extends Component { - handleUpload = e => { - const { onUpload } = this.props - - onUpload(e.target.files[0]) - this.fileInput.value = null - } - - getAllowedTypes = () => { - const { allowedFileExtensions } = this.props - - if (!allowedFileExtensions) { - return [] - } - - return allowedFileExtensions.map(ext => `.${ext}`) - } - - render() { - const { children, disabled } = this.props - return ( - <div> - <input - accept={this.getAllowedTypes()} - onChange={this.handleUpload} - ref={input => (this.fileInput = input)} - style={{ display: 'none' }} - type="file" - /> - {React.cloneElement(children, { - onClick: e => { - e.preventDefault() - !disabled && this.fileInput.click() - }, - })} - </div> - ) - } -} - -export default FilePicker diff --git a/packages/components-faraday/src/components/Files/FilePreview.js b/packages/components-faraday/src/components/Files/FilePreview.js deleted file mode 100644 index 161781195584ff55bf435f28259b69b2b2368a7d..0000000000000000000000000000000000000000 --- a/packages/components-faraday/src/components/Files/FilePreview.js +++ /dev/null @@ -1,28 +0,0 @@ -import React from 'react' -import { Icon } from '@pubsweet/ui' -import { connect } from 'react-redux' -import { compose, withHandlers } from 'recompose' - -import { Components } from './' -import { getSignedUrl } from '../../redux/files' - -const FilePreview = ({ previewFile }) => ( - <Components.IconButton onClick={previewFile}> - <Icon primary size={3}> - eye - </Icon> - </Components.IconButton> -) - -export default compose( - connect(null, { getSignedUrl }), - withHandlers({ - previewFile: ({ fileId, getSignedUrl }) => e => { - e.preventDefault() - const windowReference = window.open() - getSignedUrl(fileId).then(({ signedUrl }) => { - windowReference.location = signedUrl - }) - }, - }), -)(FilePreview) diff --git a/packages/components-faraday/src/components/Files/FileSection.js b/packages/components-faraday/src/components/Files/FileSection.js deleted file mode 100644 index 148c51a92a5b52d186eff5450ad08ee6fd80377b..0000000000000000000000000000000000000000 --- a/packages/components-faraday/src/components/Files/FileSection.js +++ /dev/null @@ -1,282 +0,0 @@ -import React from 'react' -import PropTypes from 'prop-types' -import { DropTarget } from 'react-dnd' -import { th } from '@pubsweet/ui-toolkit' -import { Icon, Spinner } from '@pubsweet/ui' -import styled, { withTheme } from 'styled-components' -import { NativeTypes } from 'react-dnd-html5-backend' -import { compose, getContext, withHandlers, withState } from 'recompose' -import { SortableList } from 'pubsweet-components-faraday/src/components' - -import FileItem from './FileItem' -import FilePicker from './FilePicker' - -const DragHandle = () => ( - <Handle> - <Icon primary size={3}> - chevron_up - </Icon> - <Icon primary size={3}> - menu - </Icon> - <Icon primary size={3}> - chevron_down - </Icon> - </Handle> -) - -const FileSection = ({ - error, - title, - files, - theme, - listId, - isOver, - isLast, - isFirst, - addFile, - canDrop, - moveItem, - isFileOver, - removeFile, - isFetching, - canDropFile, - requestPending, - connectFileDrop, - dropSortableFile, - connectDropTarget, - disabledFilepicker, - allowedFileExtensions, -}) => ( - <DropSection - innerRef={instance => { - connectFileDrop(instance) - connectDropTarget(instance) - }} - isFirst={isFirst} - isLast={isLast} - over={isFileOver || (isOver && canDrop)} - > - <Header> - <PickerContainer data-test={`upload-${listId}`}> - <Title>{title}</Title> - {!isFetching[listId] ? ( - <FilePicker - allowedFileExtensions={allowedFileExtensions} - disabled={disabledFilepicker()} - onUpload={addFile} - > - <UploadButton - data-test={`button-upload-${listId}`} - disabled={disabledFilepicker()} - > - <Icon - color={ - disabledFilepicker() - ? theme.colorSecondary - : theme.colorPrimary - } - > - file-plus - </Icon> - </UploadButton> - </FilePicker> - ) : ( - <Spinner /> - )} - </PickerContainer> - <Error>{error}</Error> - </Header> - <SortableList - beginDragProps={['id', 'index', 'name', 'listId']} - dragHandle={DragHandle} - dropItem={requestPending() ? null : dropSortableFile} - items={files} - listId={listId} - listItem={FileItem} - moveItem={moveItem} - removeFile={removeFile} - /> - <InfoContainer> - <span>Drag files here or use the add button.</span> - </InfoContainer> - </DropSection> -) - -export default compose( - withTheme, - getContext({ - isFetching: PropTypes.object, - }), - withState('error', 'setError', ''), - withHandlers({ - clearError: ({ setError }) => () => { - setError(e => '') - }, - requestPending: ({ isFetching }) => () => - Object.values(isFetching).some(Boolean), - }), - withHandlers({ - setError: ({ setError, clearError }) => err => { - setError(e => err, () => setTimeout(clearError, 3000)) - }, - disabledFilepicker: ({ - files, - maxFiles, - isFetching, - requestPending, - }) => () => files.length >= maxFiles || requestPending(), - }), - DropTarget( - 'item', - { - drop( - { - files, - maxFiles, - setError, - changeList, - listId: toListId, - allowedFileExtensions, - }, - monitor, - ) { - const { listId: fromListId, id, name } = monitor.getItem() - const fileExtention = name.split('.')[1] - - if ( - allowedFileExtensions && - !allowedFileExtensions.includes(fileExtention) - ) { - setError('Invalid file type.') - return - } - - if (files.length >= maxFiles) { - setError('No more files can be added to this section.') - return - } - if (toListId === fromListId) return - changeList(fromListId, toListId, id) - }, - canDrop({ listId: toListId, setError }, monitor) { - const { listId: fromListId } = monitor.getItem() - return toListId !== fromListId - }, - }, - (connect, monitor) => ({ - connectDropTarget: connect.dropTarget(), - isOver: monitor.isOver(), - canDrop: monitor.canDrop(), - }), - ), - DropTarget( - NativeTypes.FILE, - { - drop( - { - files, - addFile, - maxFiles, - setError, - requestPending, - allowedFileExtensions, - }, - monitor, - ) { - const [file] = monitor.getItem().files - const fileExtention = file.name.split('.')[1] - - if (files.length >= maxFiles) { - setError('No more files can be added to this section.') - return - } - - if ( - allowedFileExtensions && - !allowedFileExtensions.includes(fileExtention) - ) { - setError('Invalid file type.') - } else { - !requestPending() && addFile(file) - } - }, - }, - (connect, monitor) => ({ - isFileOver: monitor.isOver(), - canDropFile: monitor.canDrop(), - connectFileDrop: connect.dropTarget(), - }), - ), -)(FileSection) - -// #region styles -const Error = styled.span` - color: ${th('colorError')}; - font-size: ${th('fontSizeBaseSmall')}; - margin-right: ${th('subGridUnit')}; -` - -const UploadButton = styled.div` - cursor: ${({ disabled }) => (disabled ? 'not-allowed' : 'pointer')}; - display: flex; - margin-left: ${th('subGridUnit')}; -` - -const PickerContainer = styled.div` - align-items: center; - display: flex; - flex: 1; -` - -const Title = styled.span` - margin: ${th('subGridUnit')}; - text-transform: uppercase; -` - -const Header = styled.div` - align-items: center; - display: flex; - justify-content: flex-start; -` - -const DropSection = styled.div` - border: ${th('borderDefault')}; - border-top: ${({ isFirst, theme }) => - isFirst ? theme.borderDefault : 'none'}; - border-bottom: ${({ isLast, theme }) => - isLast ? theme.borderDefault : `1px dashed ${theme.colorBorder}`}; - background-color: ${({ theme, over }) => - over ? theme.colorSecondary : theme.backgroundColorReverse}; - display: flex; - flex-direction: column; - padding: ${th('subGridUnit')}; -` - -const Handle = styled.div` - align-items: center; - border-right: ${th('borderDefault')}; - cursor: move; - display: flex; - flex-direction: column; - justify-content: center; - margin-right: calc(${th('subGridUnit')} * 2); - padding: calc(${th('subGridUnit')} / 2); - span { - padding: 0; - } -` - -const InfoContainer = styled.div` - align-items: center; - display: flex; - height: calc(${th('subGridUnit')} * 10); - justify-content: center; - margin: calc(${th('subGridUnit')} * 2) 0; - - span { - color: ${th('colorTextPlaceholder')}; - font-size: ${th('fontSizeBaseSmall')}; - } -` -// #endregion diff --git a/packages/components-faraday/src/components/Files/Files.js b/packages/components-faraday/src/components/Files/Files.js deleted file mode 100644 index 79061796ae135cf5f066fa0bf020cb84b0394c2f..0000000000000000000000000000000000000000 --- a/packages/components-faraday/src/components/Files/Files.js +++ /dev/null @@ -1,208 +0,0 @@ -import React, { Fragment } from 'react' -import { get } from 'lodash' -import PropTypes from 'prop-types' -import { connect } from 'react-redux' -import styled from 'styled-components' -import { th } from '@pubsweet/ui-toolkit' -import { withRouter } from 'react-router-dom' -import { change as changeForm } from 'redux-form' -import { selectCurrentVersion } from 'xpub-selectors' -import { - compose, - lifecycle, - withState, - withContext, - withHandlers, -} from 'recompose' -import { SortableList } from 'pubsweet-components-faraday/src/components' - -import FileSection from './FileSection' -import { - uploadFile, - deleteFile, - getFileError, - getRequestStatus, -} from '../../redux/files' - -const Files = ({ - files, - error, - addFile, - moveItem, - removeFile, - changeList, - dropSortableFile, -}) => ( - <Fragment> - <FileSection - addFile={addFile('manuscripts')} - allowedFileExtensions={['pdf', 'doc', 'docx']} - changeList={changeList} - dropSortableFile={dropSortableFile} - files={get(files, 'manuscripts', [])} - isFirst - listId="manuscripts" - maxFiles={Number.POSITIVE_INFINITY} - moveItem={moveItem('manuscripts')} - removeFile={removeFile('manuscripts')} - title="Main manuscript*" - /> - <FileSection - addFile={addFile('supplementary')} - changeList={changeList} - dropSortableFile={dropSortableFile} - files={get(files, 'supplementary', [])} - listId="supplementary" - maxFiles={Number.POSITIVE_INFINITY} - moveItem={moveItem('supplementary')} - removeFile={removeFile('supplementary')} - title="Supplementarry files" - /> - <FileSection - addFile={addFile('coverLetter')} - allowedFileExtensions={['pdf', 'doc', 'docx']} - changeList={changeList} - dropSortableFile={dropSortableFile} - files={get(files, 'coverLetter', [])} - isLast - listId="coverLetter" - maxFiles={1} - moveItem={moveItem('coverLetter')} - removeFile={removeFile('coverLetter')} - title="Cover letter*" - /> - <Error show={error}> File error, please try again.</Error> - </Fragment> -) - -export default compose( - withRouter, - connect( - (state, { project, version }) => ({ - error: getFileError(state), - isFetching: getRequestStatus(state), - version: selectCurrentVersion(state, project), - }), - { - changeForm, - uploadFile, - deleteFile, - }, - ), - withState('files', 'setFiles', { - manuscripts: [], - coverLetter: [], - supplementary: [], - }), - lifecycle({ - componentDidMount() { - const { version, setFiles, filePath = 'files' } = this.props - setFiles(prev => ({ - manuscripts: get(version, `${filePath}.manuscripts`, []), - coverLetter: get(version, `${filePath}.coverLetter`, []), - supplementary: get(version, `${filePath}.supplementary`, []), - })) - }, - }), - withHandlers({ - dropSortableFile: ({ - files, - setFiles, - changeForm, - parentForm = 'wizard', - }) => (otherProps, dragProps) => { - // do something if the file is not changing list - const { listId: fromListId } = otherProps - const { listId: toListId } = dragProps - if (fromListId === toListId) { - setFiles(files) - changeForm(parentForm, 'files', files) - } - }, - changeList: ({ files, setFiles, changeForm, parentForm = 'wizard' }) => ( - fromListId, - toListId, - id, - ) => { - const swappedFile = files[fromListId].find(f => f.id === id) - - const fromFiles = files[fromListId].filter(f => f.id !== id) - const toFiles = [...files[toListId], swappedFile] - - const newFiles = { - ...files, - [toListId]: toFiles, - [fromListId]: fromFiles, - } - setFiles(newFiles) - changeForm(parentForm, 'files', newFiles) - }, - addFile: ({ - files, - version, - setFiles, - uploadFile, - changeForm, - parentForm = 'wizard', - }) => type => file => { - uploadFile(file, type, version) - .then(file => { - const newFiles = { - ...files, - [type]: [...files[type], file], - } - setFiles(newFiles) - changeForm(parentForm, 'files', newFiles) - }) - .catch(e => console.error(`Couldn't upload file.`, e)) - }, - moveItem: ({ moveFiles, files, setFiles }) => type => ( - dragIndex, - hoverIndex, - ) => { - const newFiles = { - ...files, - [type]: SortableList.moveItem(files[type], dragIndex, hoverIndex), - } - setFiles(newFiles) - }, - removeFile: ({ - files, - version, - setFiles, - changeForm, - deleteFile, - parentForm = 'wizard', - }) => type => id => e => { - e.preventDefault() - deleteFile(id, type) - .then(() => { - const newFiles = { - ...files, - [type]: files[type].filter(f => f.id !== id), - } - setFiles(newFiles) - changeForm(parentForm, 'files', newFiles) - }) - .catch(e => console.error(`Couldn't delete file.`, e)) - }, - }), - withContext( - { - isFetching: PropTypes.object, - }, - ({ isFetching }) => ({ - isFetching, - }), - ), -)(Files) - -// #region styles -const Error = styled.div` - color: firebrick; - display: flex; - justify-content: flex-end; - margin: ${th('subGridUnit')} 0; - opacity: ${({ show }) => (show ? 1 : 0)}; -` -// #endregion diff --git a/packages/components-faraday/src/components/Files/ZipFiles.js b/packages/components-faraday/src/components/Files/ZipFiles.js deleted file mode 100644 index 00c8a54bdec3d0dea15156cd59d60b62ace2a71e..0000000000000000000000000000000000000000 --- a/packages/components-faraday/src/components/Files/ZipFiles.js +++ /dev/null @@ -1,97 +0,0 @@ -import React from 'react' -import qs from 'querystring' -import PropTypes from 'prop-types' -import { connect } from 'react-redux' -import styled from 'styled-components' -import { compose, withHandlers, withState } from 'recompose' - -import { Spinner } from '../UIComponents/index' -import { currentUserIsReviewer } from '../../redux/reviewers' -import { createAnchorElement, removeAnchorElement } from './utils' -import { getUserToken } from '../../../../component-faraday-selectors' - -const ZipFiles = ({ disabled, fetching, children, downloadFiles }) => ( - <Root onClick={!disabled ? downloadFiles : null}> - {fetching ? <Spinner /> : children} - </Root> -) - -const cache = {} - -const reviewerFiles = ['manuscripts', 'supplementary'] -const defaultFiles = [...reviewerFiles, 'coverLetter'] - -const Zip = compose( - connect((state, { collectionId }) => ({ - token: getUserToken(state), - isReviewer: currentUserIsReviewer(state, collectionId), - })), - withState('fetching', 'setFetching', false), - withHandlers({ - downloadFiles: ({ - token, - isReviewer, - fragmentId, - setFetching, - archiveName, - }) => () => { - const getUrl = `${ - window.location.origin - }/api/files/${fragmentId}?${qs.stringify({ - fileTypes: isReviewer ? reviewerFiles : defaultFiles, - })}` - if (cache[fragmentId]) { - const fileName = archiveName || `${fragmentId}-archive.zip` - - const { a, url } = createAnchorElement(cache[fragmentId], fileName) - a.click() - removeAnchorElement(a, url) - } else { - setFetching(fetching => true) - const xhr = new XMLHttpRequest() - xhr.onreadystatechange = function onXhrStateChange() { - if (this.readyState === 4) { - setFetching(fetching => false) - if (this.status >= 200 && this.status < 300) { - const fileName = archiveName || `${fragmentId}-archive.zip` - const f = new File([this.response], fileName, { - type: 'application/zip', - }) - cache[fragmentId] = f - - const { a, url } = createAnchorElement(f, fileName) - a.click() - removeAnchorElement(a, url) - } - } - } - xhr.open('GET', getUrl) - xhr.responseType = 'blob' - xhr.setRequestHeader('Authorization', `Bearer ${token}`) - xhr.send() - } - }, - }), -)(ZipFiles) - -Zip.propTypes = { - disabled: PropTypes.bool, - archiveName: PropTypes.string, - fragmentId: PropTypes.string.isRequired, -} - -Zip.defaultProps = { - disabled: false, -} - -export default Zip - -// #region styled components -const Root = styled.div` - align-items: center; - cursor: pointer; - display: flex; - margin: 0 7px; - width: 38px; -` -// #endregion diff --git a/packages/components-faraday/src/components/Files/index.js b/packages/components-faraday/src/components/Files/index.js deleted file mode 100644 index f44c5fae94d711342751c9c0afc746198efabded..0000000000000000000000000000000000000000 --- a/packages/components-faraday/src/components/Files/index.js +++ /dev/null @@ -1,8 +0,0 @@ -import * as Components from './Components' - -export { Components } -export { default as Files } from './Files' -export { default as FileItem } from './FileItem' -export { default as FilePicker } from './FilePicker' -export { default as FilePreview } from './FilePreview' -export { default as FileDownload } from './FileDownload' diff --git a/packages/components-faraday/src/components/Files/utils.js b/packages/components-faraday/src/components/Files/utils.js deleted file mode 100644 index 7f8d91c1499cddd8fa9bb9624aea50595f7be6e7..0000000000000000000000000000000000000000 --- a/packages/components-faraday/src/components/Files/utils.js +++ /dev/null @@ -1,18 +0,0 @@ -export const createAnchorElement = (file, filename) => { - const url = URL.createObjectURL(file) - const a = document.createElement('a') - - a.href = url - a.download = filename - document.body.appendChild(a) - - return { - a, - url, - } -} - -export const removeAnchorElement = (a, url) => { - document.body.removeChild(a) - URL.revokeObjectURL(url) -} diff --git a/packages/components-faraday/src/components/SortableList/SortableList.js b/packages/components-faraday/src/components/SortableList/SortableList.js deleted file mode 100644 index 0858630f0aa568f250de046bc4270b0a6e0666f6..0000000000000000000000000000000000000000 --- a/packages/components-faraday/src/components/SortableList/SortableList.js +++ /dev/null @@ -1,133 +0,0 @@ -import React from 'react' -import { pick } from 'lodash' -import { compose } from 'recompose' -import { findDOMNode } from 'react-dom' -import { DragSource, DropTarget } from 'react-dnd' - -const itemSource = { - beginDrag(props) { - return pick(props, props.beginDragProps) - }, -} - -const itemTarget = { - hover({ moveItem, index, listId }, monitor, component) { - const { index: dragIndex, listId: toListId } = monitor.getItem() - const hoverIndex = index - - if (listId !== toListId) { - return - } - - // Don't replace items with themselves - if (dragIndex === hoverIndex) { - return - } - - const hoverBoundingRect = findDOMNode(component).getBoundingClientRect() // eslint-disable-line - const hoverMiddleY = (hoverBoundingRect.bottom - hoverBoundingRect.top) / 2 - const clientOffset = monitor.getClientOffset() - const hoverClientY = clientOffset.y - hoverBoundingRect.top - - if (dragIndex < hoverIndex && hoverClientY < hoverMiddleY) { - return - } - - if (dragIndex > hoverIndex && hoverClientY > hoverMiddleY) { - return - } - if (typeof moveItem === 'function') { - moveItem(dragIndex, hoverIndex) - } - monitor.getItem().index = hoverIndex - }, - drop({ dropItem, ...restProps }, monitor) { - if (dropItem && typeof dropItem === 'function') - dropItem(restProps, monitor.getItem()) - }, -} - -const Item = ({ - connectDragPreview, - connectDragSource, - connectDropTarget, - listItem, - dragHandle, - ...rest -}) => - dragHandle - ? connectDragPreview( - connectDropTarget( - <div style={{ flex: 1 }}> - {React.createElement(listItem, { - ...rest, - dragHandle: connectDragSource( - <div style={{ display: 'flex' }}> - {React.createElement(dragHandle)} - </div>, - ), - })} - </div>, - ), - ) - : connectDropTarget( - connectDragSource( - <div style={{ flex: 1 }}>{React.createElement(listItem, rest)}</div>, - ), - ) - -const DecoratedItem = compose( - DropTarget('item', itemTarget, (connect, monitor) => ({ - connectDropTarget: connect.dropTarget(), - isOver: monitor.isOver(), - })), - DragSource('item', itemSource, (connect, monitor) => ({ - connectDragSource: connect.dragSource(), - connectDragPreview: connect.dragPreview(), - isDragging: monitor.isDragging(), - })), -)(Item) - -const SortableList = ({ - items = [], - itemKey = 'id', - moveItem, - listItem, - dragHandle, - editItem, - ...rest -}) => ( - <div> - {items.map((item, i) => ( - <DecoratedItem - dragHandle={dragHandle} - index={i} - key={item[itemKey]} - listItem={listItem} - moveItem={moveItem} - {...item} - {...rest} - /> - ))} - </div> -) - -// helper function for sortable lists -SortableList.moveItem = (items, dragIndex, hoverIndex) => { - if (dragIndex <= hoverIndex) { - return [ - ...items.slice(0, dragIndex), - items[hoverIndex], - items[dragIndex], - ...items.slice(hoverIndex + 1), - ] - } - return [ - ...items.slice(0, hoverIndex), - items[dragIndex], - items[hoverIndex], - ...items.slice(dragIndex + 1), - ] -} - -export default SortableList diff --git a/packages/components-faraday/src/components/SortableList/SortableList.md b/packages/components-faraday/src/components/SortableList/SortableList.md deleted file mode 100644 index 3eb03059c3b668e86c210ea3c31221abb05349ec..0000000000000000000000000000000000000000 --- a/packages/components-faraday/src/components/SortableList/SortableList.md +++ /dev/null @@ -1,78 +0,0 @@ -A sortable list implemented with `react-dnd`. - -## Props - -| Prop | Description | Required | Default | Type | -| :--------: | :------------------------------------------------------------------------------------------------------------------------------------------: | :------: | :-------------------: | :---: | -| items | The items of the sortable list. | true | [] | Array | -| itemKey | Value used for key when mapping over items. | true | 'id' | string | -| listItem | A React component that will be rendered for each item of the list. Receives `isDragging`, `isOver` and all other props from the items array. | true | none | React component | -| moveItem | Function to be called when moving an item through the list. SortableList will provide the dragIndex of hoverIndex of the items. | true | none | function | -| dragHandle | A React component for the drag handle. If not present, the whole item can be dragged. | false | none | React component | -| dropItem | Function to be called when dropping an item. The index of the dragged item is passed. | false | none | function | -| beginDragProps | Array of keys to pick from the dragged object when beginning drag. | false | [] | Array(string) | - -## Usage - -### Pass in a list of users - -```js -const items = [ - {firstName: 'John', lastName: 'Doe'}, - {firstName: 'Michael', lastName: 'Jackson'}, - {firstName: 'David', lastName: 'Blaine'}, -] - -const Item = ({ isOver, isDragging, ...rest }) => - <div>`${rest.firstName} ${rest.lastName}`</div> - -<SortableList - items={items} - listItem={Item} - moveItem={(dragIndex, hoverIndex) => change items} - /> -``` - -### With custom drag handle -```js -const DragHandle = () => <div>Drag me!</div> - -const ItemWithDragHandle = ({ dragHandle, ...rest }) => <div> - {dragHandle} - <span>Rest of the content.</span> - </div> - -<SortableList - ... - listItem={ItemWithDragHandle} - dragHandle={DragHandle} - ... - /> -``` - -### How to move items around - -To move items of the parent container whenever `moveItem` function is called we can use the `SortableList.moveItem` helper. More info in the example below. - -```js -const Container = ({ moveItem, items }) => <div> - ... - <SortableList - items={items} - listItem={Item} - moveItem={moveItem} - /> - ... - </div> -``` -Enhanced using recompose -```js -const MoveExample = compose( - withState('items', 'setItems', [{name: 'John'}, {name: 'Nancy'}, {name: 'Adam'}]), - withHandlers({ - moveItem: ({ setItems, items }) => (dragIndex, hoverIndex) => { - setItems(prevItems => SortableList.moveItem(prevItems, dragIndex, hoverIndex)) - } - }) -)(Container) -``` diff --git a/packages/components-faraday/src/components/Steps/Steps.js b/packages/components-faraday/src/components/Steps/Steps.js deleted file mode 100644 index d5b51ffbd2e4f66a2a6c3205fc1e1867c544192c..0000000000000000000000000000000000000000 --- a/packages/components-faraday/src/components/Steps/Steps.js +++ /dev/null @@ -1,107 +0,0 @@ -import React from 'react' -import PropTypes from 'prop-types' -import { th } from '@pubsweet/ui-toolkit' -import styled, { css } from 'styled-components' -import { compose, withHandlers, setDisplayName } from 'recompose' - -const Separator = styled.div` - background-color: ${th('colorPrimary')}; - flex: 1; - height: 2px; -` - -const StyledStep = styled.div` - align-items: center; - border: ${th('borderDefault')}; - border-radius: 50%; - display: flex; - justify-content: center; - position: relative; - height: calc(${th('subGridUnit')} * 3); - width: calc(${th('subGridUnit')} * 3); -` - -const bulletStyle = css` - background-color: ${th('colorPrimary')}; - border-radius: 50%; - height: calc(${th('subGridUnit')} * 2); - width: calc(${th('subGridUnit')} * 2); -` - -const Bullet = styled.div` - ${bulletStyle}; -` - -const Success = styled.div` - ${bulletStyle}; - align-items: center; - color: ${th('colorBackground')}; - display: flex; - font-size: ${th('fontSizeBaseSmall')}; - height: ${th('fontSizeBase')}; - justify-content: center; - width: ${th('fontSizeBase')}; -` - -const StepTitle = styled.span` - font-size: ${th('fontSizeBaseSmall')}; - line-height: ${th('fontSizeBaseSmall')}; - left: -45px; - position: absolute; - text-align: center; - top: 25px; - white-space: normal; - width: 120px; -` - -const Root = styled.div` - align-items: center; - display: flex; - flex-direction: row; - justify-content: space-between; - margin: ${({ margin }) => margin || '20px'}; - min-width: 500px; -` - -const Step = ({ title, index, currentStep }) => ( - <StyledStep> - {index === currentStep && <Bullet />} - {index < currentStep && <Success>✓</Success>} - <StepTitle>{`${index + 1}. ${title}`}</StepTitle> - </StyledStep> -) - -const Steps = ({ renderSteps, margin }) => ( - <Root margin={margin}>{renderSteps()}</Root> -) - -const DecoratedSteps = compose( - setDisplayName('Steps'), - withHandlers({ - renderSteps: ({ children, renderSeparator, currentStep }) => () => { - const separator = renderSeparator || Separator - return React.Children.toArray(children).reduce( - (acc, el, index, arr) => - index === arr.length - 1 - ? [...acc, React.cloneElement(el, { index, currentStep })] - : [ - ...acc, - React.cloneElement(el, { index, currentStep }), - React.createElement(separator, { key: `sep-${el.key}` }), - ], - [], - ) - }, - }), -)(Steps) - -DecoratedSteps.Step = Step -DecoratedSteps.Separator = Separator - -DecoratedSteps.propTypes = { - currentStep: PropTypes.number.isRequired, - renderSeparator: PropTypes.func, - margin: PropTypes.string, -} - -export default DecoratedSteps diff --git a/packages/components-faraday/src/components/Steps/Steps.md b/packages/components-faraday/src/components/Steps/Steps.md deleted file mode 100644 index 339ade0de348642f71f17d86972462f7e62a9490..0000000000000000000000000000000000000000 --- a/packages/components-faraday/src/components/Steps/Steps.md +++ /dev/null @@ -1,58 +0,0 @@ -# Steps - -`Steps` is a navigation bar that guides users through the steps of a task. Use it whenever there is a sequence of tasks or steps that need to be done. By default the `Steps` modules has a `Step` and `Separator` default components, but custom components with different styles can be used as shown in the examples below. - -## Props - -| Prop | Description | Required | Default | Type | -| :-------------: | :---------------------------------------------------------------: | :------: | :-----: | :-------------: | -| currentStep | The current step of the wizard. | true | null | number | -| renderSeparator | Separator component to be rendered between two adjacent children. | false | null | React component | - -## Examples - -1.Usage with the Step component. - -```js -import { Steps } from 'pubsweet-components-faraday/src/components' -const { Step } = Steps - -<Steps currentStep={1}> - <Step title="First step" /> - <Step title="Second step" /> - <Step title="Third step" /> -</Steps> -``` - -2.Usage with a custom step component - -```js -const StepComponent = ({ index, currentStep, customProp }) => <div> - I am a custom component at step {index} / {currentStep} with a {customProp}. -</div> - -<Steps currentStep={1}> - <StepComponent customProp="Hei" /> - <StepComponent customProp="Ho" /> - <StepComponent customProp="Let's go!" /> -</Steps> -``` - -Each child of the Steps component has access to the `currentStep` and also it's own `index`. - -3.Usage with a custom separator -When the default separator is not what you want you can always pass a custom separator component. This custom separator will be placed between each two adjacent children. - -```js -const Separator = () => ( - <div style={{ backgroundColor: 'pink', flex: 1, height: 10 }}> - DIVIDER OF WORLDS - </div> -) - -<Steps currentStep={1} renderSeparator={Separator}> - <StepComponent customProp="Hei" /> - <StepComponent customProp="Ho" /> - <StepComponent customProp="Let's go!" /> -</Steps> -``` diff --git a/packages/components-faraday/src/components/UIComponents/ConfirmationPage.js b/packages/components-faraday/src/components/UIComponents/ConfirmationPage.js deleted file mode 100644 index bcb58a30fba583779012121aa362217a97785864..0000000000000000000000000000000000000000 --- a/packages/components-faraday/src/components/UIComponents/ConfirmationPage.js +++ /dev/null @@ -1,87 +0,0 @@ -import React from 'react' -import { compose } from 'recompose' -import { connect } from 'react-redux' -import { get, isEmpty } from 'lodash' -import { Button } from '@pubsweet/ui' -import styled from 'styled-components' -import { th } from '@pubsweet/ui-toolkit' -import { withJournal } from 'xpub-journal' -import { getFragmentAuthors } from 'pubsweet-components-faraday/src/redux/authors' - -const ConfirmationPage = ({ - journal, - history, - authors = [], - location: { state }, -}) => { - const email = get(authors.find(a => a.isCorresponding), 'email') - return ( - <Root> - {isEmpty(state) ? ( - <div> - <Title>Thank you for you submission</Title> - <Button onClick={() => history.push('/')} primary> - Go to Dashboard - </Button> - </div> - ) : ( - <div> - <Title>Thank You for Submitting Your Manuscript</Title> - <p> - Your manuscript has been successfully submitted to{' '} - <b>{journal.metadata.nameText}</b> and assigned the manuscript ID{' '} - <b> - {' '} - <a - href={`/projects/${state.project}/versions/${ - state.version - }/details`} - > - {state.customId} - </a> - </b>. - </p> - <p> - An acknowledgement email will be sent to {email} when our system has - finished processing the submission. At that point, you will be able - to track the status of your submission. Please note, this may take a - few minutes. - </p> - <p> - {`You can keep track of your submission's progress on your dashboard.`} - </p> - <Button onClick={() => history.push('/')} primary> - Go to Dashboard - </Button> - </div> - )} - </Root> - ) -} - -export default compose( - withJournal, - connect((state, { location: { state: locationState } }) => ({ - authors: getFragmentAuthors(state, get(locationState, 'version')), - })), -)(ConfirmationPage) - -// #region styles -const Root = styled.div` - color: ${th('colorText')}; - margin: 0 auto; - text-align: center; - width: 70vw; - - a { - color: ${th('colorText')}; - } -` - -const Title = styled.div` - color: ${th('colorPrimary')}; - font-size: ${th('fontSizeHeading5')}; - font-family: ${th('fontHeading')}; - margin: ${th('gridUnit')} auto; -` -// #endregion diff --git a/packages/components-faraday/src/components/UIComponents/Logo.js b/packages/components-faraday/src/components/UIComponents/Logo.js deleted file mode 100644 index c13036c24def5a3eeb234d2ce9b288973d0e25a1..0000000000000000000000000000000000000000 --- a/packages/components-faraday/src/components/UIComponents/Logo.js +++ /dev/null @@ -1,9 +0,0 @@ -import React from 'react' - -const Logo = ({ srcUrl, onClick }) => ( - <div onClick={onClick}> - <img alt="Hindawi" height="36" src={srcUrl} title="Hindawi" /> - </div> -) - -export default Logo diff --git a/packages/components-faraday/src/components/UIComponents/Spinner.js b/packages/components-faraday/src/components/UIComponents/Spinner.js deleted file mode 100644 index 635697bd1d6e7f33e009bfa9cb3e011eebd36b37..0000000000000000000000000000000000000000 --- a/packages/components-faraday/src/components/UIComponents/Spinner.js +++ /dev/null @@ -1,38 +0,0 @@ -import React from 'react' -import { Icon } from '@pubsweet/ui' -import styled, { keyframes } from 'styled-components' - -const Spinner = ({ icon = 'loader', size = 3, color = '#444' }) => ( - <Root> - <Icon color={color} size={size}> - {icon} - </Icon> - </Root> -) - -const rotating = keyframes` - from { - -o-transform: rotate(0deg); - -ms-transform: rotate(0deg); - -moz-transform: rotate(0deg); - -webkit-transform: rotate(0deg); - transform: rotate(0deg); - } - - to { - -o-transform: rotate(360deg); - -ms-transform: rotate(360deg); - -moz-transform: rotate(360deg); - -webkit-transform: rotate(360deg); - transform: rotate(360deg); - } -` - -const Root = styled.div` - align-items: center; - display: flex; - justify-content: center; - animation: ${rotating} 1.5s linear infinite; -` - -export default Spinner diff --git a/packages/components-faraday/src/components/UIComponents/Spinner.md b/packages/components-faraday/src/components/UIComponents/Spinner.md deleted file mode 100644 index bfcff7255f991f51dbbaa65acea0e9e07a00d41d..0000000000000000000000000000000000000000 --- a/packages/components-faraday/src/components/UIComponents/Spinner.md +++ /dev/null @@ -1,21 +0,0 @@ -# Spinner - -Spinning icon used when loading or waiting for API calls to finish. - -## Props - -| Prop | Description | Required | Default | Type | -| :---: | :--------------------------------------------------------------------------: | :------: | :------: | :----: | -| icon | Name of the icon to be used as a spinner. Can be any valid FeatherIcon icon. | false | 'loader' | string | -| size | The size of the spinner | false | 16 | number | -| color | Color of the spinner. | false | '#444' | string | - -## Examples - -```js -<Spinner /> -``` - -```js -<Spinner color="pink" size={40} icon="compass" /> -``` \ No newline at end of file diff --git a/packages/components-faraday/src/components/UIComponents/index.js b/packages/components-faraday/src/components/UIComponents/index.js index ff001b8fb3a18548136a1a88e64816e3cde7a4b8..6516ccc64fa09fc7f1295219470082a7d61efe08 100644 --- a/packages/components-faraday/src/components/UIComponents/index.js +++ b/packages/components-faraday/src/components/UIComponents/index.js @@ -1,13 +1,10 @@ import * as FormItems from './FormItems' export { FormItems } -export { default as Logo } from './Logo' -export { default as Spinner } from './Spinner' export { default as NotFound } from './NotFound' export { default as InfoPage } from './InfoPage' export { default as ErrorPage } from './ErrorPage' export { default as DateParser } from './DateParser' export { default as EQSDecisionPage } from './EQSDecisionPage' export { default as EQADecisionPage } from './EQADecisionPage' -export { default as ConfirmationPage } from './ConfirmationPage' export { default as BreadcrumbsHeader } from './BreadcrumbsHeader' diff --git a/packages/components-faraday/src/components/index.js b/packages/components-faraday/src/components/index.js index bc0fbc83d5440e8a65ad9fa27f6d7e0373411056..fc041eee217e057b7d9fc089069fdd4181f0d893 100644 --- a/packages/components-faraday/src/components/index.js +++ b/packages/components-faraday/src/components/index.js @@ -3,23 +3,11 @@ import * as Components from './UIComponents' import { Recommendation } from './MakeRecommendation' export { FormItems } from './UIComponents' -export { default as Steps } from './Steps/Steps' -export { default as Files } from './Files/Files' -export { default as AppBar } from './AppBar/AppBar' -export { default as AuthorList } from './AuthorList/AuthorList' export { default as withVersion } from './Dashboard/withVersion.js' -export { default as SortableList } from './SortableList/SortableList' export { default as UserProfilePage } from './UserProfile/UserProfilePage' export { default as ChangePasswordPage } from './UserProfile/ChangePasswordPage' export { Decision } export { Components } export { Recommendation } -export { DragHandle } from './AuthorList/FormItems' -export { - Dropdown, - DateParser, - Logo, - Spinner, - BreadcrumbsHeader, -} from './UIComponents' +export { DateParser } from './UIComponents' diff --git a/packages/xpub-faraday/app/FaradayApp.js b/packages/xpub-faraday/app/FaradayApp.js index 51b13a81a9773831c2bec76b303c561875169125..4b2e91eb2f832494b9ccb224dd73ce14bd99304d 100644 --- a/packages/xpub-faraday/app/FaradayApp.js +++ b/packages/xpub-faraday/app/FaradayApp.js @@ -63,7 +63,7 @@ const MainContainer = styled.div` display: flex; flex-direction: column; overflow-y: auto; - padding: 0 calc(${th('gridUnit')} * 17); + padding: 0 calc(${th('gridUnit')} * 10); padding-top: calc(${th('appBar.height')} + ${th('gridUnit')} * 3 )}; ` // #endregion