diff --git a/src/modules/advanced/components/FiltersContainer/index.js b/src/modules/advanced/components/FiltersContainer/index.js index 4ec96c4b2..a2e063048 100644 --- a/src/modules/advanced/components/FiltersContainer/index.js +++ b/src/modules/advanced/components/FiltersContainer/index.js @@ -1,8 +1,6 @@ -/** @jsxImportSource @emotion/react */ import React from 'react'; import { useSelector, connect } from 'react-redux'; import { bindActionCreators } from 'redux'; -// import { Link } from 'react-router-dom'; import PropTypes from 'prop-types'; import { Icon, Button } from '../../../reusable'; import getFilters from './getFilters'; @@ -133,7 +131,8 @@ class FiltersContainer extends React.Component { ); @@ -149,12 +148,6 @@ FiltersContainer.propTypes = { ]) }; -function mapDispatchToProps (dispatch) { - return bindActionCreators({ - setAdvancedFilter - }, dispatch); -} - function ActiveAdvancedFilters (datastore) { const currentDatastore = datastore.datastore.uid; const { advanced } = useSelector((state) => { @@ -201,7 +194,7 @@ function ActiveAdvancedFilters (datastore) { return (

Active filters

({items.length}) - {/* {items.length > 1 && - - Clear all active filters - } */}
-

+

Unselect active filters through the options below.

); @@ -182,7 +182,7 @@ function ActiveFilterItem ({ group, value }) { const url = getURLWithFilterRemoved({ group, value }); return ( - - + ); } @@ -386,7 +386,7 @@ FilterContainer.propTypes = { function Filter ({ value, count, url }) { return ( - {count?.toLocaleString()} - + ); } diff --git a/src/modules/lists/components/GoToList/index.js b/src/modules/lists/components/GoToList/index.js index 2dc1d1853..6e3dc5073 100644 --- a/src/modules/lists/components/GoToList/index.js +++ b/src/modules/lists/components/GoToList/index.js @@ -1,20 +1,19 @@ -import React, { Component } from 'react'; -import { withRouter, Link } from 'react-router-dom'; +import React from 'react'; +import { Anchor } from '../../../reusable'; import PropTypes from 'prop-types'; +import { withRouter } from 'react-router-dom'; -class GoToList extends Component { - render () { - const { location, list, datastore } = this.props; - if (!list) return null; - return ( -
-
-

Go to My Temporary {datastore.name} List to email, text, and export citations.

-
-

{list?.length || 0} in list

-
- ); - } +function GoToList (props) { + if (!props.list) return null; + + return ( +
+
+

Go to My Temporary {props.datastore.name} List to email, text, and export citations.

+
+

{props.list?.length || 0} in list

+
+ ); } GoToList.propTypes = { diff --git a/src/modules/records/components/BentoboxList/index.js b/src/modules/records/components/BentoboxList/index.js index 793dffeb2..1ac607e9a 100644 --- a/src/modules/records/components/BentoboxList/index.js +++ b/src/modules/records/components/BentoboxList/index.js @@ -1,143 +1,15 @@ import React from 'react'; -import { connect } from 'react-redux'; -import { Link } from 'react-router-dom'; -import { Icon } from '../../../core'; -import { getMultiSearchRecords } from '../../../pride'; -import RecordPreview from '../RecordPreview'; -import RecordPreviewPlaceholder from '../RecordPreviewPlaceholder'; import KeywordSwitch from '../KeywordSwitch'; +import { Anchor } from '../../../reusable'; +import RecordPreviewPlaceholder from '../RecordPreviewPlaceholder'; +import RecordPreview from '../RecordPreview'; import { SpecialistsWrapper } from '../../../specialists'; +import { getMultiSearchRecords } from '../../../pride'; +import { Icon } from '../../../core'; import PropTypes from 'prop-types'; +import { connect } from 'react-redux'; -class BentoboxList extends React.Component { - render () { - const { allRecords, datastoreUid, search, searchQuery, institution } = this.props; - const bentoboxListRecords = getMultiSearchRecords(datastoreUid, allRecords); - - return ( -
- - {bentoboxListRecords.map((bentobox) => { - if (!bentobox.records) { - return null; - } - - return ( -
-
- - - -
-
- ); - })} -
-
- ); - } -} - -BentoboxList.propTypes = { - allRecords: PropTypes.object, - datastoreUid: PropTypes.string, - search: PropTypes.object, - searchQuery: PropTypes.string, - institution: PropTypes.object -}; - -const BentoHeading = ({ - bentobox, - search, - searchQuery -}) => { - const totalResults = search.data[bentobox.uid].totalAvailable; - const url = `/${bentobox.slug}${searchQuery}`; - - return ( - -

{bentobox.name}

- - - ); -}; - -BentoHeading.propTypes = { - bentobox: PropTypes.object, - search: PropTypes.object, - searchQuery: PropTypes.string -}; - -const BentoFooter = ({ - bentobox, - search, - searchQuery -}) => { - const url = `/${bentobox.slug}${searchQuery}`; - const footerText = `View all ${bentobox.name} results`; - - // No results - if (search.data[bentobox.uid] && search.data[bentobox.uid].totalAvailable === 0) { - return null; - } - - // Loading results - if (bentobox.records.length === 0) { - return null; - } - - return ( - - {footerText} - - ); -}; - -BentoFooter.propTypes = { - bentobox: PropTypes.object, - search: PropTypes.object, - searchQuery: PropTypes.string -}; - -const BentoboxNoResults = ({ bentobox }) => { - const hasBrowse = !!((bentobox.uid === 'databases' || bentobox.uid === 'onlinejournals')); - - return ( -
-

No results match your search.

- - {hasBrowse && ( -

Try our Browse {bentobox.name} page to view all titles alphabetically or by academic discipline.

- )} -
- ); -}; - -BentoboxNoResults.propTypes = { - bentobox: PropTypes.object -}; - -const BentoboxResultsNum = ({ totalResults }) => { +function BentoboxResultsNum ({ totalResults }) { // Results have loaded if (typeof totalResults === 'number') { return {totalResults.toLocaleString()} {`Result${totalResults !== 1 ? 's' : ''}`}; @@ -151,16 +23,19 @@ BentoboxResultsNum.propTypes = { totalResults: PropTypes.number }; -const BentoResults = ({ search, bentobox, searchQuery, institution }) => { +function BentoResults ({ search, bentobox, searchQuery }) { // No results - if (search.data[bentobox.uid] && search.data[bentobox.uid].totalAvailable === 0) { - if (bentobox.uid === 'primo') { - return ( - - ); - } + if (search.data[bentobox.uid]?.totalAvailable === 0) { return ( - + <> + {bentobox.uid === 'primo' && } +
+

No results match your search.

+ {['databases', 'onlinejournals'].includes(bentobox.uid) && ( +

Try our Browse {bentobox.name} page to view all titles alphabetically or by academic discipline.

+ )} +
+ ); } @@ -208,8 +83,75 @@ const BentoResults = ({ search, bentobox, searchQuery, institution }) => { BentoResults.propTypes = { bentobox: PropTypes.object, search: PropTypes.object, - searchQuery: PropTypes.string, - institution: PropTypes.object + searchQuery: PropTypes.string +}; + +function BentoFooter ({ bentobox, search, searchQuery }) { + // Loading or no results + if (search.data[bentobox.uid]?.totalAvailable === 0 || bentobox.records.length === 0) { + return null; + } + + return ( + + {`View all ${bentobox.name} results`} + + ); +}; + +BentoFooter.propTypes = { + bentobox: PropTypes.object, + search: PropTypes.object, + searchQuery: PropTypes.string +}; + +function BentoboxList (props) { + return ( +
+ + {getMultiSearchRecords(props.datastoreUid, props.allRecords).map((bentobox) => { + if (!bentobox.records) { + return null; + } + + return ( +
+
+ +

{bentobox.name}

+ +
+ + +
+
+ ); + })} +
+
+ ); +} + +BentoboxList.propTypes = { + allRecords: PropTypes.object, + datastoreUid: PropTypes.string, + search: PropTypes.object, + searchQuery: PropTypes.string }; function mapStateToProps (state) { @@ -217,8 +159,7 @@ function mapStateToProps (state) { allRecords: state.records.records, datastoreUid: state.datastores.active, search: state.search, - searchQuery: state.router.location.search, - institution: state.institution + searchQuery: state.router.location.search }; } diff --git a/src/modules/reusable/components/Metadata/index.js b/src/modules/reusable/components/Metadata/index.js index 3066bd350..a9532fc8e 100644 --- a/src/modules/reusable/components/Metadata/index.js +++ b/src/modules/reusable/components/Metadata/index.js @@ -236,6 +236,14 @@ DescriptionItem.propTypes = { children: PropTypes.array }; +function browseLinkByEnvironment (type, value) { + let browseLink = 'https://search.lib.umich.edu/catalog/browse'; + if (process.env.NODE_ENV === 'development') { + browseLink = 'https://testing.browse.kubernetes.lib.umich.edu'; + } + return `${browseLink}/${type}?query=${value}`; +} + function DescriptionItemLink ({ href, search, browse, children }) { if (href) { return ( @@ -267,9 +275,9 @@ function DescriptionItemLink ({ href, search, browse, children }) { width: '1px' } }} - href={`/catalog/browse/${browse.type}?query=${browse.value}`} + href={browseLinkByEnvironment(browse.type, browse.value)} > - Browse in {browse.type === 'callnumber' ? 'call number' : browse.type} list + {browse.text} ); diff --git a/src/modules/search/components/SearchBox/index.js b/src/modules/search/components/SearchBox/index.js index 89629b27c..a99748202 100644 --- a/src/modules/search/components/SearchBox/index.js +++ b/src/modules/search/components/SearchBox/index.js @@ -1,15 +1,14 @@ /** @jsxImportSource @emotion/react */ import { Global } from '@emotion/react'; -import React from 'react'; -import PropTypes from 'prop-types'; -import { MEDIA_QUERIES, SEARCH_COLORS } from '../../../reusable/umich-lib-core-temp'; -import { Icon, Button } from '../../../reusable'; +import React, { useState, useEffect } from 'react'; import { useSelector } from 'react-redux'; +import { MEDIA_QUERIES, SEARCH_COLORS } from '../../../reusable/umich-lib-core-temp'; +import { Anchor, Icon, Button } from '../../../reusable'; import qs from 'qs'; -import { withRouter } from 'react-router'; -import { Link } from 'react-router-dom'; import SearchByOptions from '../SearchByOptions'; import SearchTip from '../SearchTip'; +import PropTypes from 'prop-types'; +import { withRouter } from 'react-router'; function SearchBox ({ history, match, location }) { const { query } = useSelector((state) => { @@ -28,12 +27,12 @@ function SearchBox ({ history, match, location }) { }); } ); - const [inputQuery, setInputQuery] = React.useState(query); + const [inputQuery, setInputQuery] = useState(query); const defaultField = fields[0].uid; - const [field, setField] = React.useState(defaultField); + const [field, setField] = useState(defaultField); // Set field and input when `activeDatastore`, `query`, or `fields` changes - React.useEffect(() => { + useEffect(() => { const fieldIDs = fields.map((field) => { return field.uid; }); @@ -276,7 +275,7 @@ function SearchBox ({ history, match, location }) { {isAdvanced && ( - {activeDatastore.name} Advanced Search - + )}