diff --git a/src/modules/records/components/Description/index.js b/src/modules/records/components/Description/index.js new file mode 100644 index 00000000..c8afcaf0 --- /dev/null +++ b/src/modules/records/components/Description/index.js @@ -0,0 +1,82 @@ +import { Anchor, Icon } from '../../../reusable'; +import { BrowseLink } from '../../../browse'; +import PropTypes from 'prop-types'; +import React from 'react'; +import { stringifySearch } from '../../../search'; +import { TrimString } from '../../../core'; + +const Description = ({ activeDatastore, data, datastores, institution, viewType }) => { + if (Array.isArray(data)) { + return ( +
    + {data.map((datum, index) => { + return ( +
  1. + {index > 0 && } + +
  2. + ); + })} +
+ ); + } + + const { browse, href, icon, search, text } = data; + const searchScope = search?.scope || {}; + const anchorAttributes = search + ? ( + () => { + const { slug, uid } = datastores.find((datastore) => { + return datastore.uid === activeDatastore; + }); + const { scope, type, value } = search; + return { + to: `/${slug}?${stringifySearch({ + filter: type === 'filtered' ? { [scope]: value } : {}, + library: uid === 'mirlyn' ? institution : '', + query: type === 'fielded' ? `${scope}:${value}` : value + })}` + }; + } + )() + : { href }; + + const { text: browseText, type, value } = browse || {}; + + const child = ( + <> + {icon && } + { ['Preview', 'Medium'].includes(viewType) ? : text } + + ); + + return ( + <> + {(href || search) ? {child} : child} + {browseText && ( + <> + | + + {browseText} + + + )} + + ); +}; + +Description.propTypes = { + activeDatastore: PropTypes.string, + data: PropTypes.oneOfType([ + PropTypes.array, + PropTypes.object + ]), + datastores: PropTypes.array, + institution: PropTypes.string, + viewType: PropTypes.string +}; + +export default Description; diff --git a/src/modules/records/components/Metadata/index.js b/src/modules/records/components/Metadata/index.js new file mode 100644 index 00000000..6b68ebc4 --- /dev/null +++ b/src/modules/records/components/Metadata/index.js @@ -0,0 +1,74 @@ +import './styles.css'; +import { + ContextProvider, + Expandable, + ExpandableButton, + ExpandableChildren +} from '../../../reusable'; +import Description from '../Description'; +import PropTypes from 'prop-types'; +import React from 'react'; +import { useSelector } from 'react-redux'; + +const Metadata = ({ metadata = {} }) => { + const { active: activeInstitution, defaultInstitution } = useSelector((state) => { + return state.institution; + }); + const { active: activeDatastore, datastores } = useSelector((state) => { + return state.datastores; + }); + + if (!metadata || Object.keys(metadata).length === 0) { + return null; + } + + const institution = activeInstitution || defaultInstitution; + + const metadataView = { + Full: metadata.full, + Medium: metadata.medium, + Preview: metadata.preview + }; + + return ( + { + return ( +
+ {(metadataView[viewType] || metadata.full).map(({ description, term, termPlural }, index) => { + if (!description) { + return null; + } + + return ( +
+ +
+ {term} +
+ + {description.map((data, dataIndex) => { + return ( +
+ +
+ ); + })} +
+ {description.length > 3 &&
} +
+
+ ); + })} +
+ ); + }} + /> + ); +}; + +Metadata.propTypes = { + metadata: PropTypes.object +}; + +export default Metadata; diff --git a/src/modules/reusable/components/Metadata/styles.css b/src/modules/records/components/Metadata/styles.css similarity index 88% rename from src/modules/reusable/components/Metadata/styles.css rename to src/modules/records/components/Metadata/styles.css index fade0773..aed74520 100644 --- a/src/modules/reusable/components/Metadata/styles.css +++ b/src/modules/records/components/Metadata/styles.css @@ -20,10 +20,6 @@ } } -.metadata-list-item > dd > img { - max-width: 16rem; -} - .metadata-list-item > dd > ol.list__unstyled > li { display: inline-block; } diff --git a/src/modules/records/components/Record/index.js b/src/modules/records/components/Record/index.js index 1b089ba4..67d7504b 100644 --- a/src/modules/records/components/Record/index.js +++ b/src/modules/records/components/Record/index.js @@ -1,7 +1,7 @@ import { AddToListButton, isInList } from '../../../lists'; import { Anchor, Icon } from '../../../reusable'; import { getField, getFieldValue } from '../../utilities'; -import { RecommendedResource, RecordMetadata } from '../../../records'; +import { Metadata, RecommendedResource } from '../../../records'; import { getDatastoreSlugByUid } from '../../../pride'; import PropTypes from 'prop-types'; import React from 'react'; @@ -85,7 +85,7 @@ const Record = ({ datastoreUid, list, record }) => { - +
diff --git a/src/modules/records/components/RecordFull/index.js b/src/modules/records/components/RecordFull/index.js index 313d38da..15a5c725 100644 --- a/src/modules/records/components/RecordFull/index.js +++ b/src/modules/records/components/RecordFull/index.js @@ -8,10 +8,10 @@ import { import { Anchor, Breadcrumb, H1 } from '../../../reusable'; import { FullRecordPlaceholder, + Metadata, RecommendedResource, RecordDescription, RecordFullFormats, - RecordMetadata, ViewMARC, Zotero } from '../../../records'; @@ -158,7 +158,7 @@ const FullRecord = () => {

Record info:

- + {inDatastore && (

The University of Michigan Library aims to describe its collections in a way that respects the people and communities who create, use, and are represented in them. We encourage you to diff --git a/src/modules/records/components/RecordMetadata/index.js b/src/modules/records/components/RecordMetadata/index.js deleted file mode 100644 index 4f945c19..00000000 --- a/src/modules/records/components/RecordMetadata/index.js +++ /dev/null @@ -1,29 +0,0 @@ -import { ContextProvider, Metadata } from '../../../reusable'; -import PropTypes from 'prop-types'; -import React from 'react'; - -const RecordMetadata = ({ metadata = {} }) => { - return ( - { - if (!metadata || Object.keys(metadata).length === 0) { - return null; - } - - const data = { - Full: metadata.full, - Medium: metadata.medium, - Preview: metadata.preview - }; - - return ; - }} - /> - ); -}; - -RecordMetadata.propTypes = { - metadata: PropTypes.object -}; - -export default RecordMetadata; diff --git a/src/modules/records/components/RecordPreview/index.js b/src/modules/records/components/RecordPreview/index.js index a980e740..dd938c82 100644 --- a/src/modules/records/components/RecordPreview/index.js +++ b/src/modules/records/components/RecordPreview/index.js @@ -1,6 +1,6 @@ import { Anchor, Icon } from '../../../reusable'; import { getField, getFieldValue } from '../../utilities'; -import { RecommendedResource, RecordMetadata, Zotero } from '../../../records'; +import { Metadata, RecommendedResource, Zotero } from '../../../records'; import { getDatastoreSlugByUid } from '../../../pride'; import PropTypes from 'prop-types'; import React from 'react'; @@ -109,7 +109,7 @@ const RecordPreview = ({ datastoreUid, record, searchQuery }) => { return (

- +
diff --git a/src/modules/records/index.js b/src/modules/records/index.js index e9213d37..e1b9d5fc 100644 --- a/src/modules/records/index.js +++ b/src/modules/records/index.js @@ -15,6 +15,7 @@ import FullRecordPlaceholder from './components/FullRecordPlaceholder'; import ILLRequestMessage from './components/ILLRequestMessage'; import KeywordSwitch from './components/KeywordSwitch'; import MARCTable from './components/MARCTable'; +import Metadata from './components/Metadata'; import Pagination from './components/Pagination'; import RecommendedResource from './components/RecommendedResource'; import Record from './components/Record'; @@ -22,7 +23,6 @@ import RecordDescription from './components/RecordDescription'; import RecordFull from './components/RecordFull'; import RecordFullFormats from './components/RecordFullFormats'; import RecordList from './components/RecordList'; -import RecordMetadata from './components/RecordMetadata'; import recordsReducer from './reducer'; import Results from './components/Results'; import ViewMARC from './components/ViewMARC'; @@ -41,6 +41,7 @@ export { loadingHoldings, loadingRecords, MARCTable, + Metadata, Pagination, RecommendedResource, Record, @@ -48,7 +49,6 @@ export { RecordFull, RecordFullFormats, RecordList, - RecordMetadata, recordsReducer, Results, setRecord, diff --git a/src/modules/reusable/components/Metadata/index.js b/src/modules/reusable/components/Metadata/index.js deleted file mode 100644 index 431c5b4b..00000000 --- a/src/modules/reusable/components/Metadata/index.js +++ /dev/null @@ -1,149 +0,0 @@ -import './styles.css'; -import { - Anchor, - Expandable, - ExpandableButton, - ExpandableChildren, - Icon -} from '../../../reusable'; -import { BrowseLink } from '../../../browse'; -import PropTypes from 'prop-types'; -import React from 'react'; -import { stringifySearch } from '../../../search'; -import { TrimString } from '../../../core'; -import { useSelector } from 'react-redux'; - -const DescriptionItem = ({ browse, children, href, search }) => { - const { active: activeInstitution, defaultInstitution } = useSelector((state) => { - return state.institution; - }); - const { slug, uid } = useSelector((state) => { - const { active, datastores } = state.datastores; - return datastores.find((datastore) => { - return datastore.uid === active; - }); - }); - - const anchorAttributes = { href }; - - if (search) { - const { scope, type, value } = search; - anchorAttributes.to = `/${slug}?${stringifySearch({ - filter: type === 'filtered' ? { [scope]: value } : {}, - library: uid === 'mirlyn' ? (activeInstitution || defaultInstitution) : {}, - query: type === 'fielded' ? `${scope}:${value}` : value - })}`; - } - - return ( - <> - {(href || search) ? {children} : children} - {browse && ( - <> - | - - {browse.text} - - - )} - - ); -}; - -DescriptionItem.propTypes = { - browse: PropTypes.object, - children: PropTypes.oneOfType([ - PropTypes.arrayOf(PropTypes.node), - PropTypes.node - ]), - href: PropTypes.string, - search: PropTypes.object -}; - -const Description = ({ data, viewType }) => { - if (Array.isArray(data)) { - return ( -
    - {data.map((datum, index) => { - return ( -
  1. - {index > 0 && } - -
  2. - ); - })} -
- ); - } - - const { icon, image, search: { scope } = {}, text } = data; - - return ( - - - {icon && ( - - )} - {scope === 'author' && viewType !== 'Full' ? : text} - - {image && ( - - )} - - ); -}; - -Description.propTypes = { - data: PropTypes.oneOfType([ - PropTypes.array, - PropTypes.object - ]), - viewType: PropTypes.string -}; - -export default function Metadata ({ data, viewType }) { - return ( -
- {data.map((datum, datumIndex) => { - const { description, term, termPlural } = datum; - const isExpandable = description.length > 5; - return ( -
- -
- {term} -
- - {description.map((descriptor, index) => { - return ( -
- -
- ); - })} -
- {isExpandable &&
} -
-
- ); - })} -
- ); -} - -Metadata.propTypes = { - data: PropTypes.array, - viewType: PropTypes.string -}; diff --git a/src/modules/reusable/index.js b/src/modules/reusable/index.js index 5d1ead74..978248a5 100644 --- a/src/modules/reusable/index.js +++ b/src/modules/reusable/index.js @@ -7,7 +7,6 @@ import ContextProvider from './components/ContextProvider'; import Dialog from './components/Dialog'; import H1 from './components/H1'; import Icon from './components/Icon'; -import Metadata from './components/Metadata'; import Tab from './components/Tab'; import TabPanel from './components/TabPanel'; import Tabs from './components/Tabs'; @@ -27,7 +26,6 @@ export { ExpandableProvider, H1, Icon, - Metadata, Tab, Tabs, TabPanel,