Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
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
4 changes: 4 additions & 0 deletions projects/packages/search/changelog/jps3-search-suggestions
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
Significance: minor
Type: added

Add auto-complete search suggestions feature
1 change: 1 addition & 0 deletions projects/packages/search/src/class-helper.php
Original file line number Diff line number Diff line change
Expand Up @@ -902,7 +902,7 @@
$is_jetpack_photon_enabled = method_exists( 'Jetpack', 'is_module_active' ) && Jetpack::is_module_active( 'photon' );

$options = array(
'overlayOptions' => array(

Check warning on line 905 in projects/packages/search/src/class-helper.php

View workflow job for this annotation

GitHub Actions / PHP Code Sniffer (non-excluded files only)

Array double arrow not aligned correctly; expected 15 space(s) between "'overlayOptions'" and double arrow, but found 14. (WordPress.Arrays.MultipleStatementAlignment.DoubleArrowNotAligned)
'colorTheme' => get_option( $prefix . 'color_theme', 'light' ),
'enableInfScroll' => get_option( $prefix . 'inf_scroll', '1' ) === '1',
'enableFilteringOpensOverlay' => get_option( $prefix . 'filtering_opens_overlay', '1' ) === '1',
Expand All @@ -924,14 +924,15 @@
),

// core config.
'homeUrl' => home_url(),

Check warning on line 927 in projects/packages/search/src/class-helper.php

View workflow job for this annotation

GitHub Actions / PHP Code Sniffer (non-excluded files only)

Array double arrow not aligned correctly; expected 22 space(s) between "'homeUrl'" and double arrow, but found 21. (WordPress.Arrays.MultipleStatementAlignment.DoubleArrowNotAligned)
'locale' => str_replace( '_', '-', self::is_valid_locale( get_locale() ) ? get_locale() : 'en_US' ),

Check warning on line 928 in projects/packages/search/src/class-helper.php

View workflow job for this annotation

GitHub Actions / PHP Code Sniffer (non-excluded files only)

Array double arrow not aligned correctly; expected 23 space(s) between "'locale'" and double arrow, but found 22. (WordPress.Arrays.MultipleStatementAlignment.DoubleArrowNotAligned)
'postsPerPage' => $posts_per_page,

Check warning on line 929 in projects/packages/search/src/class-helper.php

View workflow job for this annotation

GitHub Actions / PHP Code Sniffer (non-excluded files only)

Array double arrow not aligned correctly; expected 17 space(s) between "'postsPerPage'" and double arrow, but found 16. (WordPress.Arrays.MultipleStatementAlignment.DoubleArrowNotAligned)
'siteId' => self::get_wpcom_site_id(),

Check warning on line 930 in projects/packages/search/src/class-helper.php

View workflow job for this annotation

GitHub Actions / PHP Code Sniffer (non-excluded files only)

Array double arrow not aligned correctly; expected 23 space(s) between "'siteId'" and double arrow, but found 22. (WordPress.Arrays.MultipleStatementAlignment.DoubleArrowNotAligned)
'searchSuggestionsEnabled' => (bool) get_option( 'jetpack_search_suggestions_enabled', false ),

Check warning on line 931 in projects/packages/search/src/class-helper.php

View workflow job for this annotation

GitHub Actions / PHP Code Sniffer (non-excluded files only)

Array double arrow not aligned correctly; expected 1 space(s) between "'searchSuggestionsEnabled'" and double arrow, but found 4. (WordPress.Arrays.MultipleStatementAlignment.DoubleArrowNotAligned)

Check failure on line 931 in projects/packages/search/src/class-helper.php

View workflow job for this annotation

GitHub Actions / PHP Code Sniffer (non-excluded files only)

Array item not aligned correctly; expected 12 spaces but found 16 (WordPress.Arrays.ArrayIndentation.ItemNotAligned)
'postTypes' => $post_type_labels,

Check warning on line 932 in projects/packages/search/src/class-helper.php

View workflow job for this annotation

GitHub Actions / PHP Code Sniffer (non-excluded files only)

Array double arrow not aligned correctly; expected 20 space(s) between "'postTypes'" and double arrow, but found 19. (WordPress.Arrays.MultipleStatementAlignment.DoubleArrowNotAligned)
'webpackPublicPath' => plugins_url( '/build/instant-search/', __DIR__ ),

Check warning on line 933 in projects/packages/search/src/class-helper.php

View workflow job for this annotation

GitHub Actions / PHP Code Sniffer (non-excluded files only)

Array double arrow not aligned correctly; expected 12 space(s) between "'webpackPublicPath'" and double arrow, but found 11. (WordPress.Arrays.MultipleStatementAlignment.DoubleArrowNotAligned)
'isPhotonEnabled' => ( $is_wpcom || $is_jetpack_photon_enabled ) && ! $is_private_site,

Check warning on line 934 in projects/packages/search/src/class-helper.php

View workflow job for this annotation

GitHub Actions / PHP Code Sniffer (non-excluded files only)

Array double arrow not aligned correctly; expected 14 space(s) between "'isPhotonEnabled'" and double arrow, but found 13. (WordPress.Arrays.MultipleStatementAlignment.DoubleArrowNotAligned)
'isFreePlan' => ( new Plan() )->is_free_plan(),

Check warning on line 935 in projects/packages/search/src/class-helper.php

View workflow job for this annotation

GitHub Actions / PHP Code Sniffer (non-excluded files only)

Array double arrow not aligned correctly; expected 19 space(s) between "'isFreePlan'" and double arrow, but found 18. (WordPress.Arrays.MultipleStatementAlignment.DoubleArrowNotAligned)

// config values related to private site support.
'apiRoot' => esc_url_raw( rest_url() ),
Expand Down
15 changes: 13 additions & 2 deletions projects/packages/search/src/class-rest-controller.php
Original file line number Diff line number Diff line change
Expand Up @@ -246,8 +246,9 @@ public function update_settings( $request ) {
$module_active = isset( $request_body['module_active'] ) ? (bool) $request_body['module_active'] : null;
$instant_search_enabled = isset( $request_body['instant_search_enabled'] ) ? (bool) $request_body['instant_search_enabled'] : null;
$swap_classic_to_inline_search = isset( $request_body['swap_classic_to_inline_search'] ) ? (bool) $request_body['swap_classic_to_inline_search'] : null;
$search_suggestions_enabled = isset( $request_body['search_suggestions_enabled'] ) ? (bool) $request_body['search_suggestions_enabled'] : null;

$error = $this->validate_search_settings( $module_active, $instant_search_enabled, $swap_classic_to_inline_search );
$error = $this->validate_search_settings( $module_active, $instant_search_enabled, $swap_classic_to_inline_search, $search_suggestions_enabled );

if ( is_wp_error( $error ) ) {
return $error;
Expand Down Expand Up @@ -277,6 +278,10 @@ public function update_settings( $request ) {
$this->search_module->update_swap_classic_to_inline_search( $swap_classic_to_inline_search );
}

if ( $search_suggestions_enabled !== null ) {
update_option( 'jetpack_search_suggestions_enabled', $search_suggestions_enabled );
}

if ( ! empty( $errors ) ) {
return new WP_Error(
'some_updated',
Expand All @@ -301,12 +306,17 @@ public function update_settings( $request ) {
* @param boolean $module_active - Module status.
* @param boolean $instant_search_enabled - Instant Search status.
* @param boolean $swap_classic_to_inline_search - New inline search status.
* @param boolean $search_suggestions_enabled - New search suggestions status.
*/
protected function validate_search_settings( $module_active, $instant_search_enabled, $swap_classic_to_inline_search ) {
protected function validate_search_settings( $module_active, $instant_search_enabled, $swap_classic_to_inline_search, $search_suggestions_enabled = null ) {
if ( $module_active === null && $instant_search_enabled === null && $swap_classic_to_inline_search !== null ) {
// allow updating 'swap_classic_to_inline_search' without updating/validating other settings.
return true;
}
if ( $module_active === null && $instant_search_enabled === null && $swap_classic_to_inline_search === null && $search_suggestions_enabled !== null ) {
// allow updating 'search_suggestions_enabled' without updating/validating other settings.
return true;
}
if ( ( true === $instant_search_enabled && false === $module_active ) || ( $module_active === null && $instant_search_enabled === null ) ) {
return new WP_Error(
'rest_invalid_arguments',
Expand All @@ -326,6 +336,7 @@ public function get_settings() {
'module_active' => $this->search_module->is_active(),
'instant_search_enabled' => $this->search_module->is_instant_search_enabled(),
'swap_classic_to_inline_search' => $this->search_module->is_swap_classic_to_inline_search(),
'search_suggestions_enabled' => (bool) get_option( 'jetpack_search_suggestions_enabled', false ),
)
);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ const WIDGETS_EDITOR_URL = 'widgets.php';
* @param {boolean} props.supportsInstantSearch - true if site has plan that supports Instant Search.
* @param {boolean} props.isTogglingModule - true if toggling Search module.
* @param {boolean} props.isTogglingInstantSearch - true if toggling Instant Search option.
* @param {boolean} props.isSearchSuggestionsEnabled - true if search suggestions (autocomplete) is enabled.
* @return {import('react').Component} Search settings component.
*/
export default function SearchModuleControl( {
Expand All @@ -59,6 +60,7 @@ export default function SearchModuleControl( {
supportsInstantSearch,
isTogglingModule,
isTogglingInstantSearch,
isSearchSuggestionsEnabled,
} ) {
const { isUserConnected } = useConnection( {
redirectUri: 'admin.php?page=jetpack-search',
Expand Down Expand Up @@ -108,6 +110,15 @@ export default function SearchModuleControl( {
analytics.tracks.recordEvent( 'jetpack_search_instant_toggle', newOption );
}, [ supportsInstantSearch, isInstantSearchEnabled, updateOptions, isDisabledFromOverLimit ] );

const toggleSearchSuggestions = useCallback( () => {
if ( isDisabledFromOverLimit ) {
return;
}
const newOption = { search_suggestions_enabled: ! isSearchSuggestionsEnabled };
updateOptions( newOption );
analytics.tracks.recordEvent( 'jetpack_search_suggestions_toggle', newOption );
}, [ isSearchSuggestionsEnabled, updateOptions, isDisabledFromOverLimit ] );

return (
<div
className={ clsx( {
Expand Down Expand Up @@ -143,6 +154,16 @@ export default function SearchModuleControl( {
upgradeUrl={ upgradeUrl }
isDisabledFromOverLimit={ isDisabledFromOverLimit }
/>

{ supportsInstantSearch && isInstantSearchEnabled && (
<SearchSuggestionsToggle
isSearchSuggestionsEnabled={ isSearchSuggestionsEnabled }
isInstantSearchEnabled={ isInstantSearchEnabled }
isSavingEitherOption={ isSavingEitherOption }
isDisabledFromOverLimit={ isDisabledFromOverLimit }
toggleSearchSuggestions={ toggleSearchSuggestions }
/>
) }
</div>
</Card>
</div>
Expand Down Expand Up @@ -297,3 +318,39 @@ const SearchToggle = ( {
</div>
);
};

const SearchSuggestionsToggle = ( {
isSearchSuggestionsEnabled,
isInstantSearchEnabled,
isSavingEitherOption,
isDisabledFromOverLimit,
toggleSearchSuggestions,
} ) => {
const isToggleDisabled =
isSavingEitherOption || ! isInstantSearchEnabled || isDisabledFromOverLimit;

return (
<div className="jp-form-search-settings-group__toggle is-search-suggestions jp-search-dashboard-wrap">
<div className="jp-search-dashboard-row">
<ToggleControl
checked={ !! isSearchSuggestionsEnabled && ! isDisabledFromOverLimit }
disabled={ isToggleDisabled }
onChange={ toggleSearchSuggestions }
className="jp-search-dashboard-toggle lg-col-span-12 md-col-span-8 sm-col-span-4"
label={ __( 'Enable search suggestions', 'jetpack-search-pkg' ) }
__nextHasNoMarginBottom={ true }
/>
</div>
<div className="jp-search-dashboard-row">
<div className="jp-form-search-settings-group__toggle-description lg-col-span-7 md-col-span-5 sm-col-span-4">
<p className="jp-form-search-settings-group__toggle-explanation">
{ __(
'Show autocomplete query suggestions as visitors type, instead of updating search results on every keystroke.',
'jetpack-search-pkg'
) }
</p>
</div>
</div>
</div>
);
};
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,9 @@ export default function DashboardPage( { isLoading = false } ) {
const isTogglingInstantSearch = useSelect( select =>
select( STORE_ID ).isTogglingInstantSearch()
);
const isSearchSuggestionsEnabled = useSelect( select =>
select( STORE_ID ).isSearchSuggestionsEnabled()
);

// Record Meter data
const tierMaximumRecords = useSelect( select => select( STORE_ID ).getTierMaximumRecords() );
Expand Down Expand Up @@ -182,6 +185,7 @@ export default function DashboardPage( { isLoading = false } ) {
isSavingEitherOption={ isSavingEitherOption }
isTogglingModule={ isTogglingModule }
isTogglingInstantSearch={ isTogglingInstantSearch }
isSearchSuggestionsEnabled={ isSearchSuggestionsEnabled }
/>
</div>
<NoticesList
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,10 @@
} catch {
const oldSettings = Object.fromEntries(
Object.entries( select( STORE_ID ).getSearchModuleStatus() ).filter(
( [ k ] ) => k === 'module_active' || k === 'instant_search_enabled'
( [ k ] ) =>
k === 'module_active' ||

Check failure on line 38 in projects/packages/search/src/dashboard/store/actions/jetpack-settings.js

View workflow job for this annotation

GitHub Actions / ESLint (non-excluded files only)

Insert `↹`
k === 'instant_search_enabled' ||

Check failure on line 39 in projects/packages/search/src/dashboard/store/actions/jetpack-settings.js

View workflow job for this annotation

GitHub Actions / ESLint (non-excluded files only)

Insert `↹`
k === 'search_suggestions_enabled'

Check failure on line 40 in projects/packages/search/src/dashboard/store/actions/jetpack-settings.js

View workflow job for this annotation

GitHub Actions / ESLint (non-excluded files only)

Insert `↹`
)
);
yield setJetpackSettings( oldSettings );
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ const jetpackSettingSelectors = {
getSearchModuleStatus: state => state.jetpackSettings,
isModuleEnabled: state => state.jetpackSettings.module_active,
isInstantSearchEnabled: state => state.jetpackSettings.instant_search_enabled,
isSearchSuggestionsEnabled: state => !! state.jetpackSettings.search_suggestions_enabled,
isUpdatingJetpackSettings: state => state.jetpackSettings.is_updating,
isTogglingModule: state => state.jetpackSettings.is_toggling_module,
isTogglingInstantSearch: state => state.jetpackSettings.is_toggling_instant_search,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -311,6 +311,8 @@ class SearchApp extends Component {
enableFallbackImage={ this.state.overlayOptions.enableFallbackImage }
fallbackImageUrl={ this.state.overlayOptions.fallbackImageUrl }
showProductPrice={ this.state.overlayOptions.enableProductPrice }
suggestionsEnabled={ !! this.props.options.searchSuggestionsEnabled }
siteId={ this.props.options.siteId }
/>
</Overlay>,
document.body
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@ const SearchBox = forwardRef( ( props, ref ) => {
// IE11 will immediately fire an onChange event when the placeholder contains a unicode character.
// Ensure that the search application is visible before invoking the onChange callback to guard against this.
onChange={ props.isVisible ? props.onChange : null }
onKeyDown={ props.onKeyDown }
onBlur={ props.onBlur }
ref={ inputRef }
placeholder={ __( 'Search…', 'jetpack-search-pkg' ) }
type="search"
Expand Down
Loading
Loading