UNPKG

cspace-ui

Version:
160 lines (140 loc) 4.79 kB
import React from 'react'; import PropTypes from 'prop-types'; import { defineMessages, injectIntl } from 'react-intl'; import { useSelector } from 'react-redux'; import get from 'lodash/get'; import Immutable from 'immutable'; import SearchResultTableHeader from './SearchResultTableHeader'; import { getColumnConfig, readListItems } from '../searchResultHelpers'; import { getSearchResult, getSearchSelectedItems } from '../../../reducers'; import { SEARCH_RESULT_PAGE_SEARCH_NAME } from '../../../constants/searchNames'; import { useConfig } from '../../config/ConfigProvider'; import styles from '../../../../styles/cspace-ui/SearchTable.css'; import SearchResultTableRow from './SearchResultTableRow'; import { getListTypeFromResult } from '../../../helpers/searchHelpers'; const propTypes = { searchDescriptor: PropTypes.instanceOf(Immutable.Map), intl: PropTypes.object, }; const messages = defineMessages({ selectHeader: { id: 'searchTable.selectHeaderAll', description: 'Label for select table header', defaultMessage: 'Selected', }, }); function getSortDir(searchDescriptor) { const searchQuery = searchDescriptor.get('searchQuery'); const sortSpec = searchQuery.get('sort'); let sortDir; let sortColumnName; if (sortSpec) { [sortColumnName, sortDir] = sortSpec.split(' '); if (!sortDir) { sortDir = 'asc'; } } return { sortColumnName, sortDir }; } /** * Displays search results as a table. This uses the search descriptor to get the * record type in order to read the configuration for what headers and fields need * to be displayed. * * Once complete this should replace the older SearchResultTable component * * todo: parity with other search result table * - aria-labels + general wcag compliance * - figure out hrefs * - ??? */ function SearchResultTable({ searchDescriptor, intl }) { const config = useConfig(); const results = useSelector((state) => getSearchResult(state, SEARCH_RESULT_PAGE_SEARCH_NAME, searchDescriptor)); const selectedItems = useSelector((state) => getSearchSelectedItems(state, SEARCH_RESULT_PAGE_SEARCH_NAME)); const listType = getListTypeFromResult(config, results); const { list, items, } = readListItems(config, listType, results); if (!items) { return null; } // Might move this into the SearchResultTableHeader const { sortColumnName, sortDir, } = getSortDir(searchDescriptor); // read headers const columnConfig = getColumnConfig(config, searchDescriptor, 'default'); // todo: dataKey is for ucb support. basically it allows multiple fields to be used // in the event one is missing. See cspace-ui-plugin-profile-pahma.js const columns = Object.keys(columnConfig) .filter((name) => !columnConfig[name].disabled) .sort((nameA, nameB) => { const orderA = columnConfig[nameA].order; const orderB = columnConfig[nameB].order; return orderA - orderB; }).map((name) => { const column = columnConfig[name]; return { dataKey: column.dataKey || name, formatValue: (data) => { if (column.formatValue) { const formatterContext = { intl, config, data, }; return column.formatValue(data, formatterContext); } return data; }, label: () => { const message = get(column, ['messages', 'label']); return message ? intl.formatMessage(message) : ''; }, }; }); const renderContext = { listType, searchDescriptor, selectedItems, columns, }; const totalItems = parseInt(list.get('totalItems'), 10); const selectLabel = intl.formatMessage(messages.selectHeader); // todo: showCheckbox prop return ( <div className={styles.results}> <table> <thead> <tr> {/* eslint-disable-next-line jsx-a11y/control-has-associated-label */} <th className={styles.checkbox} aria-label={selectLabel} /> {columns.map((column) => (sortColumnName === column.dataKey ? <SearchResultTableHeader key={column.dataKey} column={column} sort={sortDir} /> : <SearchResultTableHeader key={column.dataKey} column={column} /> ))} </tr> </thead> <tbody> {items.map((item, index) => ( <SearchResultTableRow key={item.get('csid')} item={item} index={index} totalItems={totalItems} renderContext={renderContext} /> ))} </tbody> </table> </div> ); } SearchResultTable.propTypes = propTypes; export default injectIntl(SearchResultTable);