diff --git a/__tests__/src/components/SearchResults.test.js b/__tests__/src/components/SearchResults.test.js index 400081c25c37bd8d6b21217b4305efcebaa3d018..dcb477f8393f656011c8ff26066e40bbea56b03f 100644 --- a/__tests__/src/components/SearchResults.test.js +++ b/__tests__/src/components/SearchResults.test.js @@ -20,6 +20,7 @@ function createWrapper(props) { match: 'moose', }, ]} + startIndex={10} {...props} />, ); @@ -30,7 +31,7 @@ describe('SearchResults', () => { const selectContentSearchAnnotation = jest.fn(); const wrapper = createWrapper({ selectContentSearchAnnotation }); expect(wrapper.find('Connect(WithStyles(WithPlugins(SearchHit)))').length).toEqual(1); - expect(wrapper.find('Connect(WithStyles(WithPlugins(SearchHit)))').prop('index')).toEqual(0); + expect(wrapper.find('Connect(WithStyles(WithPlugins(SearchHit)))').prop('index')).toEqual(10); }); it('can focus on a single item', () => { diff --git a/__tests__/src/selectors/searches.test.js b/__tests__/src/selectors/searches.test.js index 3e5fdde0cc3b07c1470fc1ed258a776b4a4a4651..c9b10342eb2ed1b823f77ef85781e45316b1d825 100644 --- a/__tests__/src/selectors/searches.test.js +++ b/__tests__/src/selectors/searches.test.js @@ -5,6 +5,7 @@ import { getSelectedContentSearchAnnotationIds, getSelectedContentSearchAnnotations, getSearchAnnotationsForCompanionWindow, + getSearchForCompanionWindow, } from '../../../src/state/selectors'; describe('getSearchResultsForWindow', () => { @@ -36,6 +37,36 @@ describe('getSearchResultsForWindow', () => { }); }); +describe('getSearchForCompanionWindow', () => { + const companionWindowId = 'cwid'; + it('returns the search data for a completed search', () => { + const state = { + searches: { + a: { + [companionWindowId]: { + json: { hits: [1, 2, 3] }, + }, + }, + b: { + [companionWindowId]: { + isFetching: true, + json: { }, + }, + }, + }, + }; + expect( + getSearchForCompanionWindow(state, { companionWindowId, windowId: 'a' }), + ).toEqual({ hits: [1, 2, 3] }); + expect( + getSearchForCompanionWindow(state, { companionWindowId, windowId: 'b' }), + ).toEqual({}); + expect( + getSearchForCompanionWindow({}, { companionWindowId, windowId: 'a' }), + ).toEqual({}); + }); +}); + describe('getSearchHitsForCompanionWindow', () => { const companionWindowId = 'cwid'; it('returns flattened hits for a manifest', () => { diff --git a/src/components/SearchPanelNavigation.js b/src/components/SearchPanelNavigation.js index 6b01ee592c767370273cd7cfa80c96230931e08e..17dd409f49e0e3f7ce12cfb4103ab6551ef1fec5 100644 --- a/src/components/SearchPanelNavigation.js +++ b/src/components/SearchPanelNavigation.js @@ -42,9 +42,9 @@ export class SearchPanelNavigation extends Component { */ render() { const { - searchHits, selectedContentSearchAnnotation, classes, t, + searchHits, selectedContentSearchAnnotation, classes, t, startIndex, } = this.props; - const currentHitIndex = searchHits + const currentHitIndex = startIndex + searchHits .findIndex(val => val.annotations.includes(selectedContentSearchAnnotation[0])); return ( <> @@ -79,11 +79,13 @@ SearchPanelNavigation.propTypes = { }).isRequired, selectContentSearchAnnotation: PropTypes.func.isRequired, selectedContentSearchAnnotation: PropTypes.arrayOf(PropTypes.string).isRequired, + startIndex: PropTypes.number, t: PropTypes.func, windowId: PropTypes.string.isRequired, }; SearchPanelNavigation.defaultProps = { classes: {}, searchHits: [], + startIndex: 0, t: key => key, }; diff --git a/src/components/SearchResults.js b/src/components/SearchResults.js index 6827d0f70940551f8b6790534d25215fc2cec1dc..b205642db4636f932e234eefce6aecf670e84824 100644 --- a/src/components/SearchResults.js +++ b/src/components/SearchResults.js @@ -30,6 +30,7 @@ export class SearchResults extends Component { const { classes, searchHits, + startIndex, t, windowId, } = this.props; @@ -53,7 +54,7 @@ export class SearchResults extends Component { key={hit.annotations[0]} focused={focused} hit={hit} - index={index} + index={startIndex + index} windowId={windowId} showDetails={this.toggleFocus} /> @@ -68,11 +69,13 @@ export class SearchResults extends Component { SearchResults.propTypes = { classes: PropTypes.objectOf(PropTypes.string), searchHits: PropTypes.arrayOf(PropTypes.object).isRequired, + startIndex: PropTypes.number, t: PropTypes.func, windowId: PropTypes.string.isRequired, // eslint-disable-line react/no-unused-prop-types }; SearchResults.defaultProps = { classes: {}, + startIndex: 0, t: k => k, }; diff --git a/src/containers/SearchPanelNavigation.js b/src/containers/SearchPanelNavigation.js index d806158df53db84ee459d5eadb10958e3e69fef4..6515d6c1e8f4ca69f1a24584f1dbd82381dadcdb 100644 --- a/src/containers/SearchPanelNavigation.js +++ b/src/containers/SearchPanelNavigation.js @@ -8,6 +8,7 @@ import * as actions from '../state/actions'; import { getSearchHitsForCompanionWindow, getSelectedContentSearchAnnotationIds, + getSearchForCompanionWindow, } from '../state/selectors'; /** @@ -18,6 +19,7 @@ import { const mapStateToProps = (state, { companionWindowId, windowId }) => ({ searchHits: getSearchHitsForCompanionWindow(state, { companionWindowId, windowId }), selectedContentSearchAnnotation: getSelectedContentSearchAnnotationIds(state, { windowId }), + startIndex: getSearchForCompanionWindow(state, { companionWindowId, windowId }).startIndex, }); /** diff --git a/src/containers/SearchResults.js b/src/containers/SearchResults.js index 0ff45896222a417ea6b39ce589a36fbdce4fb123..68f6dc45815c33c240c7d97b3850001b0492dde2 100644 --- a/src/containers/SearchResults.js +++ b/src/containers/SearchResults.js @@ -8,6 +8,7 @@ import * as actions from '../state/actions'; import { getSearchHitsForCompanionWindow, getSelectedContentSearchAnnotationIds, + getSearchForCompanionWindow, } from '../state/selectors'; /** @@ -18,6 +19,7 @@ import { const mapStateToProps = (state, { companionWindowId, windowId }) => ({ searchHits: getSearchHitsForCompanionWindow(state, { companionWindowId, windowId }), selectedContentSearchAnnotation: getSelectedContentSearchAnnotationIds(state, { windowId }), + startIndex: getSearchForCompanionWindow(state, { companionWindowId, windowId }).startIndex, }); const mapDispatchToProps = { diff --git a/src/state/selectors/searches.js b/src/state/selectors/searches.js index 6ec1836843d60e5aebf80143ea04e69420eac1a1..6ae5062328a81398f36a5e3eda975c933a9d6f4c 100644 --- a/src/state/selectors/searches.js +++ b/src/state/selectors/searches.js @@ -25,20 +25,30 @@ export const getSearchResultsForCompanionWindow = createSelector( }, ); -export const getSearchHitsForCompanionWindow = createSelector( +export const getSearchForCompanionWindow = createSelector( [ getSearchResultsForCompanionWindow, ], (result) => { - if (!result || !result.json || result.isFetching || !result.json.hits) return []; - return result.json.hits; + if (!result || !result.json || result.isFetching) return {}; + return result.json; + }, +); + +export const getSearchHitsForCompanionWindow = createSelector( + [ + getSearchForCompanionWindow, + ], + (result) => { + if (!result.hits) return []; + return result.hits; }, ); /** convert search results to an annotation */ -const searchResultsToAnnotation = (result) => { - if (!result || !result.json || result.isFetching || !result.json.resources) return undefined; - const anno = new Annotation(result.json); +const searchResultsToAnnotation = (json) => { + if (!json.resources) return undefined; + const anno = new Annotation(json); return { id: anno.id, resources: anno.resources, @@ -47,7 +57,7 @@ const searchResultsToAnnotation = (result) => { export const getSearchAnnotationsForCompanionWindow = createSelector( [ - getSearchResultsForCompanionWindow, + getSearchForCompanionWindow, ], result => searchResultsToAnnotation(result), ); @@ -58,7 +68,9 @@ export const getSearchAnnotationsForWindow = createSelector( ], (results) => { if (!results) return []; - const arr = Object.values(results).map(result => searchResultsToAnnotation(result)); + const arr = Object.values(results).map(result => ( + result && result.json && !result.isFetching && searchResultsToAnnotation(result.json) + )); return arr.filter(e => e); }, );