Skip to content

Commit

Permalink
Merge pull request #624 from JiscSD/OC-820
Browse files Browse the repository at this point in the history
 OC-820: Visibility of peer reviews and red flags on publication tiles
  • Loading branch information
finlay-jisc authored Mar 27, 2024
2 parents d4f5bf5 + 21606ca commit 2846e51
Show file tree
Hide file tree
Showing 18 changed files with 470 additions and 134 deletions.
18 changes: 5 additions & 13 deletions api/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion api/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@
"@middy/http-json-body-parser": "^4.7.0",
"@opensearch-project/opensearch": "^2.5.0",
"@paralleldrive/cuid2": "^2.2.2",
"@prisma/client": "^4.16.2",
"@prisma/client": "^5.11.0",
"@sparticuz/chromium": "^114.0.0",
"ajv": "^8.12.0",
"ajv-formats": "^2.1.1",
Expand Down
2 changes: 1 addition & 1 deletion api/src/components/affiliations/controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ export const updateAffiliations = async (

// update affiliations for this author
await coAuthorService.update(coAuthor.id, {
affiliations: isIndependent ? [] : (affiliations as unknown[] as Prisma.JsonArray), // we can safely remove author affiliations if they declared they are independent
affiliations: isIndependent ? [] : (affiliations as unknown[] as Prisma.InputJsonValue[]), // we can safely remove author affiliations if they declared they are independent
isIndependent
});

Expand Down
110 changes: 97 additions & 13 deletions api/src/components/publication/service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ export const isIdInUse = async (id: string) => {
return Boolean(publication);
};

export const get = (id: string) =>
client.prisma.publication.findUnique({
export const get = async (id: string) => {
const publication = await client.prisma.publication.findUnique({
where: {
id
},
Expand Down Expand Up @@ -181,6 +181,17 @@ export const get = (id: string) =>
}
});

// Provide counts
return publication
? {
...publication,
flagCount: publication.publicationFlags.filter((flag) => !flag.resolved).length,
peerReviewCount: publication.linkedFrom.filter((child) => child.publicationFrom.type === 'PEER_REVIEW')
.length
}
: publication;
};

export const getSeedDataPublications = (title: string) =>
client.prisma.publication.findMany({
where: {
Expand Down Expand Up @@ -619,7 +630,7 @@ export const getLinksForPublication = async (

const publicationIds = linkedTo.map((link) => link.id).concat(linkedFrom.map((link) => link.id));

// get coAuthors for each latest LIVE version of each publication
// Get extra details for linked publications
const versions = await client.prisma.publicationVersion.findMany({
where: {
isLatestLiveVersion: true,
Expand All @@ -644,25 +655,50 @@ export const getLinksForPublication = async (
orderBy: {
position: 'asc'
}
},
publication: {
select: {
publicationFlags: {
where: {
resolved: false
}
},
linkedFrom: {
where: {
publicationFrom: {
type: 'PEER_REVIEW',
versions: {
some: {
isLatestLiveVersion: true
}
}
}
}
}
}
}
}
});

// add authors to 'linkedTo' publications
// Add authors and counts to 'linkedTo' publications
linkedTo.forEach((link) => {
const authors = versions.find((version) => version.versionOf === link.id)?.coAuthors || [];
const latestVersion = versions.find((version) => version.versionOf === link.id);

Object.assign(link, {
authors
authors: latestVersion?.coAuthors || [],
flagCount: latestVersion?.publication.publicationFlags.length || 0,
peerReviewCount: latestVersion?.publication.linkedFrom.length || 0
});
});

// add authors to 'linkedFrom' publications
// Add authors and counts to 'linkedFrom' publications
linkedFrom.forEach((link) => {
const authors = versions.find((version) => version.versionOf === link.id)?.coAuthors || [];
const latestVersion = versions.find((version) => version.versionOf === link.id);

Object.assign(link, {
authors
authors: latestVersion?.coAuthors || [],
flagCount: latestVersion?.publication.publicationFlags.length || 0,
peerReviewCount: latestVersion?.publication.linkedFrom.length || 0
});
});

Expand Down Expand Up @@ -757,7 +793,9 @@ export const getLinksForPublication = async (
firstName: author.user?.firstName || '',
lastName: author.user?.lastName || ''
}
}))
})),
flagCount: publication.flagCount,
peerReviewCount: publication.peerReviewCount
},
linkedTo: orderedParents,
linkedFrom: orderedChildren
Expand Down Expand Up @@ -823,6 +861,23 @@ export const getDirectLinksForPublication = async (
include: {
user: true
}
},
publicationFlags: {
where: {
resolved: false
}
},
linkedFrom: {
where: {
publicationFrom: {
type: 'PEER_REVIEW',
versions: {
some: {
isLatestLiveVersion: true
}
}
}
}
}
}
}
Expand Down Expand Up @@ -861,10 +916,32 @@ export const getDirectLinksForPublication = async (
include: {
user: true
}
},
publicationFlags: {
where: {
resolved: false
}
},
linkedFrom: {
where: {
publicationFrom: {
type: 'PEER_REVIEW',
versions: {
some: {
isLatestLiveVersion: true
}
}
}
}
}
}
}
}
},
publicationFlags: {
where: {
resolved: false
}
}
}
});
Expand Down Expand Up @@ -909,7 +986,9 @@ export const getDirectLinksForPublication = async (
authorLastName: user.lastName || '',
currentStatus,
publishedDate: publishedDate?.toISOString() || '',
authors: []
authors: [],
flagCount: link.publicationTo.publicationFlags.length,
peerReviewCount: link.publicationTo.linkedFrom.length
};
});

Expand All @@ -935,7 +1014,9 @@ export const getDirectLinksForPublication = async (
authorLastName: user.lastName || '',
currentStatus,
publishedDate: publishedDate?.toISOString() || '',
authors: []
authors: [],
flagCount: link.publicationFrom.publicationFlags.length,
peerReviewCount: link.publicationFrom.linkedFrom.length
};
});

Expand Down Expand Up @@ -1007,7 +1088,10 @@ export const getDirectLinksForPublication = async (
firstName: author.user?.firstName || '',
lastName: author.user?.lastName || ''
}
}))
})),
flagCount: publication.publicationFlags.length,
peerReviewCount: publication.linkedFrom.filter((child) => child.publicationFrom.type === 'PEER_REVIEW')
.length
},
linkedTo,
linkedFrom
Expand Down
38 changes: 35 additions & 3 deletions api/src/components/publicationVersion/service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,24 @@ export const getAllByPublicationIds = async (ids: string[]) => {
id: true,
type: true,
doi: true,
url_slug: true
url_slug: true,
linkedFrom: {
where: {
publicationFrom: {
type: 'PEER_REVIEW',
versions: {
some: {
isLatestLiveVersion: true
}
}
}
}
},
publicationFlags: {
where: {
resolved: false
}
}
}
},
user: {
Expand Down Expand Up @@ -166,7 +183,22 @@ export const getAllByPublicationIds = async (ids: string[]) => {
throw Error('Unable to find all latest versions for all requested publications.');
}

return latestVersions;
// Provide counts
const mappedResults = latestVersions.map((version) => {
// Remove linkedFrom and flags from return
const { linkedFrom, publicationFlags, ...rest } = version.publication;

return {
...version,
publication: {
...rest,
flagCount: version.publication.publicationFlags.length,
peerReviewCount: version.publication.linkedFrom.length
}
};
});

return mappedResults;
};

export const update = (id: string, data: Prisma.PublicationVersionUpdateInput) =>
Expand Down Expand Up @@ -425,7 +457,7 @@ export const create = async (previousVersion: I.PublicationVersion, user: I.User
linkedUser: user.id,
confirmedCoAuthor: true,
approvalRequested: false,
affiliations: coAuthor.affiliations,
affiliations: coAuthor.affiliations as unknown[] as Prisma.InputJsonValue[],
isIndependent: coAuthor.isIndependent,
position: index
}
Expand Down
33 changes: 31 additions & 2 deletions api/src/components/user/service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -259,15 +259,44 @@ export const getPublications = async (
}
}
}
},
linkedFrom: {
where: {
publicationFrom: {
type: 'PEER_REVIEW',
versions: {
some: {
isLatestLiveVersion: true
}
}
}
}
},
publicationFlags: {
where: {
resolved: false
}
}
}
});

const totalUserPublications = await client.prisma.publication.count({ where });

// Provide counts
const mappedPublications = userPublications.map((publication) => {
// Remove linkedFrom and flags from return
const { linkedFrom, publicationFlags, ...rest } = publication;

return {
...rest,
flagCount: publication.publicationFlags.length,
peerReviewCount: publication.linkedFrom.length
};
});

// Because the sorting is conditional on the publication state of a publication's versions, we can't do it in prisma.
const sortedPublications = isAccountOwner // If account owner, put publications with an active draft first (sub-sorted by updated time descending), then others (sub-sorted by published date descending)
? userPublications.sort((a, b) => {
? mappedPublications.sort((a, b) => {
const aLatest = a.versions.find((version) => version.isLatestVersion);
const bLatest = b.versions.find((version) => version.isLatestVersion);

Expand All @@ -291,7 +320,7 @@ export const getPublications = async (
return bLatest.updatedAt.getTime() - aLatest.updatedAt.getTime();
}
}) // If not account owner, we only have latest live publications - sort by published date descending
: userPublications.sort((a, b) => {
: mappedPublications.sort((a, b) => {
const aLatestLive = a.versions.find((version) => version.isLatestLiveVersion);
const bLatestLive = b.versions.find((version) => version.isLatestLiveVersion);

Expand Down
Loading

0 comments on commit 2846e51

Please sign in to comment.