diff --git a/src/client/components/facet_results/ObjectList.js b/src/client/components/facet_results/ObjectList.js deleted file mode 100644 index e7d204b523b7ac5583da2e91cd273f0da851fef1..0000000000000000000000000000000000000000 --- a/src/client/components/facet_results/ObjectList.js +++ /dev/null @@ -1,182 +0,0 @@ -import React from 'react'; -import PropTypes from 'prop-types'; -import { withStyles } from '@material-ui/core/styles'; -import Collapse from '@material-ui/core/Collapse'; -import Button from '@material-ui/core/Button'; -import { ISOStringToDate } from './Dates'; -import { Link } from 'react-router-dom'; -import { orderBy, has } from 'lodash'; - -const styles = () => ({ - valueList: { - paddingLeft: 20, - maxHeight: 200, - overflow: 'auto' - }, - valueListNoBullets: { - listStyle: 'none', - paddingLeft: 0 - }, - dateContainer: { - width: 180, - display: 'inline-block' - } -}); - -const ObjectList = props => { - - const createBasicItem = ({ data, collapsed, firstValue }) => { - let date = ''; - let observedOwner = ''; - if (props.columnId === 'event') { - date = - <span className={firstValue ? null : props.classes.dateContainer}> - {data.date == null ? 'No date ' : `${data.date} `} - </span>; - if (data.observedOwner) { // currently no separate class for provenance events - observedOwner = createLink({ - id: data.observedOwner.id, - dataProviderUrl: data.observedOwner.dataProviderUrl, - prefLabel: data.observedOwner.prefLabel, - collapsed: false - }); - } - } - return ( - <span> - {date} - {!props.makeLink && - <React.Fragment> - {Array.isArray(data.prefLabel) ? - data.prefLabel[0] - : data.prefLabel} - {collapsed && ' ...'} - </React.Fragment> - } - {props.makeLink && - <React.Fragment> - {createLink({ - id: data.id, - dataProviderUrl: data.dataProviderUrl, - prefLabel: data.prefLabel, - collapsed - })} - </React.Fragment> - } - {data.observedOwner && - <React.Fragment> - {': '} - {observedOwner} - </React.Fragment> - } - </span> - ); - }; - - const createLink = ({ id, dataProviderUrl, prefLabel, collapsed }) => { - return ( - <React.Fragment> - {props.externalLink && props.linkAsButton == null && - <a - target='_blank' rel='noopener noreferrer' - href={dataProviderUrl} - > - {Array.isArray(prefLabel) ? prefLabel[0] : prefLabel} - </a> - } - {props.externalLink && props.linkAsButton && - <Button - variant='contained' - target='_blank' - rel='noopener noreferrer' - href={id} - > - {Array.isArray(prefLabel) ? prefLabel[0] : prefLabel} - </Button> - } - {!props.externalLink && - <Link to={dataProviderUrl}> - {Array.isArray(prefLabel) ? prefLabel[0] : prefLabel} - </Link> - } - {collapsed && <span> ...</span>} - </React.Fragment> - ); - }; - - const createBasicList = data => { - return data.map((item, i) => { - const hasSource = has(item, 'source'); - return( - <li key={i}> - {createBasicItem({ data: item, collapsed: false, firstValue: false })} - {hasSource && <sup>{item.source.prefLabel}</sup>} - </li> - ); - } - - ); - }; - - const { sortValues } = props; - let { data } = props; - // if (props.columnId === 'event') { - // console.log(data) - // } - if (data == null || data === '-') { - return '-'; - } - else if (Array.isArray(data)) { - if (has(props, 'columnId') && props.columnId.endsWith('Timespan')) { - data = sortValues - ? data.sort((a,b) => { - a = has(a, 'start') ? ISOStringToDate(a.start) : ISOStringToDate(a.end); - b = has(b, 'start') ? ISOStringToDate(b.start) : ISOStringToDate(b.end); - // arrange from the most recent to the oldest - return a > b ? 1 : a < b ? -1 : 0; - }) - : data; - } else if (props.columnId === 'event') { - data = sortValues ? orderBy(data, 'date') : data; - } - else { - data = sortValues ? orderBy(data, 'prefLabel') : data; - } - return ( - <React.Fragment> - {!props.expanded && createBasicItem({ - data: data[0], - collapsed: true, - firstValue: true - })} - <Collapse in={props.expanded} timeout="auto" unmountOnExit> - <ul className={props.classes.valueList}> - {createBasicList(data)} - </ul> - </Collapse> - </React.Fragment> - ); - } else { - return createBasicItem({ data, collapsed: false, firstValue: true }); - } -}; - -ObjectList.propTypes = { - classes: PropTypes.object.isRequired, - data: PropTypes.oneOfType([PropTypes.object, PropTypes.array, PropTypes.string]), - makeLink: PropTypes.bool.isRequired, - externalLink: PropTypes.bool.isRequired, - sortValues: PropTypes.bool.isRequired, - numberedList: PropTypes.bool.isRequired, - expanded: PropTypes.bool.isRequired, - columnId: PropTypes.string.isRequired, - linkAsButton: PropTypes.bool -} ; - -export default withStyles(styles)(ObjectList); - -// old code, sorting owners: -// cell.map(item => { -// Array.isArray(item.order) ? item.earliestOrder = item.order[0] : item.earliestOrder = item.order; -// }); -// cell.sort((a, b) => a.earliestOrder - b.earliestOrder); diff --git a/src/client/components/facet_results/ObjectListCollapsible.js b/src/client/components/facet_results/ObjectListCollapsible.js new file mode 100644 index 0000000000000000000000000000000000000000..9ad8acaca573a302b5d4b41b9e3d70986fa3500e --- /dev/null +++ b/src/client/components/facet_results/ObjectListCollapsible.js @@ -0,0 +1,106 @@ +import React from 'react'; +import PropTypes from 'prop-types'; +import { withStyles } from '@material-ui/core/styles'; +import Collapse from '@material-ui/core/Collapse'; +import { ISOStringToDate } from './Dates'; +import { orderBy, has } from 'lodash'; +import ObjectListItem from './ObjectListItem'; + +const styles = () => ({ + valueList: { + paddingLeft: 20, + maxHeight: 200, + overflow: 'auto' + }, + valueListNoBullets: { + listStyle: 'none', + paddingLeft: 0 + }, + dateContainer: { + width: 180, + display: 'inline-block' + } +}); + +const ObjectList = props => { + + const sortList = data => { + if (has(props, 'columnId') && props.columnId.endsWith('Timespan')) { + data = sortValues + ? data.sort((a,b) => { + a = has(a, 'start') ? ISOStringToDate(a.start) : ISOStringToDate(a.end); + b = has(b, 'start') ? ISOStringToDate(b.start) : ISOStringToDate(b.end); + // arrange from the most recent to the oldest + return a > b ? 1 : a < b ? -1 : 0; + }) + : data; + } else if (props.columnId === 'event') { + data = sortValues ? orderBy(data, 'date') : data; + } + else { + data = sortValues ? orderBy(data, 'prefLabel') : data; + } + return data; + }; + + const { sortValues, makeLink, externalLink, linkAsButton } = props; + let { data } = props; + if (data == null || data === '-') { + return '-'; + } + else if (Array.isArray(data)) { + data = sortList(data); + return ( + <React.Fragment> + {!props.expanded && + <ObjectListItem + data={data[0]} + makeLink={makeLink} + externalLink={externalLink} + linkAsButton={linkAsButton} + collapsed={true} + /> + } + <Collapse in={props.expanded} timeout="auto" unmountOnExit> + <ul className={props.classes.valueList}> + {data.map(item => + <li key={item.id}> + <ObjectListItem + data={item} + makeLink={makeLink} + externalLink={externalLink} + linkAsButton={linkAsButton} + collapsed={false} + /> + </li> + )} + </ul> + </Collapse> + </React.Fragment> + ); + } else { + return ( + <ObjectListItem + data={data} + makeLink={makeLink} + externalLink={externalLink} + linkAsButton={linkAsButton} + collapsed={false} + /> + ); + } +}; + +ObjectList.propTypes = { + classes: PropTypes.object.isRequired, + data: PropTypes.oneOfType([PropTypes.object, PropTypes.array, PropTypes.string]), + makeLink: PropTypes.bool.isRequired, + externalLink: PropTypes.bool.isRequired, + sortValues: PropTypes.bool.isRequired, + numberedList: PropTypes.bool.isRequired, + expanded: PropTypes.bool.isRequired, + columnId: PropTypes.string.isRequired, + linkAsButton: PropTypes.bool +}; + +export default withStyles(styles)(ObjectList); diff --git a/src/client/components/facet_results/ObjectListItem.js b/src/client/components/facet_results/ObjectListItem.js new file mode 100644 index 0000000000000000000000000000000000000000..cff7412ab7c441f5fb177a279c1e391dce34eb5e --- /dev/null +++ b/src/client/components/facet_results/ObjectListItem.js @@ -0,0 +1,32 @@ +import React from 'react'; +import PropTypes from 'prop-types'; +import ObjectListItemLink from './ObjectListItemLink'; + +const ObjectListItem = props => { + const { data, makeLink, externalLink, linkAsButton, collapsed } = props; + let label = Array.isArray(data.prefLabel) ? data.prefLabel[0] : data.prefLabel; + return ( + <React.Fragment> + {!makeLink && label} + {makeLink && + <ObjectListItemLink + data={data} + label={label} + externalLink={externalLink} + linkAsButton={linkAsButton} + /> + } + {collapsed && ' ...'} + </React.Fragment> + ); +}; + +ObjectListItem.propTypes = { + data: PropTypes.object.isRequired, + makeLink: PropTypes.bool.isRequired, + externalLink: PropTypes.bool.isRequired, + linkAsButton: PropTypes.bool, + collapsed: PropTypes.bool.isRequired +}; + +export default ObjectListItem; diff --git a/src/client/components/facet_results/ObjectListItemEvent.js b/src/client/components/facet_results/ObjectListItemEvent.js new file mode 100644 index 0000000000000000000000000000000000000000..2725fbb4fda86ab76be2772bc6b0ede305a8cedb --- /dev/null +++ b/src/client/components/facet_results/ObjectListItemEvent.js @@ -0,0 +1,30 @@ +import React from 'react'; +import PropTypes from 'prop-types'; +import ObjectListItemLink from './ObjectListItemLink'; + +const ObjectListItemEvent = props => { + const { data, collapsed } = props; + let label = Array.isArray(data.prefLabel) ? data.prefLabel[0] : data.prefLabel; + return ( + <React.Fragment> + <ObjectListItemLink + data={data} + label={label} + /> + {data.observedOwner && + <React.Fragment> + {': '} + {data.observedOwner} + </React.Fragment> + } + {collapsed && ' ...'} + </React.Fragment> + ); +}; + +ObjectListItemEvent.PropTypes = { + data: PropTypes.bool.isRequired, + collapsed: PropTypes.bool.isRequired +}; + +export default ObjectListItemEvent; diff --git a/src/client/components/facet_results/ObjectListItemLink.js b/src/client/components/facet_results/ObjectListItemLink.js new file mode 100644 index 0000000000000000000000000000000000000000..22572c3e8a2d38ac9a3d00adac7970b0d9786388 --- /dev/null +++ b/src/client/components/facet_results/ObjectListItemLink.js @@ -0,0 +1,45 @@ +import React from 'react'; +import PropTypes from 'prop-types'; +import Button from '@material-ui/core/Button'; +import { Link } from 'react-router-dom'; + +const ObjectListLink = props => { + const { data, label, externalLink, linkAsButton } = props; + + return ( + <React.Fragment> + {externalLink && linkAsButton == null && + <a + target='_blank' rel='noopener noreferrer' + href={data.dataProviderUrl} + > + {label} + </a> + } + {props.externalLink && props.linkAsButton && + <Button + variant='contained' + target='_blank' + rel='noopener noreferrer' + href={data.id} + > + {label} + </Button> + } + {!props.externalLink && + <Link to={data.dataProviderUrl}> + {label} + </Link> + } + </React.Fragment> + ); +}; + +ObjectListLink.propTypes = { + externalLink: PropTypes.bool.isRequired, + data: PropTypes.object.isRequired, + label: PropTypes.string.isRequired, + linkAsButton: PropTypes.bool, +}; + +export default ObjectListLink; diff --git a/src/client/components/facet_results/ResultTableCell.js b/src/client/components/facet_results/ResultTableCell.js index 3d56d1cff56f50d3213acecb5fccadf5cc83d3cc..1f7adcf6e85a7ed10593ac3881c994ea7432586b 100644 --- a/src/client/components/facet_results/ResultTableCell.js +++ b/src/client/components/facet_results/ResultTableCell.js @@ -1,7 +1,7 @@ import React from 'react'; import PropTypes from 'prop-types'; import TableCell from '@material-ui/core/TableCell'; -import ObjectList from './ObjectList'; +import ObjectListCollapsible from './ObjectListCollapsible'; import StringList from './StringList'; const ResultTableCell = props => { @@ -12,7 +12,7 @@ const ResultTableCell = props => { switch (valueType) { case 'object': cellContent = - <ObjectList + <ObjectListCollapsible data={data} makeLink={makeLink} externalLink={externalLink}