Skip to content

Commit

Permalink
Issue #196 - Editor dashboard.
Browse files Browse the repository at this point in the history
  • Loading branch information
danielBingham committed Sep 9, 2023
1 parent 8ce8320 commit a93c93a
Show file tree
Hide file tree
Showing 45 changed files with 1,013 additions and 113 deletions.
22 changes: 19 additions & 3 deletions packages/backend/daos/JournalSubmissionDAO.js
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,8 @@ module.exports = class JournalSubmissionDAO {

const reviewer = {
userId: row.reviewer_userId,
assignedDate: row.reviewer_assignedDate
assignedDate: row.reviewer_assignedDate,
reviews: []
}

if ( reviewer.userId != null
Expand All @@ -56,6 +57,19 @@ module.exports = class JournalSubmissionDAO {
dictionary[submission.id].reviewers.push(reviewer)
}

const review = {
id: row.review_id,
version: row.review_version,
recommendation: row.review_recommendation,
userId: row.review_userId
}

// TODO Attach review to reviewer.
// Or consider a different approach, this seems like not the best approach.




const editor = {
userId: row.editor_userId,
assignedDate: row.editor_assignedDate
Expand All @@ -81,7 +95,6 @@ module.exports = class JournalSubmissionDAO {
FROM journal_submissions
LEFT OUTER JOIN journal_submission_reviewers ON journal_submissions.id = journal_submission_reviewers.submission_id
LEFT OUTER JOIN journal_submission_editors ON journal_submissions.id = journal_submission_editors.submission_id
LEFT OUTER JOIN journals ON journal_submissions.journal_id = journals.id
${where}
`

Expand Down Expand Up @@ -128,14 +141,17 @@ module.exports = class JournalSubmissionDAO {
journal_submission_reviewers.user_id as "reviewer_userId",
journal_submission_reviewers.created_date as "reviewer_assignedDate",
reviews.id as review_id, reviews.version as review_version,
reviews.recommendation as review_recommendation, reviews.user_id as "review_userId",
journal_submission_editors.submission_id as "editor_submissionId",
journal_submission_editors.user_id as "editor_userId",
journal_submission_editors.created_date as "editor_assignedDate"
FROM journal_submissions
LEFT OUTER JOIN journal_submission_reviewers ON journal_submissions.id = journal_submission_reviewers.submission_id
LEFT OUTER JOIN reviews ON journal_submission_reviewers.user_id = reviews.user_id AND journal_submissions.paper_id = reviews.paper_id AND reviews.status='submitted'
LEFT OUTER JOIN journal_submission_editors ON journal_submissions.id = journal_submission_editors.submission_id
LEFT OUTER JOIN journals ON journal_submissions.journal_id = journals.id
${where}
Expand Down
22 changes: 11 additions & 11 deletions packages/backend/daos/PaperEventDAO.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,16 @@ module.exports = class PaperEventsDAO {
return { dictionary: dictionary, list: list }
}

async selectEvents(where, params) {
async selectEvents(where, params, order) {
where = where ? where : ''
params = params ? params : []
order = order ? order : 'oldest'

let orderSql = `paper_events.event_date asc`
if ( order == 'newest' ) {
orderSql = `paper_events.event_date desc`
}

const sql = `
SELECT
paper_events.id as event_id,
Expand All @@ -60,7 +69,7 @@ SELECT
FROM paper_events
${where}
ORDER BY paper_events.event_date asc
ORDER BY ${orderSql}
`

const results = await this.database.query(sql, params)
Expand All @@ -72,15 +81,6 @@ ORDER BY paper_events.event_date asc
*
*/
async insertEvent(event) {
// If we don't have a version already, grab it from the database.
if ( ! event.version ) {
const versionResults = await this.database.query(
`SELECT version FROM paper_versions WHERE paper_id = $1 ORDER BY version desc`,
[ event.paperId ]
)
event.version = versionResults.rows[0].version
}

let columns = ``
let values = ``
let params = []
Expand Down
1 change: 1 addition & 0 deletions packages/backend/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ exports.FileService = require('./services/FileService')
exports.OpenAlexService = require('./services/OpenAlexService')
exports.ReputationGenerationService = require('./services/ReputationGenerationService')
exports.ReputationPermissionService = require('./services/ReputationPermissionService')
exports.PaperEventService = require('./services/PaperEventService')
exports.PaperPermissionsService = require('./services/PaperPermissionsService')
exports.S3FileService = require('./services/S3FileService')
exports.SubmissionPermissionService = require('./services/SubmissionPermissionService')
Expand Down
59 changes: 59 additions & 0 deletions packages/backend/services/PaperEventService.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@

const PaperEventDAO = require('../daos/PaperEventDAO')

module.exports = class PaperEventService {

constructor(core) {
this.core = core

this.paperEventDAO = new PaperEventDAO(core)
}

async getActiveSubmissionId(paperId) {
const results = await this.core.database.query(`
SELECT journal_submissions.id
FROM journal_submissions
WHERE journal_submissions.status != 'published'
AND journal_submissions.status != 'rejected'
AND journal_submissions.status != 'retracted'
AND journal_submissions.paper_id = $1
LIMIT 1
`, [ paperId ])

if ( results.rows.length <= 0 ) {
return null
}

return results.rows[0].id
}

async getCurrentPaperVersion(paperId) {
const versionResults = await this.core.database.query(
`SELECT version FROM paper_versions WHERE paper_id = $1 ORDER BY version desc`,
[ paperId ]
)
return versionResults.rows[0].version
}

async getEventVisibility(user, event) {
return [ 'public' ]
}

async createEvent(user, event) {

if ( ! event.submissionId ) {
event.submissionId = await this.getActiveSubmissionId(event.paperId)
}

// If we don't have a version already, grab it from the database.
if ( ! event.version ) {
event.version = await this.getCurrentPaperVersion(event.paperId)
}

event.visibility = await this.getEventVisibility(user, event)

console.log(event)
await this.paperEventDAO.insertEvent(event)
}

}
5 changes: 4 additions & 1 deletion web-application/client/App.js
Original file line number Diff line number Diff line change
Expand Up @@ -240,7 +240,10 @@ const App = function(props) {
<Route path=":pageTab" element={ <ReviewDashboardPage /> } />
<Route index element={ <ReviewDashboardPage /> } />
</Route>
<Route path="/edit" element={ <EditorDashboardPage />} />
<Route path="/edit">
<Route path=":pageTab" element={ <EditorDashboardPage /> } />
<Route index element={ <EditorDashboardPage />} />
</Route>
<Route path="/author">
<Route path=":pageTab" element={ <AuthorDashboardPage /> } />
<Route index element={ <AuthorDashboardPage /> } />
Expand Down
7 changes: 7 additions & 0 deletions web-application/client/app.css
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,13 @@ input[type="submit"]:hover {
filter: opacity(80%);
}

svg.icon {
display: inline-block;
width: 1em;
height: 1em;
margin-bottom: -0.2em;
}

#root {
height: 100vh;
width: 100%;
Expand Down
Empty file.
114 changes: 114 additions & 0 deletions web-application/client/components/feeds/EditorEventFeed.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
import React, { useState, useEffect } from 'react'
import { useDispatch, useSelector } from 'react-redux'

import { getEditorFeed, cleanupRequest } from '/state/paperEvents'

import { Timeline } from '/components/generic/timeline/Timeline'

import FeedPaperReviewView from './events/FeedPaperReviewView'
import FeedPaperVersionEvent from './events/FeedPaperVersionEvent'
import PaperPreprintSubmissionEvent from '/components/papers/view/timeline/events/PaperPreprintSubmissionEvent'
import FeedPaperJournalSubmissionEvent from './events/FeedPaperJournalSubmissionEvent'
import FeedPaperSubmissionAssignmentEvent from './events/FeedPaperSubmissionAssignmentEvent'
import PaperSubmissionStatusChange from '/components/papers/view/timeline/events/PaperSubmissionStatusChange'

const EditorEventFeed = function({ }) {

// ============ Request Tracking ==========================================

const [ requestId, setRequestId ] = useState(null)
const request = useSelector(function(state) {
if ( state.paperEvents.requests[requestId] ) {
return state.paperEvents.requests[requestId]
} else {
return null
}
})

// ============ Redux State ===============================================

const currentUser = useSelector(function(state) {
return state.authentication.currentUser
})

const events = useSelector(function(state) {
const results = []
const query = state.paperEvents.queries['EditorEventFeed']
if ( query ) {
for ( const eventId of query.list) {
results.push(state.paperEvents.dictionary[eventId])
}
}
return results
})

// ============ Effect Handling ===========================================

const dispatch = useDispatch()

useEffect(function() {
setRequestId(dispatch(getEditorFeed('EditorEventFeed', { relations: [ 'papers' ] })))
}, [])

useEffect(function() {
return function cleanup() {
if ( requestId ) {
dispatch(cleanupRequest({ requestId: requestId }))
}
}
}, [ requestId ])

// ============ Render ====================================================

/**
* Event Types
*
* 'version-uploaded',
* 'preprint-posted',
* 'review-posted',
* 'review-comment-reply-posted',
* 'comment-posted',
* 'submitted-to-journal',
* 'submission-status-changed',
* 'reviewer-assigned',
* 'reviewer-unassigned',
* 'editor-assigned',
* 'editor-unassigned'
*/
const eventViews = []
for(const event of events) {
if ( event.type == 'review-posted' ) {
eventViews.push(
<FeedPaperReviewView key={event.id} eventId={event.id} />
)
}

else if ( event.type =='version-uploaded' ) {
eventViews.push(
<FeedPaperVersionEvent key={event.id} eventId={event.id} />
)
}

else if ( event.type == 'submitted-to-journal') {
eventViews.push(
<FeedPaperJournalSubmissionEvent key={event.id} eventId={event.id} />
)
}

else if ( event.type == 'submission-status-changed' ) {
eventViews.push(
<PaperSubmissionStatusChange key={event.id} eventId={event.id} />
)
}
}

return (
<div className="editor-event-feed">
<Timeline>
{ eventViews }
</Timeline>
</div>
)
}

export default EditorEventFeed
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
.feed-paper-journal-submission-event.timeline-item {
margin: 20px 0;
}
.feed-paper-journal-submission-event .header {
padding: 5px 0;
}
.feed-paper-journal-submission-event .event-body {
border: thin solid var(--main-border-color);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import React from 'react'
import { useSelector } from 'react-redux'
import { Link } from 'react-router-dom'

import { EyeIcon, InboxArrowDownIcon } from '@heroicons/react/24/outline'

import { TimelineItem, TimelineIcon, TimelineItemWrapper } from '/components/generic/timeline/Timeline'
import DateTag from '/components/DateTag'

import UserTag from '/components/users/UserTag'
import JournalTag from '/components/journals/JournalTag'

import FeedEventPaperComponent from './components/FeedEventPaperComponent'
import JournalSubmissionsListItem from '/components/journals/submissions/JournalSubmissionsListItem'

import './FeedPaperJournalSubmissionEvent.css'

const FeedPaperJournalSubmissionEvent = function({ eventId }) {

// ================= Redux State ==========================================

const event = useSelector(function(state) {
return state.paperEvents.dictionary[eventId]
})

const paper = useSelector(function(state) {
return state.papers.dictionary[event.paperId]
})

const submission = useSelector(function(state) {
return state.journalSubmissions.dictionary[event.submissionId]
})

// ================= Render ===============================================

return (
<TimelineItem className="feed-paper-journal-submission-event">
<TimelineIcon>
<InboxArrowDownIcon />
</TimelineIcon>
<TimelineItemWrapper>
<div className="header">
New submission to <JournalTag id={submission.journalId} /> -- <DateTag timestamp={event.eventDate} type="full" />
</div>
<div className="event-body">
<JournalSubmissionsListItem submissionId={event.submissionId} />
</div>
</TimelineItemWrapper>
</TimelineItem>
)

}

export default FeedPaperJournalSubmissionEvent
Loading

0 comments on commit a93c93a

Please sign in to comment.