Skip to content

Commit

Permalink
Implement infinite scrolling for document search (#3855)
Browse files Browse the repository at this point in the history
* Split up render method in PdfViewerSearch

This is just a small refactoring to make it easier to adjust this method.

* Rename fetchPage to fetchSearchResults

… because that is what it actually does -- it doesn’t load a page from the document, it loads a list of pages that contain the search terms.

* Implement infinite scrolling for document search results

Fixes #3320

* Remove useless code

I’m not sure what exactly the intention here was originally, but it didn’t have any effect in its current version. `page` and `res.index` would always be undefined and as a result, the `active` class was applied to every single link. The `active` class doesn’t apply any styles.

Probably this is just leftover from a previous iteration of the UI, so I’ve removed this.
  • Loading branch information
tillprochaska authored Oct 16, 2024
1 parent 11cc0d4 commit 4adad5f
Showing 1 changed file with 42 additions and 26 deletions.
68 changes: 42 additions & 26 deletions ui/src/viewers/PdfViewerSearch.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,11 @@ import { FormattedMessage } from 'react-intl';
import classNames from 'classnames';
import { connect } from 'react-redux';
import queryString from 'query-string';
import { SectionLoading, SearchHighlight } from 'components/common';
import {
SectionLoading,
SearchHighlight,
QueryInfiniteLoad,
} from 'components/common';
import { Classes } from '@blueprintjs/core';
import c from 'classnames';
import { queryEntities } from 'actions';
Expand All @@ -17,13 +21,13 @@ class PdfViewerSearch extends Component {
}

componentDidMount() {
this.fetchPage();
this.fetchSearchResults();
}

componentDidUpdate(prevProps) {
const { query } = this.props;
if (!query.sameAs(prevProps.query)) {
this.fetchPage();
this.fetchSearchResults();
}
}

Expand All @@ -40,47 +44,37 @@ class PdfViewerSearch extends Component {
return `#${queryString.stringify(hashQuery)}`;
}

fetchPage() {
fetchSearchResults() {
const { query, result } = this.props;
if (!!query.getString('q') && result.shouldLoad) {
this.props.queryEntities({ query });
}
}

render() {
const { page, dir, result } = this.props;
const { result } = this.props;

if (result.total === undefined) {
return <SectionLoading />;
}

return (
<div className="pages">
{result.total === 0 && (
<>
<div
className={c(
Classes.CALLOUT,
Classes.INTENT_WARNING,
`${Classes.ICON}-search`
)}
>
<FormattedMessage
id="document.search.no_match"
defaultMessage="No single page within this document matches all your search terms."
/>
</div>
{this.props.children}
</>
)}
{result.total === 0 ? this.renderEmptyState() : this.renderResults()}
</div>
);
}

renderResults() {
const { dir, result, query } = this.props;

return (
<>
<ul>
{result.results.map((res) => (
<li key={`page-${res.id}`}>
<p dir={dir}>
<Link
to={this.getResultLink(res)}
className={classNames({ active: page === res.index })}
>
<Link to={this.getResultLink(res)}>
<span
className={c(Classes.ICON, `${Classes.ICON}-document`)}
/>
Expand All @@ -97,6 +91,28 @@ class PdfViewerSearch extends Component {
</li>
))}
</ul>
<QueryInfiniteLoad
query={query}
result={result}
fetch={queryEntities}
/>
</>
);
}

renderEmptyState() {
return (
<div
className={c(
Classes.CALLOUT,
Classes.INTENT_WARNING,
`${Classes.ICON}-search`
)}
>
<FormattedMessage
id="document.search.no_match"
defaultMessage="No single page within this document matches all your search terms."
/>
</div>
);
}
Expand Down

0 comments on commit 4adad5f

Please sign in to comment.