Skip to content
Snippets Groups Projects
Commit bb5c9b33 authored by Alexandru Munteanu's avatar Alexandru Munteanu
Browse files

update dashboard

parent b826e90c
No related branches found
No related tags found
No related merge requests found
...@@ -10,12 +10,10 @@ import DashboardItems from './DashboardItems' ...@@ -10,12 +10,10 @@ import DashboardItems from './DashboardItems'
import DashboardFilters from './DashboardFilters' import DashboardFilters from './DashboardFilters'
const Dashboard = ({ const Dashboard = ({
changeViewMode,
createDraftSubmission, createDraftSubmission,
currentUser, currentUser,
dashboard, dashboard,
deleteProject, deleteProject,
listView,
filters, filters,
getItems, getItems,
getFilterOptions, getFilterOptions,
...@@ -36,14 +34,11 @@ const Dashboard = ({ ...@@ -36,14 +34,11 @@ const Dashboard = ({
</div> </div>
<DashboardFilters <DashboardFilters
changeFilterValue={changeFilterValue} changeFilterValue={changeFilterValue}
changeView={changeViewMode}
getFilterOptions={getFilterOptions} getFilterOptions={getFilterOptions}
listView={listView}
/> />
<DashboardItems <DashboardItems
deleteProject={deleteProject} deleteProject={deleteProject}
list={getItems()} list={getItems()}
listView={listView}
showAbstractModal={showAbstractModal} showAbstractModal={showAbstractModal}
/> />
</div> </div>
......
import React from 'react' import React from 'react'
import classnames from 'classnames'
import { get, isEmpty } from 'lodash' import { get, isEmpty } from 'lodash'
import styled from 'styled-components' import styled from 'styled-components'
import { Button, Icon } from '@pubsweet/ui' import { Button, Icon } from '@pubsweet/ui'
import { parseVersion, getFilesURL, downloadAll } from './utils' import { parseVersion, getFilesURL, downloadAll } from './utils'
import classes from './Dashboard.local.scss'
const DashboardCard = ({ const DashboardCard = ({
deleteProject, deleteProject,
history, history,
listView,
project, project,
version, version,
showAbstractModal, showAbstractModal,
}) => { }) => {
const { submitted, author, title, type, version: vers } = parseVersion( const { submitted, title, type, version: vers } = parseVersion(version)
version,
)
const files = getFilesURL(get(version, 'files')) const files = getFilesURL(get(version, 'files'))
const status = get(project, 'status') || 'Draft' const status = get(project, 'status') || 'Draft'
const hasFiles = !isEmpty(files) const hasFiles = !isEmpty(files)
...@@ -25,96 +20,323 @@ const DashboardCard = ({ ...@@ -25,96 +20,323 @@ const DashboardCard = ({
const metadata = get(version, 'metadata') const metadata = get(version, 'metadata')
return ( return (
<div className={classes.card}> <Card>
<div className={classes.leftSide}> <ListView>
<div <Left>
className={classes.title} <Title
dangerouslySetInnerHTML={{ __html: title }} // eslint-disable-line dangerouslySetInnerHTML={{ __html: title }} // eslint-disable-line
/> />
<ManuscriptInfo>
<div className={classes.quickInfo}> <div>
<div className={classes.status}>{status}</div> <Status>{status}</Status>
<div className={classes.version}>{`v${vers} ${ <DateField>{submitted || ''}</DateField>
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>
</div> </div>
<div className={classes.column2}> <div>
<div>{submitted}</div> <Version>{`v${vers} - `}</Version>
<div> <ManuscriptId>{`ID ${version.id.split('-')[0]}`}</ManuscriptId>
<span className={classes.status}>{type}</span> <ManuscriptType>{type}</ManuscriptType>
</div>
</div> </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>
<div className={classes.column3}> <div>
<div className={classes.column2}> <Label>Reviewers</Label>
<div>Handling Editor</div> <ActionButtons>INVITE</ActionButtons>
<div>Reviewers</div>
</div>
<div className={classes.column2}>
<Button className={classes.button} primary>
Invite
</Button>
<Button className={classes.button} primary>
Invite
</Button>
</div>
</div> </div>
</div> </RightDetails>
)} </DetailsView>
</div> </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; align-items: center;
cursor: pointer; cursor: pointer;
display: flex; display: flex;
...@@ -128,5 +350,4 @@ const ViewAbstractContainer = styled.div` ...@@ -128,5 +350,4 @@ const ViewAbstractContainer = styled.div`
text-decoration: underline; text-decoration: underline;
} }
` `
// #endregion
export default DashboardCard
import React from 'react' import React from 'react'
import { Icon, Menu } from '@pubsweet/ui' import { Menu } from '@pubsweet/ui'
import { compose, withHandlers } from 'recompose' import { compose, withHandlers } from 'recompose'
import classes from './Dashboard.local.scss' import classes from './Dashboard.local.scss'
...@@ -13,7 +13,6 @@ const DashboardFilters = ({ ...@@ -13,7 +13,6 @@ const DashboardFilters = ({
view, view,
status, status,
createdAt, createdAt,
changeView,
listView, listView,
changeFilter, changeFilter,
changeSort, changeSort,
...@@ -42,12 +41,6 @@ const DashboardFilters = ({ ...@@ -42,12 +41,6 @@ const DashboardFilters = ({
<Menu onChange={changeSort} options={sortOptions} /> <Menu onChange={changeSort} options={sortOptions} />
</div> </div>
</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> </div>
) )
......
import { get } from 'lodash' import { get } from 'lodash'
import { compose } from 'recompose'
import { connect } from 'react-redux' import { connect } from 'react-redux'
import { actions } from 'pubsweet-client' import { actions } from 'pubsweet-client'
import { ConnectPage } from 'xpub-connect' import { ConnectPage } from 'xpub-connect'
import { withRouter } from 'react-router-dom' import { withRouter } from 'react-router-dom'
import { compose, withState, withHandlers } from 'recompose'
import { newestFirst, selectCurrentUser } from 'xpub-selectors' import { newestFirst, selectCurrentUser } from 'xpub-selectors'
import { createDraftSubmission } from 'pubsweet-component-wizard/src/redux/conversion' import { createDraftSubmission } from 'pubsweet-component-wizard/src/redux/conversion'
...@@ -17,10 +17,6 @@ export default compose( ...@@ -17,10 +17,6 @@ export default compose(
actions.getTeams(), actions.getTeams(),
actions.getUsers(), actions.getUsers(),
]), ]),
withState('listView', 'changeView', true),
withHandlers({
changeViewMode: ({ changeView }) => () => changeView(listView => !listView),
}),
connect( connect(
state => { state => {
const { collections, conversion } = state const { collections, conversion } = state
......
...@@ -53,7 +53,14 @@ export const parseType = version => { ...@@ -53,7 +53,14 @@ export const parseType = version => {
export const parseSubmissionDate = version => { export const parseSubmissionDate = version => {
const submitted = get(version, 'submitted') 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 => ({ export const parseVersion = version => ({
......
...@@ -25,7 +25,7 @@ module.exports = { ...@@ -25,7 +25,7 @@ module.exports = {
'pubsweet-client': { 'pubsweet-client': {
API_ENDPOINT: '/api', API_ENDPOINT: '/api',
'login-redirect': '/', 'login-redirect': '/',
'redux-log': true, 'redux-log': false,
theme: process.env.PUBSWEET_THEME, theme: process.env.PUBSWEET_THEME,
}, },
'mail-transport': { 'mail-transport': {
......
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment