Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Did you Mean in Instant Results #3564

Merged
merged 9 commits into from
Aug 8, 2023
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
Add Did you Mean in Instant Result
  • Loading branch information
burhandodhy committed Jul 20, 2023
commit 0d7727c3a154be1e0bf31f5b7fd8c65c7edf0ae8
18 changes: 14 additions & 4 deletions assets/js/api-search/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,7 @@ export const ApiSearchProvider = ({
searchResults: [],
searchedTerm: '',
totalResults: 0,
suggestedTerms: [],
});

/**
Expand All @@ -119,7 +120,7 @@ export const ApiSearchProvider = ({
stateRef.current = state;

/**
* Clear facet contraints.
* Clear facet constraints.
*
* @returns {void}
*/
Expand All @@ -128,7 +129,7 @@ export const ApiSearchProvider = ({
}, []);

/**
* Clear search resu;ts.
* Clear search results.
*
* @returns {void}
*/
Expand Down Expand Up @@ -325,8 +326,16 @@ export const ApiSearchProvider = ({
/**
* Provide state to context.
*/
const { aggregations, args, isLoading, isOn, searchResults, searchTerm, totalResults } =
stateRef.current;
const {
aggregations,
args,
isLoading,
isOn,
searchResults,
searchTerm,
totalResults,
suggestedTerms,
} = stateRef.current;

// eslint-disable-next-line react/jsx-no-constructed-context-values
const contextValue = {
Expand All @@ -347,6 +356,7 @@ export const ApiSearchProvider = ({
previousPage,
totalResults,
turnOff,
suggestedTerms,
};

return <Context.Provider value={contextValue}>{children}</Context.Provider>;
Expand Down
2 changes: 2 additions & 0 deletions assets/js/api-search/src/reducer.js
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ export default (state, action) => {
const {
hits: { hits, total },
aggregations,
suggest,
} = action.response;

/**
Expand All @@ -67,6 +68,7 @@ export default (state, action) => {
newState.searchResults = hits;
newState.searchTerm = newState.args.search;
newState.totalResults = totalNumber;
newState.suggestedTerms = suggest?.ep_suggestion?.[0]?.options || [];

break;
}
Expand Down
3 changes: 2 additions & 1 deletion assets/js/instant-results/components/layout/results.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import { useApiSearch } from '../../../api-search';
import Pagination from '../results/pagination';
import Result from '../results/result';
import Sort from '../tools/sort';
import DidYouMean from '../results/didYouMean';
JakePT marked this conversation as resolved.
Show resolved Hide resolved

/**
* Search results component.
Expand Down Expand Up @@ -75,7 +76,7 @@ export default () => {

<Sort />
</header>

<DidYouMean />
{searchResults.map((hit) => (
<Result key={hit._id} hit={hit} />
))}
Expand Down
55 changes: 55 additions & 0 deletions assets/js/instant-results/components/results/didYouMean.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
/**
* WordPress dependencies.
*/
import { __ } from '@wordpress/i18n';
import { WPElement } from '@wordpress/element';

import { useApiSearch } from '../../../api-search';

/**
* Did you mean component.
*
* @returns {WPElement} Component element.
*/
export default () => {
const { suggestedTerms, searchFor, totalResults } = useApiSearch();

const { isDidYouMean, searchBehavior } = window.epInstantResults;
JakePT marked this conversation as resolved.
Show resolved Hide resolved

const onClick = (term) => {
searchFor(term);
};

// Get other terms by excluding the first term from suggestedTerms
const otherTerms = suggestedTerms.slice(1);

return (
<>
{isDidYouMean && suggestedTerms && suggestedTerms?.[0]?.text && (
<div className="ep-spell-suggestion">
JakePT marked this conversation as resolved.
Show resolved Hide resolved
{__('Did you Mean: ', 'elasticpress')}
JakePT marked this conversation as resolved.
Show resolved Hide resolved
JakePT marked this conversation as resolved.
Show resolved Hide resolved
{/* eslint-disable-next-line jsx-a11y/anchor-is-valid */}
<a onClick={() => onClick(suggestedTerms?.[0]?.text)} href="#">
{suggestedTerms?.[0]?.text}
</a>
</div>
)}

{searchBehavior === 'list' && totalResults === 0 && otherTerms.length > 0 && (
JakePT marked this conversation as resolved.
Show resolved Hide resolved
<>
<p>{__('Other suggestions', 'elasticpress')}</p>
<ul>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we put these inside the wrapper <div>, for easier styling?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@burhandodhy Sorry, here I meant that these elements should go inside the ep-search-suggestion div above. So that all the suggestion stuff is inside that div.

{otherTerms.map((term) => (
<li key={term.text}>
{/* eslint-disable-next-line jsx-a11y/anchor-is-valid */}
<a href="#" onClick={() => onClick(term.text)}>
{term.text}
</a>
</li>
))}
</ul>
</>
)}
</>
);
};
6 changes: 5 additions & 1 deletion includes/classes/Feature/InstantResults/InstantResults.php
Original file line number Diff line number Diff line change
Expand Up @@ -301,6 +301,8 @@ public function enqueue_frontend_assets() {
*/
$api_endpoint = apply_filters( 'ep_instant_results_search_endpoint', "api/v1/search/posts/{$this->index}", $this->index );

$did_you_mean_settings = \ElasticPress\Features::factory()->get_registered_feature( 'did-you-mean' )->get_settings();

wp_localize_script(
'elasticpress-instant-results',
'epInstantResults',
Expand All @@ -318,6 +320,8 @@ public function enqueue_frontend_assets() {
'postTypeLabels' => $this->get_post_type_labels(),
'termCount' => $this->settings['term_count'],
'requestIdBase' => Utils\get_request_id_base(),
'isDidYouMean' => $did_you_mean_settings['active'],
JakePT marked this conversation as resolved.
Show resolved Hide resolved
'searchBehavior' => $did_you_mean_settings['search_behavior'],
JakePT marked this conversation as resolved.
Show resolved Hide resolved
)
);
}
Expand Down Expand Up @@ -952,7 +956,7 @@ public function get_facets_for_admin() {
*/
public function get_args_schema() {
/**
* The number of resutls per page for Instant Results.
* The number of results per page for Instant Results.
*
* @since 4.5.0
* @hook ep_instant_results_per_page
Expand Down