From 4a5edec3259e2786185c14534880788bb101847a Mon Sep 17 00:00:00 2001 From: Nicoleta Ursu <nicoleta.ursu@endava.com> Date: Mon, 5 Apr 2021 11:51:34 +0300 Subject: [PATCH] feat: add filtering manuscripts by topic --- .../component-manuscripts/src/Manuscript.js | 16 ++-- .../component-manuscripts/src/Manuscripts.jsx | 74 ++++--------------- .../component-manuscripts/src/style.js | 13 ++-- app/queries/index.js | 57 ++++++++++++++ package.json | 1 + server/model-manuscript/src/graphql.js | 13 +++- 6 files changed, 100 insertions(+), 74 deletions(-) diff --git a/app/components/component-manuscripts/src/Manuscript.js b/app/components/component-manuscripts/src/Manuscript.js index ee9edd4f8b..f088855a04 100644 --- a/app/components/component-manuscripts/src/Manuscript.js +++ b/app/components/component-manuscripts/src/Manuscript.js @@ -35,7 +35,7 @@ const DELETE_MANUSCRIPT = gql` const urlFrag = config.journal.metadata.toplevel_urlfragment // manuscriptId is always the parent manuscript's id -const User = ({ manuscriptId, manuscript, submitter }) => { +const User = ({ manuscriptId, manuscript, submitter, history, ...props }) => { const [publishManuscript] = useMutation(publishManuscriptMutation) const [deleteManuscript] = useMutation(DELETE_MANUSCRIPT, { @@ -63,6 +63,11 @@ const User = ({ manuscriptId, manuscript, submitter }) => { }) } + const filterByTopic = (topic) => { + props.setSelectedTopic(topic) + history.replace(`${urlFrag}/admin/manuscripts?topic=${topic}`) + } + return ( <Row> {process.env.INSTANCE_NAME === 'aperture' && ( @@ -75,12 +80,10 @@ const User = ({ manuscriptId, manuscript, submitter }) => { <Cell>{convertTimestampToDate(manuscript.updated)}</Cell> {process.env.INSTANCE_NAME === 'ncrc' && ( <Cell> - {manuscript.submission?.topics?.map((topic, index) => { - return ( - <StyledTopic key={index} title={convertCamelCaseToText(topic)}> + {manuscript.submission.topics.map((topic) => { + return <StyledTopic key={topic} title={convertCamelCaseToText(topic)} onClick={() => filterByTopic(topic)}> {convertCamelCaseToText(topic)} </StyledTopic> - ) })} </Cell> )} @@ -161,6 +164,9 @@ User.propTypes = { email: PropTypes.string, username: PropTypes.string.isRequired, }).isRequired, + // eslint-disable-next-line + history: PropTypes.object, + setSelectedTopic: PropTypes.func.isRequired, } export default User diff --git a/app/components/component-manuscripts/src/Manuscripts.jsx b/app/components/component-manuscripts/src/Manuscripts.jsx index dc98be42b9..a27c414f01 100644 --- a/app/components/component-manuscripts/src/Manuscripts.jsx +++ b/app/components/component-manuscripts/src/Manuscripts.jsx @@ -1,5 +1,4 @@ -import React, { useState } from 'react' -import gql from 'graphql-tag' +import React, { useEffect, useState } from 'react' import { useQuery } from '@apollo/client' import { Button } from '@pubsweet/ui' import config from 'config' @@ -18,66 +17,11 @@ import { Pagination, } from './style' import { HeadingWithAction } from '../../shared' +import { GET_MANUSCRIPTS } from '../../../queries' +import getQueryStringByName from '../../../shared/getQueryStringByName' const urlFrag = config.journal.metadata.toplevel_urlfragment -const GET_MANUSCRIPTS = gql` - query Manuscripts( - $sort: String - $filter: ManuscriptsFilter - $offset: Int - $limit: Int - ) { - paginatedManuscripts( - sort: $sort - filter: $filter - offset: $offset - limit: $limit - ) { - totalCount - manuscripts { - id - meta { - manuscriptId - title - } - submission - created - updated - status - manuscriptVersions { - id - meta { - manuscriptId - title - } - created - updated - status - submitter { - username - online - defaultIdentity { - id - name - } - profilePicture - } - } - submitter { - username - online - defaultIdentity { - id - name - } - profilePicture - } - } - } - } -` - const Manuscripts = ({ history, ...props }) => { const SortHeader = ({ thisSortName, children }) => { if (!thisSortName) { @@ -118,18 +62,24 @@ const Manuscripts = ({ history, ...props }) => { const [sortName, setSortName] = useState('created') const [sortDirection, setSortDirection] = useState('DESC') const [page, setPage] = useState(1) + const [selectedTopic, setSelectedTopic] = useState(getQueryStringByName('topic')) const limit = 10 const sort = sortName && sortDirection && `${sortName}_${sortDirection}` - - const { loading, error, data } = useQuery(GET_MANUSCRIPTS, { + + const { loading, error, data, refetch } = useQuery(GET_MANUSCRIPTS, { variables: { sort, offset: (page - 1) * limit, limit, + filter: { submission: JSON.stringify({ topics: selectedTopic }) } }, fetchPolicy: 'network-only', }) + useEffect(() => { + refetch() + }, [selectedTopic]) + if (loading) return <Spinner /> if (error) return `Error! ${error.message}` @@ -194,6 +144,8 @@ const Manuscripts = ({ history, ...props }) => { manuscriptId={manuscript.id} number={key + 1} submitter={manuscript.submitter} + history={history} + setSelectedTopic={setSelectedTopic} /> ) })} diff --git a/app/components/component-manuscripts/src/style.js b/app/components/component-manuscripts/src/style.js index 50497560ad..5578a159f3 100644 --- a/app/components/component-manuscripts/src/style.js +++ b/app/components/component-manuscripts/src/style.js @@ -34,21 +34,22 @@ export const UserAction = styled(Action)` export const StyledTopic = styled.p` background-color: red; - padding: 0 10px; - margin-bottom: 5px; border-radius: 7px; color: white; - width: fit-content; + cursor: pointer; + margin-bottom: 5px; + max-width: 150px; overflow: hidden; - white-space: nowrap; + padding: 0 10px; text-overflow: ellipsis; - max-width: 150px; + white-space: nowrap; + width: fit-content; ` export const StyledTableLabel = styled.p` background-color: #ccc; + border-radius: 7px; padding: 0 10px; text-align: center; - border-radius: 7px; white-space: nowrap; ` \ No newline at end of file diff --git a/app/queries/index.js b/app/queries/index.js index cc18666edc..d4b8427653 100644 --- a/app/queries/index.js +++ b/app/queries/index.js @@ -82,3 +82,60 @@ export const SEARCH_USERS = gql` } } ` + +export const GET_MANUSCRIPTS = gql` + query Manuscripts( + $sort: String + $filter: ManuscriptsFilter + $offset: Int + $limit: Int + ) { + paginatedManuscripts( + sort: $sort + filter: $filter + offset: $offset + limit: $limit + ) { + totalCount + manuscripts { + id + meta { + manuscriptId + title + } + submission + created + updated + status + manuscriptVersions { + id + meta { + manuscriptId + title + } + created + updated + status + submitter { + username + online + defaultIdentity { + id + name + } + profilePicture + } + } + submitter { + username + online + defaultIdentity { + id + name + } + profilePicture + } + } + } + } +` diff --git a/package.json b/package.json index ea053e7608..26aca77131 100644 --- a/package.json +++ b/package.json @@ -122,6 +122,7 @@ "fs-extra": "4.0.3", "got": "11.7.0", "graphql": "^15.5.0", + "graphql-tag": "^2.10.1", "graphql-middleware": "4.0.2", "graphql-shield": "7.5.0", "graphql-tools": "4.0.8", diff --git a/server/model-manuscript/src/graphql.js b/server/model-manuscript/src/graphql.js index c1e24b5b20..cad324e3ae 100644 --- a/server/model-manuscript/src/graphql.js +++ b/server/model-manuscript/src/graphql.js @@ -272,7 +272,7 @@ const resolvers = { } try { - const response = await axios.post( + await axios.post( 'https://api.hypothes.is/api/annotations', requestBody, { @@ -293,7 +293,7 @@ const resolvers = { return updatedManuscript } catch { - return + return null } } @@ -378,6 +378,8 @@ const resolvers = { } }, async paginatedManuscripts(_, { sort, offset, limit, filter }, ctx) { + const parsedSubmission = JSON.parse(filter?.submission) + const query = ctx.models.Manuscript.query() .where({ parentId: null }) .withGraphFetched('[submitter, manuscriptVersions(orderByCreated)]') @@ -391,6 +393,12 @@ const resolvers = { query.where({ status: filter.status }) } + if (process.env.INSTANCE_NAME === 'ncrc') { + if (filter && parsedSubmission.topics ) { + query.whereRaw("(submission->'topics')::jsonb \\? ?", [parsedSubmission.topics]) + } + } + const totalCount = await query.resultSize() if (sort) { @@ -437,6 +445,7 @@ const typeDefs = ` input ManuscriptsFilter { status: String + submission: String } type PaginatedManuscripts { -- GitLab