diff --git a/src/app/api/download-reports/doi/related-works/route.ts b/src/app/api/download-reports/doi/related-works/route.ts index ae740905..093bbfa0 100644 --- a/src/app/api/download-reports/doi/related-works/route.ts +++ b/src/app/api/download-reports/doi/related-works/route.ts @@ -1,6 +1,6 @@ import { type NextRequest } from 'next/server' import { gql } from '@apollo/client'; -import apolloClient from 'src/utils/server/apolloClient' +import apolloClient from 'src/utils/apolloClient' import { stringify } from 'csv-stringify/sync' import { Work } from 'src/data/types'; import { QueryData } from 'src/data/queries/doiQuery' @@ -159,7 +159,7 @@ export async function GET(request: NextRequest) { { key: 'connectionType', header: 'Connection Type' } ] }) - + try { return new Response(csv, { status: 200, @@ -171,4 +171,4 @@ export async function GET(request: NextRequest) { } catch (error) { return new Response(JSON.stringify({ error }), { status: 400 }) } -} \ No newline at end of file +} diff --git a/src/app/api/download-reports/ror/funders/route.ts b/src/app/api/download-reports/ror/funders/route.ts index 3be89bce..41c07736 100644 --- a/src/app/api/download-reports/ror/funders/route.ts +++ b/src/app/api/download-reports/ror/funders/route.ts @@ -1,6 +1,6 @@ import { type NextRequest } from 'next/server' import { gql } from '@apollo/client'; -import apolloClient from 'src/utils/server/apolloClient' +import apolloClient from 'src/utils/apolloClient' import { stringify } from 'csv-stringify/sync' const QUERY = gql` @@ -53,11 +53,11 @@ export async function GET(request: NextRequest) { query: QUERY, variables: variables }) - - + + const csv = stringify(data.organization.works.funders, { header: true, - columns: [ { key: 'id', header: 'Funder ID' }, { key: 'title', header: 'Title' }, { key: 'count', header: 'Work Count' } ] + columns: [{ key: 'id', header: 'Funder ID' }, { key: 'title', header: 'Title' }, { key: 'count', header: 'Work Count' }] }) diff --git a/src/app/api/download-reports/ror/related-works/route.ts b/src/app/api/download-reports/ror/related-works/route.ts index a695c77f..e54f14f7 100644 --- a/src/app/api/download-reports/ror/related-works/route.ts +++ b/src/app/api/download-reports/ror/related-works/route.ts @@ -1,6 +1,6 @@ import { type NextRequest } from 'next/server' import { gql } from '@apollo/client'; -import apolloClient from 'src/utils/server/apolloClient' +import apolloClient from 'src/utils/apolloClient' import { stringify } from 'csv-stringify/sync' const QUERY = gql` @@ -83,7 +83,7 @@ export async function GET(request: NextRequest) { // { key: '???', header: 'Connection Type(s)' } ] }) - + try { return new Response(csv, { status: 200, @@ -95,4 +95,4 @@ export async function GET(request: NextRequest) { } catch (error) { return new Response(JSON.stringify({ error }), { status: 400 }) } -} \ No newline at end of file +} diff --git a/src/app/doi.org/[...doi]/Content.tsx b/src/app/doi.org/[...doi]/Content.tsx index ea31ff80..85d5f146 100644 --- a/src/app/doi.org/[...doi]/Content.tsx +++ b/src/app/doi.org/[...doi]/Content.tsx @@ -2,8 +2,8 @@ import React from 'react' import ReactHtmlParser from 'react-html-parser' import { Row, Col } from "src/components/Layout"; -import apolloClient from 'src/utils/server/apolloClient' -import { Work as WorkType } from 'src/data/types' +import apolloClient from 'src/utils/apolloClient' +import { Work as WorkType } from 'src/data/types' import { DOI_QUERY, QueryVar, QueryData } from 'src/data/queries/doiQuery' import Error from 'src/components/Error/Error' @@ -21,7 +21,7 @@ interface Props { isBot?: boolean } -export default async function Content (props: Props) { +export default async function Content(props: Props) { const { variables, isBot = false } = props const { data, error } = await apolloClient.query({ @@ -50,13 +50,13 @@ export default async function Content (props: Props) {
- { work.registrationAgency.id == "datacite" && ( + {work.registrationAgency.id == "datacite" && ( )}
- { !isBot && } + />} @@ -74,4 +74,4 @@ export default async function Content (props: Props) {
) -} \ No newline at end of file +} diff --git a/src/app/doi.org/[...doi]/RelatedContent.tsx b/src/app/doi.org/[...doi]/RelatedContent.tsx index ce170655..25763586 100644 --- a/src/app/doi.org/[...doi]/RelatedContent.tsx +++ b/src/app/doi.org/[...doi]/RelatedContent.tsx @@ -9,7 +9,7 @@ import { RELATED_CONTENT_QUERY, QueryVar, QueryData } from 'src/data/queries/doi import { Works } from 'src/data/types' import Error from 'src/components/Error/Error' -import WorksListing from 'src/components/WorksListing/Server' +import WorksListing from 'src/components/WorksListing/WorksListing' interface Props { variables: QueryVar @@ -18,7 +18,7 @@ interface Props { isBot?: boolean } -export default function RelatedContent (props: Props) { +export default function RelatedContent(props: Props) { const { variables, showSankey, connectionType, isBot = false } = props const { loading, data, error } = useQuery( @@ -65,9 +65,9 @@ export default function RelatedContent (props: Props) { const defaultConnectionType = referenceCount > 0 ? 'references' : - citationCount > 0 ? 'citations' : - partCount > 0 ? 'parts' : - partOfCount > 0 ? 'partOf' : 'otherRelated' + citationCount > 0 ? 'citations' : + partCount > 0 ? 'parts' : + partOfCount > 0 ? 'partOf' : 'otherRelated' const displayedConnectionType = connectionType ? connectionType : defaultConnectionType @@ -78,7 +78,7 @@ export default function RelatedContent (props: Props) { const hasNextPage = works.pageInfo ? works.pageInfo.hasNextPage : false const endCursor = works.pageInfo ? works.pageInfo.endCursor : '' - + return ( <> @@ -110,4 +110,4 @@ export default function RelatedContent (props: Props) { ) -} \ No newline at end of file +} diff --git a/src/app/doi.org/[...doi]/page.tsx b/src/app/doi.org/[...doi]/page.tsx index 7e3bb5d2..2f469319 100644 --- a/src/app/doi.org/[...doi]/page.tsx +++ b/src/app/doi.org/[...doi]/page.tsx @@ -5,7 +5,7 @@ import truncate from 'lodash/truncate' import { rorFromUrl, isProject, isDMP } from 'src/utils/helpers' -import apolloClient from 'src/utils/server/apolloClient' +import apolloClient from 'src/utils/apolloClient' import { CROSSREF_FUNDER_GQL } from 'src/data/queries/crossrefFunderQuery' import Content from './Content' import { DOI_METADATA_QUERY, MetadataQueryData, MetadataQueryVar } from 'src/data/queries/doiQuery' @@ -37,7 +37,7 @@ interface Props { export async function generateMetadata({ params }: Props): Promise { const doi = params.doi.join('/') - + const { data } = await apolloClient.query({ query: DOI_METADATA_QUERY, variables: { id: doi }, @@ -73,9 +73,9 @@ export async function generateMetadata({ params }: Props): Promise { const description = !data.work.descriptions[0] ? undefined : truncate(data.work.descriptions[0].description, { - length: 2500, - separator: '… ' - }) + length: 2500, + separator: '… ' + }) // TODO: Refer here for type https://nextjs.org/docs/app/api-reference/functions/generate-metadata#generatemetadata-function:~:text=image.png%22%20/%3E-,Good%20to%20know,-%3A // https://nextjs.org/docs/app/api-reference/functions/generate-metadata#generatemetadata-function:~:text=image.png%22%20/%3E-,Good%20to%20know,-%3A @@ -85,7 +85,7 @@ export async function generateMetadata({ params }: Props): Promise { // - + return { title: title, @@ -101,7 +101,7 @@ export async function generateMetadata({ params }: Props): Promise { } } -function mapSearchparams (searchParams: Props['searchParams']) { +function mapSearchparams(searchParams: Props['searchParams']) { return { filterQuery: searchParams.filterQuery, cursor: searchParams.cursor, @@ -130,7 +130,7 @@ export default async function Page({ params, searchParams }: Props) { variables: { crossrefFunderId: doi }, errorPolicy: 'all' }) - + if (!data) notFound() redirect(`/ror.org${rorFromUrl(data.organization.id)}?filterQuery=${vars.filterQuery}`) } diff --git a/src/app/grid.ac/[...grid]/page.tsx b/src/app/grid.ac/[...grid]/page.tsx index 7c72675f..063c10c1 100644 --- a/src/app/grid.ac/[...grid]/page.tsx +++ b/src/app/grid.ac/[...grid]/page.tsx @@ -1,6 +1,6 @@ import { notFound, redirect } from "next/navigation" import { GRID_GQL, QueryData, QueryVar } from "src/data/queries/gridQuery" -import apolloClient from "src/utils/server/apolloClient" +import apolloClient from "src/utils/apolloClient" import { rorFromUrl } from "src/utils/helpers" interface Props { @@ -16,7 +16,7 @@ export default async function GridPage({ params }: Props) { variables: { gridId }, errorPolicy: 'all' }) - + if (!data) notFound() redirect(`/ror.org${rorFromUrl(data.organization.id)}`) -} \ No newline at end of file +} diff --git a/src/app/orcid.org/[orcid]/Content.tsx b/src/app/orcid.org/[orcid]/Content.tsx index 1511263a..d2f6ad60 100644 --- a/src/app/orcid.org/[orcid]/Content.tsx +++ b/src/app/orcid.org/[orcid]/Content.tsx @@ -1,7 +1,7 @@ import React from 'react' import { Row, Col } from "src/components/Layout"; -import apolloClient from 'src/utils/server/apolloClient' +import apolloClient from 'src/utils/apolloClient' import { PERSON_QUERY, QueryVar, QueryData } from 'src/data/queries/personQuery' import Error from 'src/components/Error/Error' @@ -14,7 +14,7 @@ interface Props { isBot?: boolean } -export default async function Content (props: Props) { +export default async function Content(props: Props) { const { variables } = props const { data, error } = await apolloClient.query({ @@ -48,4 +48,4 @@ export default async function Content (props: Props) { ) -} \ No newline at end of file +} diff --git a/src/app/orcid.org/[orcid]/RelatedContent.tsx b/src/app/orcid.org/[orcid]/RelatedContent.tsx index fc7dcb53..91656207 100644 --- a/src/app/orcid.org/[orcid]/RelatedContent.tsx +++ b/src/app/orcid.org/[orcid]/RelatedContent.tsx @@ -8,7 +8,7 @@ import Loading from 'src/components/Loading/Loading' import { RELATED_CONTENT_QUERY, QueryVar, QueryData } from 'src/data/queries/personQuery' import Error from 'src/components/Error/Error' -import WorksListing from 'src/components/WorksListing/Server' +import WorksListing from 'src/components/WorksListing/WorksListing' import { pluralize } from 'src/utils/helpers'; interface Props { @@ -17,7 +17,7 @@ interface Props { isBot?: boolean } -export default function RelatedContent (props: Props) { +export default function RelatedContent(props: Props) { const { orcid, variables, isBot = false } = props const { loading, data, error } = useQuery( @@ -80,4 +80,4 @@ export default function RelatedContent (props: Props) { ) -} \ No newline at end of file +} diff --git a/src/app/orcid.org/[orcid]/page.tsx b/src/app/orcid.org/[orcid]/page.tsx index a2f4ba5f..be0a6de9 100644 --- a/src/app/orcid.org/[orcid]/page.tsx +++ b/src/app/orcid.org/[orcid]/page.tsx @@ -3,7 +3,7 @@ import { Metadata } from 'next' import { notFound } from 'next/navigation' import truncate from 'lodash/truncate' -import apolloClient from 'src/utils/server/apolloClient' +import apolloClient from 'src/utils/apolloClient' import Content from './Content' import { PERSON_METADATA_QUERY, MetadataQueryData, MetadataQueryVar } from 'src/data/queries/personQuery' import RelatedContent from './RelatedContent' @@ -32,7 +32,7 @@ interface Props { export async function generateMetadata({ params }: Props): Promise { const orcid = 'http://orcid.org/' + params.orcid - + const { data } = await apolloClient.query({ query: PERSON_METADATA_QUERY, variables: { id: orcid }, @@ -79,7 +79,7 @@ export async function generateMetadata({ params }: Props): Promise { // - + return { title: title, @@ -95,7 +95,7 @@ export async function generateMetadata({ params }: Props): Promise { } } -function mapSearchparams (searchParams: Props['searchParams']) { +function mapSearchparams(searchParams: Props['searchParams']) { return { filterQuery: searchParams.filterQuery, cursor: searchParams.cursor, diff --git a/src/app/repositories/[...repoid]/Content.tsx b/src/app/repositories/[...repoid]/Content.tsx index b1621cc0..d4d6fbd3 100644 --- a/src/app/repositories/[...repoid]/Content.tsx +++ b/src/app/repositories/[...repoid]/Content.tsx @@ -1,7 +1,7 @@ import React from 'react' import { Row, Col } from "src/components/Layout"; -import apolloClient from 'src/utils/server/apolloClient' +import apolloClient from 'src/utils/apolloClient' import { Repository as RepositoryType } from 'src/data/types' import { REPOSITORY_QUERY, QueryData, QueryVar } from 'src/data/queries/repositoryQuery'; @@ -13,7 +13,7 @@ interface Props { isBot?: boolean } -export default async function Content (props: Props) { +export default async function Content(props: Props) { const { variables } = props const { data, error } = await apolloClient.query({ @@ -34,11 +34,11 @@ export default async function Content (props: Props) { return ( - + ) -} \ No newline at end of file +} diff --git a/src/app/repositories/[...repoid]/page.tsx b/src/app/repositories/[...repoid]/page.tsx index b3a72be2..58a3ed2c 100644 --- a/src/app/repositories/[...repoid]/page.tsx +++ b/src/app/repositories/[...repoid]/page.tsx @@ -1,7 +1,7 @@ import React, { Suspense } from 'react' import { Metadata } from 'next' import { notFound } from 'next/navigation' -import apolloClient from 'src/utils/server/apolloClient' +import apolloClient from 'src/utils/apolloClient' import Content from './Content' import Loading from 'src/components/Loading/Loading' import { MetadataQueryData, MetadataQueryVar, REPOSITORY_METADATA_QUERY } from 'src/data/queries/repositoryQuery' @@ -17,7 +17,7 @@ interface Props { export async function generateMetadata({ params }: Props): Promise { const repoid = params.repoid.join('/') - + const { data } = await apolloClient.query({ query: REPOSITORY_METADATA_QUERY, variables: { id: repoid }, @@ -43,8 +43,8 @@ export async function generateMetadata({ params }: Props): Promise { const baseUrl = process.env.NEXT_PUBLIC_API_URL === 'https://api.datacite.org' - ? 'https://commons.datacite.org/' - : 'https://commons.stage.datacite.org/' + ? 'https://commons.datacite.org/' + : 'https://commons.stage.datacite.org/' const pageUrl = repo.re3dataDoi ? baseUrl + "repositories/" + repo.re3dataDoi diff --git a/src/app/ror.org/[rorid]/Content.tsx b/src/app/ror.org/[rorid]/Content.tsx index cf28d82b..229d2ddf 100644 --- a/src/app/ror.org/[rorid]/Content.tsx +++ b/src/app/ror.org/[rorid]/Content.tsx @@ -1,7 +1,7 @@ import React from 'react' import { Row, Col } from "src/components/Layout"; -import apolloClient from 'src/utils/server/apolloClient' +import apolloClient from 'src/utils/apolloClient' import { Organization as OrganizationType } from 'src/data/types' import { ORGANIZATION_QUERY, QueryData, QueryVar } from 'src/data/queries/organizationQuery'; @@ -17,7 +17,7 @@ interface Props { isBot?: boolean } -export default async function Content (props: Props) { +export default async function Content(props: Props) { const { variables, isBot = false } = props const { data, error } = await apolloClient.query({ @@ -40,7 +40,7 @@ export default async function Content (props: Props) { - { !isBot && } + />} @@ -63,4 +63,4 @@ export default async function Content (props: Props) { ) -} \ No newline at end of file +} diff --git a/src/app/ror.org/[rorid]/RelatedContent.tsx b/src/app/ror.org/[rorid]/RelatedContent.tsx index 3faca504..f31bf66d 100644 --- a/src/app/ror.org/[rorid]/RelatedContent.tsx +++ b/src/app/ror.org/[rorid]/RelatedContent.tsx @@ -8,7 +8,7 @@ import Loading from 'src/components/Loading/Loading' import { RELATED_CONTENT_QUERY, QueryVar, QueryData } from 'src/data/queries/organizationQuery' import Error from 'src/components/Error/Error' -import WorksListing from 'src/components/WorksListing/Server' +import WorksListing from 'src/components/WorksListing/WorksListing' import { pluralize } from 'src/utils/helpers'; interface Props { @@ -16,7 +16,7 @@ interface Props { isBot?: boolean } -export default function RelatedContent (props: Props) { +export default function RelatedContent(props: Props) { const { variables, isBot = false } = props const { loading, data, error } = useQuery( @@ -49,7 +49,7 @@ export default function RelatedContent (props: Props) { : '' const totalCount = relatedWorks.totalCount - + return ( <> @@ -79,4 +79,4 @@ export default function RelatedContent (props: Props) { ) -} \ No newline at end of file +} diff --git a/src/app/ror.org/[rorid]/page.tsx b/src/app/ror.org/[rorid]/page.tsx index 2ff1531d..db1be533 100644 --- a/src/app/ror.org/[rorid]/page.tsx +++ b/src/app/ror.org/[rorid]/page.tsx @@ -1,7 +1,7 @@ import React, { Suspense } from 'react' import { Metadata } from 'next' import { notFound } from 'next/navigation' -import apolloClient from 'src/utils/server/apolloClient' +import apolloClient from 'src/utils/apolloClient' import Content from './Content' import RelatedContent from './RelatedContent' import Loading from 'src/components/Loading/Loading' @@ -31,7 +31,7 @@ interface Props { export async function generateMetadata({ params }: Props): Promise { const { rorid } = params - + const { data } = await apolloClient.query({ query: ORGANIZATION_METADATA_QUERY, variables: { id: rorid }, @@ -82,7 +82,7 @@ export async function generateMetadata({ params }: Props): Promise { -function mapSearchparams (searchParams: Props['searchParams']) { +function mapSearchparams(searchParams: Props['searchParams']) { return { filterQuery: searchParams.filterQuery, cursor: searchParams.cursor, diff --git a/src/components/AuthorsFacet/AuthorsFacet.tsx b/src/components/AuthorsFacet/AuthorsFacet.tsx index b41c9914..ec28036e 100644 --- a/src/components/AuthorsFacet/AuthorsFacet.tsx +++ b/src/components/AuthorsFacet/AuthorsFacet.tsx @@ -1,14 +1,6 @@ import React from 'react' -import { Tooltip } from 'react-bootstrap' -import OverlayTrigger from '../OverlayTrigger/OverlayTrigger' -import { FontAwesomeIcon } from '@fortawesome/react-fontawesome' -import { - faSquare, - faCheckSquare, - faQuestionCircle -} from '@fortawesome/free-regular-svg-icons' -import { useRouter } from 'next/router' -import Link from 'next/link' +import FacetList from 'src/components/FacetList/FacetList' +import { Facet } from 'src/data/types' type Props = { authors: Facet[] @@ -17,45 +9,13 @@ type Props = { url: string } -interface Facet { - id: string - title: string - count: number -} - const AuthorsFacet: React.FunctionComponent = ({ authors, title, model, url }) => { - const router = useRouter() - - function facetLink(param: string, value: string, id: string) { - let icon = faSquare - - // get current query parameters from next router - const params = new URLSearchParams(router.query as any) - - // delete model and cursor parameters - params.delete(model) - params.delete('cursor') - - if (params.get(param) == value) { - // if param is present, delete from query and use checked icon - params.delete(param) - icon = faCheckSquare - } else { - // otherwise replace param with new value and use unchecked icon - params.set(param, value) - } - - return ( - - {' '} - - ) - } + if (!authors || authors.length === 0) return null // Used for checking filter shouldnt show author that is already filtered function checkAuthorForPerson(author) { @@ -75,43 +35,21 @@ const AuthorsFacet: React.FunctionComponent = ({ return author } + function generateValue(facetId: string) { + return `creators_and_contributors.nameIdentifiers.nameIdentifier:"${facetId}"` + } + return ( - - {authors && authors.length > 0 && ( -
-
- - This list includes only {title} with ORCID iDs in DOI metadata. - - }> -

{title}

-
-
    - {authors.filter(removeNullAuthors).filter(checkAuthorForPerson).map((facet) => ( -
  • - {facetLink( - 'filterQuery', - 'creators_and_contributors.nameIdentifiers.nameIdentifier:"' + - facet.id + - '"', - 'co-authors-facet-' + facet.id - )} -
    {facet.title}
    - - {facet.count.toLocaleString('en-US')} - -
    -
  • - ))} -
-
-
- )} -
+ ) - } + export default AuthorsFacet diff --git a/src/components/AuthorsFacet/Server.tsx b/src/components/AuthorsFacet/Server.tsx deleted file mode 100644 index d0162d13..00000000 --- a/src/components/AuthorsFacet/Server.tsx +++ /dev/null @@ -1,55 +0,0 @@ -import React from 'react' -import FacetList from '../FacetList/Server' -import { Facet } from 'src/data/types' - -type Props = { - authors: Facet[] - title: string - model: string - url: string -} - -const AuthorsFacet: React.FunctionComponent = ({ - authors, - title, - model, - url -}) => { - if (!authors || authors.length === 0) return null - - // Used for checking filter shouldnt show author that is already filtered - function checkAuthorForPerson(author) { - // Only works on person model - if (model == 'person') { - const orcid_id = url.substring(11, url.length - 2) - if (!author.id.includes(orcid_id)) { - return author - } - } else { - return author - } - } - - function removeNullAuthors(author) { - if (author.title) - return author - } - - function generateValue (facetId: string) { - return `creators_and_contributors.nameIdentifiers.nameIdentifier:"${facetId}"` - } - - return ( - - ) -} - -export default AuthorsFacet diff --git a/src/components/Consent/Consent.tsx b/src/components/Consent/Consent.tsx deleted file mode 100644 index 4d9e64e0..00000000 --- a/src/components/Consent/Consent.tsx +++ /dev/null @@ -1,63 +0,0 @@ -import React from 'react' -import CookieConsent from 'react-cookie-consent' - -const Consent = () => { - let domain = 'localhost' - if ( - process.env.NODE_ENV === 'production' && - process.env.NEXT_PUBLIC_API_URL === 'https://api.stage.datacite.org' - ) { - domain = '.stage.datacite.org' - } else if ( - process.env.NODE_ENV === 'production' && - process.env.NEXT_PUBLIC_API_URL === 'https://api.datacite.org' - ) { - domain = '.datacite.org' - } else if ( - process.env.NODE_ENV !== 'production' && - process.env.NEXT_PUBLIC_VERCEL_URL - ) { - domain = '.vercel.app' - } - - const linkStyle = { color: '#fecd23' } - const myContentStyle = {} - - return ( - - We use cookies on our website. Some are technically necessary, others help - us improve your user experience. You can decline non-essential cookies by - selecting “Reject”. Please see our{' '} - - Privacy Policy - {' '} - for further information about our privacy practices and use of cookies.{' '} - - ) -} - -export default Consent diff --git a/src/components/Error/Server.tsx b/src/components/Error/Server.tsx deleted file mode 100644 index bc9c1843..00000000 --- a/src/components/Error/Server.tsx +++ /dev/null @@ -1,18 +0,0 @@ -import React from 'react' -import { Alert } from 'src/components/Layout' - -type Props = { - title: string - message: string -} - -const Error: React.FunctionComponent = ({ title, message }) => { - return ( - -

{title}

-

{message}

-
- ) -} - -export default Error diff --git a/src/components/FacetList/FacetList.tsx b/src/components/FacetList/FacetList.tsx index f35eab94..9f012060 100644 --- a/src/components/FacetList/FacetList.tsx +++ b/src/components/FacetList/FacetList.tsx @@ -1,55 +1,64 @@ +'use client' + import React from 'react' -import { gql } from '@apollo/client' -import FilterItem from "../FilterItem/FilterItem" - -export const FACET_FIELDS = gql` - fragment facetFields on Facet{ - id - title - count - } -` -export interface Facet { - name: string - id: string - title: string - count: number -} +import OverlayTrigger from '../OverlayTrigger/OverlayTrigger' +import { Tooltip } from 'react-bootstrap' +import { FontAwesomeIcon } from '@fortawesome/react-fontawesome' +import FacetListItem from './FacetListItem' +import { Facet } from 'src/data/types' +import { faQuestionCircle } from '@fortawesome/free-regular-svg-icons' -type Props = { - title: string - name: string - facets: Facet[] -} +interface FacetListProps { + data: Facet[] | undefined + title: string + id: string + param: string + url: string -export const FacetList: React.FunctionComponent = ({ - title, - name, - facets -}) => { - return ( - <> - {facets.length>0 && ( -
-
-

{title}

-
    - {facets.map((facet, index) => ( -
  • - -
  • - ))} -
-
-
- )} - - ) + // eslint-disable-next-line no-unused-vars + value?: (fid: string) => string + // eslint-disable-next-line no-unused-vars + checked?: (index: number) => boolean + radio?: boolean + tooltipText?: string } -export default FacetList + +export default function FacetList (props: FacetListProps) { + const { data, title, id, param, url, value, checked, radio } = props + if (!data || data.length === 0) return null + + function Title () { + if (!props.tooltipText) return

{title}

+ + return ( + {props.tooltipText}} + > +

{title}

+
+ ) + } + + return ( +
+
+ + <ul id={id}> + {data.map((facet, i) => ( + <FacetListItem + key={facet.id} + facet={facet} + param={param} + url={url} + value={value && value(facet.id)} + checked={checked && checked(i)} + radio={radio} + /> + ))} + </ul> + </div> + </div> + ) +} \ No newline at end of file diff --git a/src/components/FacetList/Server.tsx b/src/components/FacetList/Server.tsx deleted file mode 100644 index 9f012060..00000000 --- a/src/components/FacetList/Server.tsx +++ /dev/null @@ -1,64 +0,0 @@ -'use client' - -import React from 'react' -import OverlayTrigger from '../OverlayTrigger/OverlayTrigger' -import { Tooltip } from 'react-bootstrap' -import { FontAwesomeIcon } from '@fortawesome/react-fontawesome' -import FacetListItem from './FacetListItem' -import { Facet } from 'src/data/types' -import { faQuestionCircle } from '@fortawesome/free-regular-svg-icons' - - -interface FacetListProps { - data: Facet[] | undefined - title: string - id: string - param: string - url: string - - // eslint-disable-next-line no-unused-vars - value?: (fid: string) => string - // eslint-disable-next-line no-unused-vars - checked?: (index: number) => boolean - radio?: boolean - tooltipText?: string -} - -export default function FacetList (props: FacetListProps) { - const { data, title, id, param, url, value, checked, radio } = props - if (!data || data.length === 0) return null - - function Title () { - if (!props.tooltipText) return <h4>{title}</h4> - - return ( - <OverlayTrigger - placement="top" - overlay={<Tooltip id="tooltipAuthors">{props.tooltipText}</Tooltip>} - > - <h4>{title} <FontAwesomeIcon icon={faQuestionCircle} /></h4> - </OverlayTrigger> - ) - } - - return ( - <div className="panel facets add"> - <div className="panel-body"> - <Title /> - <ul id={id}> - {data.map((facet, i) => ( - <FacetListItem - key={facet.id} - facet={facet} - param={param} - url={url} - value={value && value(facet.id)} - checked={checked && checked(i)} - radio={radio} - /> - ))} - </ul> - </div> - </div> - ) -} \ No newline at end of file diff --git a/src/components/Footer/Footer.test.tsx b/src/components/Footer/Footer.test.tsx deleted file mode 100644 index 3fdc4cf9..00000000 --- a/src/components/Footer/Footer.test.tsx +++ /dev/null @@ -1,12 +0,0 @@ -// import React from 'react' -// import { mount } from '@cypress/react' -// import Footer from './Footer' - -// describe('Footer Component', () => { -// it('works', () => { -// mount(<Footer />) -// cy.get('[data-cy=about]').contains('About DataCite').should('be.visible') -// }) -// }) - -export {} diff --git a/src/components/Footer/Footer.tsx b/src/components/Footer/Footer.tsx deleted file mode 100644 index 64d3b28b..00000000 --- a/src/components/Footer/Footer.tsx +++ /dev/null @@ -1,172 +0,0 @@ -import React from 'react' -import useSWR from 'swr' -import { Grid, Row, Col } from 'react-bootstrap' -import { FontAwesomeIcon } from '@fortawesome/react-fontawesome' -import { faEnvelope, faBlog } from '@fortawesome/free-solid-svg-icons' -import { - faLinkedin, - faGithub, - faYoutube, - faMastodon -} from '@fortawesome/free-brands-svg-icons' - -// TODO import Links from yml file -// import Links from '../../../config/links.yml' - -const Links = { - about_links: [ - { name: 'What we do', url: '/what-we-do/' }, - { name: 'Governance', url: '/governance/' }, - { name: 'Steering and Working Groups', url: '/#' }, - { name: 'Team', url: '/team/' }, - { name: 'Job Opportunities', url: '/job-opportunities/' }, - { name: 'Projects', url: '/projects/' } - ], - services_links: [ - { name: 'Create DOIs', url: '/create-dois/' }, - { name: 'Integrate Workflows', url: '/integrate-workflows/' }, - { name: 'Enable Discovery', url: '/enable-discovery/' }, - { name: 'Promote Reuse', url: '/promote-reuse/' }, - { name: 'Strategic Initiatives', url: '/#' } - ], - resources_links: [ - { name: 'Metadata Schema', url: 'https://schema.datacite.org' }, - { name: 'Support', url: 'https://support.datacite.org' } - ], - community_links: [ - { name: 'Become a Member', url: '/become-a-member/' }, - { name: 'DataCite Fee Model', url: '/fee-model/' }, - { name: 'Membership Enquiry', url: '/membership-enquiry/' }, - { name: 'DataCite Members', url: '/members/' } - ], - contact_links: [ - { name: 'Privacy Policy', url: '/privacy-policy/' }, - { name: 'Terms and Conditions', url: '/terms-and-conditions/' }, - { name: 'Imprint', url: '/imprint/' } - - ] -} - -const Footer = () => { - function StatusPage() { - const fetcher = (url: string) => fetch(url).then((res) => res.json()) - const { data, error } = useSWR( - 'https://nmtzsv0smzk5.statuspage.io/api/v2/status.json', - fetcher - ) - if (error) - return ( - <a href="http://status.datacite.org" target="_blank" rel="noreferrer"> - <span className="color-dot critical"></span> - <span className="color-description">Failed to load status</span> - </a> - ) - if (!data) - return ( - <a href="http://status.datacite.org" target="_blank" rel="noreferrer"> - <span className="color-dot loading"></span> - <span className="color-description">Loading...</span> - </a> - ) - - return ( - <a href="http://status.datacite.org" target="_blank" rel="noreferrer"> - <span className={'color-dot ' + data.status.indicator}></span> - <span className="color-description">{data.status.description}</span> - </a> - ) - } - - const baseUrl = 'https://datacite.org' - - const footerLinks = (links) => { - return ( - <ul> - {links.map((link) => ( - <li key={link.name}> - <a - href={link.url.startsWith('/') ? baseUrl + link.url : link.url} - target="_blank" - rel="noreferrer" - > - {link.name} - </a> - </li> - ))} - </ul> - ) - } - - return ( - <footer className="row footer hidden-xs"> - <Grid fluid={true}> - <Row> - <Col sm={3} md={3} className="footer-column"> - <h4 data-cy="about">About Us</h4> - {footerLinks(Links.about_links)} - </Col> - <Col sm={3} md={3} className="footer-column"> - <h4>Work With Us</h4> - {footerLinks(Links.services_links)} - </Col> - <Col sm={3} md={3} className="footer-column"> - <h4>Membership</h4> - {footerLinks(Links.community_links)} - <h4>Resources</h4> - {footerLinks(Links.resources_links)} - </Col> - <Col sm={3} md={3} className="footer-column"> - <h4 className="share">Contact Us</h4> - <a href="mailto:support@datacite.org" className="share"> - <FontAwesomeIcon icon={faEnvelope} /> - </a> - <a href="https://datacite.org/blog/" className="share"> - <FontAwesomeIcon icon={faBlog} /> - </a> - <a href="https://github.com/datacite/datacite" className="share"> - <FontAwesomeIcon icon={faGithub} /> - </a> - <a href="https://twitter.com/datacite" className="share"> - <svg aria-hidden="true" focusable="false" data-prefix="fab" className="svg-inline--fa fa-twitter" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><path fill="currentColor" d="M389.2 48h70.6L305.6 224.2 487 464H345L233.7 318.6 106.5 464H35.8L200.7 275.5 26.8 48H172.4L272.9 180.9 389.2 48zM364.4 421.8h39.1L151.1 88h-42L364.4 421.8z"></path></svg> - </a> - <a href="https://openbiblio.social/@datacite" className="share"> - <FontAwesomeIcon icon={faMastodon} /> - </a> - <a - href="https://www.linkedin.com/company/datacite" - className="share" - > - <FontAwesomeIcon icon={faLinkedin} /> - </a> - <a - href="https://www.youtube.com/@DataCiteChannel" - className="share" - > - <FontAwesomeIcon icon={faYoutube} /> - </a> - {footerLinks(Links.contact_links)} - {StatusPage()} - <h4>Funding</h4> - <ul> - <li className="funding"> - The work on DataCite Commons is supported by funding from the - European Union’s Horizon 2020 research and innovation programme - under grant agreement No{' '} - <a - href="https://cordis.europa.eu/project/id/777523" - target="_blank" - rel="noreferrer" - > - 777523 - </a> - . - </li> - </ul> - </Col> - </Row> - </Grid> - </footer> - ) -} - -export default Footer diff --git a/src/components/Header/Header.test.tsx b/src/components/Header/Header.test.tsx deleted file mode 100644 index aee69b21..00000000 --- a/src/components/Header/Header.test.tsx +++ /dev/null @@ -1,20 +0,0 @@ -import React from 'react' -import { mount } from '@cypress/react' -import Header from './Header' - -describe('Header Component', () => { - it('title', () => { - mount(<Header path={'/doi.org'} />) - cy.get('.navbar-brand').contains('DataCite Commons').should('be.visible') - }) - - it('about link', () => { - mount(<Header path={'/doi.org'} />) - cy.get('[data-cy=about]').contains('About').should('be.visible') - }) - - it('support link', () => { - mount(<Header path={'/doi.org'} />) - cy.get('[data-cy=support]').contains('Support').should('be.visible') - }) -}) diff --git a/src/components/Header/Header.tsx b/src/components/Header/Header.tsx deleted file mode 100644 index 2f9ce542..00000000 --- a/src/components/Header/Header.tsx +++ /dev/null @@ -1,228 +0,0 @@ -import React, { useState, useEffect } from 'react' -import { useRouter } from 'next/router' -import { - Navbar, - Nav, - NavItem, - NavDropdown, - MenuItem, - InputGroup, - Button -} from 'react-bootstrap' -import { FontAwesomeIcon } from '@fortawesome/react-fontawesome' -import { - faSignInAlt, - faSignOutAlt, - faUserCog, - faUserTag, - faAddressCard, - faTimes, - faSearch, - faNewspaper, - faUserGraduate, - faUniversity, - faDatabase, -} from '@fortawesome/free-solid-svg-icons' -import { faOrcid } from '@fortawesome/free-brands-svg-icons' -import { session } from '../../utils/session' - -type Props = { - path: string -} - -const Header: React.FunctionComponent<Props> = ({ path }) => { - const router = useRouter() - - const [searchInput, setSearchInput] = useState('') - - useEffect(() => { - if (router && router.query.query && !searchInput) { - setSearchInput(router.query.query.toString()) - } - }, [router.query.query]) - - const onSubmit = () => { - if (router) { - router.push({ - pathname: path, - query: { query: searchInput } - }) - } - } - - const onKeyDown = (event) => { - if (event.key === 'Enter') { - onSubmit() - } - } - - const onSearchChange = (e: React.FormEvent<HTMLInputElement>): void => { - setSearchInput(e.currentTarget.value) - } - - const onSearchClear = () => { - setSearchInput('') - } - - const profilesUrl = - process.env.NEXT_PUBLIC_PROFILES_URL || - 'https://profiles.stage.datacite.org' - - const orcidUrl = - process.env.NEXT_PUBLIC_API_URL === 'https://api.datacite.org' - ? 'https://orcid.org/' - : 'https://sandbox.orcid.org/' - - const user = session() - - return ( - <Navbar fluid collapseOnSelect> - <Navbar.Header> - <Navbar.Brand> - <a href="/"> - <img src="/images/commons-logo.svg" height="50" className="commons-logo"/> - </a> - </Navbar.Brand> - <Navbar.Toggle /> - </Navbar.Header> - <Navbar.Collapse> - <Navbar.Form pullLeft> - <InputGroup> - <input - name="query" - value={searchInput} - onChange={onSearchChange} - key="searchInput" - onKeyDown={onKeyDown} - placeholder="Type to search..." - className="form-control" - type="text" - /> - <Button type="submit" className="search-submit" onClick={onSubmit}> - <FontAwesomeIcon icon={faSearch} /> - </Button> - {searchInput !== '' && ( - <span - id="search-clear" - title="Clear" - aria-label="Clear" - onClick={onSearchClear} - > - <FontAwesomeIcon icon={faTimes} /> - </span> - )} - </InputGroup> - <div> - <Nav id="search-nav" activeKey={path}> - <NavItem - id="works-link" - eventKey={'/doi.org'} - href={'/doi.org?query=' + searchInput} - > - <FontAwesomeIcon icon={faNewspaper} /> Works - </NavItem> - <NavItem - id="people-link" - eventKey={'/orcid.org'} - href={'/orcid.org?query=' + searchInput} - > - <FontAwesomeIcon icon={faUserGraduate} /> People - </NavItem> - <NavItem - id="organizations-link" - eventKey={'/ror.org'} - href={'/ror.org?query=' + searchInput} - > - <FontAwesomeIcon icon={faUniversity} /> Organizations - </NavItem> - <NavItem - id="repositories-link" - eventKey={'/repositories'} - href={'/repositories?query=' + searchInput} - > - <FontAwesomeIcon icon={faDatabase} /> Repositories - </NavItem> - </Nav> - </div> - </Navbar.Form> - <Nav className="hidden-mobile" pullRight> - <NavDropdown - eventKey={1} - title="Pages" - id="pages-dropdown" - data-cy="pages" - > - <MenuItem eventKey={1.1} data-cy="about" href="/about"> - About - </MenuItem> - <MenuItem eventKey={1.2} data-cy="statistics" href="/statistics"> - Statistics - </MenuItem> - </NavDropdown> - <NavItem - eventKey={2} - data-cy="support" - href="https://support.datacite.org/docs/datacite-commons" - target="_blank" - rel="noreferrer" - > - Support - </NavItem> - {user && ( - <NavDropdown eventKey={3} title={user.name} id="basic-nav-dropdown"> - {user.beta_tester && ( - <> - <MenuItem eventKey={3.1} data-cy="beta" href="/beta"> - <FontAwesomeIcon icon={faUserTag} /> Beta Tester - </MenuItem> - <MenuItem divider /> - </> - )} - <MenuItem - eventKey={3.2} - data-cy="settings" - href={profilesUrl + '/settings/me'} - > - <FontAwesomeIcon icon={faUserCog} /> Settings - </MenuItem> - <MenuItem - eventKey={3.3} - data-cy="commons-page" - href={'/orcid.org/' + user.uid} - > - <FontAwesomeIcon icon={faAddressCard} /> Commons Page - </MenuItem> - <MenuItem - eventKey={3.4} - data-cy="orcid" - href={orcidUrl + user.uid} - target="_blank" - rel="noreferrer" - > - <FontAwesomeIcon icon={faOrcid} /> ORCID Record - </MenuItem> - <MenuItem - eventKey={3.5} - data-cy="signout" - href={profilesUrl + '/sign_out'} - > - <FontAwesomeIcon icon={faSignOutAlt} /> Sign Out - </MenuItem> - </NavDropdown> - )} - {!user && ( - <NavItem - id="sign-in" - className="btn sign-in" - href={profilesUrl + '/sign_in'} - > - <FontAwesomeIcon icon={faSignInAlt} /> Sign In - </NavItem> - )} - </Nav> - </Navbar.Collapse> - </Navbar> - ) -} - -export default Header diff --git a/src/components/HorizontalStackedBarChart/HorizontalStackedBarChart.tsx b/src/components/HorizontalStackedBarChart/HorizontalStackedBarChart.tsx index f3d56298..15e23df1 100644 --- a/src/components/HorizontalStackedBarChart/HorizontalStackedBarChart.tsx +++ b/src/components/HorizontalStackedBarChart/HorizontalStackedBarChart.tsx @@ -1,10 +1,10 @@ import React, { useEffect, useRef, useState } from 'react' import { VegaLite } from 'react-vega' -import { Facet } from '../FacetList/FacetList' -import EmptyChart from '../EmptyChart/EmptyChart' -import HelpIcon from '../HelpIcon/HelpIcon' +import EmptyChart from 'src/components/EmptyChart/EmptyChart' +import HelpIcon from 'src/components/HelpIcon/HelpIcon' import styles from './HorizontalStackedBarChart.module.scss' import stackedBarChartSpec from './HorizontalStackedBarChartSpec' +import { Facet } from 'src/data/types' type Props = { @@ -54,10 +54,10 @@ export function getTopFive(data: HorizontalBarRecord[]) { if (missingCount > 0) topFive.push({ title: 'Missing', count: missingCount }) - + topFive.sort((a, b) => b.count - a.count)[0] - + return { data: topFive, topCategory: topFive[0].title, @@ -77,7 +77,7 @@ const HorizontalBarChart: React.FunctionComponent<Props> = ({ const [width, setWidth] = useState(500); const graphDivRef = useRef<HTMLDivElement | null>(null); - function handleResize () { + function handleResize() { if (!graphDivRef.current) return setWidth(graphDivRef.current.offsetWidth - 20); } @@ -88,15 +88,15 @@ const HorizontalBarChart: React.FunctionComponent<Props> = ({ window.addEventListener('resize', handleResize); return () => window.removeEventListener('resize', handleResize); }, []) - + useEffect(() => { handleResize(); }); - - if (data.length==0) { - return <EmptyChart title={`Percent ${Array.isArray(chartTitle) ? chartTitle.join(' ') : chartTitle}`}/> + + if (data.length == 0) { + return <EmptyChart title={`Percent ${Array.isArray(chartTitle) ? chartTitle.join(' ') : chartTitle}`} /> } if (domain) { @@ -105,7 +105,7 @@ const HorizontalBarChart: React.FunctionComponent<Props> = ({ range = range.filter((_, i) => indices.includes(i)) } - + return ( <div className="panel panel-transparent"> diff --git a/src/components/Layout/Layout.tsx b/src/components/Layout/Layout.tsx deleted file mode 100644 index 169dc1fc..00000000 --- a/src/components/Layout/Layout.tsx +++ /dev/null @@ -1,80 +0,0 @@ -import React, { PropsWithChildren } from 'react' -import Head from 'next/head' -import { Cookies } from 'react-cookie-consent' - -import Header from '../Header/Header' -import Footer from '../Footer/Footer' -import Consent from '../Consent/Consent' -import { GA_TRACKING_ID } from '../../utils/gtag' - -type Props = PropsWithChildren<{ - path: string -}> - -const Layout: React.FunctionComponent<Props> = ({ children, path }) => { - // check whether user has given consent to google analytics tracking - const hasGivenConsent = Cookies.get('_consent') == 'true' - const cdnUrl = process.env.NEXT_PUBLIC_CDN_URL || 'https://assets.datacite.org' - const isProduction = - process.env.NEXT_PUBLIC_API_URL === 'https://api.datacite.org' - - return ( - <div> - <Head> - <title>DataCite Commons - {!isProduction && } - - - - - - - {hasGivenConsent && GA_TRACKING_ID && ( - <> -