diff --git a/packages/component-aws-s3/.gitignore b/packages/component-aws-s3/.gitignore deleted file mode 100644 index 3614a810088d89d9ccaa28d82401545634874a18..0000000000000000000000000000000000000000 --- a/packages/component-aws-s3/.gitignore +++ /dev/null @@ -1,8 +0,0 @@ -_build/ -api/ -logs/ -node_modules/ -uploads/ -.env.* -.env -config/local*.* \ No newline at end of file diff --git a/packages/component-aws-s3/README.md b/packages/component-aws-s3/README.md deleted file mode 100644 index 94f89caed032ad7806d7c9f9e3a9db0b86fc654e..0000000000000000000000000000000000000000 --- a/packages/component-aws-s3/README.md +++ /dev/null @@ -1,86 +0,0 @@ -# AWS S3 File Upload - -In order to use `component-xpub-aws-s3` you first need to have a `.env` file containing AWS data in the root folder of the starting point of your applications. - -The `.env` file should look like this: -```bash -AWS_ACCESS_KEY = exampleKey -AWS_SECRET_KEY = exampleKey/sads/21 -AWS_REGION = region-name -AWS_BUCKET = bucket-name -``` - -Then, as soon as possible in your app you should add the `dotenv` package: -```js -require('dotenv').config() -``` - -# `component-xpub-aws-s3` API -A list of endpoints that help you upload, download and delete S3 files. - -## Upload a file [POST] -#### Request -`POST /api/file` -#### Request body -``` -Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryWfPNVh4wuWBlyEyQ - -------WebKitFormBoundaryWfPNVh4wuWBlyEyQ -Content-Disposition: form-data; name="fileType" - -supplementary -------WebKitFormBoundaryWfPNVh4wuWBlyEyQ -Content-Disposition: form-data; name="fragmentId" - -545 -------WebKitFormBoundaryWfPNVh4wuWBlyEyQ -Content-Disposition: form-data; name="file"; filename="attachment.txt" -Content-Type: text/plain - -[file content goes there] -------WebKitFormBoundaryWfPNVh4wuWBlyEyQ -``` -#### Response -```json -{ - "id": "fragment-id/file-id", - "name": "Document Name.doc", - "size": 452097 -} -``` - -## Retrieve file signed URL [GET] -This endpoint allows you to retrieve a file's signed URL that can be used to download the file. -#### Request -`GET /api/file/{fileId}` - -| URI Parameter | Requiered | Requirements | Description | -| -------- | -------- | -------- | -------- | -| fileId | Yes | String | The ID of the file | - -#### Response -```json -HTTP/1.1 200 -{ - "signedUrl": "aws-url" -} -``` - -## Delete file [DELETE] -#### Request -`DELETE /api/file/{fileId}` - -| URI Parameter | Requiered | Requirements | Description | -| -------- | -------- | -------- | -------- | -| fileId | Yes | String | The ID of the file | - -#### Response -```json -HTTP/1.1 204 -``` ---- - - - - - diff --git a/packages/component-aws-s3/config/default.js b/packages/component-aws-s3/config/default.js deleted file mode 100644 index a2ddb5d58b13713de19c40c31dacc7fd1ebcf3e5..0000000000000000000000000000000000000000 --- a/packages/component-aws-s3/config/default.js +++ /dev/null @@ -1,7 +0,0 @@ -const path = require('path') - -module.exports = { - 'pubsweet-component-aws-s3': { - validations: path.resolve(__dirname, './upload-validations-test'), - }, -} diff --git a/packages/component-aws-s3/config/upload-validations-test.js b/packages/component-aws-s3/config/upload-validations-test.js deleted file mode 100644 index 23fa37d7d5a7b0403731429eb910f5f402799000..0000000000000000000000000000000000000000 --- a/packages/component-aws-s3/config/upload-validations-test.js +++ /dev/null @@ -1,19 +0,0 @@ -const Joi = require('joi') - -module.exports = { - manuscripts: Joi.any() - .valid([ - 'application/vnd.openxmlformats-officedocument.wordprocessingml.document', - 'application/pdf', - 'application/msword', - ]) - .error(new Error('Only Word documents and PDFs are allowed')), - supplementary: Joi.any(), - coverLetter: Joi.any() - .valid([ - 'application/vnd.openxmlformats-officedocument.wordprocessingml.document', - 'application/pdf', - 'application/msword', - ]) - .error(new Error('Only Word documents and PDFs are allowed')), -} diff --git a/packages/component-aws-s3/index.js b/packages/component-aws-s3/index.js deleted file mode 100644 index 140b65ac0183438e989b7e7f552b3498baa32820..0000000000000000000000000000000000000000 --- a/packages/component-aws-s3/index.js +++ /dev/null @@ -1,5 +0,0 @@ -require('dotenv').config() - -module.exports = { - backend: () => app => require('./src/FileBackend')(app), -} diff --git a/packages/component-aws-s3/package.json b/packages/component-aws-s3/package.json deleted file mode 100644 index 2d3692c09378a039531e3cf23be80d094f3a77ae..0000000000000000000000000000000000000000 --- a/packages/component-aws-s3/package.json +++ /dev/null @@ -1,34 +0,0 @@ -{ - "name": "pubsweet-components-aws-s3", - "version": "0.0.1", - "description": "xpub aws s3 configured for faraday", - "license": "MIT", - "files": [ - "src" - ], - "scripts": { - "test": "jest" - }, - "repository": { - "type": "git", - "url": "https://gitlab.coko.foundation/xpub/xpub" - }, - "dependencies": { - "aws-sdk": "^2.185.0", - "body-parser": "^1.17.2", - "multer": "^1.3.0", - "multer-s3": "^2.7.0", - "node-mocks-http": "^1.6.6", - "nodemailer": "^4.4.2" - }, - "peerDependencies": { - "@pubsweet/logger": "^0.0.1", - "pubsweet": "^1.1.1", - "pubsweet-client": "^1.1.1", - "pubsweet-server": "^1.0.1" - }, - "devDependencies": { - "jest": "^22.1.1", - "supertest": "^3.0.0" - } -} diff --git a/packages/component-aws-s3/src/FileBackend.js b/packages/component-aws-s3/src/FileBackend.js deleted file mode 100644 index 4fb30e1916158653367317a3806001e1752779a7..0000000000000000000000000000000000000000 --- a/packages/component-aws-s3/src/FileBackend.js +++ /dev/null @@ -1,61 +0,0 @@ -const AWS = require('aws-sdk') -const logger = require('@pubsweet/logger') -const config = require('config') -const _ = require('lodash') - -const s3Config = _.get(config, 'pubsweet-component-aws-s3') - -const FileBackend = app => { - const authBearer = app.locals.passport.authenticate('bearer', { - session: false, - }) - AWS.config.update({ - secretAccessKey: s3Config.secretAccessKey, - accessKeyId: s3Config.accessKeyId, - region: s3Config.region, - }) - const s3 = new AWS.S3() - const upload = require('./middeware/upload').setupMulter(s3) - - app.post( - '/api/file', - authBearer, - upload.single('file'), - require('./routeHandlers/postFile'), - ) - app.get('/api/file/:fragmentId/:fileId', authBearer, async (req, res) => { - const params = { - Bucket: s3Config.bucket, - Key: `${req.params.fragmentId}/${req.params.fileId}`, - } - - s3.getSignedUrl('getObject', params, (err, data) => { - if (err) { - res.status(err.statusCode).json({ error: err.message }) - logger.error(err.message) - return - } - - res.status(200).json({ - signedUrl: data, - }) - }) - }) - app.delete('/api/file/:fragmentId/:fileId', authBearer, async (req, res) => { - const params = { - Bucket: s3Config.bucket, - Key: `${req.params.fragmentId}/${req.params.fileId}`, - } - s3.deleteObject(params, (err, data) => { - if (err) { - res.status(err.statusCode).json({ error: err.message }) - logger.error(err.message) - return - } - - res.status(204).json() - }) - }) -} - -module.exports = FileBackend diff --git a/packages/component-aws-s3/src/FileBackend.test.js b/packages/component-aws-s3/src/FileBackend.test.js deleted file mode 100644 index 250e90381ab533fbb563a82784f3b10f063109e6..0000000000000000000000000000000000000000 --- a/packages/component-aws-s3/src/FileBackend.test.js +++ /dev/null @@ -1,89 +0,0 @@ -process.env.NODE_TLS_REJECT_UNAUTHORIZED = '0' -process.env.SUPPRESS_NO_CONFIG_WARNING = true - -const httpMocks = require('node-mocks-http') - -describe('ValidateFile for multer fileFilter', () => { - it('should return TRUE when fileType is supplementary', () => { - const validateFile = require('./middeware/upload').validateFile( - ...buildValidateFileParams('supplementary', 'image/png'), - ) - expect(validateFile).toBe(true) - }) - it('should return TRUE when fileType is manuscripts or coverLetter and the file is either Word Doc or PDF', () => { - const randFileType = getRandValueFromArray(['manuscripts', 'coverLetter']) - const randMimeType = getRandValueFromArray([ - 'application/pdf', - 'application/msword', - 'application/vnd.openxmlformats-officedocument.wordprocessingml.document', - ]) - - const validateFile = require('./middeware/upload').validateFile( - ...buildValidateFileParams(randFileType, randMimeType), - ) - expect(validateFile).toBe(true) - }) - it('should return FALSE when fileType is manuscripts or coverLetter and the file is neither Word Doc or PDF', () => { - const randFileType = getRandValueFromArray(['manuscripts', 'coverLetter']) - const randMimeType = getRandValueFromArray([ - 'text/plain', - 'text/html', - 'image/jpeg', - 'image/png', - ]) - - const validateFile = require('./middeware/upload').validateFile( - ...buildValidateFileParams(randFileType, randMimeType), - ) - expect(validateFile).toBe(false) - }) -}) - -describe('Upload file route handler', () => { - it('should return success when the file passed validation', async () => { - const file = { - key: '123abc', - originalname: 'file.txt', - size: 128, - } - const req = httpMocks.createRequest({ - file, - }) - const res = httpMocks.createResponse() - await require('./routeHandlers/postFile')(req, res) - expect(res.statusCode).toBe(200) - const data = JSON.parse(res._getData()) - expect(data.id).toEqual(file.key) - expect(data.name).toEqual(file.originalname) - expect(data.size).toEqual(file.size) - }) - it('should return an error when the file failed validation', async () => { - const req = httpMocks.createRequest({ - fileValidationError: 'Only Word documents and PDFs are allowed', - }) - const res = httpMocks.createResponse() - await require('./routeHandlers/postFile')(req, res) - expect(res.statusCode).toBe(400) - const data = JSON.parse(res._getData()) - expect(data.error).toEqual(req.fileValidationError) - }) -}) - -const getRandValueFromArray = arr => arr[Math.floor(Math.random() * arr.length)] - -const buildValidateFileParams = (fileType, mimetype) => { - const req = { - body: { - fileType, - }, - } - const file = { - mimetype, - } - const cb = (p1, p2) => { - if (p2 === true) return true - return false - } - - return [req, file, cb] -} diff --git a/packages/component-aws-s3/src/middeware/upload.js b/packages/component-aws-s3/src/middeware/upload.js deleted file mode 100644 index 29aa00bbccc9db9d4221a6dcc0d4b56ad6d5b42d..0000000000000000000000000000000000000000 --- a/packages/component-aws-s3/src/middeware/upload.js +++ /dev/null @@ -1,47 +0,0 @@ -const multer = require('multer') -const multerS3 = require('multer-s3') -const uuid = require('uuid') -const Joi = require('joi') -const _ = require('lodash') -const config = require('config') - -const s3Config = _.get(config, 'pubsweet-component-aws-s3') -const uploadValidations = require(s3Config.validations) - -const setupMulter = s3 => { - const upload = multer({ - storage: multerS3({ - s3, - bucket: s3Config.bucket, - contentType: (req, file, cb) => { - cb(null, file.mimetype) - }, - key: (req, file, cb) => { - const fileKey = `${req.body.fragmentId}/${uuid.v4()}` - cb(null, fileKey) - }, - }), - fileFilter: (req, file, cb) => validateFile(req, file, cb), - }) - - return upload -} - -const validateFile = (req, file, cb) => { - const { fileType } = req.body - const { mimetype } = file - - const valid = Joi.validate({ [fileType]: mimetype }, uploadValidations) - - if (valid.error) { - req.fileValidationError = valid.error.message - return cb(null, false) - } - - return cb(null, true) -} - -module.exports = { - setupMulter, - validateFile, -} diff --git a/packages/component-aws-s3/src/routeHandlers/postFile.js b/packages/component-aws-s3/src/routeHandlers/postFile.js deleted file mode 100644 index 499c380024682da64f7ab148278aa6e5213f27f4..0000000000000000000000000000000000000000 --- a/packages/component-aws-s3/src/routeHandlers/postFile.js +++ /dev/null @@ -1,15 +0,0 @@ -const logger = require('@pubsweet/logger') - -module.exports = async (req, res) => { - if (req.fileValidationError !== undefined) { - logger.error(req.fileValidationError) - return res.status(400).json({ error: req.fileValidationError }) - } - logger.debug(`${req.file.originalname} has been uploaded`) - - res.status(200).json({ - id: req.file.key, - name: req.file.originalname, - size: req.file.size, - }) -} diff --git a/packages/component-invite/package.json b/packages/component-invite/package.json index 8f82cd7d50bd7f9e4efbe47bab8c7511bc48405b..2dccf4558f2289d8c7c2ac97c6e50d408a2dbe7f 100644 --- a/packages/component-invite/package.json +++ b/packages/component-invite/package.json @@ -11,7 +11,8 @@ }, "repository": { "type": "git", - "url": "https://gitlab.coko.foundation/xpub/xpub" + "url": "https://gitlab.coko.foundation/xpub/xpub", + "path": "component-invite" }, "dependencies": { "body-parser": "^1.17.2", diff --git a/packages/components-faraday/src/components/Dashboard/Dashboard.js b/packages/components-faraday/src/components/Dashboard/Dashboard.js index fbf0cdcb4767a840ceba2db862f9d584d549b3e9..6fb0797f1e44e513604adfb3cc14886fd4738687 100644 --- a/packages/components-faraday/src/components/Dashboard/Dashboard.js +++ b/packages/components-faraday/src/components/Dashboard/Dashboard.js @@ -10,12 +10,10 @@ import DashboardItems from './DashboardItems' import DashboardFilters from './DashboardFilters' const Dashboard = ({ - changeViewMode, createDraftSubmission, currentUser, dashboard, deleteProject, - listView, filters, getItems, getFilterOptions, @@ -36,14 +34,11 @@ const Dashboard = ({ </div> <DashboardFilters changeFilterValue={changeFilterValue} - changeView={changeViewMode} getFilterOptions={getFilterOptions} - listView={listView} /> <DashboardItems deleteProject={deleteProject} list={getItems()} - listView={listView} showAbstractModal={showAbstractModal} /> </div> diff --git a/packages/components-faraday/src/components/Dashboard/DashboardCard.js b/packages/components-faraday/src/components/Dashboard/DashboardCard.js index 08596722864c7401152e8ed74f8b983dda189ac8..97b4952b465204b5231b5f3af52f1fb3911b5c96 100644 --- a/packages/components-faraday/src/components/Dashboard/DashboardCard.js +++ b/packages/components-faraday/src/components/Dashboard/DashboardCard.js @@ -1,23 +1,18 @@ import React from 'react' -import classnames from 'classnames' import { get, isEmpty } from 'lodash' import styled from 'styled-components' import { Button, Icon } from '@pubsweet/ui' import { parseVersion, getFilesURL, downloadAll } from './utils' -import classes from './Dashboard.local.scss' const DashboardCard = ({ deleteProject, history, - listView, project, version, showAbstractModal, }) => { - const { submitted, author, title, type, version: vers } = parseVersion( - version, - ) + const { submitted, title, type, version: vers } = parseVersion(version) const files = getFilesURL(get(version, 'files')) const status = get(project, 'status') || 'Draft' const hasFiles = !isEmpty(files) @@ -25,96 +20,323 @@ const DashboardCard = ({ const metadata = get(version, 'metadata') return ( - <div className={classes.card}> - <div className={classes.leftSide}> - <div - className={classes.title} - dangerouslySetInnerHTML={{ __html: title }} // eslint-disable-line - /> - - <div className={classes.quickInfo}> - <div className={classes.status}>{status}</div> - <div className={classes.version}>{`v${vers} ${ - submitted ? `- updated on ${submitted}` : '' - }`}</div> - </div> - </div> - <div className={classes.rightSide}> - <div - className={classnames({ - [classes.disabled]: !hasFiles, - [classes.pointer]: true, - })} - onClick={() => (hasFiles ? downloadAll(files) : null)} - > - <Icon>download</Icon> - </div> - <div className={classes.pointer} onClick={() => deleteProject(project)}> - <Icon>trash-2</Icon> - </div> - <div - className={classes.pointer} - onClick={() => - history.push( - `/projects/${project.id}/versions/${version.id}/submit`, - ) - } - > - <Icon>file-text</Icon> - </div> - </div> - {!listView && ( - <div className={classes.expandedView}> - <div className={classes.column3}> - <div className={classes.column2}> - <div>Submission author</div> - <div>Abstract</div> - </div> - <div className={classes.column2}> - <div>{author}</div> - {abstract && ( - <ViewAbstractContainer onClick={showAbstractModal(metadata)}> - <Icon color="#667080" size={18}> - eye - </Icon> - <span>View</span> - </ViewAbstractContainer> - )} - </div> - </div> - <div className={classes.column3}> - <div className={classes.column2}> - <div>Submitted On</div> - <div>Type</div> + <Card> + <ListView> + <Left> + <Title + dangerouslySetInnerHTML={{ __html: title }} // eslint-disable-line + /> + <ManuscriptInfo> + <div> + <Status>{status}</Status> + <DateField>{submitted || ''}</DateField> </div> - <div className={classes.column2}> - <div>{submitted}</div> - <div> - <span className={classes.status}>{type}</span> - </div> + <div> + <Version>{`v${vers} - `}</Version> + <ManuscriptId>{`ID ${version.id.split('-')[0]}`}</ManuscriptId> + <ManuscriptType>{type}</ManuscriptType> </div> + </ManuscriptInfo> + </Left> + <Right> + <ClickableIcon + disabled={!hasFiles} + onClick={() => (hasFiles ? downloadAll(files) : null)} + > + <Icon>download</Icon> + </ClickableIcon> + <ClickableIcon onClick={() => deleteProject(project)}> + <Icon>trash-2</Icon> + </ClickableIcon> + <ClickableIcon> + <Icon>more-horizontal</Icon> + </ClickableIcon> + <Details + onClick={() => + history.push( + `/projects/${project.id}/versions/${version.id}/submit`, + ) + } + > + Details + <Icon color="#667080">chevron-right</Icon> + </Details> + </Right> + </ListView> + <DetailsView> + <LeftDetails> + <JournalTitle>{metadata.journal}</JournalTitle> + <Issue>{metadata.issue}</Issue> + {get(version, 'authors') && ( + <Authors> + <span>Authors:</span> + <AuthorList> + {version.authors + .map(({ firstName, lastName }) => `${firstName} ${lastName}`) + .join(', ')} + </AuthorList> + </Authors> + )} + <PreviewContainer> + {abstract && ( + <ClickableIconContainer onClick={showAbstractModal(metadata)}> + <Icon color="#667080" size={18}> + eye + </Icon> + <span>Abstract</span> + </ClickableIconContainer> + )} + <ClickableIconContainer> + <Icon color="#667080" size={18}> + eye + </Icon> + <span>Cover letter</span> + </ClickableIconContainer> + </PreviewContainer> + </LeftDetails> + <RightDetails> + <div> + <Label>Handling editor</Label> + <ActionButtons>ASSIGN</ActionButtons> </div> - <div className={classes.column3}> - <div className={classes.column2}> - <div>Handling Editor</div> - <div>Reviewers</div> - </div> - <div className={classes.column2}> - <Button className={classes.button} primary> - Invite - </Button> - <Button className={classes.button} primary> - Invite - </Button> - </div> + <div> + <Label>Reviewers</Label> + <ActionButtons>INVITE</ActionButtons> </div> - </div> - )} - </div> + </RightDetails> + </DetailsView> + </Card> ) } -const ViewAbstractContainer = styled.div` +export default DashboardCard + +// #region styled-components +const PreviewContainer = styled.div` + display: flex; + margin-top: 18px; +` + +const AuthorList = styled.span` + color: #667080; + font-family: Helvetica; + font-size: 14px; + overflow: hidden; + text-overflow: ellipsis; + text-align: left; + white-space: nowrap; + max-width: 400px; + width: 400px; +` + +const Authors = styled.div` + align-items: center; + display: flex; + flex-direction: row; + justify-content: flex-start; + margin-top: 15px; + + span:first-child { + color: #667080; + font-family: Helvetica; + font-size: 12px; + margin-right: 8px; + text-align: left; + text-transform: uppercase; + } +` + +const ActionButtons = styled(Button)` + align-items: center; + background-color: #667080; + display: flex; + height: 20px; + padding: 4px 8px; + font-family: Helvetica; + font-size: 12px; + text-align: center; + color: #ffffff; +` + +const LeftDetails = styled.div` + display: flex; + flex: 1; + flex-direction: column; + justify-content: flex-start; + padding: 10px 20px; +` + +const RightDetails = styled.div` + display: flex; + flex: 1; + flex-direction: column; + + div { + align-items: center; + display: flex; + flex-direction: row; + margin: 6px 0; + } +` + +const Label = styled.span` + color: #667080; + font-family: Helvetica; + font-size: 12px; + text-align: left; + text-transform: uppercase; + width: 150px; +` + +const JournalTitle = styled.span` + color: #667080; + font-family: Helvetica; + font-size: 14px; + font-weight: bold; + text-align: left; +` + +const Issue = styled.span` + color: #667080; + font-family: Helvetica; + font-size: 14px; + text-align: left; +` + +const DetailsView = styled.div` + align-items: center; + border-top: 1px solid #667080; + display: flex; + flex-direction: row; + justify-content: space-between; + width: 100%; +` + +const ListView = styled.div` + align-items: center; + display: flex; + flex-direction: row; + justify-content: space-between; + width: 100%; +` + +const ManuscriptId = styled.span` + color: #667080; + font-family: Helvetica; + font-size: 12px; + margin-left: 8px; + text-align: left; + text-decoration: underline; + text-transform: uppercase; +` + +const Version = styled.span` + color: #667080; + font-family: Helvetica; + font-size: 13px; + text-align: left; +` +const Details = styled.div` + align-items: center; + color: #667080; + cursor: pointer; + display: flex; + font-family: Helvetica; + font-size: 14px; + margin-left: 8px; + text-decoration: underline; + text-align: center; +` + +const ClickableIcon = styled.div` + cursor: ${({ disabled }) => (disabled ? 'not-allowed' : 'pointer')}; + margin: 0 7px; + + svg { + stroke: ${({ disabled }) => (disabled ? '#eee' : '#667080')}; + } +` + +const Card = styled.div` + align-items: center; + border: 1px solid #667080; + display: flex; + flex-direction: column; + justify-content: flex-start; + margin-bottom: 10px; +` + +const Right = styled.div` + align-items: center; + flex: 1; + display: flex; + flex-direction: row; + justify-content: space-between; + margin: 0 15px; +` + +const Left = styled.div` + border-right: 1px solid #667080; + display: flex; + flex-direction: column; + flex: 5; + margin: 10px 0; + padding: 0 10px; +` + +const ManuscriptInfo = styled.div` + align-items: center; + display: flex; + justify-content: space-between; + + div { + display: flex; + flex-direction: row; + align-items: center; + justify-content: center; + } +` + +const ManuscriptType = styled.div` + border: 1px solid #667080; + color: #667080; + font-family: Helvetica; + font-size: 12px; + font-weight: bold; + padding: 6px 4px; + margin-left: 10px; + text-align: left; + text-transform: uppercase; +` + +const Title = styled.span` + color: #667080; + font-family: Helvetica; + font-size: 18px; + text-align: left; +` + +const Status = styled.div` + border: 1px solid #667080; + color: #667080; + font-family: Helvetica; + font-size: 12px; + font-weight: bold; + text-align: left; + margin: 0.5em 0; + padding: 0.2em 0.5em; + text-transform: uppercase; +` + +const DateField = styled.span` + color: #667080; + font-family: Helvetica; + font-size: 13px; + margin: 0 8px; + text-align: left; +` + +const ClickableIconContainer = styled.div` align-items: center; cursor: pointer; display: flex; @@ -128,5 +350,4 @@ const ViewAbstractContainer = styled.div` text-decoration: underline; } ` - -export default DashboardCard +// #endregion diff --git a/packages/components-faraday/src/components/Dashboard/DashboardFilters.js b/packages/components-faraday/src/components/Dashboard/DashboardFilters.js index 3a2ae74005be770013c39138013a188174111c5b..b7ca2b2afd595966fbbc1eb96f26ab3313ac3e73 100644 --- a/packages/components-faraday/src/components/Dashboard/DashboardFilters.js +++ b/packages/components-faraday/src/components/Dashboard/DashboardFilters.js @@ -1,5 +1,5 @@ import React from 'react' -import { Icon, Menu } from '@pubsweet/ui' +import { Menu } from '@pubsweet/ui' import { compose, withHandlers } from 'recompose' import classes from './Dashboard.local.scss' @@ -13,7 +13,6 @@ const DashboardFilters = ({ view, status, createdAt, - changeView, listView, changeFilter, changeSort, @@ -42,12 +41,6 @@ const DashboardFilters = ({ <Menu onChange={changeSort} options={sortOptions} /> </div> </div> - <div className={classes.viewMode} onClick={changeView}> - <div className={classes.icon}> - {listView ? <Icon>list</Icon> : <Icon>credit-card</Icon>} - </div> - {listView ? ' List' : ' Card'} View - </div> </div> ) diff --git a/packages/components-faraday/src/components/Dashboard/DashboardPage.js b/packages/components-faraday/src/components/Dashboard/DashboardPage.js index 4154a7b1ba1bfcf8084436e3f45bd38d9535aa0c..a1a4176b6a2b3bd9c33d3de3da325e77001822fe 100644 --- a/packages/components-faraday/src/components/Dashboard/DashboardPage.js +++ b/packages/components-faraday/src/components/Dashboard/DashboardPage.js @@ -1,9 +1,9 @@ import { get } from 'lodash' +import { compose } from 'recompose' import { connect } from 'react-redux' import { actions } from 'pubsweet-client' import { ConnectPage } from 'xpub-connect' import { withRouter } from 'react-router-dom' -import { compose, withState, withHandlers } from 'recompose' import { newestFirst, selectCurrentUser } from 'xpub-selectors' import { createDraftSubmission } from 'pubsweet-component-wizard/src/redux/conversion' @@ -17,10 +17,6 @@ export default compose( actions.getTeams(), actions.getUsers(), ]), - withState('listView', 'changeView', true), - withHandlers({ - changeViewMode: ({ changeView }) => () => changeView(listView => !listView), - }), connect( state => { const { collections, conversion } = state diff --git a/packages/components-faraday/src/components/Dashboard/utils.js b/packages/components-faraday/src/components/Dashboard/utils.js index 50d39d73b6082c05a4efe3bda58ae82d0335cccc..84a1700491ccc80f1a0cd3a4cccaa80a9b68c962 100644 --- a/packages/components-faraday/src/components/Dashboard/utils.js +++ b/packages/components-faraday/src/components/Dashboard/utils.js @@ -53,7 +53,14 @@ export const parseType = version => { export const parseSubmissionDate = version => { const submitted = get(version, 'submitted') - return submitted ? moment(submitted).format('DD-MM-YYYY') : 'N/A' + const submittedDate = moment(submitted) + const today = moment() + const daysAgo = moment.duration(today - moment(submitted)).days() + return submitted + ? `${submittedDate.format('DD.MM.YYYY')} ${ + daysAgo > 0 ? `(${daysAgo} days)` : '' + }` + : 'N/A' } export const parseVersion = version => ({ diff --git a/packages/xpub-faraday/config/components.json b/packages/xpub-faraday/config/components.json index cd73a0b129407ec50dd69fe8f408f7aae2aaab87..a6b66287113c39f421842f3d071e277c953150cb 100644 --- a/packages/xpub-faraday/config/components.json +++ b/packages/xpub-faraday/config/components.json @@ -6,6 +6,6 @@ "pubsweet-component-wizard", "pubsweet-component-modal", "pubsweet-components-faraday", - "pubsweet-components-aws-s3", + "@pubsweet/component-aws-s3", "pubsweet-component-invite" ] diff --git a/packages/xpub-faraday/config/default.js b/packages/xpub-faraday/config/default.js index fd1592d877fbab18168c974cf4fe37cba7fd327c..c78cdecc488485f1bf753ea57efbc6ce4dd2da05 100644 --- a/packages/xpub-faraday/config/default.js +++ b/packages/xpub-faraday/config/default.js @@ -26,7 +26,7 @@ module.exports = { 'pubsweet-client': { API_ENDPOINT: '/api', 'login-redirect': '/', - 'redux-log': true, + 'redux-log': false, theme: process.env.PUBSWEET_THEME, }, 'mail-transport': { diff --git a/packages/xpub-faraday/package.json b/packages/xpub-faraday/package.json index 2daa19e53bce4f5fbf3f4ce538ae0eeb9ea6b08a..9e306a496ad153f449454a2d6e7177d4ccf64fe3 100644 --- a/packages/xpub-faraday/package.json +++ b/packages/xpub-faraday/package.json @@ -10,6 +10,7 @@ "dependencies": { "aws-sdk": "^2.197.0", "@pubsweet/ui": "^2.0.0", + "@pubsweet/component-aws-s3": "^0.1.1", "babel-core": "^6.26.0", "config": "^1.26.2", "dotenv": "^5.0.0", @@ -28,7 +29,6 @@ "pubsweet-component-login": "^1.0.1", "pubsweet-component-signup": "^1.0.0", "pubsweet-component-xpub-manuscript": "^0.0.2", - "pubsweet-components-aws-s3": "^0.0.1", "pubsweet-component-invite": "^0.0.1", "pubsweet-server": "^1.0.1", "react": "^16.2.0", diff --git a/yarn.lock b/yarn.lock index 64ea891182ed071404ff630e09312f9883528d84..17a9872bc795a46e40d990c3e2a83bfadcf21904 100644 --- a/yarn.lock +++ b/yarn.lock @@ -71,6 +71,17 @@ lodash "^4.2.0" to-fast-properties "^2.0.0" +"@pubsweet/component-aws-s3@^0.1.1": + version "0.1.1" + resolved "https://registry.yarnpkg.com/@pubsweet/component-aws-s3/-/component-aws-s3-0.1.1.tgz#2faa379c1b8c12dbc6573a5627b09f536a484cc3" + dependencies: + aws-sdk "^2.185.0" + body-parser "^1.17.2" + multer "^1.3.0" + multer-s3 "^2.7.0" + node-mocks-http "^1.6.6" + nodemailer "^4.4.2" + "@pubsweet/db-manager@^0.0.17": version "0.0.17" resolved "https://registry.yarnpkg.com/@pubsweet/db-manager/-/db-manager-0.0.17.tgz#f4fc6d17847f020fb4fa8a4e3ea5885c1181c51b"