mirror of
https://git.mirrors.martin98.com/https://github.com/langgenius/dify.git
synced 2025-08-20 19:59:11 +08:00
fix: replace useQuery with useInfiniteQuery in search members
This commit is contained in:
parent
eddf4eeac6
commit
bfdcd78942
@ -19,27 +19,26 @@ export default function AddMemberOrGroupDialog() {
|
|||||||
const { t } = useTranslation()
|
const { t } = useTranslation()
|
||||||
const [open, setOpen] = useState(false)
|
const [open, setOpen] = useState(false)
|
||||||
const [keyword, setKeyword] = useState('')
|
const [keyword, setKeyword] = useState('')
|
||||||
const [pageNumber, setPageNumber] = useState(1)
|
|
||||||
const debouncedKeyword = useDebounce(keyword, { wait: 500 })
|
const debouncedKeyword = useDebounce(keyword, { wait: 500 })
|
||||||
|
|
||||||
const { isPending, data } = useSearchForWhiteListCandidates({ keyword: debouncedKeyword, pageNumber, resultsPerPage: 10 }, open)
|
const { isPending, isFetchingNextPage, fetchNextPage, data } = useSearchForWhiteListCandidates({ keyword: debouncedKeyword, resultsPerPage: 10 }, open)
|
||||||
const handleKeywordChange = (e: React.ChangeEvent<HTMLInputElement>) => {
|
const handleKeywordChange = (e: React.ChangeEvent<HTMLInputElement>) => {
|
||||||
setKeyword(e.target.value)
|
setKeyword(e.target.value)
|
||||||
}
|
}
|
||||||
|
|
||||||
const anchorRef = useRef<HTMLDivElement>(null)
|
const anchorRef = useRef<HTMLDivElement>(null)
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const hasMore = data?.has_more ?? true
|
const hasMore = data?.pages?.[0].hasMore ?? false
|
||||||
let observer: IntersectionObserver | undefined
|
let observer: IntersectionObserver | undefined
|
||||||
if (anchorRef.current) {
|
if (anchorRef.current) {
|
||||||
observer = new IntersectionObserver((entries) => {
|
observer = new IntersectionObserver((entries) => {
|
||||||
if (entries[0].isIntersecting && !isPending && hasMore)
|
if (entries[0].isIntersecting && !isPending && hasMore)
|
||||||
setPageNumber((size: number) => size + 1)
|
fetchNextPage()
|
||||||
}, { rootMargin: '20px' })
|
}, { rootMargin: '20px' })
|
||||||
observer.observe(anchorRef.current)
|
observer.observe(anchorRef.current)
|
||||||
}
|
}
|
||||||
return () => observer?.disconnect()
|
return () => observer?.disconnect()
|
||||||
}, [isPending, setPageNumber, anchorRef, data])
|
}, [isPending, fetchNextPage, anchorRef, data])
|
||||||
|
|
||||||
return <PortalToFollowElem open={open} onOpenChange={setOpen} offset={{ crossAxis: 300 }} placement='bottom-end'>
|
return <PortalToFollowElem open={open} onOpenChange={setOpen} offset={{ crossAxis: 300 }} placement='bottom-end'>
|
||||||
<PortalToFollowElemTrigger asChild>
|
<PortalToFollowElemTrigger asChild>
|
||||||
@ -54,40 +53,37 @@ export default function AddMemberOrGroupDialog() {
|
|||||||
<Input value={keyword} onChange={handleKeywordChange} showLeftIcon placeholder={t('app.accessControlDialog.operateGroupAndMember.searchPlaceholder') as string} />
|
<Input value={keyword} onChange={handleKeywordChange} showLeftIcon placeholder={t('app.accessControlDialog.operateGroupAndMember.searchPlaceholder') as string} />
|
||||||
</div>
|
</div>
|
||||||
{
|
{
|
||||||
(data?.subjects?.length ?? 0) > 0
|
isPending
|
||||||
|
? <div className='p-1'><Loading /></div>
|
||||||
|
: (data?.pages?.length ?? 0) > 0
|
||||||
? <>
|
? <>
|
||||||
<div className='flex items-center h-7 px-2 py-0.5'>
|
<div className='flex items-center h-7 px-2 py-0.5'>
|
||||||
<span className='system-xs-regular text-text-tertiary'>{t('app.accessControlDialog.operateGroupAndMember.allMembers')}</span>
|
<span className='system-xs-regular text-text-tertiary'>{t('app.accessControlDialog.operateGroupAndMember.allMembers')}</span>
|
||||||
</div>
|
</div>
|
||||||
<RenderGroupOrMember data={data?.subjects ?? []} />
|
{renderGroupOrMember(data?.pages ?? [])}
|
||||||
|
{isFetchingNextPage && <div className='p-1'><Loading /></div>}
|
||||||
<div ref={anchorRef} className='h-0'> </div>
|
<div ref={anchorRef} className='h-0'> </div>
|
||||||
</>
|
</>
|
||||||
: isPending
|
|
||||||
? null
|
|
||||||
: <div className='flex items-center justify-center h-7 px-2 py-0.5'>
|
: <div className='flex items-center justify-center h-7 px-2 py-0.5'>
|
||||||
<span className='system-xs-regular text-text-tertiary'>{t('app.accessControlDialog.operateGroupAndMember.noResult')}</span>
|
<span className='system-xs-regular text-text-tertiary'>{t('app.accessControlDialog.operateGroupAndMember.noResult')}</span>
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
{
|
|
||||||
isPending && <div className='p-1'><Loading /></div>
|
|
||||||
}
|
|
||||||
</div>
|
</div>
|
||||||
</PortalToFollowElemContent>
|
</PortalToFollowElemContent>
|
||||||
</PortalToFollowElem>
|
</PortalToFollowElem>
|
||||||
}
|
}
|
||||||
|
|
||||||
type RenderGroupOrMemberProps = {
|
type GroupOrMemberData = { subjects: Subject[]; currPage: number }[]
|
||||||
data: Subject[]
|
function renderGroupOrMember(data: GroupOrMemberData) {
|
||||||
}
|
return data?.map((page) => {
|
||||||
|
return <div key={`search_group_member_page_${page.currPage}`} className='p-1'>
|
||||||
function RenderGroupOrMember({ data }: RenderGroupOrMemberProps) {
|
{page.subjects?.map((item, index) => {
|
||||||
return <div className='p-1'>
|
|
||||||
{data.map((item, index) => {
|
|
||||||
if (item.subjectType === SubjectType.Group)
|
if (item.subjectType === SubjectType.Group)
|
||||||
return <GroupItem key={index} group={(item as SubjectGroup).groupData} />
|
return <GroupItem key={index} group={(item as SubjectGroup).groupData} />
|
||||||
return <MemberItem key={index} member={(item as SubjectAccount).accountData} />
|
return <MemberItem key={index} member={(item as SubjectAccount).accountData} />
|
||||||
})}
|
})}
|
||||||
</div>
|
</div>
|
||||||
|
}) ?? null
|
||||||
}
|
}
|
||||||
|
|
||||||
type GroupItemProps = {
|
type GroupItemProps = {
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { useMutation, useQuery } from '@tanstack/react-query'
|
import { useInfiniteQuery, useMutation, useQuery } from '@tanstack/react-query'
|
||||||
import { get, post } from './base'
|
import { get, post } from './base'
|
||||||
import type { AccessControlAccount, AccessControlGroup, Subject } from '@/models/access-control'
|
import type { AccessControlAccount, AccessControlGroup, Subject } from '@/models/access-control'
|
||||||
import type { App } from '@/types/app'
|
import type { App } from '@/types/app'
|
||||||
@ -17,21 +17,28 @@ type SearchResults = {
|
|||||||
currPage: number
|
currPage: number
|
||||||
totalPages: number
|
totalPages: number
|
||||||
subjects: Subject[]
|
subjects: Subject[]
|
||||||
has_more: boolean
|
hasMore: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
export const useSearchForWhiteListCandidates = (query: { appId?: string; keyword?: string; pageNumber?: number; resultsPerPage?: number }, enabled: boolean) => {
|
export const useSearchForWhiteListCandidates = (query: { keyword?: string; resultsPerPage?: number }, enabled: boolean) => {
|
||||||
return useQuery({
|
return useInfiniteQuery({
|
||||||
queryKey: [NAME_SPACE, 'app-whitelist-candidates', query],
|
queryKey: [NAME_SPACE, 'app-whitelist-candidates', query],
|
||||||
queryFn: () => {
|
queryFn: ({ pageParam }) => {
|
||||||
const params = new URLSearchParams()
|
const params = new URLSearchParams()
|
||||||
Object.keys(query).forEach((key) => {
|
Object.keys(query).forEach((key) => {
|
||||||
const typedKey = key as keyof typeof query
|
const typedKey = key as keyof typeof query
|
||||||
if (query[typedKey])
|
if (query[typedKey])
|
||||||
params.append(key, `${query[typedKey]}`)
|
params.append(key, `${query[typedKey]}`)
|
||||||
})
|
})
|
||||||
|
params.append('pageNumber', `${pageParam}`)
|
||||||
return get<SearchResults>(`/enterprise/webapp/app/subject/search?${new URLSearchParams(params).toString()}`)
|
return get<SearchResults>(`/enterprise/webapp/app/subject/search?${new URLSearchParams(params).toString()}`)
|
||||||
},
|
},
|
||||||
|
initialPageParam: 1,
|
||||||
|
getNextPageParam: (lastPage) => {
|
||||||
|
if (lastPage.hasMore)
|
||||||
|
return lastPage.currPage + 1
|
||||||
|
return undefined
|
||||||
|
},
|
||||||
enabled,
|
enabled,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user