1
- import { type CurrentUser , type ObjectSchemaType , type Schema } from '@sanity/types'
1
+ import { type ObjectSchemaType , type Schema } from '@sanity/types'
2
2
import omit from 'lodash/omit'
3
+ import { useMemo } from 'react'
3
4
5
+ import { useSchema } from '../../../../../hooks'
4
6
import { type SearchTerms } from '../../../../../search'
5
- import { supportsLocalStorage } from '../../../../../util/supportsLocalStorage'
6
- import { type SearchFieldDefinitionDictionary } from '../definitions/fields'
7
- import { type SearchFilterDefinitionDictionary } from '../definitions/filters'
8
- import { type SearchOperatorDefinitionDictionary } from '../definitions/operators'
7
+ import { useSource } from '../../../../source'
8
+ import {
9
+ createFieldDefinitionDictionary ,
10
+ createFieldDefinitions ,
11
+ type SearchFieldDefinitionDictionary ,
12
+ } from '../definitions/fields'
13
+ import {
14
+ createFilterDefinitionDictionary ,
15
+ type SearchFilterDefinitionDictionary ,
16
+ } from '../definitions/filters'
17
+ import {
18
+ createOperatorDefinitionDictionary ,
19
+ type SearchOperatorDefinitionDictionary ,
20
+ } from '../definitions/operators'
9
21
import { type SearchFilter } from '../types'
10
22
import { validateFilter } from '../utils/filterUtils'
11
23
import { getSearchableOmnisearchTypes } from '../utils/selectors'
24
+ import { useStoredSearch } from './useStoredSearch'
12
25
13
- const RECENT_SEARCHES_KEY = 'search::recent'
14
26
export const MAX_RECENT_SEARCHES = 5
15
27
/**
16
28
* Current recent search version.
@@ -50,37 +62,28 @@ interface StoredSearchItem {
50
62
terms : Omit < SearchTerms , 'types' > & { typeNames : string [ ] }
51
63
}
52
64
53
- export function createRecentSearchesStore ( {
54
- dataset,
55
- fieldDefinitions,
56
- filterDefinitions,
57
- operatorDefinitions,
58
- projectId,
59
- schema,
60
- user,
61
- version = RECENT_SEARCH_VERSION ,
62
- } : {
63
- dataset ?: string
64
- fieldDefinitions : SearchFieldDefinitionDictionary
65
- filterDefinitions : SearchFilterDefinitionDictionary
66
- operatorDefinitions : SearchOperatorDefinitionDictionary
67
- projectId ?: string
68
- schema : Schema
69
- user : CurrentUser | null
70
- version : number
71
- } ) : RecentSearchesStore | undefined {
72
- if ( ! dataset || ! projectId || ! supportsLocalStorage || ! user ) {
73
- return undefined
74
- }
65
+ export function useRecentSearchesStore ( ) : RecentSearchesStore {
66
+ const [ storedSearch , setStoredSearch ] = useStoredSearch ( )
67
+ const schema = useSchema ( )
68
+ const {
69
+ search : { operators, filters} ,
70
+ } = useSource ( )
75
71
76
- const lsKey = `${ RECENT_SEARCHES_KEY } __${ projectId } :${ dataset } :${ user . id } `
72
+ // Create field, filter and operator dictionaries
73
+ const { fieldDefinitions, filterDefinitions, operatorDefinitions} = useMemo ( ( ) => {
74
+ return {
75
+ fieldDefinitions : createFieldDefinitionDictionary ( createFieldDefinitions ( schema , filters ) ) ,
76
+ filterDefinitions : createFilterDefinitionDictionary ( filters ) ,
77
+ operatorDefinitions : createOperatorDefinitionDictionary ( operators ) ,
78
+ }
79
+ } , [ filters , operators , schema ] )
77
80
78
81
return {
79
82
/**
80
83
* Write a search term to Local Storage and return updated recent searches.
81
84
*/
82
- addSearch : ( searchTerm : SearchTerms , filters ?: SearchFilter [ ] ) : RecentSearch [ ] => {
83
- const storedFilters = ( filters || [ ] ) . map (
85
+ addSearch : ( searchTerm : SearchTerms , searchFilters ?: SearchFilter [ ] ) : RecentSearch [ ] => {
86
+ const storedFilters = ( searchFilters || [ ] ) . map (
84
87
( filter ) : SearchFilter => ( {
85
88
fieldId : filter . fieldId ,
86
89
filterName : filter . filterName ,
@@ -111,23 +114,23 @@ export function createRecentSearchesStore({
111
114
// When comparing search items, don't compare against the created date (which will always be different).
112
115
const comparator = JSON . stringify ( omit ( newSearchItem , 'created' ) )
113
116
const newRecent : StoredSearch = {
114
- version,
117
+ version : RECENT_SEARCH_VERSION ,
115
118
recentSearches : [
116
119
newSearchItem ,
117
- ...getRecentStoredSearch ( lsKey , version ) . recentSearches . filter ( ( r ) => {
120
+ ...storedSearch . recentSearches . filter ( ( r ) => {
118
121
return JSON . stringify ( omit ( r , 'created' ) ) !== comparator
119
122
} ) ,
120
123
] . slice ( 0 , MAX_RECENT_SEARCHES ) ,
121
124
}
122
- window . localStorage . setItem ( lsKey , JSON . stringify ( newRecent ) )
125
+ setStoredSearch ( newRecent )
123
126
124
127
return getRecentSearchTerms ( {
125
128
fieldDefinitions,
126
129
filterDefinitions,
127
- lsKey,
128
130
operatorDefinitions,
129
131
schema,
130
- version,
132
+ storedSearch : newRecent ,
133
+ setStoredSearch,
131
134
} )
132
135
} ,
133
136
/**
@@ -138,114 +141,94 @@ export function createRecentSearchesStore({
138
141
getRecentSearchTerms ( {
139
142
fieldDefinitions,
140
143
filterDefinitions,
141
- lsKey,
142
144
operatorDefinitions,
143
145
schema,
144
- version,
146
+ storedSearch,
147
+ setStoredSearch,
145
148
} ) ,
146
149
/**
147
150
* Remove all search terms from Local Storage and return updated recent searches.
148
151
*/
149
152
removeSearch : ( ) => {
150
- const searchTerms = getRecentStoredSearch ( lsKey , version )
151
-
152
153
const newRecent : StoredSearch = {
153
- ...searchTerms ,
154
+ ...storedSearch ,
154
155
recentSearches : [ ] ,
155
156
}
156
157
157
- window . localStorage . setItem ( lsKey , JSON . stringify ( newRecent ) )
158
+ setStoredSearch ( newRecent )
158
159
159
160
return getRecentSearchTerms ( {
160
161
fieldDefinitions,
161
162
filterDefinitions,
162
- lsKey,
163
163
operatorDefinitions,
164
164
schema,
165
- version,
165
+ storedSearch : newRecent ,
166
+ setStoredSearch,
166
167
} )
167
168
} ,
168
169
/**
169
170
* Remove a search term from Local Storage and return updated recent searches.
170
171
*/
171
172
removeSearchAtIndex : ( index : number ) => {
172
- const searchTerms = getRecentStoredSearch ( lsKey , version )
173
-
174
- if ( index < 0 || index > searchTerms . recentSearches . length ) {
173
+ if ( index < 0 || index > storedSearch . recentSearches . length ) {
175
174
return getRecentSearchTerms ( {
176
175
fieldDefinitions,
177
176
filterDefinitions,
178
- lsKey,
179
177
operatorDefinitions,
180
178
schema,
181
- version,
179
+ storedSearch,
180
+ setStoredSearch,
182
181
} )
183
182
}
184
183
185
184
const newRecent : StoredSearch = {
186
- ...searchTerms ,
185
+ ...storedSearch ,
187
186
recentSearches : [
188
- ...searchTerms . recentSearches . slice ( 0 , index ) ,
189
- ...searchTerms . recentSearches . slice ( index + 1 ) ,
187
+ ...storedSearch . recentSearches . slice ( 0 , index ) ,
188
+ ...storedSearch . recentSearches . slice ( index + 1 ) ,
190
189
] ,
191
190
}
192
191
193
- window . localStorage . setItem ( lsKey , JSON . stringify ( newRecent ) )
192
+ setStoredSearch ( newRecent )
194
193
195
194
return getRecentSearchTerms ( {
196
195
fieldDefinitions,
197
196
filterDefinitions,
198
- lsKey,
199
197
operatorDefinitions,
200
198
schema,
201
- version,
199
+ storedSearch : newRecent ,
200
+ setStoredSearch,
202
201
} )
203
202
} ,
204
203
}
205
204
}
206
205
207
- /**
208
- * Get the 'raw' stored search terms from Local Storage.
209
- * Stored search terms are the minimal representation of saved terms and only include schema names.
210
- */
211
- function getRecentStoredSearch ( lsKey : string , version : number ) : StoredSearch {
212
- const recentString = supportsLocalStorage ? window . localStorage . getItem ( lsKey ) : undefined
213
-
214
- return recentString ? ( JSON . parse ( recentString ) as StoredSearch ) : { version, recentSearches : [ ] }
215
- }
216
-
217
206
/**
218
207
* Get a list of recent searches from Local Storage.
219
208
* Recent searches contain full document schema types.
220
209
*/
221
210
function getRecentSearchTerms ( {
222
- lsKey,
223
211
schema,
224
212
fieldDefinitions,
225
213
filterDefinitions,
226
214
operatorDefinitions,
227
- version,
215
+ storedSearch,
216
+ setStoredSearch,
228
217
} : {
229
- lsKey : string
230
218
schema : Schema
231
219
fieldDefinitions : SearchFieldDefinitionDictionary
232
220
filterDefinitions : SearchFilterDefinitionDictionary
233
221
operatorDefinitions : SearchOperatorDefinitionDictionary
234
- version : number
222
+ storedSearch : StoredSearch
223
+ setStoredSearch : ( _value : StoredSearch ) => void
235
224
} ) : RecentSearch [ ] {
236
- const storedSearchTerms = verifySearchVersionNumber ( {
237
- lsKey,
238
- storedSearch : getRecentStoredSearch ( lsKey , version ) ,
239
- } )
240
-
241
225
return sanitizeStoredSearch ( {
242
226
studioSchema : schema ,
243
- storedSearch : storedSearchTerms ,
244
- lsKey,
245
227
filterDefinitions,
246
228
fieldDefinitions,
247
229
operatorDefinitions,
248
- version,
230
+ storedSearch,
231
+ setStoredSearch,
249
232
} )
250
233
. recentSearches . filter ( ( r ) => ! ! r . terms )
251
234
. map ( ( r , index ) => ( {
@@ -261,34 +244,6 @@ function getRecentSearchTerms({
261
244
} ) )
262
245
}
263
246
264
- /**
265
- * Check if there's a mismatch between the _search_ version in Local Storage and
266
- * the current studio.
267
- *
268
- * If there's a mismatch, clear all recent searches and update the stored search version.
269
- *
270
- * This mutates Local Storage if a mismatch is found.
271
- */
272
-
273
- function verifySearchVersionNumber ( {
274
- lsKey,
275
- storedSearch,
276
- } : {
277
- lsKey : string
278
- storedSearch : StoredSearch
279
- } ) : StoredSearch {
280
- if ( storedSearch . version !== RECENT_SEARCH_VERSION ) {
281
- const newStoredSearch : StoredSearch = {
282
- version : RECENT_SEARCH_VERSION ,
283
- recentSearches : [ ] ,
284
- }
285
- window . localStorage . setItem ( lsKey , JSON . stringify ( newStoredSearch ) )
286
- return newStoredSearch
287
- }
288
-
289
- return storedSearch
290
- }
291
-
292
247
/**
293
248
* Sanitize stored search.
294
249
*
@@ -302,19 +257,17 @@ function verifySearchVersionNumber({
302
257
function sanitizeStoredSearch ( {
303
258
fieldDefinitions,
304
259
filterDefinitions,
305
- lsKey,
306
260
operatorDefinitions,
307
- storedSearch,
308
261
studioSchema,
309
- version,
262
+ storedSearch,
263
+ setStoredSearch,
310
264
} : {
311
265
fieldDefinitions : SearchFieldDefinitionDictionary
312
266
filterDefinitions : SearchFilterDefinitionDictionary
313
- lsKey : string
314
267
operatorDefinitions : SearchOperatorDefinitionDictionary
315
- storedSearch : StoredSearch
316
268
studioSchema : Schema
317
- version : number
269
+ storedSearch : StoredSearch
270
+ setStoredSearch : ( _value : StoredSearch ) => void
318
271
} ) : StoredSearch {
319
272
// Obtain all 'searchable' type names – defined as a type that exists in
320
273
// the current schema and also visible to omnisearch.
@@ -338,8 +291,8 @@ function sanitizeStoredSearch({
338
291
}
339
292
340
293
if ( newStoredSearch . recentSearches . length < storedSearch . recentSearches . length ) {
341
- window . localStorage . setItem ( lsKey , JSON . stringify ( newStoredSearch ) )
294
+ setStoredSearch ( newStoredSearch )
342
295
}
343
296
344
- return getRecentStoredSearch ( lsKey , version )
297
+ return newStoredSearch
345
298
}
0 commit comments