-
Notifications
You must be signed in to change notification settings - Fork 1.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Relationship select fixes #6839
Conversation
🦋 Changeset detectedLatest commit: 09dcceb The changes in this PR will be included in the next version bump. This PR includes changesets to release 1 package
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
This pull request is being automatically deployed with Vercel (learn more). 🔍 Inspect: https://vercel.com/keystonejs/keystone-next-docs/CetaHHFoWZrM8XxC5s8cC9E3AUYM |
This pull request is automatically built and testable in CodeSandbox. To see build info of the built libraries, click here or the icon next to each commit SHA. |
@@ -1,6 +1,6 @@ | |||
import * as Path from 'path'; | |||
import { GraphQLSchema } from 'graphql'; | |||
import type { AdminMetaRootVal, KeystoneConfig, AdminFileToWrite } from '../../../types'; | |||
import type { AdminMetaRootVal, KeystoneConfig, AdminFileToWrite } from '../../types'; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This and the change in the file below is unrelated to the rest of this, it's just a thing I noticed after doing a build and running tsc because the previous path points to the dist location of that entrypoint rather than src location which it should point to which makes this point to nowhere in the .d.ts
files, probably gonna add something to prevent this sort of problem soon.
@@ -39,12 +64,15 @@ function useFilter(search: string, list: ListMeta) { | |||
const trimmedSearch = search.trim(); | |||
const isValidId = idValidators[idFieldKind](trimmedSearch); | |||
if (isValidId) { | |||
conditions.push({ id: trimmedSearch }); | |||
conditions.push({ id: { equals: trimmedSearch } }); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is the fix for #6823, we were passing a bad filter previously, try this by putting in an id of an item and that item should be in the options.
[field.path]: { | ||
contains: trimmedSearch, | ||
mode: field.search === 'insensitive' ? 'insensitive' : undefined, | ||
}, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This in combination with the changes to createAdminMeta
mean that what you type in the select will actually filter the options again assuming the ui.labelField
is filterable or you've configured ui.searchFields
so try searching for an item and you should only see items that match the search.
@@ -120,11 +148,43 @@ export const RelationshipSelect = ({ | |||
} | |||
`; | |||
|
|||
const where = useFilter(search, list); | |||
const debouncedSearch = useDebouncedValue(search, 200); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This means till you're done typing before fetching so you shouldn't see a bunch of network requests when you're typing
// we want to avoid fetching more again and `loading` from Apollo | ||
// doesn't seem to become true when fetching more | ||
const [lastFetchMore, setLastFetchMore] = useState<{ | ||
where: Record<string, any>; | ||
extraSelection: string; | ||
list: ListMeta; | ||
skip: number; | ||
} | null>(null); | ||
|
||
useIntersectionObserver( | ||
([{ isIntersecting }]) => { | ||
if (!loading && isIntersecting && options.length < count) { | ||
const skip = data?.items.length; | ||
if ( | ||
!loading && | ||
skip && | ||
isIntersecting && | ||
options.length < count && | ||
(lastFetchMore?.extraSelection !== extraSelection || | ||
lastFetchMore?.where !== where || | ||
lastFetchMore?.list !== list || | ||
lastFetchMore?.skip !== skip) | ||
) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
All this and the stuff below is to avoid fetching more when we're already fetching more, previously if you scrolled to the bottom and then scrolled up a bit so you couldn't see the thing that said loading and then scrolled down it would fetch again if the previous request was still in progress.
cache: new InMemoryCache({ | ||
typePolicies: { | ||
Query: { | ||
fields: { | ||
[list.gqlNames.listQueryName]: { | ||
keyArgs: ['where'], | ||
merge: (existing: readonly any[], incoming: readonly any[], { args }) => { | ||
const merged = existing ? existing.slice() : []; | ||
const { skip } = args!; | ||
for (let i = 0; i < incoming.length; ++i) { | ||
merged[skip + i] = incoming[i]; | ||
} | ||
return merged; | ||
}, | ||
}, | ||
}, | ||
}, | ||
}, | ||
}), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This fixes the duplicate items thing because we're assigning an item to the position based on the skip
of the request rather than blindly concatenating the responses together
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we use unknown
instead of any
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Works well.
Closes #6822
Closes #6823