Skip to content

Commit

Permalink
refactor(core): use KeyValueStore for recent searches (#5872)
Browse files Browse the repository at this point in the history
* refactor(core): create useStoredSearch hook

* refactor: pass useStoredSearch to recentSearchesStore

* refactor(core): convert createRecentSearchesStore to useRecentSearchesStore

* fix(core): use default studio client options

* fix: pass recent terms for more predictable UI behavior

* refactor: remove recent searches from search state and invoke hook wherever needed

* fix: remove typos, spaces
  • Loading branch information
cngonzalez authored Mar 8, 2024
1 parent dd0794a commit c531a6b
Show file tree
Hide file tree
Showing 11 changed files with 631 additions and 559 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import {
} from '../../../../../../components'
import {useTranslation} from '../../../../../../i18n'
import {useSearchState} from '../../contexts/search/useSearchState'
import {type RecentSearch} from '../../datastores/recentSearches'
import {type RecentSearch, useRecentSearchesStore} from '../../datastores/recentSearches'
import {Instructions} from '../Instructions'
import {RecentSearchItem} from './item/RecentSearchItem'

Expand All @@ -33,9 +33,14 @@ interface RecentSearchesProps {
export function RecentSearches({inputElement}: RecentSearchesProps) {
const {
dispatch,
recentSearchesStore,
state: {filtersVisible, fullscreen, recentSearches},
state: {filtersVisible, fullscreen},
} = useSearchState()
const recentSearchesStore = useRecentSearchesStore()
const recentSearches = useMemo(
() => recentSearchesStore?.getRecentSearches(),
[recentSearchesStore],
)

const commandListRef = useRef<CommandListHandle | null>(null)

const {t} = useTranslation()
Expand All @@ -46,11 +51,10 @@ export function RecentSearches({inputElement}: RecentSearchesProps) {
*/
const handleClearRecentSearchesClick = useCallback(() => {
if (recentSearchesStore) {
const updatedRecentSearches = recentSearchesStore.removeSearch()
dispatch({recentSearches: updatedRecentSearches, type: 'RECENT_SEARCHES_SET'})
recentSearchesStore.removeSearch()
}
commandListRef?.current?.focusInputElement()
}, [dispatch, recentSearchesStore])
}, [recentSearchesStore])

const mediaIndex = useMediaIndex()

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import {type MouseEvent, useCallback} from 'react'
import styled from 'styled-components'

import {useSearchState} from '../../../contexts/search/useSearchState'
import {type RecentSearch} from '../../../datastores/recentSearches'
import {type RecentSearch, useRecentSearchesStore} from '../../../datastores/recentSearches'
import {DocumentTypesPill} from '../../common/DocumentTypesPill'
import {FilterPill} from '../../common/FilterPill'

Expand Down Expand Up @@ -60,7 +60,8 @@ export function RecentSearchItem({
value,
...rest
}: RecentSearchesProps) {
const {dispatch, recentSearchesStore} = useSearchState()
const {dispatch} = useSearchState()
const recentSearchesStore = useRecentSearchesStore()

// Determine how many characters are left to render type pills
const availableCharacters = maxVisibleTypePillChars - value.query.length
Expand All @@ -70,8 +71,7 @@ export function RecentSearchItem({

// Add to Local Storage
if (recentSearchesStore) {
const updatedRecentSearches = recentSearchesStore?.addSearch(value, value?.filters)
dispatch({recentSearches: updatedRecentSearches, type: 'RECENT_SEARCHES_SET'})
recentSearchesStore?.addSearch(value, value?.filters)
}
}, [dispatch, recentSearchesStore, value])

Expand All @@ -80,11 +80,10 @@ export function RecentSearchItem({
event.stopPropagation()
// Remove from Local Storage
if (recentSearchesStore) {
const updatedRecentSearches = recentSearchesStore?.removeSearchAtIndex(index)
dispatch({recentSearches: updatedRecentSearches, type: 'RECENT_SEARCHES_SET'})
recentSearchesStore?.removeSearchAtIndex(index)
}
},
[dispatch, index, recentSearchesStore],
[index, recentSearchesStore],
)

return (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import {useTranslation} from '../../../../../../i18n'
import {type WeightedHit} from '../../../../../../search'
import {getPublishedId} from '../../../../../../util/draftUtils'
import {useSearchState} from '../../contexts/search/useSearchState'
import {useRecentSearchesStore} from '../../datastores/recentSearches'
import {NoResults} from '../NoResults'
import {SearchError} from '../SearchError'
import {SortMenu} from '../SortMenu'
Expand Down Expand Up @@ -35,11 +36,11 @@ export function SearchResults({disableIntentLink, inputElement, onItemSelect}: S
const {
dispatch,
onClose,
recentSearchesStore,
setSearchCommandList,
state: {debug, filters, fullscreen, lastActiveIndex, result, terms},
} = useSearchState()
const {t} = useTranslation()
const recentSearchesStore = useRecentSearchesStore()

const hasSearchResults = !!result.hits.length
const hasNoSearchResults = !result.hits.length && result.loaded
Expand All @@ -50,11 +51,10 @@ export function SearchResults({disableIntentLink, inputElement, onItemSelect}: S
*/
const handleSearchResultClick = useCallback(() => {
if (recentSearchesStore) {
const updatedRecentSearches = recentSearchesStore.addSearch(terms, filters)
dispatch({recentSearches: updatedRecentSearches, type: 'RECENT_SEARCHES_SET'})
recentSearchesStore.addSearch(terms, filters)
}
onClose?.()
}, [dispatch, filters, onClose, recentSearchesStore, terms])
}, [filters, onClose, recentSearchesStore, terms])

const handleEndReached = useCallback(() => {
dispatch({type: 'PAGE_INCREMENT'})
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import {createContext, type Dispatch, type SetStateAction} from 'react'

import {type CommandListHandle} from '../../../../../../components/commandList/types'
import {type RecentSearchesStore} from '../../datastores/recentSearches'
import {type SearchAction, type SearchReducerState} from './reducer'

/**
Expand All @@ -10,7 +9,6 @@ import {type SearchAction, type SearchReducerState} from './reducer'
export interface SearchContextValue {
dispatch: Dispatch<SearchAction>
onClose: (() => void) | null
recentSearchesStore?: RecentSearchesStore
searchCommandList: CommandListHandle | null
setSearchCommandList: Dispatch<SetStateAction<CommandListHandle | null>>
setOnClose: (onClose: () => void) => void
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,12 @@ import isEqual from 'lodash/isEqual'
import {type ReactNode, useCallback, useEffect, useMemo, useReducer, useRef, useState} from 'react'

import {type CommandListHandle} from '../../../../../../components'
import {useClient, useSchema} from '../../../../../../hooks'
import {useSchema} from '../../../../../../hooks'
import {type SearchableType, type SearchTerms} from '../../../../../../search'
import {useCurrentUser} from '../../../../../../store'
import {DEFAULT_STUDIO_CLIENT_OPTIONS} from '../../../../../../studioClient'
import {useSource} from '../../../../../source'
import {SEARCH_LIMIT} from '../../constants'
import {
createRecentSearchesStore,
RECENT_SEARCH_VERSION,
type RecentSearch,
} from '../../datastores/recentSearches'
import {type RecentSearch} from '../../datastores/recentSearches'
import {createFieldDefinitionDictionary, createFieldDefinitions} from '../../definitions/fields'
import {createFilterDefinitionDictionary} from '../../definitions/filters'
import {createOperatorDefinitionDictionary} from '../../definitions/operators'
Expand All @@ -36,15 +31,12 @@ export function SearchProvider({children, fullscreen}: SearchProviderProps) {
const onCloseRef = useRef<(() => void) | null>(null)
const [searchCommandList, setSearchCommandList] = useState<CommandListHandle | null>(null)

const client = useClient(DEFAULT_STUDIO_CLIENT_OPTIONS)
const schema = useSchema()
const currentUser = useCurrentUser()
const {
search: {operators, filters},
} = useSource()

const {dataset, projectId} = client.config()

// Create field, filter and operator dictionaries
const {fieldDefinitions, filterDefinitions, operatorDefinitions} = useMemo(() => {
return {
Expand All @@ -54,41 +46,11 @@ export function SearchProvider({children, fullscreen}: SearchProviderProps) {
}
}, [filters, operators, schema])

// Create local storage store
const recentSearchesStore = useMemo(
() =>
createRecentSearchesStore({
dataset,
fieldDefinitions,
filterDefinitions,
operatorDefinitions,
projectId,
schema,
user: currentUser,
version: RECENT_SEARCH_VERSION,
}),
[
currentUser,
dataset,
fieldDefinitions,
filterDefinitions,
operatorDefinitions,
projectId,
schema,
],
)

const recentSearches = useMemo(
() => recentSearchesStore?.getRecentSearches(),
[recentSearchesStore],
)

const initialState = useMemo(
() =>
initialSearchState({
currentUser,
fullscreen,
recentSearches,
definitions: {
fields: fieldDefinitions,
operators: operatorDefinitions,
Expand All @@ -99,14 +61,7 @@ export function SearchProvider({children, fullscreen}: SearchProviderProps) {
nextCursor: null,
},
}),
[
currentUser,
fieldDefinitions,
filterDefinitions,
fullscreen,
operatorDefinitions,
recentSearches,
],
[currentUser, fieldDefinitions, filterDefinitions, fullscreen, operatorDefinitions],
)
const [state, dispatch] = useReducer(searchReducer, initialState)

Expand Down Expand Up @@ -224,7 +179,6 @@ export function SearchProvider({children, fullscreen}: SearchProviderProps) {
value={{
dispatch,
onClose: onCloseRef?.current,
recentSearchesStore,
searchCommandList,
setSearchCommandList,
setOnClose: handleSetOnClose,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,6 @@ export type SearchReducerState = PaginationState & {
lastAddedFilter?: SearchFilter | null
lastActiveIndex: number
ordering: SearchOrdering
recentSearches: RecentSearch[]
result: SearchResult
terms: RecentSearch | SearchTerms
}
Expand All @@ -60,15 +59,13 @@ export interface SearchResult {
export interface InitialSearchState {
currentUser: CurrentUser | null
fullscreen?: boolean
recentSearches?: RecentSearch[]
definitions: SearchDefinitions
pagination: PaginationState
}

export function initialSearchState({
currentUser,
fullscreen,
recentSearches = [],
definitions,
pagination,
}: InitialSearchState): SearchReducerState {
Expand All @@ -82,7 +79,6 @@ export function initialSearchState({
lastActiveIndex: -1,
ordering: ORDERINGS.relevance,
...pagination,
recentSearches,
result: {
error: null,
hasLocal: false,
Expand All @@ -101,10 +97,6 @@ export function initialSearchState({
export type FiltersVisibleSet = {type: 'FILTERS_VISIBLE_SET'; visible: boolean}
export type LastActiveIndexSet = {type: 'LAST_ACTIVE_INDEX_SET'; index: number}
export type PageIncrement = {type: 'PAGE_INCREMENT'}
export type RecentSearchesSet = {
recentSearches: RecentSearch[]
type: 'RECENT_SEARCHES_SET'
}
export type OrderingReset = {type: 'ORDERING_RESET'}
export type OrderingSet = {ordering: SearchOrdering; type: 'ORDERING_SET'}
export type SearchClear = {type: 'SEARCH_CLEAR'}
Expand Down Expand Up @@ -140,7 +132,6 @@ export type SearchAction =
| OrderingReset
| OrderingSet
| PageIncrement
| RecentSearchesSet
| SearchClear
| SearchRequestComplete
| SearchRequestError
Expand Down Expand Up @@ -198,11 +189,6 @@ export function searchReducer(state: SearchReducerState, action: SearchAction):
nextCursor: null,
terms: stripRecent(state.terms),
}
case 'RECENT_SEARCHES_SET':
return {
...state,
recentSearches: action.recentSearches,
}
case 'SEARCH_CLEAR':
return {
...state,
Expand Down
Loading

0 comments on commit c531a6b

Please sign in to comment.