issue-43: MiniSearchUI can now be integrated with "external" results and components#44
issue-43: MiniSearchUI can now be integrated with "external" results and components#44brandon-bogan wants to merge 12 commits intoattivio:masterfrom
Conversation
… search functions
src/components/MiniSearchUI.js
Outdated
| * Optional callback to handle searching if not using the context's | ||
| * Searcher component to do the searching (otherwise the searcher's onSearch method is used). | ||
| */ | ||
| onSearch: null | (q: string) => void; |
There was a problem hiding this comment.
Indicate this is optional: onSearch?: null | (q: string) => void;
The difference between
A: onSearch: null | (q: string) => void; and
B: onSearch?: null | (q: string) => void;
In example A, you are specifying that the user must explicitly pass a prop named onSearch and it may have the value of null or it could be a function like (q: string) => void. Omitting a function is not the same as null. If onSearch was not passed as a prop, it would be undefined.
Same goes for updateQuery, response, and errror.
There was a problem hiding this comment.
Done. Made onSearch, updateQuery, response, and error optional props. I also removed the null option for onSearch and updateQuery and removed these props from the default props, since these should either be valid functions or not exist at all as props.
src/components/MiniSearchUI.js
Outdated
|
|
||
| type MiniSearchUIDefaultProps = { | ||
| scale: number; | ||
| onSearch: null | (q: string) => void; |
There was a problem hiding this comment.
Unlike MiniSearchUIProps, MiniSearchUIDefaultProps is explicitly defined in your component. defaultProps are based on your specifications on lines 60-66 and are not based on what the parent passes through as a prop. Keeping that in mind, onSearch, updateQuery, response, and error, can only be null here.
There was a problem hiding this comment.
Done. Made all defaultProps null, removed onSearch and updateQuery from defaultProps.
src/components/SearchResults.js
Outdated
| showScores: boolean; | ||
| showTags: boolean; | ||
| showRatings: boolean; | ||
| response: QueryResponse | null; |
There was a problem hiding this comment.
As a defaultProp, response in this instance can only be null.
src/components/SearchResults.js
Outdated
| * A response can be passed in from custom searches if you don't want | ||
| * to use the response on the searcher in this.context | ||
| */ | ||
| response: QueryResponse | null; |
There was a problem hiding this comment.
This should be made optional for backwards compatibility.
response?: QueryResponse | null;
src/components/SearchResults.js
Outdated
| */ | ||
| response: QueryResponse | null; | ||
| /** Offset of search results for long scrolling or pagination */ | ||
| offset: number; |
There was a problem hiding this comment.
This should be made optional for backwards compatibility.
offset?: number;
src/components/SearchResults.js
Outdated
| const response = searcher.state.response; | ||
| const offset = searcher.state.resultsOffset; | ||
| const response = this.props.response !== null ? this.props.response : searcher.state.response; | ||
| const offset = this.props.response ? this.props.offset : searcher.state.resultsOffset; |
There was a problem hiding this comment.
Make offset optional for backwards compatibility.
There was a problem hiding this comment.
Changed to:
const offset = this.props.response && this.props.offset ? this.props.offset : searcher.state.resultsOffset;
Is this what you meant?
src/components/SearchResultsCount.js
Outdated
|
|
||
| static displayName = 'SearchResultsCount'; | ||
|
|
||
| render() { |
There was a problem hiding this comment.
Here's an example of a more functional approach. It follows immutable principles so you never modify props. It also cleans up the main render by moving the logic out into a new function.
renderMessage = () => {
const { response, error } = this.props;
const { searcher } = this.context;
const derivedResponse = response ? response : searcher.state.response | null;
let message;
let countMessage;
if (response) {
const { totalHits: count } = response;
if (count === 0 || typeof count !== 'number') {
countMessage = 'No results found';
} else if (count === 1) {
countMessage = '1 result found';
} else {
countMessage = `${count} results found`;
}
return (
<span>
{countMessage}
<span style={{ fontWeight: 'normal' }}>
{' '}
(in {response.totalTime}ms)
</span>
</span>
);
} else if (error) {
return `Error: ${error}`;
} else if (searcher.state.error) {
// got an error...
return `Error: ${searcher.state.error}`;
} else {
// Not yet searched...
return '';
}
}
render() {
return (
<div className="attivio-globalmastnavbar-results">
{this.renderMessage()}
</div>
);
}
There was a problem hiding this comment.
Done. Note that I wrote the 3rd line of renderMessage slightly different to avoid a lint error but otherwise incorporated your code suggestion above.
MiniSearchUI can now take optional props for results to render. These props, in one way or another, are propagated on to SearchResultsCount and SearchResults, and so these components were also updated as part of this new feature.
MiniSearchUI also takes props for functions to call when the user enters a query and/or clicks search, so that the results being passed in can be updated accordingly.