Newer
Older
const merge = require('lodash/merge')
const form = require('../../../app/storage/forms/submit.json')
const resolvers = {
Mutation: {
async createManuscript(_, vars, ctx) {
Jure
committed
// We want the submission information to be stored as JSONB
// but we want the input to come in as a JSON string
const submission = vars.input.submission
? JSON.parse(vars.input.submission)
: {}
const emptyManuscript = {
meta: Object.assign(meta, {
notes: [
{
notesType: 'fundingAcknowledgement',
content: '',
},
{
notesType: 'specialInstructions',
content: '',
},
],
}),
status: 'new',
Jure
committed
submission,
Jure
committed
const manuscript = await new ctx.models.Manuscript(
// Create two channels: 1. free for all involved, 2. editorial
manuscriptId: manuscript.id,
topic: 'Manuscript discussion',
type: 'all',
}).save()
manuscriptId: manuscript.id,
topic: 'Editorial discussion',
type: 'editorial',
}).save()
manuscript.manuscriptVersions = []
manuscript.files = []
files.map(async file => {
const newFile = Object.assign({}, file, {
fileType: 'manuscript',
object: 'Manuscript',
objectId: manuscript.id,
})
const createdTeam = await Team.query().upsertGraphAndFetch(
{
role: 'author',
name: 'Author',
objectId: manuscript.id,
objectType: 'Manuscript',
manuscript.channels = [allChannel, editorialChannel]
return manuscript
},
async deleteManuscript(_, { id }, ctx) {
const deleteManuscript = []
const manuscript = await ctx.models.Manuscript.find(id)
deleteManuscript.push(manuscript.id)
if (manuscript.parentId) {
const parentManuscripts = await ctx.models.Manuscript.findByField(
'parent_id',
manuscript.parentId,
)
parentManuscripts.forEach(manuscript => {
deleteManuscript.push(manuscript.id)
})
}
// Delete Manuscript
if (deleteManuscript.length > 0) {
deleteManuscript.forEach(async manuscript => {
await ctx.models.Manuscript.query().deleteById(manuscript)
})
}
return id
},
async reviewerResponse(_, { currentUserId, action, teamId }, context) {
const { Team, Review } = require('@pubsweet/models')
if (action !== 'accepted' && action !== 'rejected')
throw new Error(
`Invalid action provided to handleInvitation:
Must be either "accepted" or "rejected"`,
)
const team = await Team.query()
.findById(teamId)
.eager('members')
})
if (!team) throw new Error('No team was found')
if (action === 'accepted') {
const review = {
recommendation: '',
isDecision: false,
userId: currentUserId,
}
await new Review(review).save()
}
return team
},
async updateManuscript(_, { id, input }, ctx) {
const data = JSON.parse(input)
const manuscript = await ctx.models.Manuscript.findById(id)
return ctx.models.Manuscript.update(id, update, ctx)
async makeDecision(_, { id, decision }, ctx) {
const manuscript = await ctx.models.Manuscript.findById(id)
manuscript.status = decision
return manuscript.save()
async manuscript(_, { id }, ctx) {
const Manuscript = require('./manuscript')
const manuscript = await Manuscript.query()
.findById(id)
if (!manuscript.meta) {
manuscript.meta = {}
}
manuscript.meta.notes = (manuscript.meta || {}).notes || [
{
notesType: 'fundingAcknowledgement',
content: '',
},
{
notesType: 'specialInstructions',
content: '',
},
]
manuscript.decision = ''
manuscript.files = await ctx.models.File.findByObject({
object: 'Manuscript',
object_id: manuscript.id,
})
manuscript.manuscriptVersions = await manuscript.getManuscriptVersions()
// manuscript.channel = await ctx.connectors.Channel.model.find(
// manuscript.channelId,
// )
return ctx.models.Manuscript.query().eager('[teams, reviews]')
async paginatedManuscripts(_, { sort, offset, limit, filter }, ctx) {
const query = ctx.models.Manuscript.query().eager('submitter')
if (filter && filter.status) {
query.where({ status: filter.status })
}
const totalCount = await query.resultSize()
if (sort) {
const [sortName, sortDirection] = sort.split('_')
query.orderBy(ref(sortName), sortDirection)
// }
// // e.g. 'created_DESC' into 'created' and 'DESC' arguments
// query.orderBy(...sort.split('_'))
}
if (limit) {
query.limit(limit)
}
if (offset) {
query.offset(offset)
}
const manuscripts = await query
return {
totalCount,
manuscripts,
}
// return ctx.connectors.User.fetchAll(where, ctx, { eager })
},
async getFile() {
return form
},
},
Jure
committed
// We want submission into to come out as a stringified JSON, so that we don't have to
// change our queries if the submission form changes. We still want to store it as JSONB
// so that we can easily search through the information within.
Manuscript: {
submission(parent) {
return JSON.stringify(parent.submission)
},
},
ManuscriptVersion: {
submission(parent) {
Jure
committed
return JSON.stringify(parent.submission)
},
},
const typeDefs = `
extend type Query {
globalTeams: [Team]
manuscript(id: ID!): Manuscript!
manuscripts: [Manuscript]!
paginatedManuscripts(sort: String, offset: Int, limit: Int, filter: ManuscriptsFilter): PaginatedManuscripts
input ManuscriptsFilter {
status: String
}
type PaginatedManuscripts {
totalCount: Int
manuscripts: [Manuscript]
}
# enum ManuscriptsSort {
# meta->>'title'_DESC
# created_ASC
# created_DESC
# updated_ASC
# updated_DESC
# }
extend type Mutation {
createManuscript(input: ManuscriptInput): Manuscript!
updateManuscript(id: ID!, input: String): Manuscript!
makeDecision(id: ID!, decision: String): Manuscript!
deleteManuscript(id: ID!): ID!
reviewerResponse(currentUserId: ID, action: String, teamId: ID! ): Team
assignTeamEditor(id: ID!, input: String): [Team]
}
type Manuscript implements Object {
id: ID!
created: DateTime!
updated: DateTime
manuscriptVersions: [ManuscriptVersion]
files: [File]
teams: [Team]
reviews: [Review!]
status: String
decision: String
suggestions: Suggestions
authors: [Author]
meta: ManuscriptMeta
submission: String
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
}
type ManuscriptVersion implements Object {
id: ID!
created: DateTime!
updated: DateTime
files: [File]
teams: [Team]
reviews: [Review]
status: String
formState: String
decision: String
suggestions: Suggestions
authors: [Author]
meta: ManuscriptMeta
submission: String
}
input ManuscriptInput {
files: [FileInput]
meta: ManuscriptMetaInput
submission: String
}
input ManuscriptMetaInput {
title: String
source: String
}
input FileInput {
filename: String
url: String
mimeType: String
size: Int
}
type Author {
firstName: String
lastName: String
email: String
affiliation: String
}
type Suggestion {
suggested: String
opposed: String
}
type Suggestions {
reviewers: Suggestion
editors: Suggestion
}
type ManuscriptMeta {
title: String!
source: String
articleType: String
declarations: Declarations
articleSections: [String]
articleIds: [ArticleId]
abstract: String
subjects: [String]
history: [MetaDate]
publicationDates: [MetaDate]
notes: [Note]
keywords: String
}
type ArticleId {
pubIdType: String
id: String
}
type MetaDate {
type: String
date: DateTime
}
type Declarations {
openData: String
openPeerReview: String
preregistered: String
previouslySubmitted: String
researchNexus: String
streamlinedReview: String
}
type Note implements Object {
id: ID!
created: DateTime!
updated: DateTime
notesType: String
content: String
}
`
module.exports = {
typeDefs,
resolvers,
}