diff --git a/server/webdriver/shared_tests/place_explorer_test.py b/server/webdriver/shared_tests/place_explorer_test.py index c32c276624..e7d7dd5ab9 100644 --- a/server/webdriver/shared_tests/place_explorer_test.py +++ b/server/webdriver/shared_tests/place_explorer_test.py @@ -180,10 +180,16 @@ def test_explorer_redirect_place_explorer(self): # Assert 200 HTTP code: successful page load. self.assertEqual(shared.safe_url_open(self.driver.current_url), 200) - # Assert page title is correct. + # Assert page title is correct, and that the query string is set in the url. WebDriverWait(self.driver, self.TIMEOUT_SEC).until( EC.title_contains('United States of America')) - self.assertTrue("place/country/USA" in self.driver.current_url) + self.assertTrue("place/country/USA?q=United%20States%20Of%20America" in + self.driver.current_url) + + # Ensure the query string is set in the NL Search Bar. + search_bar = self.driver.find_element(By.ID, "query-search-input") + self.assertEqual(search_bar.get_attribute("value"), + "United States Of America") def test_ranking_chart_present(self): """Test basic ranking chart.""" diff --git a/static/js/apps/base/components/header_bar/header_bar_search.tsx b/static/js/apps/base/components/header_bar/header_bar_search.tsx index e6b1ef35b0..db0d87363c 100644 --- a/static/js/apps/base/components/header_bar/header_bar_search.tsx +++ b/static/js/apps/base/components/header_bar/header_bar_search.tsx @@ -40,6 +40,9 @@ interface HeaderBarSearchProps { gaValueSearchSource?: string; } +// The search query param name. Used to pre-populate the search bar. +const QUERY_PARAM = "q"; + const HeaderBarSearch = ({ inputId = "query-search-input", searchBarHashMode, @@ -47,6 +50,14 @@ const HeaderBarSearch = ({ }: HeaderBarSearchProps): ReactElement => { const { queryString, placeholder, queryResult, debugData } = useQueryStore(); + // Get the query string from the url params. + const urlParams = new URLSearchParams(window.location.search); + const urlQuery = urlParams.get(QUERY_PARAM) || ""; + + // If the search bar is in hash mode, use the query string from the url params. + // Otherwise, use the query string from the query store. + const initialValue = searchBarHashMode ? queryString : urlQuery; + return (
diff --git a/static/js/apps/explore/app.tsx b/static/js/apps/explore/app.tsx index 1d51e89b7c..0b4384ef20 100644 --- a/static/js/apps/explore/app.tsx +++ b/static/js/apps/explore/app.tsx @@ -196,7 +196,18 @@ export function App(props: AppProps): ReactElement { return hasPlace || fulfillData["entities"]; } - function processFulfillData(fulfillData: any, shouldSetQuery: boolean): void { + /** + * Process the fulfill data from the search API response. + * + * This processes the fulfill data by setting up page metadata, debug data, and user + * messages for rendering the explore page. However, if the fulfill response only + * contains place information, a page overview configuration, but no charts, it will + * redirect to /place/{placeDcid} instead. + * + * @param fulfillData The fulfill data from the search API response + * @param userQuery The user's search query + */ + function processFulfillData(fulfillData: any, userQuery?: string): void { setDebugData(fulfillData["debug"]); setStoreDebugData(fulfillData["debug"]); const userMessage = { @@ -238,7 +249,8 @@ export function App(props: AppProps): ReactElement { isPendingRedirect = shouldSkipPlaceOverview(pageMetadata); if (isPendingRedirect) { const placeDcid = pageMetadata.place.dcid; - const url = `/place/${placeDcid}`; + // If the user has a query, append it to the url + const url = `/place/${placeDcid}${userQuery ? `?q=${userQuery}` : ""}`; window.location.replace(url); } // Note: for category links, we only use the main-topic. @@ -253,7 +265,7 @@ export function App(props: AppProps): ReactElement { } } if ( - shouldSetQuery && + !userQuery && !_.isEmpty(pageMetadata.mainTopics) && pageMetadata.place.name ) { @@ -347,7 +359,7 @@ export function App(props: AppProps): ReactElement { includeStopWords ) .then((resp) => { - processFulfillData(resp, false); + processFulfillData(resp, query); }) .catch(() => { setLoadingStatus(LoadingStatus.FAILED); @@ -371,7 +383,7 @@ export function App(props: AppProps): ReactElement { client ) .then((resp) => { - processFulfillData(resp, true); + processFulfillData(resp); }) .catch(() => { setLoadingStatus(LoadingStatus.FAILED);