From c0fdd5f190f30e2c269102d97fb2ceb2b221efb7 Mon Sep 17 00:00:00 2001 From: Diego Cohen Date: Tue, 26 Sep 2023 14:54:38 -0400 Subject: [PATCH 01/57] Implement TemplateContent for sidebar --- pages/search/index.tsx | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/pages/search/index.tsx b/pages/search/index.tsx index e97637c3b..1b700495f 100644 --- a/pages/search/index.tsx +++ b/pages/search/index.tsx @@ -3,7 +3,9 @@ import { Card, CardHeading, Heading, - SimpleGrid, + TemplateContent, + TemplateContentPrimary, + TemplateContentSidebar, } from "@nypl/design-system-react-components" import { useRouter } from "next/router" import { isEmpty } from "underscore" @@ -42,8 +44,8 @@ export default function Search({ results }) { NYPL Research Catalog {totalResults ? ( -
- + + {`Displaying 1-50 of ${results.results.totalResults.toLocaleString()} results for keyword "${ searchParams.searchKeywords @@ -59,9 +61,11 @@ export default function Search({ results }) { ) })} - - -
+ + + + + ) : ( /** * TODO: The logic and copy for different scenarios will need to be added when From 72858c5a355d227c4388da736ac1377286524abc Mon Sep 17 00:00:00 2001 From: Diego Cohen Date: Tue, 26 Sep 2023 15:22:14 -0400 Subject: [PATCH 02/57] Move z index style to sx prop --- src/components/SearchForm/SearchForm.tsx | 3 +++ styles/components/Search.module.scss | 21 --------------------- 2 files changed, 3 insertions(+), 21 deletions(-) diff --git a/src/components/SearchForm/SearchForm.tsx b/src/components/SearchForm/SearchForm.tsx index d65e7465a..75784972f 100644 --- a/src/components/SearchForm/SearchForm.tsx +++ b/src/components/SearchForm/SearchForm.tsx @@ -56,6 +56,9 @@ const SearchForm = () => { placeholder: "Keyword, title, journal title, or author/contributor", }} + sx={{ + ".chakra-select__icon-wrapper": { "z-index": "999 !important" }, + }} />
diff --git a/styles/components/Search.module.scss b/styles/components/Search.module.scss index dcb1e2ccb..4af2be9b1 100644 --- a/styles/components/Search.module.scss +++ b/styles/components/Search.module.scss @@ -8,27 +8,6 @@ .searchContainerInner { @include maxWidth; - - @include media($nypl-max-width) { - > div { - width: 85%; - } - } - - form { - select { - font-size: 16px; - } - // Select down SVG arrow: - .chakra-select__icon-wrapper { - z-index: 999 !important; - } - - input::placeholder { - font-style: normal; - font-size: 16px; - } - } } .advancedSearchContainer { From 883606da2ea41285a6a1206ca2d758fbcfb57ea4 Mon Sep 17 00:00:00 2001 From: Diego Cohen Date: Tue, 26 Sep 2023 16:46:23 -0400 Subject: [PATCH 03/57] Add border and description text to drb container, rename to DRB --- pages/search/index.tsx | 4 +- src/components/DRB/DRB.tsx | 57 ++++++++++++++++++++ src/components/DRBContainer/DRBContainer.tsx | 39 -------------- src/config/constants.ts | 2 + styles/components/DRB.module.scss | 4 ++ 5 files changed, 65 insertions(+), 41 deletions(-) create mode 100644 src/components/DRB/DRB.tsx delete mode 100644 src/components/DRBContainer/DRBContainer.tsx create mode 100644 styles/components/DRB.module.scss diff --git a/pages/search/index.tsx b/pages/search/index.tsx index 1b700495f..ef2823e60 100644 --- a/pages/search/index.tsx +++ b/pages/search/index.tsx @@ -11,7 +11,7 @@ import { useRouter } from "next/router" import { isEmpty } from "underscore" import RCLink from "../../src/components/RCLink/RCLink" -import DRBContainer from "../../src/components/DRBContainer/DRBContainer" +import DRB from "../../src/components/DRB/DRB" import { fetchResults } from "../api/search" import { mapQueryToSearchParams } from "../../src/utils/searchUtils" import type { SearchResultsElement } from "../../src/types/searchTypes" @@ -63,7 +63,7 @@ export default function Search({ results }) { })} - + ) : ( diff --git a/src/components/DRB/DRB.tsx b/src/components/DRB/DRB.tsx new file mode 100644 index 000000000..e40f79c67 --- /dev/null +++ b/src/components/DRB/DRB.tsx @@ -0,0 +1,57 @@ +import { + Card, + CardHeading, + CardContent, + Text, +} from "@nypl/design-system-react-components" +import useSWRImmutable from "swr/immutable" + +import RCLink from "../RCLink/RCLink" +import styles from "../../../styles/components/DRB.module.scss" +import { BASE_URL, DRB_ABOUT_URL } from "../../config/constants" +import type { SearchParams } from "../../types/searchTypes" +import type { DRBWork } from "../../types/drbTypes" +import { getQueryString } from "../../utils/searchUtils" + +interface DRBProps { + searchParams: SearchParams +} + +/** + * The DRB fetches and displays DRB search results + */ +const DRB = ({ searchParams }: DRBProps) => { + const searchQuery = getQueryString(searchParams) + const drbUrl = `${BASE_URL}/api/drb?${searchQuery}` + const fetcher = (url: string) => fetch(url).then((res) => res.json()) + + const { data, error, isValidating } = useSWRImmutable(drbUrl, fetcher) + + return isValidating ? ( + + Loading + + ) : ( + + + Results from Digital Research Books Beta + + + + Digital books for research from multiple sources world wide- all free + to read, download, and keep. No Library Card is Required.{" "} + Read more about the project. + + {!error && data?.works ? ( + data.works.map((drbWork: DRBWork) => ( +
{drbWork.title}
+ )) + ) : ( +
There was an error getting DRB results. Please try again.
+ )} +
+
+ ) +} + +export default DRB diff --git a/src/components/DRBContainer/DRBContainer.tsx b/src/components/DRBContainer/DRBContainer.tsx deleted file mode 100644 index d458f6f4f..000000000 --- a/src/components/DRBContainer/DRBContainer.tsx +++ /dev/null @@ -1,39 +0,0 @@ -import { Heading } from "@nypl/design-system-react-components" -import useSWRImmutable from "swr/immutable" - -import { BASE_URL } from "../../config/constants" -import type { SearchParams } from "../../types/searchTypes" -import type { DRBWork } from "../../types/drbTypes" -import { getQueryString } from "../../utils/searchUtils" - -interface DRBContainerProps { - searchParams: SearchParams -} - -/** - * The DRBContainer fetches and displays DRB search results - */ -const DRBContainer = ({ searchParams }: DRBContainerProps) => { - const searchQuery = getQueryString(searchParams) - const drbUrl = `${BASE_URL}/api/drb?${searchQuery}` - const fetcher = (url: string) => fetch(url).then((res) => res.json()) - - const { data, error, isValidating } = useSWRImmutable(drbUrl, fetcher) - - return isValidating ? ( -
Loading
- ) : ( -
- Results from Digital Research Books Beta - {!error && data?.works ? ( - data.works.map((drbWork: DRBWork) => ( -
{drbWork.title}
- )) - ) : ( -
There was an error getting DRB results. Please try again.
- )} -
- ) -} - -export default DRBContainer diff --git a/src/config/constants.ts b/src/config/constants.ts index 45b19a74c..fe1ba4be5 100644 --- a/src/config/constants.ts +++ b/src/config/constants.ts @@ -9,6 +9,8 @@ export const DRB_API_NAME = "drb" // URLs export const CIRCULATING_CATALOG_URL = "https://nypl.na2.iiivega.com/" export const LEGACY_CATALOG_URL = "https://legacycatalog.nypl.org/" +export const DRB_ABOUT_URL = + "https://digital-research-books-beta.nypl.org/about?source=catalog" // API Routes export const DISCOVERY_API_SEARCH_ROUTE = "/discovery/resources" diff --git a/styles/components/DRB.module.scss b/styles/components/DRB.module.scss new file mode 100644 index 000000000..268ff452e --- /dev/null +++ b/styles/components/DRB.module.scss @@ -0,0 +1,4 @@ +.drbContainer { + border-radius: var(--nypl-space-xs); + padding: var(--nypl-space-s); +} \ No newline at end of file From bfcc49fb595fb46bf4f7fff5037387a9d171e06a Mon Sep 17 00:00:00 2001 From: Diego Cohen Date: Tue, 26 Sep 2023 17:00:58 -0400 Subject: [PATCH 04/57] Initialize DRBItem component --- src/components/DRB/DRB.tsx | 25 ++++++++++++++++++++++--- styles/components/DRB.module.scss | 4 ++-- 2 files changed, 24 insertions(+), 5 deletions(-) diff --git a/src/components/DRB/DRB.tsx b/src/components/DRB/DRB.tsx index e40f79c67..a6633d992 100644 --- a/src/components/DRB/DRB.tsx +++ b/src/components/DRB/DRB.tsx @@ -3,6 +3,7 @@ import { CardHeading, CardContent, Text, + SimpleGrid, } from "@nypl/design-system-react-components" import useSWRImmutable from "swr/immutable" @@ -17,6 +18,10 @@ interface DRBProps { searchParams: SearchParams } +interface DRBItemProps { + drbWork: DRBWork +} + /** * The DRB fetches and displays DRB search results */ @@ -43,9 +48,11 @@ const DRB = ({ searchParams }: DRBProps) => { Read more about the project. {!error && data?.works ? ( - data.works.map((drbWork: DRBWork) => ( -
{drbWork.title}
- )) + + {data.works.map((drbWork: DRBWork) => ( + + ))} + ) : (
There was an error getting DRB results. Please try again.
)} @@ -54,4 +61,16 @@ const DRB = ({ searchParams }: DRBProps) => { ) } +const DRBItem = ({ drbWork }: DRBItemProps) => { + const { title } = drbWork + console.log(drbWork) + return ( + + + {title} + + + ) +} + export default DRB diff --git a/styles/components/DRB.module.scss b/styles/components/DRB.module.scss index 268ff452e..baf768fb3 100644 --- a/styles/components/DRB.module.scss +++ b/styles/components/DRB.module.scss @@ -1,4 +1,4 @@ .drbContainer { - border-radius: var(--nypl-space-xs); + border-radius: var(--nypl-space-xs); padding: var(--nypl-space-s); -} \ No newline at end of file +} From 0c2e1fa02aae75ca11fef2a40e89e724763ef3ed Mon Sep 17 00:00:00 2001 From: Diego Cohen Date: Tue, 26 Sep 2023 17:01:51 -0400 Subject: [PATCH 05/57] Decrease grid gap size --- src/components/DRB/DRB.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/DRB/DRB.tsx b/src/components/DRB/DRB.tsx index a6633d992..93547ea1a 100644 --- a/src/components/DRB/DRB.tsx +++ b/src/components/DRB/DRB.tsx @@ -48,7 +48,7 @@ const DRB = ({ searchParams }: DRBProps) => { Read more about the project. {!error && data?.works ? ( - + {data.works.map((drbWork: DRBWork) => ( ))} From 4bef13a597db225c7aaa25ffc481e594d6c6127a Mon Sep 17 00:00:00 2001 From: Diego Cohen Date: Fri, 29 Sep 2023 13:34:26 -0400 Subject: [PATCH 06/57] Move layout to page level --- pages/404/index.tsx | 23 +-- pages/404/redirect.tsx | 33 ++-- pages/_app.tsx | 10 +- pages/index.tsx | 271 ++++++++++++++++--------------- pages/search/advanced.tsx | 238 ++++++++++++++------------- pages/search/index.tsx | 53 +++--- src/components/Layout/Layout.tsx | 13 +- src/utils/appUtils.ts | 20 --- 8 files changed, 335 insertions(+), 326 deletions(-) delete mode 100644 src/utils/appUtils.ts diff --git a/pages/404/index.tsx b/pages/404/index.tsx index af0c58441..3db038440 100644 --- a/pages/404/index.tsx +++ b/pages/404/index.tsx @@ -1,6 +1,7 @@ import Head from "next/head" import { Heading } from "@nypl/design-system-react-components" +import Layout from "../../src/components/Layout/Layout" import RCLink from "../../src/components/RCLink/RCLink" import { LEGACY_CATALOG_URL } from "../../src/config/constants" @@ -10,16 +11,18 @@ export default function Custom404() { 404 Not Found - 404 Not Found -
-

We're sorry...

-

The page you were looking for doesn't exist.

-

- Search the Research Catalog or our{" "} - Legacy Catalog for research - materials. -

-
+ + <> + 404 Not Found +

We're sorry...

+

The page you were looking for doesn't exist.

+

+ Search the Research Catalog or our{" "} + Legacy Catalog for + research materials. +

+ +
) } diff --git a/pages/404/redirect.tsx b/pages/404/redirect.tsx index 6ddc44c39..b304c924d 100644 --- a/pages/404/redirect.tsx +++ b/pages/404/redirect.tsx @@ -1,6 +1,7 @@ import Head from "next/head" import { Heading } from "@nypl/design-system-react-components" +import Layout from "../../src/components/Layout/Layout" import RCLink from "../../src/components/RCLink/RCLink" import { CIRCULATING_CATALOG_URL, @@ -13,20 +14,24 @@ export default function Redirect404() { 404 Not Found - We're sorry... -
-

You've followed an out-of-date link to our research catalog.

-

- You may be able to find what you're looking for in the{" "} - Research Catalog or the{" "} - Circulating Catalog. - for research materials. -

-

- You can also try the{" "} - Legacy Catalog -

-
+ + <> + We're sorry... +

+ You've followed an out-of-date link to our research catalog. +

+

+ You may be able to find what you're looking for in the{" "} + Research Catalog or the{" "} + Circulating Catalog. + for research materials. +

+

+ You can also try the{" "} + Legacy Catalog +

+ +
) } diff --git a/pages/_app.tsx b/pages/_app.tsx index e13eb28f2..8e805bb74 100644 --- a/pages/_app.tsx +++ b/pages/_app.tsx @@ -1,19 +1,13 @@ import Head from "next/head" import "@nypl/design-system-react-components/dist/styles.css" -import Layout from "../src/components/Layout/Layout" -import { getActivePage } from "../src/utils/appUtils" - -function App({ Component, pageProps, router }) { - const activePage = getActivePage(router.pathname) +function App({ Component, pageProps }) { return ( <> - - - + ) } diff --git a/pages/index.tsx b/pages/index.tsx index caec5c420..8b3a00397 100644 --- a/pages/index.tsx +++ b/pages/index.tsx @@ -7,6 +7,7 @@ import { CardContent, } from "@nypl/design-system-react-components" +import Layout from "../src/components/Layout/Layout" import RCLink from "../src/components/RCLink/RCLink" import { SITE_NAME } from "../src/config/constants" @@ -16,140 +17,150 @@ export default function Home() { {SITE_NAME} - - Explore the Library's Vast Research Collections & More - -
-

- Discover millions of items from The New York Public Library's - Stephen A. Schwarzman Building, Schomburg Center for Research in Black - Culture, and The New York Public Library for the Performing Arts. - Plus, access materials from library collections at Columbia - University, Harvard University, and Princeton University.{" "} - - Learn more. - -

-

- Please note that the Research Catalog does not include circulating - materials. For books and more that you can check out to take home - please visit our{" "} - - circulating branch catalog. - {" "} - The{" "} - - legacy research catalog - {" "} - is still available, but does not include all of our Scan & Deliver - options or the Columbia University, Harvard University, and Princeton - University material from the Shared Collection. -

-
- - - Research at NYPL - - - - - Collections - - - + + <> + + Explore the Library's Vast Research Collections & More + +

- Discover our world-renowned research collections, featuring more - than 46 million items. + Discover millions of items from The New York Public Library's + Stephen A. Schwarzman Building, Schomburg Center for Research in + Black Culture, and The New York Public Library for the Performing + Arts. Plus, access materials from library collections at Columbia + University, Harvard University, and Princeton University.{" "} + + Learn more. +

- - - - - - Locations - - -

- Access items, one-on-one reference help, and dedicated research - study rooms. + Please note that the Research Catalog does not include circulating + materials. For books and more that you can check out to take home + please visit our{" "} + + circulating branch catalog. + {" "} + The{" "} + + legacy research catalog + {" "} + is still available, but does not include all of our Scan & Deliver + options or the Columbia University, Harvard University, and + Princeton University material from the Shared Collection.

-
-
- - - Divisions - - -

- Learn about the subject and media specializations of our research - divisions. -

-
-
- - - Support - - -

- Plan your in-person research visit and discover resources for - scholars and writers. -

-
-
- - - Services - - -

- Explore services for online and remote researchers, as well as our - interlibrary services. -

-
-
- +
+ + + Research at NYPL + + + + + Collections + + + +

+ Discover our world-renowned research collections, featuring + more than 46 million items. +

+
+
+ + + + Locations + + + +

+ Access items, one-on-one reference help, and dedicated + research study rooms. +

+
+
+ + + + Divisions + + + +

+ Learn about the subject and media specializations of our + research divisions. +

+
+
+ + + + Support + + + +

+ Plan your in-person research visit and discover resources for + scholars and writers. +

+
+
+ + + + Services + + + +

+ Explore services for online and remote researchers, as well as + our interlibrary services. +

+
+
+
+ +
) } diff --git a/pages/search/advanced.tsx b/pages/search/advanced.tsx index 6b845ba40..75d032273 100644 --- a/pages/search/advanced.tsx +++ b/pages/search/advanced.tsx @@ -23,6 +23,7 @@ import { Button, } from "@nypl/design-system-react-components" +import Layout from "../../src/components/Layout/Layout" import { BASE_URL, SITE_NAME } from "../../src/config/constants" import { searchFormReducer } from "../../src/reducers/searchFormReducer" import { @@ -114,127 +115,136 @@ export default function AdvancedSearch() { Advanced Search | {SITE_NAME} - {alert && ( - Please enter at least one field to submit an advanced search. - } - /> - )} - Advanced Search -
- - - {textInputFields.map(({ name, label }) => { - return ( - + <> + {alert && ( + + Please enter at least one field to submit an advanced search. + + } + /> + )} + Advanced Search + + + + {textInputFields.map(({ name, label }) => { + return ( + handleInputChange(e, "input_change"), + debounceInterval + )} + ref={inputRef} + /> + ) + })} + + + + handleInputChange(e, "input_change"), + (e) => handleDateChange(e), debounceInterval )} - ref={inputRef} /> - ) - })} - - - - handleDateChange(e), debounceInterval)} - /> - div": { + display: "grid", + "grid-template-columns": "repeat(2, minmax(0, 1fr))", + "grid-gap": "var(--nypl-space-s)", + div: { + marginTop: "0 !important", + }, + }, + }} + > + {materialTypeOptions.map((materialType) => { + return ( + + ) + })} + + + + + div": { - display: "grid", - "grid-template-columns": "repeat(2, minmax(0, 1fr))", - "grid-gap": "var(--nypl-space-s)", - div: { - marginTop: "0 !important", - }, - }, + gap: "xs", + marginLeft: "auto", }} > - {materialTypeOptions.map((materialType) => { - return ( - - ) - })} - - - - - - - - - + + + + + + ) } diff --git a/pages/search/index.tsx b/pages/search/index.tsx index 30819038d..ec4ca8924 100644 --- a/pages/search/index.tsx +++ b/pages/search/index.tsx @@ -3,14 +3,13 @@ import { Card, CardHeading, Heading, - TemplateContent, - TemplateContentPrimary, - TemplateContentSidebar, + SimpleGrid, } from "@nypl/design-system-react-components" import { useRouter } from "next/router" import { isEmpty } from "underscore" import RCLink from "../../src/components/RCLink/RCLink" +import Layout from "../../src/components/Layout/Layout" import DRB from "../../src/components/DRB/DRB" import { fetchResults } from "../api/search" import { mapQueryToSearchParams } from "../../src/utils/searchUtils" @@ -44,36 +43,34 @@ export default function Search({ results }) { Search Results | {SITE_NAME} - {totalResults ? ( - - + }> + {totalResults ? ( + <> {`Displaying 1-50 of ${results.results.totalResults.toLocaleString()} results for keyword "${ searchParams.q }"`} - {searchResultBibs.map((bib: SearchResultsBib) => { - // TODO: Create SearchResult component to manage result display (https://jira.nypl.org/browse/SCC-3714) - return ( - - - {bib.title} - - - ) - })} - - - - - - ) : ( - /** - * TODO: The logic and copy for different scenarios will need to be added when - * filters are implemented - */ - No results. Try a different search. - )} + + {searchResultBibs.map((bib: SearchResultsBib) => { + return ( + + + {bib.title} + + + ) + })} + + + ) : ( + /** + * TODO: The logic and copy for different scenarios will need to be added when + * filters are implemented + */ + No results. Try a different search. + )} + ) } diff --git a/src/components/Layout/Layout.tsx b/src/components/Layout/Layout.tsx index 34675afa6..dd6c98b12 100644 --- a/src/components/Layout/Layout.tsx +++ b/src/components/Layout/Layout.tsx @@ -14,15 +14,16 @@ import SearchForm from "../SearchForm/SearchForm" import { BASE_URL } from "../../config/constants" interface LayoutProps { - activePage?: RCPage children: ReactElement + sidebar?: ReactElement + activePage?: RCPage } /** * The Layout component wraps the TemplateAppContainer from the DS and * controls the rendering of Research Catalog header components per-page. */ -const Layout = ({ children, activePage }: LayoutProps) => { +const Layout = ({ children, sidebar, activePage }: LayoutProps) => { const showSearch = activePage === "search" const showHeader = activePage !== "404" @@ -51,7 +52,15 @@ const Layout = ({ children, activePage }: LayoutProps) => { ) } + sidebar={sidebar ? "right" : "none"} contentPrimary={{children}} + contentSidebar={ + sidebar && ( + +
{sidebar}
+
+ ) + } /> ) diff --git a/src/utils/appUtils.ts b/src/utils/appUtils.ts deleted file mode 100644 index 27160b369..000000000 --- a/src/utils/appUtils.ts +++ /dev/null @@ -1,20 +0,0 @@ -import type { RCPage } from "../types/pageTypes" -import { PATHS } from "../config/constants" - -/** - * getActivePage(pathname) - * Returns the Research Catalog page ID for a given pathname. - * Used for determining the current page for activating menu links and - * conditionally rendering the Search. - */ -export const getActivePage = (pathname: string): RCPage => { - if (pathname === PATHS.HOME || pathname === PATHS.SEARCH) { - return "search" - } else if (pathname === PATHS.ADVANCED_SEARCH) { - return "advanced" - } else if (pathname === PATHS["404"] || pathname === PATHS["404_REDIRECT"]) { - return "404" - } else { - return "" - } -} From 712ecf5d9425adc8ea5fd137cb17f02d3380a17d Mon Sep 17 00:00:00 2001 From: Diego Cohen Date: Fri, 29 Sep 2023 14:32:27 -0400 Subject: [PATCH 07/57] Rename DRB component to DRBContainer --- pages/search/index.tsx | 7 ++-- .../DRB/{DRB.tsx => DRBContainer.tsx} | 36 ++++++++----------- src/utils/drbUtils.ts | 12 +++---- styles/components/DRB.module.scss | 4 --- styles/components/DRBContainer.module.scss | 4 +++ 5 files changed, 30 insertions(+), 33 deletions(-) rename src/components/DRB/{DRB.tsx => DRBContainer.tsx} (72%) delete mode 100644 styles/components/DRB.module.scss create mode 100644 styles/components/DRBContainer.module.scss diff --git a/pages/search/index.tsx b/pages/search/index.tsx index ec4ca8924..1e7a2653f 100644 --- a/pages/search/index.tsx +++ b/pages/search/index.tsx @@ -10,7 +10,7 @@ import { isEmpty } from "underscore" import RCLink from "../../src/components/RCLink/RCLink" import Layout from "../../src/components/Layout/Layout" -import DRB from "../../src/components/DRB/DRB" +import DRBContainer from "../../src/components/DRB/DRBContainer" import { fetchResults } from "../api/search" import { mapQueryToSearchParams } from "../../src/utils/searchUtils" import type { SearchResultsElement } from "../../src/types/searchTypes" @@ -43,7 +43,10 @@ export default function Search({ results }) { Search Results | {SITE_NAME} - }> + } + > {totalResults ? ( <> diff --git a/src/components/DRB/DRB.tsx b/src/components/DRB/DRBContainer.tsx similarity index 72% rename from src/components/DRB/DRB.tsx rename to src/components/DRB/DRBContainer.tsx index 93547ea1a..8f08ceff3 100644 --- a/src/components/DRB/DRB.tsx +++ b/src/components/DRB/DRBContainer.tsx @@ -8,7 +8,7 @@ import { import useSWRImmutable from "swr/immutable" import RCLink from "../RCLink/RCLink" -import styles from "../../../styles/components/DRB.module.scss" +import styles from "../../../styles/components/DRBContainer.module.scss" import { BASE_URL, DRB_ABOUT_URL } from "../../config/constants" import type { SearchParams } from "../../types/searchTypes" import type { DRBWork } from "../../types/drbTypes" @@ -18,14 +18,10 @@ interface DRBProps { searchParams: SearchParams } -interface DRBItemProps { - drbWork: DRBWork -} - /** - * The DRB fetches and displays DRB search results + * The DRBContainer fetches and displays DRBContainer search results */ -const DRB = ({ searchParams }: DRBProps) => { +const DRBContainer = ({ searchParams }: DRBProps) => { const searchQuery = getQueryString(searchParams) const drbUrl = `${BASE_URL}/api/drb?${searchQuery}` const fetcher = (url: string) => fetch(url).then((res) => res.json()) @@ -50,7 +46,17 @@ const DRB = ({ searchParams }: DRBProps) => { {!error && data?.works ? ( {data.works.map((drbWork: DRBWork) => ( - + + + + {drbWork.title} + + + ))} ) : ( @@ -61,16 +67,4 @@ const DRB = ({ searchParams }: DRBProps) => { ) } -const DRBItem = ({ drbWork }: DRBItemProps) => { - const { title } = drbWork - console.log(drbWork) - return ( - - - {title} - - - ) -} - -export default DRB +export default DRBContainer diff --git a/src/utils/drbUtils.ts b/src/utils/drbUtils.ts index e0ffe59eb..e547dcb25 100644 --- a/src/utils/drbUtils.ts +++ b/src/utils/drbUtils.ts @@ -12,14 +12,14 @@ const mapSearchFieldToDRBField = { } /** - * Given a keyword and a search field, format and return a keyword query string expected by the DRB API + * Given a keyword and a search field, format and return a keyword query string expected by the DRBContainer API */ function getDRBKeywordQuery(keywords = "*", field = "keyword"): string { return `${field}:${keywords}` } /** - * Given a hash of SearchQueryParams, format and return an advanced field query string expected by the DRB API + * Given a hash of SearchQueryParams, format and return an advanced field query string expected by the DRBContainer API */ function getDRBAdvancedQuery(params: SearchParams): string { return ["contributor", "title", "subject"] @@ -34,7 +34,7 @@ function getDRBAdvancedQuery(params: SearchParams): string { } /** - * Given a hash of SearchFilters, returns an array of DRBFilters as expected by the DRB API + * Given a hash of SearchFilters, returns an array of DRBFilters as expected by the DRBContainer API */ function mapSearchFiltersToDRBFilters(filters: SearchFilters = {}): DRBFilters { let drbFilters: DRBFilters = [] @@ -54,7 +54,7 @@ function mapSearchFiltersToDRBFilters(filters: SearchFilters = {}): DRBFilters { } /** - * Given a hash of SearchParams, returns a hash representing an equivalent query against DRB API + * Given a hash of SearchParams, returns a hash representing an equivalent query against DRBContainer API */ function mapSearchParamsToDRBQueryParams(params: SearchParams): DRBQueryParams { const { q, field, sortBy, order, selectedFilters } = params @@ -85,7 +85,7 @@ function mapSearchParamsToDRBQueryParams(params: SearchParams): DRBQueryParams { dateBefore, } = selectedFilters || {} - // DRB doesn't handle subject or contributor in `filter` param, so handle + // DRBContainer doesn't handle subject or contributor in `filter` param, so handle // them separately: if (subjectLiteral) { drbQuery.query = drbQuery.query.concat( @@ -141,7 +141,7 @@ export function getQueryStringFromDRBQueryParams( } /** - * Given a SearchParams hash, return a DRB query string. + * Given a SearchParams hash, return a DRBContainer query string. */ export function getDRBQueryStringFromSearchParams( searchParams: SearchParams diff --git a/styles/components/DRB.module.scss b/styles/components/DRB.module.scss deleted file mode 100644 index baf768fb3..000000000 --- a/styles/components/DRB.module.scss +++ /dev/null @@ -1,4 +0,0 @@ -.drbContainer { - border-radius: var(--nypl-space-xs); - padding: var(--nypl-space-s); -} diff --git a/styles/components/DRBContainer.module.scss b/styles/components/DRBContainer.module.scss new file mode 100644 index 000000000..8855469f2 --- /dev/null +++ b/styles/components/DRBContainer.module.scss @@ -0,0 +1,4 @@ +.drbContainer { + border-radius: var(--nypl-space-xxs); + padding: var(--nypl-space-xs); +} From b3cc4624790f88dfb0823f3154eb50c2c8a29b9a Mon Sep 17 00:00:00 2001 From: Diego Cohen Date: Fri, 29 Sep 2023 15:27:39 -0400 Subject: [PATCH 08/57] Render DRB query link --- pages/404/index.tsx | 8 ++-- pages/404/redirect.tsx | 15 ++++---- src/components/DRB/DRBContainer.tsx | 57 ++++++++++++++++++++--------- src/config/config.ts | 11 +++++- src/config/constants.ts | 15 -------- src/server/nyplApiClient/index.ts | 6 +-- 6 files changed, 65 insertions(+), 47 deletions(-) diff --git a/pages/404/index.tsx b/pages/404/index.tsx index 3db038440..32d23ffd9 100644 --- a/pages/404/index.tsx +++ b/pages/404/index.tsx @@ -1,9 +1,9 @@ import Head from "next/head" import { Heading } from "@nypl/design-system-react-components" +import { appConfig } from "../../src/config/config" import Layout from "../../src/components/Layout/Layout" import RCLink from "../../src/components/RCLink/RCLink" -import { LEGACY_CATALOG_URL } from "../../src/config/constants" export default function Custom404() { return ( @@ -18,8 +18,10 @@ export default function Custom404() {

The page you were looking for doesn't exist.

Search the Research Catalog or our{" "} - Legacy Catalog for - research materials. + + Legacy Catalog + {" "} + for research materials.

diff --git a/pages/404/redirect.tsx b/pages/404/redirect.tsx index b304c924d..5cf7d0048 100644 --- a/pages/404/redirect.tsx +++ b/pages/404/redirect.tsx @@ -1,12 +1,9 @@ import Head from "next/head" import { Heading } from "@nypl/design-system-react-components" +import { appConfig } from "../../src/config/config" import Layout from "../../src/components/Layout/Layout" import RCLink from "../../src/components/RCLink/RCLink" -import { - CIRCULATING_CATALOG_URL, - LEGACY_CATALOG_URL, -} from "../../src/config/constants" export default function Redirect404() { return ( @@ -23,12 +20,16 @@ export default function Redirect404() {

You may be able to find what you're looking for in the{" "} Research Catalog or the{" "} - Circulating Catalog. - for research materials. + + Circulating Catalog + + . for research materials.

You can also try the{" "} - Legacy Catalog + + Legacy Catalog +

diff --git a/src/components/DRB/DRBContainer.tsx b/src/components/DRB/DRBContainer.tsx index 8f08ceff3..95c46ff32 100644 --- a/src/components/DRB/DRBContainer.tsx +++ b/src/components/DRB/DRBContainer.tsx @@ -7,12 +7,15 @@ import { } from "@nypl/design-system-react-components" import useSWRImmutable from "swr/immutable" +import { appConfig } from "../../config/config" import RCLink from "../RCLink/RCLink" +import { Link as DSLink } from "@nypl/design-system-react-components" import styles from "../../../styles/components/DRBContainer.module.scss" -import { BASE_URL, DRB_ABOUT_URL } from "../../config/constants" +import { BASE_URL } from "../../config/constants" import type { SearchParams } from "../../types/searchTypes" import type { DRBWork } from "../../types/drbTypes" import { getQueryString } from "../../utils/searchUtils" +import { getDRBQueryStringFromSearchParams } from "../../utils/drbUtils" interface DRBProps { searchParams: SearchParams @@ -24,6 +27,7 @@ interface DRBProps { const DRBContainer = ({ searchParams }: DRBProps) => { const searchQuery = getQueryString(searchParams) const drbUrl = `${BASE_URL}/api/drb?${searchQuery}` + const drbQuery = getDRBQueryStringFromSearchParams(searchParams) const fetcher = (url: string) => fetch(url).then((res) => res.json()) const { data, error, isValidating } = useSWRImmutable(drbUrl, fetcher) @@ -41,24 +45,43 @@ const DRBContainer = ({ searchParams }: DRBProps) => { Digital books for research from multiple sources world wide- all free to read, download, and keep. No Library Card is Required.{" "} - Read more about the project. + + Read more about the project + + . - {!error && data?.works ? ( - - {data.works.map((drbWork: DRBWork) => ( - + + {data.works.map((drbWork: DRBWork) => ( + + + + + {drbWork.title} + + + + + ))} + + {data.totalWorks && ( + - - - {drbWork.title} - - - - ))} - + + See {data.totalWorks.toLocaleString()} result + {data.totalWorks === 1 ? "" : "s"} from Digital Research Books + Beta + + + )} + ) : (
There was an error getting DRB results. Please try again.
)} diff --git a/src/config/config.ts b/src/config/config.ts index fdff211d7..972dda130 100644 --- a/src/config/config.ts +++ b/src/config/config.ts @@ -1,5 +1,5 @@ -export const apiConfig = { - baseUrls: { +export const appConfig = { + apiUrls: { platform: { development: process.env.PLATFORM_API_BASE_URL || @@ -29,5 +29,12 @@ export const apiConfig = { "https://digital-research-books-api.nypl.org/search", }, }, + externalUrls: { + drbFrontEnd: "https://digital-research-books-beta.nypl.org", + drbAbout: + "https://digital-research-books-beta.nypl.org/about?source=catalog", + circulatingCatalog: "https://nypl.na2.iiivega.com/", + legacyCatalog: "https://legacycatalog.nypl.org/", + }, tokenUrl: "https://isso.nypl.org/", } diff --git a/src/config/constants.ts b/src/config/constants.ts index ad96f9db0..c578ed1fe 100644 --- a/src/config/constants.ts +++ b/src/config/constants.ts @@ -7,20 +7,5 @@ export const DRB_RESULTS_PER_PAGE = 3 export const DISCOVERY_API_NAME = "discovery" export const DRB_API_NAME = "drb" -// Internal path names -export const PATHS = { - HOME: "/", - SEARCH: "/search", - ADVANCED_SEARCH: "/search/advanced", - "404": "/404", - "404_REDIRECT": "/404/redirect", -} - -// URLs -export const CIRCULATING_CATALOG_URL = "https://nypl.na2.iiivega.com/" -export const LEGACY_CATALOG_URL = "https://legacycatalog.nypl.org/" -export const DRB_ABOUT_URL = - "https://digital-research-books-beta.nypl.org/about?source=catalog" - // API Routes export const DISCOVERY_API_SEARCH_ROUTE = "/discovery/resources" diff --git a/src/server/nyplApiClient/index.ts b/src/server/nyplApiClient/index.ts index 81494cd4f..33ce084cf 100644 --- a/src/server/nyplApiClient/index.ts +++ b/src/server/nyplApiClient/index.ts @@ -1,7 +1,7 @@ import NyplApiClient from "@nypl/nypl-data-api-client" import aws from "aws-sdk" -import { apiConfig } from "../../config/config" +import { appConfig } from "../../config/config" interface KMSCache { clients: string[] @@ -46,7 +46,7 @@ const nyplApiClient = async (options = { apiName: "platform" }) => { return await Promise.resolve(CACHE.clients[apiName]) } - const baseUrl = apiConfig.baseUrls[apiName][appEnvironment] + const baseUrl = appConfig.apiUrls[apiName][appEnvironment] return await new Promise((resolve, reject) => { Promise.all(keys.map(decryptKMS)) @@ -55,7 +55,7 @@ const nyplApiClient = async (options = { apiName: "platform" }) => { base_url: baseUrl, oauth_key: decryptedClientId, oauth_secret: decryptedClientSecret, - oauth_url: apiConfig.tokenUrl, + oauth_url: appConfig.tokenUrl, }) CACHE.clientId = clientId From 6e1a1f2d2738eb268bb739e017afb5066c7f468c Mon Sep 17 00:00:00 2001 From: Diego Cohen Date: Fri, 29 Sep 2023 15:37:37 -0400 Subject: [PATCH 09/57] Initialize DRB item component --- src/components/DRB/DRBContainer.tsx | 19 +++-------- src/components/DRB/DRBItem.tsx | 32 +++++++++++++++++++ ...BContainer.module.scss => DRB.module.scss} | 2 +- 3 files changed, 37 insertions(+), 16 deletions(-) create mode 100644 src/components/DRB/DRBItem.tsx rename styles/components/{DRBContainer.module.scss => DRB.module.scss} (97%) diff --git a/src/components/DRB/DRBContainer.tsx b/src/components/DRB/DRBContainer.tsx index 95c46ff32..a30b2d2b1 100644 --- a/src/components/DRB/DRBContainer.tsx +++ b/src/components/DRB/DRBContainer.tsx @@ -4,13 +4,14 @@ import { CardContent, Text, SimpleGrid, + Link as DSLink, } from "@nypl/design-system-react-components" import useSWRImmutable from "swr/immutable" import { appConfig } from "../../config/config" import RCLink from "../RCLink/RCLink" -import { Link as DSLink } from "@nypl/design-system-react-components" -import styles from "../../../styles/components/DRBContainer.module.scss" +import DRBItem from "./DRBItem" +import styles from "../../../styles/components/DRB.module.scss" import { BASE_URL } from "../../config/constants" import type { SearchParams } from "../../types/searchTypes" import type { DRBWork } from "../../types/drbTypes" @@ -54,19 +55,7 @@ const DRBContainer = ({ searchParams }: DRBProps) => { <> {data.works.map((drbWork: DRBWork) => ( - - - - - {drbWork.title} - - - - + ))} {data.totalWorks && ( diff --git a/src/components/DRB/DRBItem.tsx b/src/components/DRB/DRBItem.tsx new file mode 100644 index 000000000..5b638f844 --- /dev/null +++ b/src/components/DRB/DRBItem.tsx @@ -0,0 +1,32 @@ +import { Card, CardContent, Text } from "@nypl/design-system-react-components" + +import RCLink from "../RCLink/RCLink" +import type { DRBWork } from "../../types/drbTypes" +import styles from "../../../styles/components/DRB.module.scss" + +interface DRBItemProps { + drbWork: DRBWork +} + +/** + * The DRBContainer fetches and displays DRBContainer search results + */ +const DRBItem = ({ drbWork }: DRBItemProps) => { + return ( + + + + + {drbWork.title} + + + + + ) +} + +export default DRBItem diff --git a/styles/components/DRBContainer.module.scss b/styles/components/DRB.module.scss similarity index 97% rename from styles/components/DRBContainer.module.scss rename to styles/components/DRB.module.scss index 8855469f2..a007ce599 100644 --- a/styles/components/DRBContainer.module.scss +++ b/styles/components/DRB.module.scss @@ -1,4 +1,4 @@ .drbContainer { border-radius: var(--nypl-space-xxs); padding: var(--nypl-space-xs); -} +} \ No newline at end of file From 5d4d5422cf41962c2c0d04a3b82729cb305007cb Mon Sep 17 00:00:00 2001 From: Diego Cohen Date: Fri, 29 Sep 2023 15:49:55 -0400 Subject: [PATCH 10/57] Initialize DRB edition types --- src/components/DRB/DRBContainer.tsx | 8 +++++--- src/components/DRB/DRBItem.tsx | 17 +++++++++++++---- src/types/drbTypes.ts | 14 ++++++++++++++ src/utils/drbUtils.ts | 7 +++++++ styles/components/DRB.module.scss | 2 +- 5 files changed, 40 insertions(+), 8 deletions(-) diff --git a/src/components/DRB/DRBContainer.tsx b/src/components/DRB/DRBContainer.tsx index a30b2d2b1..e2bbc32b9 100644 --- a/src/components/DRB/DRBContainer.tsx +++ b/src/components/DRB/DRBContainer.tsx @@ -54,9 +54,11 @@ const DRBContainer = ({ searchParams }: DRBProps) => { {!error && data.works ? ( <> - {data.works.map((drbWork: DRBWork) => ( - - ))} + {data.works.map( + (work: DRBWork) => + work?.uuid && + work?.title && + )} {data.totalWorks && ( { +const DRBItem = ({ work }: DRBItemProps) => { + const { title, editions } = work + console.log(editions) + + // const editions = work.editions + // + // // Get authors from `authors` property (DRB v4) or `agents` property (DRB v3) + // const authors = work.authors + // ? work.authors + // : work.agents.filter((agent) => agent.roles.includes("author")) + return ( - {drbWork.title} + {title} diff --git a/src/types/drbTypes.ts b/src/types/drbTypes.ts index 5986af3ce..53f590de4 100644 --- a/src/types/drbTypes.ts +++ b/src/types/drbTypes.ts @@ -9,9 +9,23 @@ export interface DRBQueryParams { export type DRBFilters = string[] +export interface Edition { + title: string + items?: EditionItem[] +} + +export interface EditionItem { + links?: EditionLink[] +} + +type EditionLink = { + link_id: string +} + export interface DRBWork { title?: string uuid?: string + editions?: Edition[] } export interface DRBResultsResponse { diff --git a/src/utils/drbUtils.ts b/src/utils/drbUtils.ts index e547dcb25..fbf0c3294 100644 --- a/src/utils/drbUtils.ts +++ b/src/utils/drbUtils.ts @@ -149,3 +149,10 @@ export function getDRBQueryStringFromSearchParams( const drbQueryParams = mapSearchParamsToDRBQueryParams(searchParams) return getQueryStringFromDRBQueryParams(drbQueryParams) } + +export const readOnlineMediaTypes = [ + "application/epub+xml", + "application/webpub+json", + "text/html", +] +export const downloadMediaTypes = ["application/epub+zip", "application/pdf"] diff --git a/styles/components/DRB.module.scss b/styles/components/DRB.module.scss index a007ce599..8855469f2 100644 --- a/styles/components/DRB.module.scss +++ b/styles/components/DRB.module.scss @@ -1,4 +1,4 @@ .drbContainer { border-radius: var(--nypl-space-xxs); padding: var(--nypl-space-xs); -} \ No newline at end of file +} From e9e9665b1c05a419464e947862f3e0260c83c28f Mon Sep 17 00:00:00 2001 From: Diego Cohen Date: Fri, 29 Sep 2023 15:50:44 -0400 Subject: [PATCH 11/57] Rename DRBItem to DRBResult --- src/components/DRB/DRBContainer.tsx | 4 ++-- src/components/DRB/{DRBItem.tsx => DRBResult.tsx} | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) rename src/components/DRB/{DRBItem.tsx => DRBResult.tsx} (93%) diff --git a/src/components/DRB/DRBContainer.tsx b/src/components/DRB/DRBContainer.tsx index e2bbc32b9..ef3dab179 100644 --- a/src/components/DRB/DRBContainer.tsx +++ b/src/components/DRB/DRBContainer.tsx @@ -10,7 +10,7 @@ import useSWRImmutable from "swr/immutable" import { appConfig } from "../../config/config" import RCLink from "../RCLink/RCLink" -import DRBItem from "./DRBItem" +import DRBResult from "./DRBResult" import styles from "../../../styles/components/DRB.module.scss" import { BASE_URL } from "../../config/constants" import type { SearchParams } from "../../types/searchTypes" @@ -57,7 +57,7 @@ const DRBContainer = ({ searchParams }: DRBProps) => { {data.works.map( (work: DRBWork) => work?.uuid && - work?.title && + work?.title && )}
{data.totalWorks && ( diff --git a/src/components/DRB/DRBItem.tsx b/src/components/DRB/DRBResult.tsx similarity index 93% rename from src/components/DRB/DRBItem.tsx rename to src/components/DRB/DRBResult.tsx index 7052f0c07..ffce13466 100644 --- a/src/components/DRB/DRBItem.tsx +++ b/src/components/DRB/DRBResult.tsx @@ -11,7 +11,7 @@ interface DRBItemProps { /** * The DRBContainer fetches and displays DRBContainer search results */ -const DRBItem = ({ work }: DRBItemProps) => { +const DRBResult = ({ work }: DRBItemProps) => { const { title, editions } = work console.log(editions) @@ -38,4 +38,4 @@ const DRBItem = ({ work }: DRBItemProps) => { ) } -export default DRBItem +export default DRBResult From ffe6276276d6188b64db01207158257e4cda8027 Mon Sep 17 00:00:00 2001 From: Diego Cohen Date: Fri, 29 Sep 2023 15:57:36 -0400 Subject: [PATCH 12/57] Initialize author and edition check --- src/components/DRB/DRBResult.tsx | 14 +++++++------- src/types/drbTypes.ts | 30 ++++++++++++++++++++---------- 2 files changed, 27 insertions(+), 17 deletions(-) diff --git a/src/components/DRB/DRBResult.tsx b/src/components/DRB/DRBResult.tsx index ffce13466..7bba40740 100644 --- a/src/components/DRB/DRBResult.tsx +++ b/src/components/DRB/DRBResult.tsx @@ -13,14 +13,14 @@ interface DRBItemProps { */ const DRBResult = ({ work }: DRBItemProps) => { const { title, editions } = work - console.log(editions) - // const editions = work.editions - // - // // Get authors from `authors` property (DRB v4) or `agents` property (DRB v3) - // const authors = work.authors - // ? work.authors - // : work.agents.filter((agent) => agent.roles.includes("author")) + // Get authors from `authors` property (DRB v4) or `agents` property (DRB v3) + const authors = work.authors + ? work.authors + : work.agents.filter((agent) => agent.roles.includes("author")) + + console.log(authors) + console.log(editions) return ( Date: Fri, 29 Sep 2023 16:01:58 -0400 Subject: [PATCH 13/57] Initialize DRBResult model --- src/models/DRBResult.ts | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 src/models/DRBResult.ts diff --git a/src/models/DRBResult.ts b/src/models/DRBResult.ts new file mode 100644 index 000000000..f3a2df18e --- /dev/null +++ b/src/models/DRBResult.ts @@ -0,0 +1,16 @@ +import type { DRBWork } from "../types/drbTypes" + +/** + * The DRBResult class contains the data and getter functions + * for a single DRB search result entity. + * + * DRB Results returned from the API are mapped and initialized into + * DRBResult objects in the DRBContainer component. + */ +export default class DRBResult { + id: string + + constructor(work: DRBWork) { + this.id = work.uuid + } +} From 64b5dbe4d3fe1117b61ad4d628bd136ab80fe68f Mon Sep 17 00:00:00 2001 From: Diego Cohen Date: Fri, 29 Sep 2023 16:35:22 -0400 Subject: [PATCH 14/57] Add selectedLink and selectedEdition getters to drb model --- src/components/DRB/DRBContainer.tsx | 4 ++- src/config/config.ts | 11 ++++++- src/models/DRBResult.ts | 46 ++++++++++++++++++++++++++++- src/types/drbTypes.ts | 4 ++- 4 files changed, 61 insertions(+), 4 deletions(-) diff --git a/src/components/DRB/DRBContainer.tsx b/src/components/DRB/DRBContainer.tsx index ef3dab179..2b079c99c 100644 --- a/src/components/DRB/DRBContainer.tsx +++ b/src/components/DRB/DRBContainer.tsx @@ -62,7 +62,9 @@ const DRBContainer = ({ searchParams }: DRBProps) => {
{data.totalWorks && ( diff --git a/src/config/config.ts b/src/config/config.ts index 972dda130..d114950e2 100644 --- a/src/config/config.ts +++ b/src/config/config.ts @@ -1,4 +1,5 @@ export const appConfig = { + environment: process.env.APP_ENV || "production", apiUrls: { platform: { development: @@ -30,7 +31,15 @@ export const appConfig = { }, }, externalUrls: { - drbFrontEnd: "https://digital-research-books-beta.nypl.org", + drbFrontEnd: { + development: + "http://sfr-front-end-development.us-east-1.elasticbeanstalk.com", + production: "https://digital-research-books-beta.nypl.org", + }, + drbEreader: { + development: "https://researchnow-reader.nypl.org", + production: "https://digital-research-books-reader.nypl.org", + }, drbAbout: "https://digital-research-books-beta.nypl.org/about?source=catalog", circulatingCatalog: "https://nypl.na2.iiivega.com/", diff --git a/src/models/DRBResult.ts b/src/models/DRBResult.ts index f3a2df18e..c242325e5 100644 --- a/src/models/DRBResult.ts +++ b/src/models/DRBResult.ts @@ -1,4 +1,12 @@ -import type { DRBWork } from "../types/drbTypes" +import type { + DRBWork, + Edition, + Author, + Agent, + EditionItem, + EditionLink, +} from "../types/drbTypes" +import { readOnlineMediaTypes } from "../utils/drbUtils" /** * The DRBResult class contains the data and getter functions @@ -9,8 +17,44 @@ import type { DRBWork } from "../types/drbTypes" */ export default class DRBResult { id: string + title: string + editions?: Edition[] + authors?: Author[] | Agent[] constructor(work: DRBWork) { this.id = work.uuid + this.title = work.title + this.editions = work.editions + this.authors = this.getAuthorsFromWork(work) + } + + get selectedEdition(): Edition { + return ( + this.editions.find( + (edition) => edition?.items?.length && edition.items[0].links.length + ) || this.editions[0] + ) + } + + get selectedLink(): EditionLink | null { + const { items } = this.selectedEdition + if (!items) return null + let selectedLink: EditionLink + const selectedItem = items.find((item) => + item.links.find((link) => { + selectedLink = link + // See above for media types that are used for "Read Online" links + return readOnlineMediaTypes.indexOf(link.mediaType) > -1 + }) + ) + + if (!selectedItem || !selectedLink || !selectedLink.url) return null + return selectedLink + } + + getAuthorsFromWork(work: DRBWork): Author[] | Agent[] { + return work.authors + ? work.authors + : work.agents.filter((agent) => agent.roles.includes("author")) } } diff --git a/src/types/drbTypes.ts b/src/types/drbTypes.ts index d21517385..9f8269e61 100644 --- a/src/types/drbTypes.ts +++ b/src/types/drbTypes.ts @@ -39,6 +39,8 @@ export interface Agent { roles: string[] } -type EditionLink = { +export interface EditionLink { link_id: string + mediaType: string + url?: string } From fde69769469816642fe2d3dc744e1e7a401d364d Mon Sep 17 00:00:00 2001 From: Diego Cohen Date: Fri, 29 Sep 2023 16:35:41 -0400 Subject: [PATCH 15/57] Add selectedLink and selectedEdition getters to drb model --- src/models/DRBResult.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/src/models/DRBResult.ts b/src/models/DRBResult.ts index c242325e5..57e4d7428 100644 --- a/src/models/DRBResult.ts +++ b/src/models/DRBResult.ts @@ -3,7 +3,6 @@ import type { Edition, Author, Agent, - EditionItem, EditionLink, } from "../types/drbTypes" import { readOnlineMediaTypes } from "../utils/drbUtils" From cbae7eb5b2c374e85bb361e956723332fa0f7fae Mon Sep 17 00:00:00 2001 From: Diego Cohen Date: Fri, 29 Sep 2023 16:46:52 -0400 Subject: [PATCH 16/57] Add read online url getter function to drb model --- src/models/DRBResult.ts | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/src/models/DRBResult.ts b/src/models/DRBResult.ts index 57e4d7428..15dddfa01 100644 --- a/src/models/DRBResult.ts +++ b/src/models/DRBResult.ts @@ -6,6 +6,7 @@ import type { EditionLink, } from "../types/drbTypes" import { readOnlineMediaTypes } from "../utils/drbUtils" +import { appConfig } from "../config/config" /** * The DRBResult class contains the data and getter functions @@ -35,20 +36,24 @@ export default class DRBResult { ) } - get selectedLink(): EditionLink | null { + get readOnlineUrl(): string | null { const { items } = this.selectedEdition if (!items) return null let selectedLink: EditionLink const selectedItem = items.find((item) => item.links.find((link) => { selectedLink = link - // See above for media types that are used for "Read Online" links return readOnlineMediaTypes.indexOf(link.mediaType) > -1 }) ) - if (!selectedItem || !selectedLink || !selectedLink.url) return null - return selectedLink + if (!selectedItem || !selectedLink || !selectedLink.url) { + return null + } else { + return `${ + appConfig.externalUrls.drbFrontEnd[appConfig.environment] + }/read/${selectedLink.link_id}` + } } getAuthorsFromWork(work: DRBWork): Author[] | Agent[] { From 871b7bb3be294c1c2a065dc137e6c60f50c0d56d Mon Sep 17 00:00:00 2001 From: Diego Cohen Date: Fri, 29 Sep 2023 16:50:14 -0400 Subject: [PATCH 17/57] Return full link element and add comment --- src/models/DRBResult.ts | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/src/models/DRBResult.ts b/src/models/DRBResult.ts index 15dddfa01..668000af9 100644 --- a/src/models/DRBResult.ts +++ b/src/models/DRBResult.ts @@ -36,7 +36,8 @@ export default class DRBResult { ) } - get readOnlineUrl(): string | null { + // TODO: Check to see if selectedItem is necessary + get readOnlineLink(): EditionLink | null { const { items } = this.selectedEdition if (!items) return null let selectedLink: EditionLink @@ -47,13 +48,9 @@ export default class DRBResult { }) ) - if (!selectedItem || !selectedLink || !selectedLink.url) { - return null - } else { - return `${ - appConfig.externalUrls.drbFrontEnd[appConfig.environment] - }/read/${selectedLink.link_id}` - } + return !selectedItem || !selectedLink || !selectedLink.link_id + ? null + : selectedLink } getAuthorsFromWork(work: DRBWork): Author[] | Agent[] { From ae3d87aa79e7a7f4090ed16cf60798fd50db7814 Mon Sep 17 00:00:00 2001 From: Diego Cohen Date: Fri, 29 Sep 2023 16:54:56 -0400 Subject: [PATCH 18/57] Add download link getter function --- src/models/DRBResult.ts | 19 +++++++++++++++++-- src/types/drbTypes.ts | 1 + 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/src/models/DRBResult.ts b/src/models/DRBResult.ts index 668000af9..8a6d36e5c 100644 --- a/src/models/DRBResult.ts +++ b/src/models/DRBResult.ts @@ -5,8 +5,7 @@ import type { Agent, EditionLink, } from "../types/drbTypes" -import { readOnlineMediaTypes } from "../utils/drbUtils" -import { appConfig } from "../config/config" +import { readOnlineMediaTypes, downloadMediaTypes } from "../utils/drbUtils" /** * The DRBResult class contains the data and getter functions @@ -53,6 +52,22 @@ export default class DRBResult { : selectedLink } + get downloadLink(): EditionLink | null { + const { items } = this.selectedEdition + if (!items) return null + + let downloadLink: EditionLink + items.find((item) => + item.links.find((link) => { + downloadLink = link + // See above for downloadable media types + return downloadMediaTypes.indexOf(link.mediaType) > -1 + }) + ) + + return !downloadLink || !downloadLink.download ? null : downloadLink + } + getAuthorsFromWork(work: DRBWork): Author[] | Agent[] { return work.authors ? work.authors diff --git a/src/types/drbTypes.ts b/src/types/drbTypes.ts index 9f8269e61..f7711c217 100644 --- a/src/types/drbTypes.ts +++ b/src/types/drbTypes.ts @@ -43,4 +43,5 @@ export interface EditionLink { link_id: string mediaType: string url?: string + download?: string } From f34a72ad345eeead826118a8209c76a1dae4faef Mon Sep 17 00:00:00 2001 From: Diego Cohen Date: Fri, 29 Sep 2023 17:26:37 -0400 Subject: [PATCH 19/57] Map works to drb params in drb container --- pages/search/index.tsx | 2 +- .../DRB/{DRBResult.tsx => DRBCard.tsx} | 22 +++++-------------- src/components/DRB/DRBContainer.tsx | 21 ++++++++++-------- src/utils/drbUtils.ts | 15 ++++++++++++- 4 files changed, 33 insertions(+), 27 deletions(-) rename src/components/DRB/{DRBResult.tsx => DRBCard.tsx} (53%) diff --git a/pages/search/index.tsx b/pages/search/index.tsx index 1e7a2653f..fd3516ae2 100644 --- a/pages/search/index.tsx +++ b/pages/search/index.tsx @@ -50,7 +50,7 @@ export default function Search({ results }) { {totalResults ? ( <> - {`Displaying 1-50 of ${results.results.totalResults.toLocaleString()} results for keyword "${ + {`Displaying 1-50 of ${totalResults.toLocaleString()} results for keyword "${ searchParams.q }"`} diff --git a/src/components/DRB/DRBResult.tsx b/src/components/DRB/DRBCard.tsx similarity index 53% rename from src/components/DRB/DRBResult.tsx rename to src/components/DRB/DRBCard.tsx index 7bba40740..2076707b6 100644 --- a/src/components/DRB/DRBResult.tsx +++ b/src/components/DRB/DRBCard.tsx @@ -1,27 +1,17 @@ import { Card, CardContent, Text } from "@nypl/design-system-react-components" import RCLink from "../RCLink/RCLink" -import type { DRBWork } from "../../types/drbTypes" +import type DRBResult from "../../models/DRBResult" import styles from "../../../styles/components/DRB.module.scss" -interface DRBItemProps { - work: DRBWork +interface DRBCardProps { + drbResult: DRBResult } /** * The DRBContainer fetches and displays DRBContainer search results */ -const DRBResult = ({ work }: DRBItemProps) => { - const { title, editions } = work - - // Get authors from `authors` property (DRB v4) or `agents` property (DRB v3) - const authors = work.authors - ? work.authors - : work.agents.filter((agent) => agent.roles.includes("author")) - - console.log(authors) - console.log(editions) - +const DRBCard = ({ drbResult }: DRBCardProps) => { return ( { - {title} + {drbResult.title} @@ -38,4 +28,4 @@ const DRBResult = ({ work }: DRBItemProps) => { ) } -export default DRBResult +export default DRBCard diff --git a/src/components/DRB/DRBContainer.tsx b/src/components/DRB/DRBContainer.tsx index 2b079c99c..6550bf37b 100644 --- a/src/components/DRB/DRBContainer.tsx +++ b/src/components/DRB/DRBContainer.tsx @@ -10,13 +10,16 @@ import useSWRImmutable from "swr/immutable" import { appConfig } from "../../config/config" import RCLink from "../RCLink/RCLink" -import DRBResult from "./DRBResult" +import DRBCard from "./DRBCard" import styles from "../../../styles/components/DRB.module.scss" import { BASE_URL } from "../../config/constants" import type { SearchParams } from "../../types/searchTypes" -import type { DRBWork } from "../../types/drbTypes" +import type DRBResult from "../../models/DRBResult" import { getQueryString } from "../../utils/searchUtils" -import { getDRBQueryStringFromSearchParams } from "../../utils/drbUtils" +import { + getDRBQueryStringFromSearchParams, + mapWorksToDRBResults, +} from "../../utils/drbUtils" interface DRBProps { searchParams: SearchParams @@ -33,6 +36,8 @@ const DRBContainer = ({ searchParams }: DRBProps) => { const { data, error, isValidating } = useSWRImmutable(drbUrl, fetcher) + const drbResults = mapWorksToDRBResults(data?.works) + return isValidating ? ( Loading @@ -51,14 +56,12 @@ const DRBContainer = ({ searchParams }: DRBProps) => { . - {!error && data.works ? ( + {!error && drbResults?.length ? ( <> - {data.works.map( - (work: DRBWork) => - work?.uuid && - work?.title && - )} + {drbResults.map((result: DRBResult) => ( + + ))} {data.totalWorks && ( { + return !isEmpty(work) || !work.uuid || !work.title + }) + .map((work: DRBWork) => { + return new DRBResult(work) + }) +} + export const readOnlineMediaTypes = [ "application/epub+xml", "application/webpub+json", From 671e667068c1119a29d7f2e620eda67002c3baf1 Mon Sep 17 00:00:00 2001 From: Diego Cohen Date: Fri, 29 Sep 2023 17:41:26 -0400 Subject: [PATCH 20/57] Write url getter --- src/components/DRB/DRBCard.tsx | 2 +- src/models/DRBResult.ts | 8 ++++++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/src/components/DRB/DRBCard.tsx b/src/components/DRB/DRBCard.tsx index 2076707b6..d1df799de 100644 --- a/src/components/DRB/DRBCard.tsx +++ b/src/components/DRB/DRBCard.tsx @@ -18,7 +18,7 @@ const DRBCard = ({ drbResult }: DRBCardProps) => { className={styles.drbContainer} > - + {drbResult.title} diff --git a/src/models/DRBResult.ts b/src/models/DRBResult.ts index 8a6d36e5c..72fcdfc7f 100644 --- a/src/models/DRBResult.ts +++ b/src/models/DRBResult.ts @@ -6,6 +6,7 @@ import type { EditionLink, } from "../types/drbTypes" import { readOnlineMediaTypes, downloadMediaTypes } from "../utils/drbUtils" +import { appConfig } from "../config/config" /** * The DRBResult class contains the data and getter functions @@ -27,6 +28,13 @@ export default class DRBResult { this.authors = this.getAuthorsFromWork(work) } + // Constructs the external url with the source parameter added (?source=catalog) + get urlWithSourceParam(): string { + return `${appConfig.externalUrls.drbFrontEnd[appConfig.environment]}/work/${ + this.id + }?source=catalog` + } + get selectedEdition(): Edition { return ( this.editions.find( From 059b8f106e6d627783f0f5a7f3dac643e0c6eb41 Mon Sep 17 00:00:00 2001 From: Diego Cohen Date: Fri, 29 Sep 2023 18:06:44 -0400 Subject: [PATCH 21/57] Render authors --- src/components/DRB/DRBCard.tsx | 20 ++++++++++++++++---- src/models/DRBResult.ts | 5 ++--- src/types/drbTypes.ts | 1 + src/utils/drbUtils.ts | 15 ++++++++++++++- 4 files changed, 33 insertions(+), 8 deletions(-) diff --git a/src/components/DRB/DRBCard.tsx b/src/components/DRB/DRBCard.tsx index d1df799de..ca0061685 100644 --- a/src/components/DRB/DRBCard.tsx +++ b/src/components/DRB/DRBCard.tsx @@ -2,7 +2,9 @@ import { Card, CardContent, Text } from "@nypl/design-system-react-components" import RCLink from "../RCLink/RCLink" import type DRBResult from "../../models/DRBResult" +import { getAuthorURL } from "../../utils/drbUtils" import styles from "../../../styles/components/DRB.module.scss" +import type { Author, Agent } from "../../types/drbTypes" interface DRBCardProps { drbResult: DRBResult @@ -18,11 +20,21 @@ const DRBCard = ({ drbResult }: DRBCardProps) => { className={styles.drbContainer} > - - - {drbResult.title} - + + {drbResult.title} + + {drbResult?.authors && ( + + By{" "} + {drbResult.authors.map((author: Author | Agent, index: number) => ( + <> + {index > 0 && ","} + {author.name} + + ))} + + )} ) diff --git a/src/models/DRBResult.ts b/src/models/DRBResult.ts index 72fcdfc7f..c724f56c5 100644 --- a/src/models/DRBResult.ts +++ b/src/models/DRBResult.ts @@ -28,11 +28,10 @@ export default class DRBResult { this.authors = this.getAuthorsFromWork(work) } - // Constructs the external url with the source parameter added (?source=catalog) - get urlWithSourceParam(): string { + get url(): string { return `${appConfig.externalUrls.drbFrontEnd[appConfig.environment]}/work/${ this.id - }?source=catalog` + }&source=catalog` } get selectedEdition(): Edition { diff --git a/src/types/drbTypes.ts b/src/types/drbTypes.ts index f7711c217..b78d2883a 100644 --- a/src/types/drbTypes.ts +++ b/src/types/drbTypes.ts @@ -36,6 +36,7 @@ export interface Author { } export interface Agent { + name: string roles: string[] } diff --git a/src/utils/drbUtils.ts b/src/utils/drbUtils.ts index 365e47b77..4930c6097 100644 --- a/src/utils/drbUtils.ts +++ b/src/utils/drbUtils.ts @@ -1,8 +1,15 @@ import type { SearchFilters, SearchParams } from "../types/searchTypes" -import type { DRBQueryParams, DRBFilters, DRBWork } from "../types/drbTypes" +import type { + DRBQueryParams, + DRBFilters, + DRBWork, + Author, + Agent, +} from "../types/drbTypes" import DRBResult from "../models/DRBResult" import { DRB_RESULTS_PER_PAGE } from "../config/constants" import { isEmpty } from "underscore" +import { appConfig } from "../config/config" const mapSearchFieldToDRBField = { all: "keyword", @@ -169,3 +176,9 @@ export const readOnlineMediaTypes = [ "text/html", ] export const downloadMediaTypes = ["application/epub+zip", "application/pdf"] + +export function getAuthorURL(author: Author | Agent) { + return `${ + appConfig.externalUrls.drbFrontEnd[appConfig.environment] + }/search?query=${`author:${author.name}&source=catalog`}` +} From 7abbde6788e93b0f6da8322666ffd729f7b08d2b Mon Sep 17 00:00:00 2001 From: Diego Cohen Date: Mon, 2 Oct 2023 11:55:15 -0400 Subject: [PATCH 22/57] Remove DRB stylesheet --- src/components/DRB/DRBCard.tsx | 11 +++++++---- src/components/DRB/DRBContainer.tsx | 5 ++--- styles/components/DRB.module.scss | 4 ---- 3 files changed, 9 insertions(+), 11 deletions(-) delete mode 100644 styles/components/DRB.module.scss diff --git a/src/components/DRB/DRBCard.tsx b/src/components/DRB/DRBCard.tsx index ca0061685..5ae4806dd 100644 --- a/src/components/DRB/DRBCard.tsx +++ b/src/components/DRB/DRBCard.tsx @@ -3,7 +3,6 @@ import { Card, CardContent, Text } from "@nypl/design-system-react-components" import RCLink from "../RCLink/RCLink" import type DRBResult from "../../models/DRBResult" import { getAuthorURL } from "../../utils/drbUtils" -import styles from "../../../styles/components/DRB.module.scss" import type { Author, Agent } from "../../types/drbTypes" interface DRBCardProps { @@ -17,15 +16,19 @@ const DRBCard = ({ drbResult }: DRBCardProps) => { return ( - {drbResult.title} + + {drbResult.title} + {drbResult?.authors && ( - + By{" "} {drbResult.authors.map((author: Author | Agent, index: number) => ( <> diff --git a/src/components/DRB/DRBContainer.tsx b/src/components/DRB/DRBContainer.tsx index 6550bf37b..5da02e117 100644 --- a/src/components/DRB/DRBContainer.tsx +++ b/src/components/DRB/DRBContainer.tsx @@ -11,7 +11,6 @@ import useSWRImmutable from "swr/immutable" import { appConfig } from "../../config/config" import RCLink from "../RCLink/RCLink" import DRBCard from "./DRBCard" -import styles from "../../../styles/components/DRB.module.scss" import { BASE_URL } from "../../config/constants" import type { SearchParams } from "../../types/searchTypes" import type DRBResult from "../../models/DRBResult" @@ -39,11 +38,11 @@ const DRBContainer = ({ searchParams }: DRBProps) => { const drbResults = mapWorksToDRBResults(data?.works) return isValidating ? ( - + Loading ) : ( - + Results from Digital Research Books Beta diff --git a/styles/components/DRB.module.scss b/styles/components/DRB.module.scss deleted file mode 100644 index 8855469f2..000000000 --- a/styles/components/DRB.module.scss +++ /dev/null @@ -1,4 +0,0 @@ -.drbContainer { - border-radius: var(--nypl-space-xxs); - padding: var(--nypl-space-xs); -} From 3a987f1d7c6f95022301eded828cfb4acd81eedc Mon Sep 17 00:00:00 2001 From: Diego Cohen Date: Mon, 2 Oct 2023 12:07:44 -0400 Subject: [PATCH 23/57] Render read online and download link --- src/client/icons/Download.tsx | 15 +++++++++++++++ src/components/DRB/DRBCard.tsx | 35 +++++++++++++++++++++++++++++----- src/models/DRBResult.ts | 6 ++++-- 3 files changed, 49 insertions(+), 7 deletions(-) create mode 100644 src/client/icons/Download.tsx diff --git a/src/client/icons/Download.tsx b/src/client/icons/Download.tsx new file mode 100644 index 000000000..f706441fd --- /dev/null +++ b/src/client/icons/Download.tsx @@ -0,0 +1,15 @@ +import React from "react" + +const DownloadIcon = () => ( + + + + +) + +export default DownloadIcon diff --git a/src/components/DRB/DRBCard.tsx b/src/components/DRB/DRBCard.tsx index 5ae4806dd..670cb73f4 100644 --- a/src/components/DRB/DRBCard.tsx +++ b/src/components/DRB/DRBCard.tsx @@ -1,9 +1,14 @@ -import { Card, CardContent, Text } from "@nypl/design-system-react-components" +import { + Card, + CardContent, + Text, + Link as DSLink, +} from "@nypl/design-system-react-components" -import RCLink from "../RCLink/RCLink" import type DRBResult from "../../models/DRBResult" import { getAuthorURL } from "../../utils/drbUtils" import type { Author, Agent } from "../../types/drbTypes" +import DownloadIcon from "../../client/icons/Download" interface DRBCardProps { drbResult: DRBResult @@ -21,11 +26,11 @@ const DRBCard = ({ drbResult }: DRBCardProps) => { }} > - + {drbResult.title} - + {drbResult?.authors && ( @@ -33,11 +38,31 @@ const DRBCard = ({ drbResult }: DRBCardProps) => { {drbResult.authors.map((author: Author | Agent, index: number) => ( <> {index > 0 && ","} - {author.name} + + {author.name} + ))} )} + + {drbResult?.readOnlineUrl && ( + + + Read Online + + + )} + + {drbResult?.downloadLink && ( + + + + Download + {drbResult.downloadLink.mediaType || ""} + + + )} ) diff --git a/src/models/DRBResult.ts b/src/models/DRBResult.ts index c724f56c5..9bae124e0 100644 --- a/src/models/DRBResult.ts +++ b/src/models/DRBResult.ts @@ -43,7 +43,7 @@ export default class DRBResult { } // TODO: Check to see if selectedItem is necessary - get readOnlineLink(): EditionLink | null { + get readOnlineUrl(): string | null { const { items } = this.selectedEdition if (!items) return null let selectedLink: EditionLink @@ -56,7 +56,9 @@ export default class DRBResult { return !selectedItem || !selectedLink || !selectedLink.link_id ? null - : selectedLink + : `${appConfig.externalUrls.drbFrontEnd[appConfig.environment]}/read/${ + selectedLink.link_id + }` } get downloadLink(): EditionLink | null { From 35dcb6a84629bf4c3679509e50610b817c8ef9aa Mon Sep 17 00:00:00 2001 From: Diego Cohen Date: Mon, 2 Oct 2023 12:54:59 -0400 Subject: [PATCH 24/57] Style read online link as button --- src/components/DRB/DRBCard.tsx | 31 +++++++++++++++++++------------ src/config/constants.ts | 3 +++ src/models/DRBResult.ts | 16 +++++++++++++--- 3 files changed, 35 insertions(+), 15 deletions(-) diff --git a/src/components/DRB/DRBCard.tsx b/src/components/DRB/DRBCard.tsx index 670cb73f4..16850a45a 100644 --- a/src/components/DRB/DRBCard.tsx +++ b/src/components/DRB/DRBCard.tsx @@ -2,6 +2,7 @@ import { Card, CardContent, Text, + Box, Link as DSLink, } from "@nypl/design-system-react-components" @@ -27,13 +28,11 @@ const DRBCard = ({ drbResult }: DRBCardProps) => { > - - {drbResult.title} - + {drbResult.title} {drbResult?.authors && ( - + By{" "} {drbResult.authors.map((author: Author | Agent, index: number) => ( <> @@ -47,19 +46,27 @@ const DRBCard = ({ drbResult }: DRBCardProps) => { )} {drbResult?.readOnlineUrl && ( - - - Read Online - + + Read Online )} {drbResult?.downloadLink && ( - - - Download - {drbResult.downloadLink.mediaType || ""} + + + + {" "} + Download {drbResult.downloadLink.mediaType || ""} )} diff --git a/src/config/constants.ts b/src/config/constants.ts index c578ed1fe..a35c75de4 100644 --- a/src/config/constants.ts +++ b/src/config/constants.ts @@ -9,3 +9,6 @@ export const DRB_API_NAME = "drb" // API Routes export const DISCOVERY_API_SEARCH_ROUTE = "/discovery/resources" + +// Query params +export const sourceParam = "?source=catalog" diff --git a/src/models/DRBResult.ts b/src/models/DRBResult.ts index 9bae124e0..ee02cc8ab 100644 --- a/src/models/DRBResult.ts +++ b/src/models/DRBResult.ts @@ -5,6 +5,7 @@ import type { Agent, EditionLink, } from "../types/drbTypes" +import { sourceParam } from "../config/constants" import { readOnlineMediaTypes, downloadMediaTypes } from "../utils/drbUtils" import { appConfig } from "../config/config" @@ -31,7 +32,7 @@ export default class DRBResult { get url(): string { return `${appConfig.externalUrls.drbFrontEnd[appConfig.environment]}/work/${ this.id - }&source=catalog` + }${sourceParam}` } get selectedEdition(): Edition { @@ -69,12 +70,21 @@ export default class DRBResult { items.find((item) => item.links.find((link) => { downloadLink = link - // See above for downloadable media types return downloadMediaTypes.indexOf(link.mediaType) > -1 }) ) - return !downloadLink || !downloadLink.download ? null : downloadLink + // Format media type to show label in all uppercase (e.g. EPUB) + downloadLink.mediaType = downloadLink.mediaType + .replace(/(application|text)\/|\+zip/gi, "") + .toUpperCase() + + // Add https if not present in download link and add source="catalog" query param + downloadLink.url = downloadLink.url.startsWith("http") + ? `${downloadLink.url}${sourceParam}` + : `https://${downloadLink.url}/${sourceParam}` + + return !downloadLink?.download || !downloadLink?.url ? null : downloadLink } getAuthorsFromWork(work: DRBWork): Author[] | Agent[] { From 0b0f4404e8134e96f2b62b0618938945fea1604c Mon Sep 17 00:00:00 2001 From: Diego Cohen Date: Mon, 2 Oct 2023 13:51:14 -0400 Subject: [PATCH 25/57] Render DRB results on server side --- pages/api/drb.ts | 4 ++-- pages/api/search.ts | 15 +++++++++--- pages/search/index.tsx | 18 +++++++++++---- src/components/DRB/DRBContainer.tsx | 36 ++++++++--------------------- src/config/constants.ts | 1 + src/types/drbTypes.ts | 2 +- src/types/searchTypes.ts | 2 ++ 7 files changed, 42 insertions(+), 36 deletions(-) diff --git a/pages/api/drb.ts b/pages/api/drb.ts index c93ff05e8..ef2092eb3 100644 --- a/pages/api/drb.ts +++ b/pages/api/drb.ts @@ -1,7 +1,7 @@ import type { NextApiRequest, NextApiResponse } from "next" import type { SearchParams } from "../../src/types/searchTypes" -import type { DRBResultsResponse } from "../../src/types/drbTypes" +import type { DRBResults } from "../../src/types/drbTypes" import nyplApiClient from "../../src/server/nyplApiClient/index" import { DRB_API_NAME } from "../../src/config/constants" import { getDRBQueryStringFromSearchParams } from "../../src/utils/drbUtils" @@ -12,7 +12,7 @@ import { mapQueryToSearchParams } from "../../src/utils/searchUtils" */ export async function fetchDRBResults( searchParams: SearchParams -): Promise { +): Promise { const drbQueryString = getDRBQueryStringFromSearchParams(searchParams) try { diff --git a/pages/api/search.ts b/pages/api/search.ts index 7023d835f..6296aa64d 100644 --- a/pages/api/search.ts +++ b/pages/api/search.ts @@ -7,6 +7,7 @@ import type { import { DISCOVERY_API_NAME, DISCOVERY_API_SEARCH_ROUTE, + DRB_API_NAME, RESULTS_PER_PAGE, } from "../../src/config/constants" import nyplApiClient from "../../src/server/nyplApiClient/index" @@ -15,6 +16,7 @@ import { mapQueryToSearchParams, } from "../../src/utils/searchUtils" import { standardizeBibId } from "../../src/utils/bibUtils" +import { getDRBQueryStringFromSearchParams } from "../../src/utils/drbUtils" export async function fetchResults( searchParams: SearchParams @@ -36,29 +38,36 @@ export async function fetchResults( } : {} - const queryString = getQueryString({ + const modifiedSearchParams = { ...searchParams, ...journalParams, q: keywordsOrBibId, - }) + } + + const queryString = getQueryString(modifiedSearchParams) const aggregationQuery = `/aggregations?${queryString}` const resultsQuery = `?${queryString}&per_page=${RESULTS_PER_PAGE.toString()}` + const drbQuery = getDRBQueryStringFromSearchParams(modifiedSearchParams) // Get the following in parallel: // - search results // - aggregations + // - drb results const client = await nyplApiClient({ apiName: DISCOVERY_API_NAME }) + const drbClient = await nyplApiClient({ apiName: DRB_API_NAME }) - const [results, aggregations] = await Promise.all([ + const [results, aggregations, drbResults] = await Promise.all([ await client.get(`${DISCOVERY_API_SEARCH_ROUTE}${resultsQuery}`), await client.get(`${DISCOVERY_API_SEARCH_ROUTE}${aggregationQuery}`), + await drbClient.get(drbQuery), ]) try { return { results, aggregations, + drbResults, page: searchParams.page, } } catch (error) { diff --git a/pages/search/index.tsx b/pages/search/index.tsx index fd3516ae2..245274fb7 100644 --- a/pages/search/index.tsx +++ b/pages/search/index.tsx @@ -13,6 +13,7 @@ import Layout from "../../src/components/Layout/Layout" import DRBContainer from "../../src/components/DRB/DRBContainer" import { fetchResults } from "../api/search" import { mapQueryToSearchParams } from "../../src/utils/searchUtils" +import { mapWorksToDRBResults } from "../../src/utils/drbUtils" import type { SearchResultsElement } from "../../src/types/searchTypes" import { SITE_NAME } from "../../src/config/constants" import SearchResultsBib from "../../src/models/SearchResultsBib" @@ -24,12 +25,12 @@ import SearchResultsBib from "../../src/models/SearchResultsBib" export default function Search({ results }) { const { query } = useRouter() const { itemListElement, totalResults } = results.results + const drbResponse = results.drbResults?.data + const drbWorks = drbResponse?.works const searchParams = mapQueryToSearchParams(query) - // Remove page and identifiers fields from drbParams to prevent re-fetches - const drbParams = { ...searchParams, page: undefined, identifiers: undefined } - + // Map Search Results from response to SearchResultBib objects const searchResultBibs = itemListElement .filter((result: SearchResultsElement) => { return !(isEmpty(result) || (result.result && isEmpty(result.result))) @@ -38,6 +39,9 @@ export default function Search({ results }) { return new SearchResultsBib(result.result) }) + // Map DRB Works from response to DRBResult objects + const drbResults = mapWorksToDRBResults(drbWorks) + return ( <> @@ -45,7 +49,13 @@ export default function Search({ results }) { } + sidebar={ + + } > {totalResults ? ( <> diff --git a/src/components/DRB/DRBContainer.tsx b/src/components/DRB/DRBContainer.tsx index 5da02e117..c9eba7e6d 100644 --- a/src/components/DRB/DRBContainer.tsx +++ b/src/components/DRB/DRBContainer.tsx @@ -6,42 +6,27 @@ import { SimpleGrid, Link as DSLink, } from "@nypl/design-system-react-components" -import useSWRImmutable from "swr/immutable" import { appConfig } from "../../config/config" import RCLink from "../RCLink/RCLink" import DRBCard from "./DRBCard" -import { BASE_URL } from "../../config/constants" -import type { SearchParams } from "../../types/searchTypes" import type DRBResult from "../../models/DRBResult" -import { getQueryString } from "../../utils/searchUtils" -import { - getDRBQueryStringFromSearchParams, - mapWorksToDRBResults, -} from "../../utils/drbUtils" +import type { SearchParams } from "../../types/searchTypes" +import { getDRBQueryStringFromSearchParams } from "../../utils/drbUtils" interface DRBProps { + drbResults: DRBResult[] + totalWorks: number searchParams: SearchParams } /** * The DRBContainer fetches and displays DRBContainer search results */ -const DRBContainer = ({ searchParams }: DRBProps) => { - const searchQuery = getQueryString(searchParams) - const drbUrl = `${BASE_URL}/api/drb?${searchQuery}` +const DRBContainer = ({ drbResults, totalWorks, searchParams }: DRBProps) => { const drbQuery = getDRBQueryStringFromSearchParams(searchParams) - const fetcher = (url: string) => fetch(url).then((res) => res.json()) - const { data, error, isValidating } = useSWRImmutable(drbUrl, fetcher) - - const drbResults = mapWorksToDRBResults(data?.works) - - return isValidating ? ( - - Loading - - ) : ( + return ( Results from Digital Research Books Beta @@ -55,14 +40,14 @@ const DRBContainer = ({ searchParams }: DRBProps) => { . - {!error && drbResults?.length ? ( + {drbResults?.length ? ( <> {drbResults.map((result: DRBResult) => ( ))} - {data.totalWorks && ( + {totalWorks && ( { target="_blank" > - See {data.totalWorks.toLocaleString()} result - {data.totalWorks === 1 ? "" : "s"} from Digital Research Books - Beta + See {totalWorks.toLocaleString()} result + {totalWorks === 1 ? "" : "s"} from Digital Research Books Beta )} diff --git a/src/config/constants.ts b/src/config/constants.ts index a35c75de4..5ba827bf6 100644 --- a/src/config/constants.ts +++ b/src/config/constants.ts @@ -9,6 +9,7 @@ export const DRB_API_NAME = "drb" // API Routes export const DISCOVERY_API_SEARCH_ROUTE = "/discovery/resources" +export const DRB_API_SEARCH_ROUTE = "/api/drb" // Query params export const sourceParam = "?source=catalog" diff --git a/src/types/drbTypes.ts b/src/types/drbTypes.ts index b78d2883a..cefd5c2e9 100644 --- a/src/types/drbTypes.ts +++ b/src/types/drbTypes.ts @@ -9,7 +9,7 @@ export interface DRBQueryParams { export type DRBFilters = string[] -export interface DRBResultsResponse { +export interface DRBResults { works?: DRBWork[] totalWorks?: number } diff --git a/src/types/searchTypes.ts b/src/types/searchTypes.ts index ba0b54c90..a3a2cd7bb 100644 --- a/src/types/searchTypes.ts +++ b/src/types/searchTypes.ts @@ -1,4 +1,5 @@ import type { ElectronicResource } from "./bibTypes" +import type { DRBResults } from "./drbTypes" type Language = string type SubjectLiteral = string @@ -70,6 +71,7 @@ export interface SearchFormEvent { export interface SearchResultsResponse { results?: SearchResults aggregations?: SearchResults + drbResults?: DRBResults page: number } From 3be8a61797b7bc3e9acee2a38920ce90ed0a808b Mon Sep 17 00:00:00 2001 From: Diego Cohen Date: Mon, 2 Oct 2023 13:53:45 -0400 Subject: [PATCH 26/57] Add comment about search results context --- src/components/DRB/DRBContainer.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/src/components/DRB/DRBContainer.tsx b/src/components/DRB/DRBContainer.tsx index c9eba7e6d..0f20be1fa 100644 --- a/src/components/DRB/DRBContainer.tsx +++ b/src/components/DRB/DRBContainer.tsx @@ -17,6 +17,7 @@ import { getDRBQueryStringFromSearchParams } from "../../utils/drbUtils" interface DRBProps { drbResults: DRBResult[] totalWorks: number + // TODO: Get these from context when SearchParamsContext is added searchParams: SearchParams } From 1895bcf89a3bcef8476a1ace9883c20c2bd49a37 Mon Sep 17 00:00:00 2001 From: Diego Cohen Date: Mon, 2 Oct 2023 14:01:01 -0400 Subject: [PATCH 27/57] Clean imports --- pages/search/index.tsx | 36 ++++++++++++++++++------------------ src/utils/searchUtils.ts | 30 ++++++++++++++++++++---------- 2 files changed, 38 insertions(+), 28 deletions(-) diff --git a/pages/search/index.tsx b/pages/search/index.tsx index 245274fb7..52905b686 100644 --- a/pages/search/index.tsx +++ b/pages/search/index.tsx @@ -6,17 +6,18 @@ import { SimpleGrid, } from "@nypl/design-system-react-components" import { useRouter } from "next/router" -import { isEmpty } from "underscore" import RCLink from "../../src/components/RCLink/RCLink" import Layout from "../../src/components/Layout/Layout" import DRBContainer from "../../src/components/DRB/DRBContainer" import { fetchResults } from "../api/search" -import { mapQueryToSearchParams } from "../../src/utils/searchUtils" +import { + mapQueryToSearchParams, + mapElementsToSearchResultsBibs, +} from "../../src/utils/searchUtils" import { mapWorksToDRBResults } from "../../src/utils/drbUtils" -import type { SearchResultsElement } from "../../src/types/searchTypes" import { SITE_NAME } from "../../src/config/constants" -import SearchResultsBib from "../../src/models/SearchResultsBib" +import type SearchResultsBib from "../../src/models/SearchResultsBib" /** * The Search page is responsible for fetching and displaying the Search results, @@ -24,20 +25,17 @@ import SearchResultsBib from "../../src/models/SearchResultsBib" */ export default function Search({ results }) { const { query } = useRouter() - const { itemListElement, totalResults } = results.results + const { itemListElement: searchResultsElements, totalResults } = + results.results + const drbResponse = results.drbResults?.data const drbWorks = drbResponse?.works + // TODO: Move this to global context const searchParams = mapQueryToSearchParams(query) - // Map Search Results from response to SearchResultBib objects - const searchResultBibs = itemListElement - .filter((result: SearchResultsElement) => { - return !(isEmpty(result) || (result.result && isEmpty(result.result))) - }) - .map((result: SearchResultsElement) => { - return new SearchResultsBib(result.result) - }) + // Map Search Results Elements from response to SearchResultBib objects + const searchResultBibs = mapElementsToSearchResultsBibs(searchResultsElements) // Map DRB Works from response to DRBResult objects const drbResults = mapWorksToDRBResults(drbWorks) @@ -50,11 +48,13 @@ export default function Search({ results }) { + drbResponse && ( + + ) } > {totalResults ? ( diff --git a/src/utils/searchUtils.ts b/src/utils/searchUtils.ts index 51b7d8122..658520a04 100644 --- a/src/utils/searchUtils.ts +++ b/src/utils/searchUtils.ts @@ -1,16 +1,13 @@ -import { - isArray as _isArray, - isEmpty as _isEmpty, - mapObject as _mapObject, - forEach as _forEach, -} from "underscore" +import { isArray, isEmpty, mapObject, forEach } from "underscore" import type { SearchParams, SearchQueryParams, SearchFilters, Identifiers, + SearchResultsElement, } from "../types/searchTypes" +import SearchResultsBib from "../models/SearchResultsBib" /** * getSortQuery @@ -55,11 +52,11 @@ function getIdentifierQuery(identifiers: Identifiers): string { function getFilterQuery(filters: SearchFilters) { let filterQuery = "" - if (!_isEmpty(filters)) { - _mapObject(filters, (val, key) => { + if (!isEmpty(filters)) { + mapObject(filters, (val, key) => { // Property contains an array of its selected filter values: - if (val?.length && _isArray(val)) { - _forEach(val, (filter, index) => { + if (val?.length && isArray(val)) { + forEach(val, (filter, index) => { if (filter.value && filter.value !== "") { filterQuery += `&filters[${key}][${index}]=${encodeURIComponent( filter.value @@ -155,3 +152,16 @@ export function mapQueryToSearchParams({ }, } } + +export function mapElementsToSearchResultsBibs( + elements: SearchResultsElement[] +): SearchResultsBib[] | null { + if (!elements) return null + return elements + .filter((result) => { + return !(isEmpty(result) || (result.result && isEmpty(result.result))) + }) + .map((result) => { + return new SearchResultsBib(result.result) + }) +} From a4c5dd9d6c11edb6a7843b38fb56d442d7df1836 Mon Sep 17 00:00:00 2001 From: Diego Cohen Date: Mon, 2 Oct 2023 14:02:44 -0400 Subject: [PATCH 28/57] Add comment above mapElementsToSearchResultsBibs --- src/utils/searchUtils.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/utils/searchUtils.ts b/src/utils/searchUtils.ts index 658520a04..58caa317c 100644 --- a/src/utils/searchUtils.ts +++ b/src/utils/searchUtils.ts @@ -153,6 +153,10 @@ export function mapQueryToSearchParams({ } } +/** + * mapElementsToSearchResultsBibs + * Maps the SearchResultsElement structure from the search results response to an array of SearchResultsBib objects + */ export function mapElementsToSearchResultsBibs( elements: SearchResultsElement[] ): SearchResultsBib[] | null { From 8eb84217648340feeb23ec8e25225b4526f5426e Mon Sep 17 00:00:00 2001 From: Diego Cohen Date: Mon, 2 Oct 2023 14:03:30 -0400 Subject: [PATCH 29/57] Remove null check from mapElementsToSearchResultsBibs --- src/utils/searchUtils.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/src/utils/searchUtils.ts b/src/utils/searchUtils.ts index 58caa317c..80a795c21 100644 --- a/src/utils/searchUtils.ts +++ b/src/utils/searchUtils.ts @@ -160,7 +160,6 @@ export function mapQueryToSearchParams({ export function mapElementsToSearchResultsBibs( elements: SearchResultsElement[] ): SearchResultsBib[] | null { - if (!elements) return null return elements .filter((result) => { return !(isEmpty(result) || (result.result && isEmpty(result.result))) From 5df34e5f87e366bbf562adbd3c0d59097420033b Mon Sep 17 00:00:00 2001 From: Diego Cohen Date: Mon, 2 Oct 2023 14:05:39 -0400 Subject: [PATCH 30/57] Only render DRB container when totalWorks is positive --- pages/search/index.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pages/search/index.tsx b/pages/search/index.tsx index 52905b686..dafcfa020 100644 --- a/pages/search/index.tsx +++ b/pages/search/index.tsx @@ -48,7 +48,7 @@ export default function Search({ results }) { Date: Mon, 2 Oct 2023 14:07:08 -0400 Subject: [PATCH 31/57] Remove length check in DRB container --- src/components/DRB/DRBContainer.tsx | 40 ++++++++++++----------------- 1 file changed, 17 insertions(+), 23 deletions(-) diff --git a/src/components/DRB/DRBContainer.tsx b/src/components/DRB/DRBContainer.tsx index 0f20be1fa..6a5631e32 100644 --- a/src/components/DRB/DRBContainer.tsx +++ b/src/components/DRB/DRBContainer.tsx @@ -41,29 +41,23 @@ const DRBContainer = ({ drbResults, totalWorks, searchParams }: DRBProps) => { . - {drbResults?.length ? ( - <> - - {drbResults.map((result: DRBResult) => ( - - ))} - - {totalWorks && ( - - - See {totalWorks.toLocaleString()} result - {totalWorks === 1 ? "" : "s"} from Digital Research Books Beta - - - )} - - ) : ( -
There was an error getting DRB results. Please try again.
+ + {drbResults.map((result: DRBResult) => ( + + ))} + + {totalWorks && ( + + + See {totalWorks.toLocaleString()} result + {totalWorks === 1 ? "" : "s"} from Digital Research Books Beta + + )}
From 7863079d1e2be0bc49a8e1477cc66dfac3b78b45 Mon Sep 17 00:00:00 2001 From: Diego Cohen Date: Mon, 2 Oct 2023 16:40:32 -0400 Subject: [PATCH 32/57] Fix DRB naming in drbUtil comments --- src/utils/drbUtils.ts | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/utils/drbUtils.ts b/src/utils/drbUtils.ts index 4930c6097..8ee41061f 100644 --- a/src/utils/drbUtils.ts +++ b/src/utils/drbUtils.ts @@ -21,14 +21,14 @@ const mapSearchFieldToDRBField = { } /** - * Given a keyword and a search field, format and return a keyword query string expected by the DRBContainer API + * Given a keyword and a search field, format and return a keyword query string expected by the DRB API */ function getDRBKeywordQuery(keywords = "*", field = "keyword"): string { return `${field}:${keywords}` } /** - * Given a hash of SearchQueryParams, format and return an advanced field query string expected by the DRBContainer API + * Given a hash of SearchQueryParams, format and return an advanced field query string expected by the DRB API */ function getDRBAdvancedQuery(params: SearchParams): string { return ["contributor", "title", "subject"] @@ -43,7 +43,7 @@ function getDRBAdvancedQuery(params: SearchParams): string { } /** - * Given a hash of SearchFilters, returns an array of DRBFilters as expected by the DRBContainer API + * Given a hash of SearchFilters, returns an array of DRBFilters as expected by the DRB API */ function mapSearchFiltersToDRBFilters(filters: SearchFilters = {}): DRBFilters { let drbFilters: DRBFilters = [] @@ -63,7 +63,7 @@ function mapSearchFiltersToDRBFilters(filters: SearchFilters = {}): DRBFilters { } /** - * Given a hash of SearchParams, returns a hash representing an equivalent query against DRBContainer API + * Given a hash of SearchParams, returns a hash representing an equivalent query against DRB API */ function mapSearchParamsToDRBQueryParams(params: SearchParams): DRBQueryParams { const { q, field, sortBy, order, selectedFilters } = params @@ -94,7 +94,7 @@ function mapSearchParamsToDRBQueryParams(params: SearchParams): DRBQueryParams { dateBefore, } = selectedFilters || {} - // DRBContainer doesn't handle subject or contributor in `filter` param, so handle + // DRB doesn't handle subject or contributor in `filter` param, so handle // them separately: if (subjectLiteral) { drbQuery.query = drbQuery.query.concat( @@ -150,7 +150,7 @@ export function getQueryStringFromDRBQueryParams( } /** - * Given a SearchParams hash, return a DRBContainer query string. + * Given a SearchParams hash, return a DRB query string. */ export function getDRBQueryStringFromSearchParams( searchParams: SearchParams From 2ab25e3642e2cace2d56a0b7b0fb908a3d011a09 Mon Sep 17 00:00:00 2001 From: Diego Cohen Date: Tue, 3 Oct 2023 13:24:11 -0400 Subject: [PATCH 33/57] Refactor drbResult class --- src/components/DRB/DRBContainer.tsx | 8 ++--- src/config/constants.ts | 8 ++++- src/models/DRBResult.ts | 52 +++++++++++++++++------------ src/utils/drbUtils.ts | 4 +-- 4 files changed, 41 insertions(+), 31 deletions(-) diff --git a/src/components/DRB/DRBContainer.tsx b/src/components/DRB/DRBContainer.tsx index 6a5631e32..ae6acbc46 100644 --- a/src/components/DRB/DRBContainer.tsx +++ b/src/components/DRB/DRBContainer.tsx @@ -13,6 +13,7 @@ import DRBCard from "./DRBCard" import type DRBResult from "../../models/DRBResult" import type { SearchParams } from "../../types/searchTypes" import { getDRBQueryStringFromSearchParams } from "../../utils/drbUtils" +import { DRB_BASE_URL } from "../../config/constants" interface DRBProps { drbResults: DRBResult[] @@ -47,12 +48,7 @@ const DRBContainer = ({ drbResults, totalWorks, searchParams }: DRBProps) => { ))}
{totalWorks && ( - + See {totalWorks.toLocaleString()} result {totalWorks === 1 ? "" : "s"} from Digital Research Books Beta diff --git a/src/config/constants.ts b/src/config/constants.ts index 5ba827bf6..43a9dbe78 100644 --- a/src/config/constants.ts +++ b/src/config/constants.ts @@ -1,3 +1,5 @@ +import { appConfig } from "./config" + export const BASE_URL = "/research/research-catalog" export const SITE_NAME = "NYPL Research Catalog" export const RESULTS_PER_PAGE = 50 @@ -12,4 +14,8 @@ export const DISCOVERY_API_SEARCH_ROUTE = "/discovery/resources" export const DRB_API_SEARCH_ROUTE = "/api/drb" // Query params -export const sourceParam = "?source=catalog" +export const SOURCE_PARAM = "?source=catalog" + +// External URLs +export const DRB_BASE_URL = + appConfig.externalUrls.drbFrontEnd[appConfig.environment] diff --git a/src/models/DRBResult.ts b/src/models/DRBResult.ts index ee02cc8ab..040a249cd 100644 --- a/src/models/DRBResult.ts +++ b/src/models/DRBResult.ts @@ -5,10 +5,8 @@ import type { Agent, EditionLink, } from "../types/drbTypes" -import { sourceParam } from "../config/constants" +import { SOURCE_PARAM, DRB_BASE_URL } from "../config/constants" import { readOnlineMediaTypes, downloadMediaTypes } from "../utils/drbUtils" -import { appConfig } from "../config/config" - /** * The DRBResult class contains the data and getter functions * for a single DRB search result entity. @@ -30,9 +28,7 @@ export default class DRBResult { } get url(): string { - return `${appConfig.externalUrls.drbFrontEnd[appConfig.environment]}/work/${ - this.id - }${sourceParam}` + return `${DRB_BASE_URL}/work/${this.id}${SOURCE_PARAM}` } get selectedEdition(): Edition { @@ -43,48 +39,60 @@ export default class DRBResult { ) } - // TODO: Check to see if selectedItem is necessary get readOnlineUrl(): string | null { - const { items } = this.selectedEdition - if (!items) return null + if (!this.selectedEdition.items) return null + + // Populate selected link with first item on the selected edition that includes + // a link with a media type included in the readOnlineMediaTypes array. let selectedLink: EditionLink - const selectedItem = items.find((item) => + this.selectedEdition.items.find((item) => item.links.find((link) => { selectedLink = link return readOnlineMediaTypes.indexOf(link.mediaType) > -1 }) ) - return !selectedItem || !selectedLink || !selectedLink.link_id + // Return null if no selected link is found. Otherwise, return the URL + return !selectedLink?.link_id ? null - : `${appConfig.externalUrls.drbFrontEnd[appConfig.environment]}/read/${ - selectedLink.link_id - }` + : `${DRB_BASE_URL}/read/${selectedLink.link_id}` } get downloadLink(): EditionLink | null { - const { items } = this.selectedEdition - if (!items) return null + if (!this.selectedEdition.items) return null + // Populate download link with first item on the selected edition that includes + // a link with a media type included in the downloadMediaTypes array. let downloadLink: EditionLink - items.find((item) => + this.selectedEdition.items.find((item) => item.links.find((link) => { downloadLink = link return downloadMediaTypes.indexOf(link.mediaType) > -1 }) ) + const formattedDownloadLink = this.formatDownloadLink(downloadLink) + + return !formattedDownloadLink?.download || !formattedDownloadLink?.url + ? null + : formattedDownloadLink + } + + // Formats the download link media type and url for rendering + formatDownloadLink(downloadLink: EditionLink) { + const formattedDownloadLink: EditionLink = downloadLink + // Format media type to show label in all uppercase (e.g. EPUB) - downloadLink.mediaType = downloadLink.mediaType + formattedDownloadLink.mediaType = downloadLink.mediaType .replace(/(application|text)\/|\+zip/gi, "") .toUpperCase() // Add https if not present in download link and add source="catalog" query param - downloadLink.url = downloadLink.url.startsWith("http") - ? `${downloadLink.url}${sourceParam}` - : `https://${downloadLink.url}/${sourceParam}` + formattedDownloadLink.url = downloadLink.url.startsWith("http") + ? `${downloadLink.url}${SOURCE_PARAM}` + : `https://${downloadLink.url}/${SOURCE_PARAM}` - return !downloadLink?.download || !downloadLink?.url ? null : downloadLink + return formattedDownloadLink } getAuthorsFromWork(work: DRBWork): Author[] | Agent[] { diff --git a/src/utils/drbUtils.ts b/src/utils/drbUtils.ts index 8ee41061f..38c3d6655 100644 --- a/src/utils/drbUtils.ts +++ b/src/utils/drbUtils.ts @@ -7,7 +7,7 @@ import type { Agent, } from "../types/drbTypes" import DRBResult from "../models/DRBResult" -import { DRB_RESULTS_PER_PAGE } from "../config/constants" +import { DRB_RESULTS_PER_PAGE, SOURCE_PARAM } from "../config/constants" import { isEmpty } from "underscore" import { appConfig } from "../config/config" @@ -180,5 +180,5 @@ export const downloadMediaTypes = ["application/epub+zip", "application/pdf"] export function getAuthorURL(author: Author | Agent) { return `${ appConfig.externalUrls.drbFrontEnd[appConfig.environment] - }/search?query=${`author:${author.name}&source=catalog`}` + }/search?query=${`author:${author.name}${SOURCE_PARAM}`}` } From 7f4b3ac1ee1877e4ec81d52817d92a0845e2bc09 Mon Sep 17 00:00:00 2001 From: Diego Cohen Date: Tue, 3 Oct 2023 13:34:43 -0400 Subject: [PATCH 34/57] Rename selectedFilters to filters in advanced search --- pages/search/advanced.tsx | 8 ++++---- src/config/constants.ts | 9 +++++++++ src/utils/searchUtils.ts | 2 +- 3 files changed, 14 insertions(+), 5 deletions(-) diff --git a/pages/search/advanced.tsx b/pages/search/advanced.tsx index b78ba4c38..a5a412974 100644 --- a/pages/search/advanced.tsx +++ b/pages/search/advanced.tsx @@ -160,7 +160,7 @@ export default function AdvancedSearch() { name="language" labelText="Language" aria-labelledby="languageSelect-label" - value={searchFormState["selectedFilters"].language} + value={searchFormState["filters"].language} onChange={(e) => handleInputChange(e, "filter_change")} > {languageOptions.map((language) => { @@ -183,8 +183,8 @@ export default function AdvancedSearch() { labelText="Dates" nameFrom="dateAfter" nameTo="dateBefore" - initialDate={searchFormState["selectedFilters"].dateAfter} - initialDateTo={searchFormState["selectedFilters"].dateBefore} + initialDate={searchFormState["filters"].dateAfter} + initialDateTo={searchFormState["filters"].dateBefore} onChange={debounce( (e) => handleDateChange(e), debounceInterval @@ -195,7 +195,7 @@ export default function AdvancedSearch() { name="formats" labelText="Formats" onChange={handleCheckboxChange} - value={searchFormState["selectedFilters"].materialType} + value={searchFormState["filters"].materialType} sx={{ "> div": { display: "grid", diff --git a/src/config/constants.ts b/src/config/constants.ts index 43a9dbe78..c7cd08cbe 100644 --- a/src/config/constants.ts +++ b/src/config/constants.ts @@ -5,6 +5,15 @@ export const SITE_NAME = "NYPL Research Catalog" export const RESULTS_PER_PAGE = 50 export const DRB_RESULTS_PER_PAGE = 3 +// Internal path names +export const PATHS = { + HOME: "/", + SEARCH: "/search", + ADVANCED_SEARCH: "/search/advanced", + "404": "/404", + "404_REDIRECT": "/404/redirect", +} + // API Names export const DISCOVERY_API_NAME = "discovery" export const DRB_API_NAME = "drb" diff --git a/src/utils/searchUtils.ts b/src/utils/searchUtils.ts index 4eb29b5db..3fd2efc27 100644 --- a/src/utils/searchUtils.ts +++ b/src/utils/searchUtils.ts @@ -197,4 +197,4 @@ export function mapElementsToSearchResultsBibs( .map((result) => { return new SearchResultsBib(result.result) }) -} \ No newline at end of file +} From 07e4fcf04a1336405f3827ffad33a8784c5a4f9f Mon Sep 17 00:00:00 2001 From: Diego Cohen Date: Tue, 3 Oct 2023 13:35:38 -0400 Subject: [PATCH 35/57] Remove duplicated form --- pages/search/advanced.tsx | 121 -------------------------------------- 1 file changed, 121 deletions(-) diff --git a/pages/search/advanced.tsx b/pages/search/advanced.tsx index a5a412974..92a7903fa 100644 --- a/pages/search/advanced.tsx +++ b/pages/search/advanced.tsx @@ -245,127 +245,6 @@ export default function AdvancedSearch() { - {alert && ( - Please enter at least one field to submit an advanced search. - } - /> - )} - Advanced Search -
- - - {textInputFields.map(({ name, label }) => { - return ( - handleInputChange(e, "input_change"), - debounceInterval - )} - ref={inputRef} - /> - ) - })} - - - - handleDateChange(e), debounceInterval)} - /> - div": { - display: "grid", - "grid-template-columns": "repeat(2, minmax(0, 1fr))", - "grid-gap": "var(--nypl-space-s)", - div: { - marginTop: "0 !important", - }, - }, - }} - > - {materialTypeOptions.map((materialType) => { - return ( - - ) - })} - - - - - - - - - ) } From 0baabf7173af98eb6623194834a425f17eb27a8e Mon Sep 17 00:00:00 2001 From: Diego Cohen Date: Tue, 3 Oct 2023 13:37:49 -0400 Subject: [PATCH 36/57] Add bottom margin to read online only when download link present --- src/components/DRB/DRBCard.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/DRB/DRBCard.tsx b/src/components/DRB/DRBCard.tsx index 16850a45a..c16ba1e22 100644 --- a/src/components/DRB/DRBCard.tsx +++ b/src/components/DRB/DRBCard.tsx @@ -50,7 +50,7 @@ const DRBCard = ({ drbResult }: DRBCardProps) => { href={drbResult.readOnlineUrl} target="_blank" type="buttonPrimary" - mb="s" + mb={drbResult?.downloadLink ? "s" : ""} > Read Online
From aa66b1405130bd083c60f995b5abfe7fd2ebbae8 Mon Sep 17 00:00:00 2001 From: Diego Cohen Date: Tue, 3 Oct 2023 13:51:38 -0400 Subject: [PATCH 37/57] Remove duplicated homepage content --- pages/index.tsx | 130 ------------------------------------------------ 1 file changed, 130 deletions(-) diff --git a/pages/index.tsx b/pages/index.tsx index 2239a7785..b6689f0cd 100644 --- a/pages/index.tsx +++ b/pages/index.tsx @@ -162,136 +162,6 @@ export default function Home() { - - Explore the Library's Vast Research Collections & More - -
-

- Discover millions of items from The New York Public Library's - Stephen A. Schwarzman Building, Schomburg Center for Research in Black - Culture, and The New York Public Library for the Performing Arts. - Plus, access materials from library collections at Columbia - University, Harvard University, and Princeton University.{" "} - - Learn more. - -

-

- Please note that the Research Catalog does not include circulating - materials. For books and more that you can check out to take home - please visit our{" "} - - circulating branch catalog. - {" "} - The{" "} - - legacy research catalog - {" "} - is still available, but does not include all of our Scan & Deliver - options or the Columbia University, Harvard University, and Princeton - University material from the Shared Collection. -

-
- - - Research at NYPL - - - - Collections - - -

- Discover our world-renowned research collections, featuring more - than 46 million items. -

-
-
- - - Locations - - -

- Access items, one-on-one reference help, and dedicated research - study rooms. -

-
-
- - - Divisions - - -

- Learn about the subject and media specializations of our research - divisions. -

-
-
- - - Support - - -

- Plan your in-person research visit and discover resources for - scholars and writers. -

-
-
- - - Services - - -

- Explore services for online and remote researchers, as well as our - interlibrary services. -

-
-
-
) } From ff08d0e81ae68aa8bc04cec5d9fe81dad84e5a0c Mon Sep 17 00:00:00 2001 From: Diego Cohen Date: Tue, 3 Oct 2023 13:52:41 -0400 Subject: [PATCH 38/57] Remove duplicated homepage content --- pages/index.tsx | 26 ++++++++------------------ 1 file changed, 8 insertions(+), 18 deletions(-) diff --git a/pages/index.tsx b/pages/index.tsx index b6689f0cd..61ed0aec7 100644 --- a/pages/index.tsx +++ b/pages/index.tsx @@ -30,15 +30,15 @@ export default function Home() { Black Culture, and The New York Public Library for the Performing Arts. Plus, access materials from library collections at Columbia University, Harvard University, and Princeton University.{" "} - + Learn more. - +

Please note that the Research Catalog does not include circulating materials. For books and more that you can check out to take home please visit our{" "} - + circulating branch catalog. {" "} The{" "} @@ -64,9 +64,7 @@ export default function Home() { layout="row" > - - Collections - + Collections

@@ -85,9 +83,7 @@ export default function Home() { layout="row" > - - Locations - + Locations

@@ -106,9 +102,7 @@ export default function Home() { layout="row" > - - Divisions - + Divisions

@@ -127,9 +121,7 @@ export default function Home() { layout="row" > - - Support - + Support

@@ -148,9 +140,7 @@ export default function Home() { layout="row" > - - Services - + Services

From 634b5a48268c8ff9107cecc4fdaf9504c98c4c5d Mon Sep 17 00:00:00 2001 From: Diego Cohen Date: Tue, 10 Oct 2023 12:55:38 -0400 Subject: [PATCH 39/57] Extend PropsWithChildren in Layout component --- pages/404/index.tsx | 22 +- pages/404/redirect.tsx | 36 ++- pages/index.tsx | 260 +++++++++--------- pages/search/advanced.tsx | 242 ++++++++-------- src/components/Layout/Layout.tsx | 9 +- .../Layout/__tests__/Layout.test.tsx | 6 +- 6 files changed, 281 insertions(+), 294 deletions(-) diff --git a/pages/404/index.tsx b/pages/404/index.tsx index 32d23ffd9..84f22a027 100644 --- a/pages/404/index.tsx +++ b/pages/404/index.tsx @@ -12,18 +12,16 @@ export default function Custom404() { 404 Not Found - <> - 404 Not Found -

We're sorry...

-

The page you were looking for doesn't exist.

-

- Search the Research Catalog or our{" "} - - Legacy Catalog - {" "} - for research materials. -

- + 404 Not Found +

We're sorry...

+

The page you were looking for doesn't exist.

+

+ Search the Research Catalog or our{" "} + + Legacy Catalog + {" "} + for research materials. +

) diff --git a/pages/404/redirect.tsx b/pages/404/redirect.tsx index 5cf7d0048..4fe3a9ca1 100644 --- a/pages/404/redirect.tsx +++ b/pages/404/redirect.tsx @@ -12,26 +12,22 @@ export default function Redirect404() { 404 Not Found - <> - We're sorry... -

- You've followed an out-of-date link to our research catalog. -

-

- You may be able to find what you're looking for in the{" "} - Research Catalog or the{" "} - - Circulating Catalog - - . for research materials. -

-

- You can also try the{" "} - - Legacy Catalog - -

- + We're sorry... +

You've followed an out-of-date link to our research catalog.

+

+ You may be able to find what you're looking for in the{" "} + Research Catalog or the{" "} + + Circulating Catalog + + . for research materials. +

+

+ You can also try the{" "} + + Legacy Catalog + +

) diff --git a/pages/index.tsx b/pages/index.tsx index 61ed0aec7..68d3d018c 100644 --- a/pages/index.tsx +++ b/pages/index.tsx @@ -19,138 +19,136 @@ export default function Home() { {SITE_NAME} - <> - - Explore the Library's Vast Research Collections & More + + Explore the Library's Vast Research Collections & More + +
+

+ Discover millions of items from The New York Public Library's + Stephen A. Schwarzman Building, Schomburg Center for Research in + Black Culture, and The New York Public Library for the Performing + Arts. Plus, access materials from library collections at Columbia + University, Harvard University, and Princeton University.{" "} + + Learn more. + +

+

+ Please note that the Research Catalog does not include circulating + materials. For books and more that you can check out to take home + please visit our{" "} + + circulating branch catalog. + {" "} + The{" "} + + legacy research catalog + {" "} + is still available, but does not include all of our Scan & Deliver + options or the Columbia University, Harvard University, and + Princeton University material from the Shared Collection. +

+
+ + + Research at NYPL -
-

- Discover millions of items from The New York Public Library's - Stephen A. Schwarzman Building, Schomburg Center for Research in - Black Culture, and The New York Public Library for the Performing - Arts. Plus, access materials from library collections at Columbia - University, Harvard University, and Princeton University.{" "} - - Learn more. - -

-

- Please note that the Research Catalog does not include circulating - materials. For books and more that you can check out to take home - please visit our{" "} - - circulating branch catalog. - {" "} - The{" "} - - legacy research catalog - {" "} - is still available, but does not include all of our Scan & Deliver - options or the Columbia University, Harvard University, and - Princeton University material from the Shared Collection. -

-
- - - Research at NYPL - - - - Collections - - -

- Discover our world-renowned research collections, featuring - more than 46 million items. -

-
-
- - - Locations - - -

- Access items, one-on-one reference help, and dedicated - research study rooms. -

-
-
- - - Divisions - - -

- Learn about the subject and media specializations of our - research divisions. -

-
-
- - - Support - - -

- Plan your in-person research visit and discover resources for - scholars and writers. -

-
-
- - - Services - - -

- Explore services for online and remote researchers, as well as - our interlibrary services. -

-
-
-
- + + + Collections + + +

+ Discover our world-renowned research collections, featuring more + than 46 million items. +

+
+
+ + + Locations + + +

+ Access items, one-on-one reference help, and dedicated research + study rooms. +

+
+
+ + + Divisions + + +

+ Learn about the subject and media specializations of our + research divisions. +

+
+
+ + + Support + + +

+ Plan your in-person research visit and discover resources for + scholars and writers. +

+
+
+ + + Services + + +

+ Explore services for online and remote researchers, as well as + our interlibrary services. +

+
+
+
) diff --git a/pages/search/advanced.tsx b/pages/search/advanced.tsx index 92a7903fa..db323c218 100644 --- a/pages/search/advanced.tsx +++ b/pages/search/advanced.tsx @@ -116,134 +116,130 @@ export default function AdvancedSearch() { Advanced Search | {SITE_NAME} - <> - {alert && ( - - Please enter at least one field to submit an advanced search. - - } - /> - )} - Advanced Search -
- - - {textInputFields.map(({ name, label }) => { + {alert && ( + Please enter at least one field to submit an advanced search. + } + /> + )} + Advanced Search + + + + {textInputFields.map(({ name, label }) => { + return ( + handleInputChange(e, "input_change"), + debounceInterval + )} + ref={inputRef} + /> + ) + })} + handleInputChange(e, "filter_change")} - > - {languageOptions.map((language) => { - return ( - - ) - })} - - - - handleDateChange(e), - debounceInterval - )} - /> - div": { - display: "grid", - "grid-template-columns": "repeat(2, minmax(0, 1fr))", - "grid-gap": "var(--nypl-space-s)", - div: { - marginTop: "0 !important", - }, + + + + handleDateChange(e), + debounceInterval + )} + /> + div": { + display: "grid", + "grid-template-columns": "repeat(2, minmax(0, 1fr))", + "grid-gap": "var(--nypl-space-s)", + div: { + marginTop: "0 !important", }, - }} - > - {materialTypeOptions.map((materialType) => { - return ( - - ) - })} - - - - - - - - - - + {materialTypeOptions.map((materialType) => { + return ( + + ) + })} + + +
+ + + + + +
) diff --git a/src/components/Layout/Layout.tsx b/src/components/Layout/Layout.tsx index dd6c98b12..ca975a5c0 100644 --- a/src/components/Layout/Layout.tsx +++ b/src/components/Layout/Layout.tsx @@ -1,4 +1,4 @@ -import { type ReactElement } from "react" +import type { ReactElement, PropsWithChildren } from "react" import { Box, TemplateAppContainer, @@ -14,7 +14,6 @@ import SearchForm from "../SearchForm/SearchForm" import { BASE_URL } from "../../config/constants" interface LayoutProps { - children: ReactElement sidebar?: ReactElement activePage?: RCPage } @@ -23,7 +22,11 @@ interface LayoutProps { * The Layout component wraps the TemplateAppContainer from the DS and * controls the rendering of Research Catalog header components per-page. */ -const Layout = ({ children, sidebar, activePage }: LayoutProps) => { +const Layout = ({ + children, + sidebar, + activePage, +}: PropsWithChildren) => { const showSearch = activePage === "search" const showHeader = activePage !== "404" diff --git a/src/components/Layout/__tests__/Layout.test.tsx b/src/components/Layout/__tests__/Layout.test.tsx index 0d95f8e6e..b69e2fa08 100644 --- a/src/components/Layout/__tests__/Layout.test.tsx +++ b/src/components/Layout/__tests__/Layout.test.tsx @@ -5,11 +5,7 @@ import Layout from "../Layout" describe("Layout", () => { it("should render an H1", () => { - render( - - <> - - ) + render() const header = screen.getByRole("heading", { level: 1 }) const headerText = "Research Catalog" From 06c0547912763b3717f63e884f4c20c14d830062 Mon Sep 17 00:00:00 2001 From: Diego Cohen Date: Tue, 10 Oct 2023 13:05:34 -0400 Subject: [PATCH 40/57] Replace download icon with design system icon --- src/client/icons/Download.tsx | 15 --------------- src/components/DRB/DRBCard.tsx | 12 +++++++----- src/models/DRBResult.ts | 15 +++++++++++---- 3 files changed, 18 insertions(+), 24 deletions(-) delete mode 100644 src/client/icons/Download.tsx diff --git a/src/client/icons/Download.tsx b/src/client/icons/Download.tsx deleted file mode 100644 index f706441fd..000000000 --- a/src/client/icons/Download.tsx +++ /dev/null @@ -1,15 +0,0 @@ -import React from "react" - -const DownloadIcon = () => ( - - - - -) - -export default DownloadIcon diff --git a/src/components/DRB/DRBCard.tsx b/src/components/DRB/DRBCard.tsx index c16ba1e22..d62a1cd71 100644 --- a/src/components/DRB/DRBCard.tsx +++ b/src/components/DRB/DRBCard.tsx @@ -2,14 +2,13 @@ import { Card, CardContent, Text, - Box, + Icon, Link as DSLink, } from "@nypl/design-system-react-components" import type DRBResult from "../../models/DRBResult" import { getAuthorURL } from "../../utils/drbUtils" import type { Author, Agent } from "../../types/drbTypes" -import DownloadIcon from "../../client/icons/Download" interface DRBCardProps { drbResult: DRBResult @@ -63,9 +62,12 @@ const DRBCard = ({ drbResult }: DRBCardProps) => { sx={{ display: "flex", alignItems: "center" }} noSpace > - - - {" "} + Download {drbResult.downloadLink.mediaType || ""}
diff --git a/src/models/DRBResult.ts b/src/models/DRBResult.ts index 040a249cd..5679a38f8 100644 --- a/src/models/DRBResult.ts +++ b/src/models/DRBResult.ts @@ -71,11 +71,18 @@ export default class DRBResult { }) ) - const formattedDownloadLink = this.formatDownloadLink(downloadLink) + return { + link_id: "string", + mediaType: "string", + url: "string", + download: "string", + } - return !formattedDownloadLink?.download || !formattedDownloadLink?.url - ? null - : formattedDownloadLink + // const formattedDownloadLink = this.formatDownloadLink(downloadLink) + // + // return !formattedDownloadLink?.download || !formattedDownloadLink?.url + // ? null + // : formattedDownloadLink } // Formats the download link media type and url for rendering From ad611d13f5a878888b03ec8d857ce969af8c4434 Mon Sep 17 00:00:00 2001 From: Diego Cohen Date: Tue, 10 Oct 2023 13:06:01 -0400 Subject: [PATCH 41/57] Replace download icon with design system icon --- src/models/DRBResult.ts | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-) diff --git a/src/models/DRBResult.ts b/src/models/DRBResult.ts index 5679a38f8..040a249cd 100644 --- a/src/models/DRBResult.ts +++ b/src/models/DRBResult.ts @@ -71,18 +71,11 @@ export default class DRBResult { }) ) - return { - link_id: "string", - mediaType: "string", - url: "string", - download: "string", - } + const formattedDownloadLink = this.formatDownloadLink(downloadLink) - // const formattedDownloadLink = this.formatDownloadLink(downloadLink) - // - // return !formattedDownloadLink?.download || !formattedDownloadLink?.url - // ? null - // : formattedDownloadLink + return !formattedDownloadLink?.download || !formattedDownloadLink?.url + ? null + : formattedDownloadLink } // Formats the download link media type and url for rendering From 1f5273d0a0c98302a44110bd44fb3b6b501b1f36 Mon Sep 17 00:00:00 2001 From: Diego Cohen Date: Wed, 11 Oct 2023 08:37:23 -0400 Subject: [PATCH 42/57] Replace promise.all with promise.allSettled --- pages/api/search.ts | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/pages/api/search.ts b/pages/api/search.ts index 9cf0acd3f..400d8ffb0 100644 --- a/pages/api/search.ts +++ b/pages/api/search.ts @@ -60,11 +60,22 @@ export async function fetchResults( const client = await nyplApiClient({ apiName: DISCOVERY_API_NAME }) const drbClient = await nyplApiClient({ apiName: DRB_API_NAME }) - const [results, aggregations, drbResults] = await Promise.all([ - await client.get(`${DISCOVERY_API_SEARCH_ROUTE}${resultsQuery}`), - await client.get(`${DISCOVERY_API_SEARCH_ROUTE}${aggregationQuery}`), - await drbClient.get(drbQuery), - ]) + const [resultsResponse, aggregationsResponse, drbResultsResponse] = + await Promise.allSettled([ + await client.get(`${DISCOVERY_API_SEARCH_ROUTE}${resultsQuery}`), + await client.get(`${DISCOVERY_API_SEARCH_ROUTE}${aggregationQuery}`), + await drbClient.get(drbQuery), + ]) + + // Assign results values for each response when status is fulfilled + const results = + resultsResponse.status === "fulfilled" && resultsResponse.value + + const aggregations = + aggregationsResponse.status === "fulfilled" && aggregationsResponse.value + + const drbResults = + drbResultsResponse.status === "fulfilled" && drbResultsResponse.value try { return { From 4c5f2986ae509a72c766b0c69367e83309c3afa6 Mon Sep 17 00:00:00 2001 From: Diego Cohen Date: Wed, 11 Oct 2023 08:38:52 -0400 Subject: [PATCH 43/57] Rename DRBProps to DRBContainerProps --- src/components/DRB/DRBContainer.tsx | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/components/DRB/DRBContainer.tsx b/src/components/DRB/DRBContainer.tsx index ae6acbc46..c69d4dd3e 100644 --- a/src/components/DRB/DRBContainer.tsx +++ b/src/components/DRB/DRBContainer.tsx @@ -15,7 +15,7 @@ import type { SearchParams } from "../../types/searchTypes" import { getDRBQueryStringFromSearchParams } from "../../utils/drbUtils" import { DRB_BASE_URL } from "../../config/constants" -interface DRBProps { +interface DRBContainerProps { drbResults: DRBResult[] totalWorks: number // TODO: Get these from context when SearchParamsContext is added @@ -25,7 +25,11 @@ interface DRBProps { /** * The DRBContainer fetches and displays DRBContainer search results */ -const DRBContainer = ({ drbResults, totalWorks, searchParams }: DRBProps) => { +const DRBContainer = ({ + drbResults, + totalWorks, + searchParams, +}: DRBContainerProps) => { const drbQuery = getDRBQueryStringFromSearchParams(searchParams) return ( From 6bc4669fa36b804c8430b211771ac761c475cfd6 Mon Sep 17 00:00:00 2001 From: Diego Cohen Date: Wed, 11 Oct 2023 08:42:27 -0400 Subject: [PATCH 44/57] Add sidebar position prop --- src/components/Layout/Layout.tsx | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/components/Layout/Layout.tsx b/src/components/Layout/Layout.tsx index ca975a5c0..d59cc86b1 100644 --- a/src/components/Layout/Layout.tsx +++ b/src/components/Layout/Layout.tsx @@ -16,6 +16,7 @@ import { BASE_URL } from "../../config/constants" interface LayoutProps { sidebar?: ReactElement activePage?: RCPage + sidebarPosition?: "right" | "left" } /** @@ -26,6 +27,7 @@ const Layout = ({ children, sidebar, activePage, + sidebarPosition = "right", }: PropsWithChildren) => { const showSearch = activePage === "search" const showHeader = activePage !== "404" @@ -55,7 +57,7 @@ const Layout = ({ ) } - sidebar={sidebar ? "right" : "none"} + sidebar={sidebar ? sidebarPosition : "none"} contentPrimary={{children}} contentSidebar={ sidebar && ( From fce63ffde97586654a6f5db7878074706d24dbfd Mon Sep 17 00:00:00 2001 From: Diego Cohen Date: Wed, 11 Oct 2023 09:02:22 -0400 Subject: [PATCH 45/57] Assign found link values from find return value --- src/models/DRBResult.ts | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/models/DRBResult.ts b/src/models/DRBResult.ts index 040a249cd..f4aae16ce 100644 --- a/src/models/DRBResult.ts +++ b/src/models/DRBResult.ts @@ -45,11 +45,11 @@ export default class DRBResult { // Populate selected link with first item on the selected edition that includes // a link with a media type included in the readOnlineMediaTypes array. let selectedLink: EditionLink - this.selectedEdition.items.find((item) => - item.links.find((link) => { - selectedLink = link - return readOnlineMediaTypes.indexOf(link.mediaType) > -1 - }) + this.selectedEdition.items.find( + (item) => + (selectedLink = item.links.find( + (link) => readOnlineMediaTypes.indexOf(link.mediaType) > -1 + )) ) // Return null if no selected link is found. Otherwise, return the URL @@ -64,11 +64,11 @@ export default class DRBResult { // Populate download link with first item on the selected edition that includes // a link with a media type included in the downloadMediaTypes array. let downloadLink: EditionLink - this.selectedEdition.items.find((item) => - item.links.find((link) => { - downloadLink = link - return downloadMediaTypes.indexOf(link.mediaType) > -1 - }) + this.selectedEdition.items.find( + (item) => + (downloadLink = item.links.find( + (link) => downloadMediaTypes.indexOf(link.mediaType) > -1 + )) ) const formattedDownloadLink = this.formatDownloadLink(downloadLink) From 78d4a8ff6b5740823b71668f62bbf4c7e83c8582 Mon Sep 17 00:00:00 2001 From: Diego Cohen Date: Wed, 11 Oct 2023 09:03:55 -0400 Subject: [PATCH 46/57] Add null check before formatting download link --- src/models/DRBResult.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/models/DRBResult.ts b/src/models/DRBResult.ts index f4aae16ce..a371d854e 100644 --- a/src/models/DRBResult.ts +++ b/src/models/DRBResult.ts @@ -71,7 +71,8 @@ export default class DRBResult { )) ) - const formattedDownloadLink = this.formatDownloadLink(downloadLink) + const formattedDownloadLink = + downloadLink && this.formatDownloadLink(downloadLink) return !formattedDownloadLink?.download || !formattedDownloadLink?.url ? null From 8c7072204616b871666f9b3a79ec37b8192d0c58 Mon Sep 17 00:00:00 2001 From: Diego Cohen Date: Wed, 11 Oct 2023 09:42:53 -0400 Subject: [PATCH 47/57] Restore naming convention settings and add disable lines --- .eslintrc.js | 15 ++++++++ pages/_app.tsx | 1 + src/types/drbTypes.ts | 2 + src/types/searchTypes.ts | 72 ++++++++++++++++++------------------ src/utils/searchUtils.ts | 80 ++++++++++++++++++++-------------------- 5 files changed, 95 insertions(+), 75 deletions(-) diff --git a/.eslintrc.js b/.eslintrc.js index c7e6b9bf7..18fc679b8 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -33,5 +33,20 @@ module.exports = { "@typescript-eslint/strict-boolean-expressions": ["off"], "@typescript-eslint/explicit-function-return-type": ["off"], "@typescript-eslint/consistent-type-imports": "error", + "@typescript-eslint/naming-convention": [ + "warn", + { + selector: ["typeProperty", "parameter"], + format: ["camelCase"], + }, + { + selector: ["function"], + format: ["camelCase", "PascalCase"], + }, + { + selector: "variable", + format: ["camelCase", "PascalCase", "UPPER_CASE"], + }, + ], }, } diff --git a/pages/_app.tsx b/pages/_app.tsx index 8e805bb74..e660a2975 100644 --- a/pages/_app.tsx +++ b/pages/_app.tsx @@ -1,6 +1,7 @@ import Head from "next/head" import "@nypl/design-system-react-components/dist/styles.css" +// eslint-disable-next-line @typescript-eslint/naming-convention function App({ Component, pageProps }) { return ( <> diff --git a/src/types/drbTypes.ts b/src/types/drbTypes.ts index cefd5c2e9..d1097d118 100644 --- a/src/types/drbTypes.ts +++ b/src/types/drbTypes.ts @@ -40,6 +40,8 @@ export interface Agent { roles: string[] } +/* eslint-disable @typescript-eslint/naming-convention */ + export interface EditionLink { link_id: string mediaType: string diff --git a/src/types/searchTypes.ts b/src/types/searchTypes.ts index 5753c4c46..d640486df 100644 --- a/src/types/searchTypes.ts +++ b/src/types/searchTypes.ts @@ -42,6 +42,43 @@ export interface SearchParams { identifiers?: Identifiers } +type SearchFormField = { value: string } + +export interface SearchResultsResponse { + results?: SearchResults + aggregations?: SearchResults + drbResults?: DRBResults + page: number +} + +export interface SearchResults { + totalResults: number + itemListElement: SearchResultsElement[] +} + +export interface SearchResultsElement { + result?: SearchResult + field?: string +} + +export interface SearchFormInputField { + name: string + label: string +} + +export type SearchFormActionType = + | "input_change" + | "filter_change" + | "form_reset" + +export interface SearchFormAction { + type: SearchFormActionType + field?: string + payload: SearchParams | SearchFilters | string | string[] +} + +/* eslint-disable @typescript-eslint/naming-convention */ + export interface SearchQueryParams extends Identifiers { q?: string contributor?: string @@ -56,8 +93,6 @@ export interface SearchQueryParams extends Identifiers { per_page?: number } -type SearchFormField = { value: string } - export interface SearchFormEvent { q?: SearchFormField search_scope?: SearchFormField @@ -70,23 +105,6 @@ export interface SearchFormEvent { materialType?: SearchFormField } -export interface SearchResultsResponse { - results?: SearchResults - aggregations?: SearchResults - drbResults?: DRBResults - page: number -} - -export interface SearchResults { - totalResults: number - itemListElement: SearchResultsElement[] -} - -export interface SearchResultsElement { - result?: SearchResult - field?: string -} - export interface SearchResult { "@id"?: string uri?: string @@ -100,19 +118,3 @@ export interface SearchResult { electronicResources?: ElectronicResource[] numItemsTotal?: number } - -export interface SearchFormInputField { - name: string - label: string -} - -export type SearchFormActionType = - | "input_change" - | "filter_change" - | "form_reset" - -export interface SearchFormAction { - type: SearchFormActionType - field?: string - payload: SearchParams | SearchFilters | string | string[] -} diff --git a/src/utils/searchUtils.ts b/src/utils/searchUtils.ts index 3fd2efc27..53bfe9abe 100644 --- a/src/utils/searchUtils.ts +++ b/src/utils/searchUtils.ts @@ -113,46 +113,6 @@ export function getQueryString({ return completeQuery?.length ? `?q=${completeQuery}` : "" } -/** - * mapQueryToSearchParams - * Maps the SearchQueryParams structure from the request to a SearchParams object, which is expected by fetchResults - */ -export function mapQueryToSearchParams({ - q, - // eslint-disable-next-line @typescript-eslint/naming-convention - search_scope, - // eslint-disable-next-line @typescript-eslint/naming-convention - sort_direction, - page, - contributor, - title, - subject, - sort, - issn, - isbn, - oclc, - lccn, - filters, -}: SearchQueryParams): SearchParams { - return { - q, - field: search_scope, - page, - contributor, - title, - subject, - sortBy: sort, - order: sort_direction, - filters, - identifiers: { - issn, - isbn, - oclc, - lccn, - }, - } -} - /** * mapRequestBodyToSearchParams * Maps the POST request body from an JS disabled advanced search to a SearchParams object @@ -198,3 +158,43 @@ export function mapElementsToSearchResultsBibs( return new SearchResultsBib(result.result) }) } + +/* eslint-disable @typescript-eslint/naming-convention */ + +/** + * mapQueryToSearchParams + * Maps the SearchQueryParams structure from the request to a SearchParams object, which is expected by fetchResults + */ +export function mapQueryToSearchParams({ + q, + search_scope, + sort_direction, + page, + contributor, + title, + subject, + sort, + issn, + isbn, + oclc, + lccn, + filters, +}: SearchQueryParams): SearchParams { + return { + q, + field: search_scope, + page, + contributor, + title, + subject, + sortBy: sort, + order: sort_direction, + filters, + identifiers: { + issn, + isbn, + oclc, + lccn, + }, + } +} From 91e98b53b14ebb180b1975a1fb43072146f00bd0 Mon Sep 17 00:00:00 2001 From: Diego Cohen Date: Wed, 11 Oct 2023 13:44:17 -0400 Subject: [PATCH 48/57] Add size class to download icon --- src/components/DRB/DRBCard.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/DRB/DRBCard.tsx b/src/components/DRB/DRBCard.tsx index d62a1cd71..6a551b79d 100644 --- a/src/components/DRB/DRBCard.tsx +++ b/src/components/DRB/DRBCard.tsx @@ -66,7 +66,7 @@ const DRBCard = ({ drbResult }: DRBCardProps) => { className="more-link" name="download" align="left" - sx={{ maxWidth: "var(--nypl-space-xs)" }} + size="small" /> Download {drbResult.downloadLink.mediaType || ""} From d6428bfa6fd0b89ea4c1849baa3dbc67102a3c9b Mon Sep 17 00:00:00 2001 From: Diego Cohen Date: Thu, 12 Oct 2023 15:49:29 -0400 Subject: [PATCH 49/57] Replace constant with appconfig value --- pages/404/404.test.tsx | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/pages/404/404.test.tsx b/pages/404/404.test.tsx index bb4fa98b5..731e9f9ff 100644 --- a/pages/404/404.test.tsx +++ b/pages/404/404.test.tsx @@ -3,7 +3,7 @@ import { render, screen } from "@testing-library/react" import Custom404 from "." import Redirect404 from "./redirect" -import { LEGACY_CATALOG_URL } from "../../src/config/constants" +import { appConfig } from "../../src/config/config" describe("404", () => { it("should display 404 text", () => { @@ -21,7 +21,10 @@ describe("404", () => { const legacyLink = screen.getByRole("link", { name: "Legacy Catalog", }) - expect(legacyLink).toHaveAttribute("href", LEGACY_CATALOG_URL) + expect(legacyLink).toHaveAttribute( + "href", + appConfig.externalUrls.legacyCatalog + ) }) }) From 2c2092328adf1dbaef8f42d64ce026cd760ceba8 Mon Sep 17 00:00:00 2001 From: Diego Cohen Date: Thu, 12 Oct 2023 15:51:23 -0400 Subject: [PATCH 50/57] Use appconfig urls on homepage --- pages/index.tsx | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/pages/index.tsx b/pages/index.tsx index 68d3d018c..aa8329bb6 100644 --- a/pages/index.tsx +++ b/pages/index.tsx @@ -11,6 +11,7 @@ import { import Layout from "../src/components/Layout/Layout" import RCLink from "../src/components/RCLink/RCLink" import { SITE_NAME } from "../src/config/constants" +import { appConfig } from "../src/config/config" export default function Home() { return ( @@ -37,11 +38,11 @@ export default function Home() { Please note that the Research Catalog does not include circulating materials. For books and more that you can check out to take home please visit our{" "} - + circulating branch catalog. {" "} The{" "} - + legacy research catalog {" "} is still available, but does not include all of our Scan & Deliver From 6e6ddc4ad3aace3353ebe9c72a18943022403467 Mon Sep 17 00:00:00 2001 From: Diego Cohen Date: Thu, 12 Oct 2023 15:54:43 -0400 Subject: [PATCH 51/57] Remove composite request type --- src/types/searchTypes.ts | 11 ----------- src/utils/searchUtils.ts | 3 +-- 2 files changed, 1 insertion(+), 13 deletions(-) diff --git a/src/types/searchTypes.ts b/src/types/searchTypes.ts index 1e78866ad..d640486df 100644 --- a/src/types/searchTypes.ts +++ b/src/types/searchTypes.ts @@ -51,17 +51,6 @@ export interface SearchResultsResponse { page: number } -export interface SearchRequestBody extends SearchFilters, Identifiers { - q?: string - field?: string - sortBy?: string - order?: string - contributor?: string - title?: string - subject?: string - page?: number -} - export interface SearchResults { totalResults: number itemListElement: SearchResultsElement[] diff --git a/src/utils/searchUtils.ts b/src/utils/searchUtils.ts index 8d02e1f71..2f3bd76ad 100644 --- a/src/utils/searchUtils.ts +++ b/src/utils/searchUtils.ts @@ -6,7 +6,6 @@ import type { SearchFilters, Identifiers, SearchResultsElement, - SearchRequestBody, } from "../types/searchTypes" import SearchResultsBib from "../models/SearchResultsBib" @@ -120,7 +119,7 @@ export function getQueryString({ * Maps the POST request body from an JS disabled advanced search to a SearchParams object */ export function mapRequestBodyToSearchParams( - reqBody: SearchRequestBody + reqBody: SearchParams & SearchFilters ): SearchParams { const { q, From 2908b1eba6df8275b461f6da2b6016f477ed9140 Mon Sep 17 00:00:00 2001 From: Diego Cohen Date: Fri, 13 Oct 2023 10:30:59 -0400 Subject: [PATCH 52/57] Add timeout to advanced search clearing test --- pages/search/advancedSearchForm.test.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pages/search/advancedSearchForm.test.tsx b/pages/search/advancedSearchForm.test.tsx index 88ff9d050..f9887bee3 100644 --- a/pages/search/advancedSearchForm.test.tsx +++ b/pages/search/advancedSearchForm.test.tsx @@ -99,5 +99,5 @@ describe("Advanced Search Form", () => { "Please enter at least one field to submit an advanced search." ) }) - }) + }, 10000) }) From c44e7e9f36ac5b2ee85f4dc97596de2ba25c4391 Mon Sep 17 00:00:00 2001 From: Diego Cohen Date: Fri, 13 Oct 2023 10:34:20 -0400 Subject: [PATCH 53/57] Remove added whitespace from advanced --- pages/search/advanced.tsx | 2 -- 1 file changed, 2 deletions(-) diff --git a/pages/search/advanced.tsx b/pages/search/advanced.tsx index 23a2944e3..5362c7168 100644 --- a/pages/search/advanced.tsx +++ b/pages/search/advanced.tsx @@ -58,7 +58,6 @@ export default function AdvancedSearch() { e.preventDefault() alert && setAlert(false) const target = e.target as HTMLInputElement - dispatch({ type: type, field: target.name, @@ -95,7 +94,6 @@ export default function AdvancedSearch() { const handleSubmit = async (e: SyntheticEvent) => { e.preventDefault() - const queryString = getQueryString(searchFormState as SearchParams) if (!queryString.length) { setAlert(true) From f6e46abe20907791eaaedd41112e02cfaf8caeb6 Mon Sep 17 00:00:00 2001 From: Diego Cohen Date: Fri, 13 Oct 2023 10:40:05 -0400 Subject: [PATCH 54/57] Increase timeout --- pages/search/advancedSearchForm.test.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pages/search/advancedSearchForm.test.tsx b/pages/search/advancedSearchForm.test.tsx index f9887bee3..caaf4139e 100644 --- a/pages/search/advancedSearchForm.test.tsx +++ b/pages/search/advancedSearchForm.test.tsx @@ -99,5 +99,5 @@ describe("Advanced Search Form", () => { "Please enter at least one field to submit an advanced search." ) }) - }, 10000) + }, 15000) }) From 94fe255600dd3dd4c062a8e6b432c011be6b1c72 Mon Sep 17 00:00:00 2001 From: Diego Cohen Date: Fri, 13 Oct 2023 10:46:05 -0400 Subject: [PATCH 55/57] Increase timeout --- __test__/pages/search/advancedSearchForm.test.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/__test__/pages/search/advancedSearchForm.test.tsx b/__test__/pages/search/advancedSearchForm.test.tsx index 00d126ea5..2c5ca11cf 100644 --- a/__test__/pages/search/advancedSearchForm.test.tsx +++ b/__test__/pages/search/advancedSearchForm.test.tsx @@ -99,5 +99,5 @@ describe("Advanced Search Form", () => { "Please enter at least one field to submit an advanced search." ) }) - }, 15000) + }, 30000) }) From 3dbcd59298a4dba4158fdfd0a29b020b56e9bcbf Mon Sep 17 00:00:00 2001 From: Diego Cohen Date: Fri, 13 Oct 2023 10:52:02 -0400 Subject: [PATCH 56/57] Set timeouts for other tests --- __test__/pages/search/advancedSearchForm.test.tsx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/__test__/pages/search/advancedSearchForm.test.tsx b/__test__/pages/search/advancedSearchForm.test.tsx index 2c5ca11cf..b588ceef5 100644 --- a/__test__/pages/search/advancedSearchForm.test.tsx +++ b/__test__/pages/search/advancedSearchForm.test.tsx @@ -43,7 +43,7 @@ describe("Advanced Search Form", () => { "/search?q=spaghetti&contributor=il+amore+di+pasta&title=strega+nonna" ) }) - }) + }, 10000) it("can select languages", async () => { render() @@ -69,7 +69,7 @@ describe("Advanced Search Form", () => { "/search?q=&filters%5BmaterialType%5D%5B0%5D=resourcetypes%3Anot&filters%5BmaterialType%5D%5B1%5D=resourcetypes%3Acar" ) }) - }) + }, 10000) it("can clear the form", async () => { render() @@ -99,5 +99,5 @@ describe("Advanced Search Form", () => { "Please enter at least one field to submit an advanced search." ) }) - }, 30000) + }, 10000) }) From 3b43c2523f07246e43108981f77f685d2dcabd3d Mon Sep 17 00:00:00 2001 From: Diego Cohen Date: Fri, 13 Oct 2023 11:07:02 -0400 Subject: [PATCH 57/57] Move timeout to jest setup --- __test__/pages/search/advancedSearchForm.test.tsx | 6 +++--- jest.setup.js | 3 +++ 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/__test__/pages/search/advancedSearchForm.test.tsx b/__test__/pages/search/advancedSearchForm.test.tsx index b588ceef5..b9043e641 100644 --- a/__test__/pages/search/advancedSearchForm.test.tsx +++ b/__test__/pages/search/advancedSearchForm.test.tsx @@ -43,7 +43,7 @@ describe("Advanced Search Form", () => { "/search?q=spaghetti&contributor=il+amore+di+pasta&title=strega+nonna" ) }) - }, 10000) + }) it("can select languages", async () => { render() @@ -69,7 +69,7 @@ describe("Advanced Search Form", () => { "/search?q=&filters%5BmaterialType%5D%5B0%5D=resourcetypes%3Anot&filters%5BmaterialType%5D%5B1%5D=resourcetypes%3Acar" ) }) - }, 10000) + }) it("can clear the form", async () => { render() @@ -99,5 +99,5 @@ describe("Advanced Search Form", () => { "Please enter at least one field to submit an advanced search." ) }) - }, 10000) + }) }) diff --git a/jest.setup.js b/jest.setup.js index 6d55101b5..9c1d4be7f 100644 --- a/jest.setup.js +++ b/jest.setup.js @@ -5,3 +5,6 @@ import "@testing-library/jest-dom" // logged and we don't want to see expected errors while we test. jest.spyOn(global.console, "error").mockImplementation(() => jest.fn()) jest.spyOn(global.console, "warn").mockImplementation(() => jest.fn()) + +// Increase timeout on tests +jest.setTimeout(35000)