diff --git a/images/collapseWhite.svg b/images/collapseWhite.svg new file mode 100644 index 000000000..fd1997ce4 --- /dev/null +++ b/images/collapseWhite.svg @@ -0,0 +1,3 @@ + + + diff --git a/images/expandWhite.svg b/images/expandWhite.svg new file mode 100644 index 000000000..f0e42c2a5 --- /dev/null +++ b/images/expandWhite.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/actions/search.js b/src/actions/search.js index 4bd1df991..bd23c3201 100644 --- a/src/actions/search.js +++ b/src/actions/search.js @@ -33,6 +33,14 @@ const getSortParam = (config, searchDescriptor, columnSetName) => { return null; } + // prefer the new sort.js config + const sort = get(config, + ['recordTypes', searchDescriptor.get('recordType'), 'sort', sortColumnName]); + + if (sort && sort.sortBy) { + return sort.sortBy + (sortDir ? ' DESC' : ''); + } + const column = get(config, ['recordTypes', searchDescriptor.get('recordType'), 'columns', columnSetName, sortColumnName]); diff --git a/src/components/pages/SearchResultPage.jsx b/src/components/pages/SearchResultPage.jsx index 4c20d5b6a..ab0c4a3e0 100644 --- a/src/components/pages/SearchResultPage.jsx +++ b/src/components/pages/SearchResultPage.jsx @@ -19,6 +19,8 @@ import { createPageSizeChangeHandler, createPageChangeHandler, extractAdvancedSearchGroupedTerms, + createSortByHandler, + createSortDirHandler, } from '../../helpers/searchHelpers'; import { SEARCH_RESULT_PAGE_SEARCH_NAME } from '../../constants/searchNames'; @@ -30,6 +32,7 @@ import styles from '../../../styles/cspace-ui/SearchResultPage.css'; import pageBodyStyles from '../../../styles/cspace-ui/PageBody.css'; import ExportResults from '../search/ExportResults'; import RelateResults from '../search/RelateResults'; +import SortBy from '../search/SortBy'; // const stopPropagation = (event) => { // event.stopPropagation(); @@ -467,6 +470,8 @@ export default class SearchResultPage extends Component { renderHeader({ searchError, searchResult }) { const { + history, + location, selectedItems, setAllItemsSelected, perms, @@ -515,6 +520,23 @@ export default class SearchResultPage extends Component { ); } + const { + search, + } = location; + + const query = qs.parse(search.substring(1)); + const sortChangeHandler = createSortByHandler({ history, location }); + const sortDirChangeHandler = createSortDirHandler({ history, location }); + + const renderSortBy = () => ( + + ); + return (
renderSortBy()} /> {selectBar}
diff --git a/src/components/pages/search/SearchResults.jsx b/src/components/pages/search/SearchResults.jsx index 7c5fc9a3a..eb83a1a41 100644 --- a/src/components/pages/search/SearchResults.jsx +++ b/src/components/pages/search/SearchResults.jsx @@ -13,6 +13,7 @@ import SearchResultGrid from '../../search/grid/SearchResultGrid'; import SearchDetailList from '../../search/list/SearchList'; import SearchResultSidebar from '../../search/SearchResultSidebar'; import SearchResultSummary from '../../search/SearchResultSummary'; +import SortBy from '../../search/SortBy'; import { ToggleButton, ToggleButtonContainer } from '../../search/header/ToggleButtons'; import { useConfig } from '../../config/ConfigProvider'; import styles from '../../../../styles/cspace-ui/SearchResults.css'; @@ -37,6 +38,8 @@ import { getListTypeFromResult, createPageSizeChangeHandler, extractAdvancedSearchGroupedTerms, + createSortByHandler, + createSortDirHandler, } from '../../../helpers/searchHelpers'; import { setSearchPageAdvanced, @@ -276,6 +279,18 @@ export default function SearchResults(props) { }); }; + const handleSortChange = createSortByHandler({ history, location }); + const handleSortDirChange = createSortDirHandler({ history, location }); + + const renderSortBy = () => ( + + ); + const searchResults = useSelector((state) => getSearchResult(state, SEARCH_RESULT_PAGE_SEARCH_NAME, searchDescriptor)); @@ -351,6 +366,7 @@ export default function SearchResults(props) { searchDescriptor={searchDescriptor} onPageSizeChange={handlePageSizeChange} onEditSearchLinkClick={handleEditSearchLinkClick} + renderSortBy={() => renderSortBy()} /> {content} - {pageSizeChooser} +
+ {renderSortBy?.()} + {pageSizeChooser} +
); } diff --git a/src/components/search/SortBy.jsx b/src/components/search/SortBy.jsx new file mode 100644 index 000000000..42bcc0348 --- /dev/null +++ b/src/components/search/SortBy.jsx @@ -0,0 +1,102 @@ +import React from 'react'; +import PropTypes from 'prop-types'; +import { baseComponents as components } from 'cspace-input'; +import { + defineMessages, injectIntl, intlShape, +} from 'react-intl'; + +import { get } from 'lodash'; +import classNames from 'classnames'; +import styles from '../../../styles/cspace-ui/SortBy.css'; +import { useConfig } from '../config/ConfigProvider'; + +const { DropdownMenuInput, Button } = components; + +const messages = defineMessages({ + sortBy: { + id: 'search.sortBy', + defaultMessage: 'Sort By', + }, + ascendingAriaLabel: { + id: 'search.sortDir.ascending.label', + defaultMessage: 'Current sort: ascending', + }, + descendingAriaLabel: { + id: 'search.sortDir.descending.label', + defaultMessage: 'Current sort: descending', + }, +}); + +function SortBy({ + intl, + onSortChange, + onSortDirChange, + recordType, + sort, +}) { + const config = useConfig(); + const sortConfig = get(config, ['recordTypes', recordType, 'sort']) + ?? get(config, ['recordTypes', recordType, 'columns', 'default']); + + if (!sortConfig) { + return null; + } + + const { + defaultSortBy = 'updatedAt', + defaultSortDir = 'desc', + } = sortConfig; + + const options = Object.keys(sortConfig) + .filter((key) => sortConfig[key].sortBy !== undefined) + .map((key) => { + const option = sortConfig[key]; + const label = intl.formatMessage(option.messages.label) ?? key; + + return { + value: key, + label, + }; + }); + + const [sortBy, sortDir] = sort?.split(' ') ?? [defaultSortBy, defaultSortDir]; + const input = ( + onSortChange(value)} + /> + ); + + const sortDirClass = sortDir ? styles.descending : styles.ascending; + const sortDirLabel = sortDir ? intl.formatMessage(messages.descendingAriaLabel) + : intl.formatMessage(messages.ascendingAriaLabel); + const sortDirButton = ( +