diff --git a/src/redux/actions/search.js b/src/redux/actions/search.js index 6a3c6983f..1bdf6ffe3 100644 --- a/src/redux/actions/search.js +++ b/src/redux/actions/search.js @@ -1,6 +1,7 @@ import { saveSearchToHistory } from '../../components/SearchBar/previousSearchData'; import LinkedEventsAPI from '../../utils/newFetch/LinkedEventsAPI'; import ServiceMapAPI from '../../utils/newFetch/ServiceMapAPI'; +import optionsToSearchQuery from '../../utils/search'; import { getLocaleString } from '../selectors/locale'; import { searchResults } from './fetchDataActions'; import { isEmbed } from '../../utils/path'; @@ -62,13 +63,7 @@ const fetchSearchResults = (options = null) => async (dispatch, getState) => { const searchFetchState = getState().searchResults; const { locale } = getState().user; - const searchQuery = options.q - || options.address - || options.service_node - || options.mobility_node - || options.service_id - || options.id - || options.events; + const searchQuery = optionsToSearchQuery(options); if (searchFetchState.isFetching) { throw Error('Unable to fetch search results because previous fetch is still active'); @@ -99,7 +94,8 @@ const fetchSearchResults = (options = null) => async (dispatch, getState) => { saveSearchToHistory(searchQuery, { object_type: 'searchHistory', text: searchQuery }); } // Handle unit results that have no object_type - if (options.service_node || options.mobility_node || options.service_id || options.id || options.level) { + const keys = ['service_node', 'mobility_node', 'service_id', 'id', 'level']; + if (keys.some(key => !!options[key])) { results.forEach((item) => { item.object_type = 'unit'; }); diff --git a/src/redux/selectors/settings.js b/src/redux/selectors/settings.js index ea035f6df..cdfb15647 100644 --- a/src/redux/selectors/settings.js +++ b/src/redux/selectors/settings.js @@ -1,5 +1,6 @@ import { createSelector } from 'reselect'; import config from '../../../config'; +import { arraysEqual } from '../../utils'; import SettingsUtility from '../../utils/settings'; export const selectSettings = state => state.settings; @@ -7,11 +8,17 @@ export const getCitySettings = state => state.settings.cities; export const selectCities = state => state.settings.cities; export const selectOrganizations = state => state.settings.organizations; +/** + * Returns an array of city ids. + */ export const selectSelectedCities = createSelector( [selectCities], cities => config.cities.filter(c => cities[c]), ); +/** + * Returns an array of organization objects. + */ export const selectSelectedOrganizations = createSelector( [selectOrganizations], organizations => config.organizations?.filter(org => organizations[org.id]), @@ -27,17 +34,7 @@ export const selectSelectedAccessibilitySettings = createSelector( { memoizeOptions: { // Check for equal array content, assume non-nil and sorted arrays - resultEqualityCheck: (a, b) => { - if (a.length !== b.length) { - return false; - } - for (let i = 0; i < a.length; i += 1) { - if (a[i] !== b[i]) { - return false; - } - } - return true; - }, + resultEqualityCheck: (a, b) => arraysEqual(a, b), }, }, ); diff --git a/src/utils/index.js b/src/utils/index.js index 6d3fe469d..74d2b3fa0 100644 --- a/src/utils/index.js +++ b/src/utils/index.js @@ -141,8 +141,7 @@ export const arraysEqual = (a, b) => { if (a == null || b == null) return false; if (a.length !== b.length) return false; - - for (let i = 0; i < a.length; i + 1) { + for (let i = 0; i < a.length; i += 1) { if (a[i] !== b[i]) return false; } return true; diff --git a/src/utils/search.js b/src/utils/search.js new file mode 100644 index 000000000..a54ff1057 --- /dev/null +++ b/src/utils/search.js @@ -0,0 +1,14 @@ +/** + * This function is used to convert search params to a string that is saved as "previousSearch" + * @param options + * @returns a query string representing the search params, not unique + */ +const optionsToSearchQuery = (options) => options.q + || options.address + || options.service_node + || options.mobility_node + || options.service_id + || options.id + || options.events; + +export default optionsToSearchQuery; diff --git a/src/views/SearchView/SearchView.js b/src/views/SearchView/SearchView.js index baa5605a4..b012d0247 100644 --- a/src/views/SearchView/SearchView.js +++ b/src/views/SearchView/SearchView.js @@ -11,6 +11,7 @@ import { visuallyHidden } from '@mui/utils'; import { FormattedMessage, useIntl } from 'react-intl'; import fetchSearchResults from '../../redux/actions/search'; import { parseSearchParams, getSearchParam, keyboardHandler } from '../../utils'; +import optionsToSearchQuery from '../../utils/search'; import { fitUnitsToMap } from '../MapView/utils/mapActions'; import { isEmbed } from '../../utils/path'; import { useNavigationParams } from '../../utils/address'; @@ -181,13 +182,7 @@ const SearchView = (props) => { return false; } const data = getSearchParamData(); - const searchQuery = data.q - || data.address - || data.service_node - || data.mobility_node - || data.service_id - || data.id - || data.events; + const searchQuery = optionsToSearchQuery(data); // Should fetch if previousSearch has changed and data has required parameters if (previousSearch) { @@ -389,12 +384,17 @@ const SearchView = (props) => { const { previousSearch, isFetching } = searchFetchState; const shouldRender = !isFetching && previousSearch && !searchResults.length; const messageIDs = ['spelling', 'city', 'service', 'address', 'keyword']; + // This was same as previousSearch, but the text was not user-friendly when searching by nodes. + const options = parseSearchParams(location.search); + delete options.mobility_node; + delete options.service_node; + const searchQuery = optionsToSearchQuery(options); return shouldRender ? ( - +