feat: marketplace add exclude
This commit is contained in:
parent
e145dba487
commit
d4cda69b0e
@ -8,7 +8,7 @@ const PluginList = async () => {
|
||||
return (
|
||||
<PluginPage
|
||||
plugins={<PluginsPanel />}
|
||||
marketplace={<Marketplace locale={locale} />}
|
||||
marketplace={<Marketplace locale={locale} shouldExclude />}
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
@ -6,6 +6,7 @@ import type {
|
||||
import {
|
||||
useCallback,
|
||||
useEffect,
|
||||
useMemo,
|
||||
useRef,
|
||||
useState,
|
||||
} from 'react'
|
||||
@ -30,6 +31,7 @@ import {
|
||||
useMarketplacePlugins,
|
||||
} from './hooks'
|
||||
import { getMarketplaceListCondition } from './utils'
|
||||
import { useInstalledPluginList } from '@/service/use-plugins'
|
||||
|
||||
export type MarketplaceContextValue = {
|
||||
intersected: boolean
|
||||
@ -74,6 +76,7 @@ export const MarketplaceContext = createContext<MarketplaceContextValue>({
|
||||
type MarketplaceContextProviderProps = {
|
||||
children: ReactNode
|
||||
searchParams?: SearchParams
|
||||
shouldExclude?: boolean
|
||||
}
|
||||
|
||||
export function useMarketplaceContext(selector: (value: MarketplaceContextValue) => any) {
|
||||
@ -83,7 +86,13 @@ export function useMarketplaceContext(selector: (value: MarketplaceContextValue)
|
||||
export const MarketplaceContextProvider = ({
|
||||
children,
|
||||
searchParams,
|
||||
shouldExclude,
|
||||
}: MarketplaceContextProviderProps) => {
|
||||
const { data, isSuccess } = useInstalledPluginList(!shouldExclude)
|
||||
const exclude = useMemo(() => {
|
||||
if (shouldExclude)
|
||||
return data?.plugins.map(plugin => plugin.plugin_id)
|
||||
}, [data?.plugins, shouldExclude])
|
||||
const queryFromSearchParams = searchParams?.q || ''
|
||||
const tagsFromSearchParams = searchParams?.tags ? getValidTagKeys(searchParams.tags.split(',')) : []
|
||||
const hasValidTags = !!tagsFromSearchParams.length
|
||||
@ -125,8 +134,15 @@ export const MarketplaceContextProvider = ({
|
||||
})
|
||||
history.pushState({}, '', `/${searchParams?.language ? `?language=${searchParams?.language}` : ''}`)
|
||||
}
|
||||
else {
|
||||
if (shouldExclude && isSuccess) {
|
||||
queryMarketplaceCollectionsAndPlugins({
|
||||
exclude,
|
||||
})
|
||||
}
|
||||
}
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [queryPlugins])
|
||||
}, [queryPlugins, queryMarketplaceCollectionsAndPlugins, isSuccess, exclude])
|
||||
|
||||
const handleSearchPluginTextChange = useCallback((text: string) => {
|
||||
setSearchPluginText(text)
|
||||
@ -136,6 +152,7 @@ export const MarketplaceContextProvider = ({
|
||||
queryMarketplaceCollectionsAndPlugins({
|
||||
category: activePluginTypeRef.current === PLUGIN_TYPE_SEARCH_MAP.all ? undefined : activePluginTypeRef.current,
|
||||
condition: getMarketplaceListCondition(activePluginTypeRef.current),
|
||||
exclude,
|
||||
})
|
||||
resetPlugins()
|
||||
|
||||
@ -148,8 +165,9 @@ export const MarketplaceContextProvider = ({
|
||||
tags: filterPluginTagsRef.current,
|
||||
sortBy: sortRef.current.sortBy,
|
||||
sortOrder: sortRef.current.sortOrder,
|
||||
exclude,
|
||||
})
|
||||
}, [queryPluginsWithDebounced, queryMarketplaceCollectionsAndPlugins, resetPlugins])
|
||||
}, [queryPluginsWithDebounced, queryMarketplaceCollectionsAndPlugins, resetPlugins, exclude])
|
||||
|
||||
const handleFilterPluginTagsChange = useCallback((tags: string[]) => {
|
||||
setFilterPluginTags(tags)
|
||||
@ -159,6 +177,7 @@ export const MarketplaceContextProvider = ({
|
||||
queryMarketplaceCollectionsAndPlugins({
|
||||
category: activePluginTypeRef.current === PLUGIN_TYPE_SEARCH_MAP.all ? undefined : activePluginTypeRef.current,
|
||||
condition: getMarketplaceListCondition(activePluginTypeRef.current),
|
||||
exclude,
|
||||
})
|
||||
resetPlugins()
|
||||
|
||||
@ -171,8 +190,9 @@ export const MarketplaceContextProvider = ({
|
||||
tags,
|
||||
sortBy: sortRef.current.sortBy,
|
||||
sortOrder: sortRef.current.sortOrder,
|
||||
exclude,
|
||||
})
|
||||
}, [queryPlugins, resetPlugins, queryMarketplaceCollectionsAndPlugins])
|
||||
}, [queryPlugins, resetPlugins, queryMarketplaceCollectionsAndPlugins, exclude])
|
||||
|
||||
const handleActivePluginTypeChange = useCallback((type: string) => {
|
||||
setActivePluginType(type)
|
||||
@ -182,6 +202,7 @@ export const MarketplaceContextProvider = ({
|
||||
queryMarketplaceCollectionsAndPlugins({
|
||||
category: type === PLUGIN_TYPE_SEARCH_MAP.all ? undefined : type,
|
||||
condition: getMarketplaceListCondition(type),
|
||||
exclude,
|
||||
})
|
||||
resetPlugins()
|
||||
|
||||
@ -194,8 +215,9 @@ export const MarketplaceContextProvider = ({
|
||||
tags: filterPluginTagsRef.current,
|
||||
sortBy: sortRef.current.sortBy,
|
||||
sortOrder: sortRef.current.sortOrder,
|
||||
exclude,
|
||||
})
|
||||
}, [queryPlugins, resetPlugins, queryMarketplaceCollectionsAndPlugins])
|
||||
}, [queryPlugins, resetPlugins, queryMarketplaceCollectionsAndPlugins, exclude])
|
||||
|
||||
const handleSortChange = useCallback((sort: PluginsSort) => {
|
||||
setSort(sort)
|
||||
@ -207,8 +229,9 @@ export const MarketplaceContextProvider = ({
|
||||
tags: filterPluginTagsRef.current,
|
||||
sortBy: sortRef.current.sortBy,
|
||||
sortOrder: sortRef.current.sortOrder,
|
||||
exclude,
|
||||
})
|
||||
}, [queryPlugins])
|
||||
}, [queryPlugins, exclude])
|
||||
|
||||
return (
|
||||
<MarketplaceContext.Provider
|
||||
|
@ -17,7 +17,9 @@ import {
|
||||
getPluginIconInMarketplace,
|
||||
} from './utils'
|
||||
import i18n from '@/i18n/i18next-config'
|
||||
import { useMutationPluginsFromMarketplace } from '@/service/use-plugins'
|
||||
import {
|
||||
useMutationPluginsFromMarketplace,
|
||||
} from '@/service/use-plugins'
|
||||
|
||||
export const useMarketplaceCollectionsAndPlugins = () => {
|
||||
const [isLoading, setIsLoading] = useState(false)
|
||||
@ -55,7 +57,7 @@ export const useMarketplacePlugins = () => {
|
||||
mutate(pluginsSearchParams)
|
||||
}, [mutate])
|
||||
|
||||
const { run: queryPluginsWithDebounced } = useDebounceFn((pluginsSearchParams) => {
|
||||
const { run: queryPluginsWithDebounced } = useDebounceFn((pluginsSearchParams: PluginsSearchParams) => {
|
||||
mutate(pluginsSearchParams)
|
||||
}, {
|
||||
wait: 500,
|
||||
|
@ -11,18 +11,26 @@ import { TanstackQueryIniter } from '@/context/query-client'
|
||||
type MarketplaceProps = {
|
||||
locale: string
|
||||
showInstallButton?: boolean
|
||||
shouldExclude?: boolean
|
||||
searchParams?: SearchParams
|
||||
}
|
||||
const Marketplace = async ({
|
||||
locale,
|
||||
showInstallButton = true,
|
||||
shouldExclude,
|
||||
searchParams,
|
||||
}: MarketplaceProps) => {
|
||||
const { marketplaceCollections, marketplaceCollectionPluginsMap } = await getMarketplaceCollectionsAndPlugins()
|
||||
let marketplaceCollections: any = []
|
||||
let marketplaceCollectionPluginsMap = {}
|
||||
if (!shouldExclude) {
|
||||
const marketplaceCollectionsAndPluginsData = await getMarketplaceCollectionsAndPlugins()
|
||||
marketplaceCollections = marketplaceCollectionsAndPluginsData.marketplaceCollections
|
||||
marketplaceCollectionPluginsMap = marketplaceCollectionsAndPluginsData.marketplaceCollectionPluginsMap
|
||||
}
|
||||
|
||||
return (
|
||||
<TanstackQueryIniter>
|
||||
<MarketplaceContextProvider searchParams={searchParams}>
|
||||
<MarketplaceContextProvider searchParams={searchParams} shouldExclude={shouldExclude}>
|
||||
<Description locale={locale} />
|
||||
<IntersectionLine />
|
||||
<SearchBoxWrapper locale={locale} />
|
||||
|
@ -27,6 +27,7 @@ export type PluginsSearchParams = {
|
||||
sortOrder?: string
|
||||
category?: string
|
||||
tags?: string[]
|
||||
exclude?: string[]
|
||||
}
|
||||
|
||||
export type PluginsSort = {
|
||||
@ -37,6 +38,7 @@ export type PluginsSort = {
|
||||
export type CollectionsAndPluginsSearchParams = {
|
||||
category?: string
|
||||
condition?: string
|
||||
exclude?: string[]
|
||||
}
|
||||
|
||||
export type SearchParams = {
|
||||
|
@ -3,7 +3,6 @@ import { PluginType } from '@/app/components/plugins/types'
|
||||
import type {
|
||||
CollectionsAndPluginsSearchParams,
|
||||
MarketplaceCollection,
|
||||
PluginsSearchParams,
|
||||
} from '@/app/components/plugins/marketplace/types'
|
||||
import { MARKETPLACE_API_PREFIX } from '@/config'
|
||||
|
||||
@ -22,10 +21,18 @@ export const getMarketplaceCollectionsAndPlugins = async (query?: CollectionsAnd
|
||||
const marketplaceCollectionsDataJson = await marketplaceCollectionsData.json()
|
||||
marketplaceCollections = marketplaceCollectionsDataJson.data.collections
|
||||
await Promise.all(marketplaceCollections.map(async (collection: MarketplaceCollection) => {
|
||||
let url = `${MARKETPLACE_API_PREFIX}/collections/${collection.name}/plugins?page=1&page_size=100`
|
||||
if (query?.category)
|
||||
url += `&category=${query.category}`
|
||||
const marketplaceCollectionPluginsData = await globalThis.fetch(url, { cache: 'no-store' })
|
||||
const url = `${MARKETPLACE_API_PREFIX}/collections/${collection.name}/plugins`
|
||||
const marketplaceCollectionPluginsData = await globalThis.fetch(
|
||||
url,
|
||||
{
|
||||
cache: 'no-store',
|
||||
method: 'POST',
|
||||
body: JSON.stringify({
|
||||
category: query?.category,
|
||||
exclude: query?.exclude,
|
||||
}),
|
||||
},
|
||||
)
|
||||
const marketplaceCollectionPluginsDataJson = await marketplaceCollectionPluginsData.json()
|
||||
const plugins = marketplaceCollectionPluginsDataJson.data.plugins.map((plugin: Plugin) => {
|
||||
return {
|
||||
@ -49,45 +56,6 @@ export const getMarketplaceCollectionsAndPlugins = async (query?: CollectionsAnd
|
||||
}
|
||||
}
|
||||
|
||||
export const getMarketplacePlugins = async (query: PluginsSearchParams) => {
|
||||
let marketplacePlugins = [] as Plugin[]
|
||||
try {
|
||||
const marketplacePluginsData = await globalThis.fetch(
|
||||
`${MARKETPLACE_API_PREFIX}/plugins/search/basic`,
|
||||
{
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
body: JSON.stringify({
|
||||
page: 1,
|
||||
page_size: 10,
|
||||
query: query.query,
|
||||
sort_by: query.sortBy,
|
||||
sort_order: query.sortOrder,
|
||||
category: query.category,
|
||||
tags: query.tags,
|
||||
}),
|
||||
},
|
||||
)
|
||||
const marketplacePluginsDataJson = await marketplacePluginsData.json()
|
||||
marketplacePlugins = marketplacePluginsDataJson.data.plugins.map((plugin: Plugin) => {
|
||||
return {
|
||||
...plugin,
|
||||
icon: getPluginIconInMarketplace(plugin),
|
||||
}
|
||||
})
|
||||
}
|
||||
// eslint-disable-next-line unused-imports/no-unused-vars
|
||||
catch (e) {
|
||||
marketplacePlugins = []
|
||||
}
|
||||
|
||||
return {
|
||||
marketplacePlugins,
|
||||
}
|
||||
}
|
||||
|
||||
export const getMarketplaceListCondition = (pluginType: string) => {
|
||||
if (pluginType === PluginType.tool)
|
||||
return 'category=tool'
|
||||
|
@ -1,5 +1,6 @@
|
||||
import {
|
||||
useEffect,
|
||||
useMemo,
|
||||
} from 'react'
|
||||
import {
|
||||
useMarketplaceCollectionsAndPlugins,
|
||||
@ -7,8 +8,14 @@ import {
|
||||
} from '@/app/components/plugins/marketplace/hooks'
|
||||
import { PluginType } from '@/app/components/plugins/types'
|
||||
import { getMarketplaceListCondition } from '@/app/components/plugins/marketplace/utils'
|
||||
import { useAllToolProviders } from '@/service/use-tools'
|
||||
|
||||
export const useMarketplace = (searchPluginText: string, filterPluginTags: string[]) => {
|
||||
const { data: toolProvidersData, isSuccess } = useAllToolProviders()
|
||||
const exclude = useMemo(() => {
|
||||
if (isSuccess)
|
||||
return toolProvidersData?.filter(toolProvider => !!toolProvider.plugin_id).map(toolProvider => toolProvider.plugin_id!)
|
||||
}, [isSuccess, toolProvidersData])
|
||||
const {
|
||||
isLoading,
|
||||
marketplaceCollections,
|
||||
@ -24,12 +31,13 @@ export const useMarketplace = (searchPluginText: string, filterPluginTags: strin
|
||||
} = useMarketplacePlugins()
|
||||
|
||||
useEffect(() => {
|
||||
if (searchPluginText || filterPluginTags.length) {
|
||||
if ((searchPluginText || filterPluginTags.length) && isSuccess) {
|
||||
if (searchPluginText) {
|
||||
queryPluginsWithDebounced({
|
||||
category: PluginType.tool,
|
||||
query: searchPluginText,
|
||||
tags: filterPluginTags,
|
||||
exclude,
|
||||
})
|
||||
return
|
||||
}
|
||||
@ -37,16 +45,20 @@ export const useMarketplace = (searchPluginText: string, filterPluginTags: strin
|
||||
category: PluginType.tool,
|
||||
query: searchPluginText,
|
||||
tags: filterPluginTags,
|
||||
exclude,
|
||||
})
|
||||
}
|
||||
else {
|
||||
queryMarketplaceCollectionsAndPlugins({
|
||||
category: PluginType.tool,
|
||||
condition: getMarketplaceListCondition(PluginType.tool),
|
||||
})
|
||||
resetPlugins()
|
||||
if (isSuccess) {
|
||||
queryMarketplaceCollectionsAndPlugins({
|
||||
category: PluginType.tool,
|
||||
condition: getMarketplaceListCondition(PluginType.tool),
|
||||
exclude,
|
||||
})
|
||||
resetPlugins()
|
||||
}
|
||||
}
|
||||
}, [searchPluginText, filterPluginTags, queryPlugins, queryMarketplaceCollectionsAndPlugins, queryPluginsWithDebounced, resetPlugins])
|
||||
}, [searchPluginText, filterPluginTags, queryPlugins, queryMarketplaceCollectionsAndPlugins, queryPluginsWithDebounced, resetPlugins, exclude, isSuccess])
|
||||
|
||||
return {
|
||||
isLoading: isLoading || isPluginsLoading,
|
||||
|
@ -29,10 +29,12 @@ import { useInvalidateAllBuiltInTools } from './use-tools'
|
||||
const NAME_SPACE = 'plugins'
|
||||
|
||||
const useInstalledPluginListKey = [NAME_SPACE, 'installedPluginList']
|
||||
export const useInstalledPluginList = () => {
|
||||
export const useInstalledPluginList = (disable?: boolean) => {
|
||||
return useQuery<InstalledPluginListResponse>({
|
||||
queryKey: useInstalledPluginListKey,
|
||||
queryFn: () => get<InstalledPluginListResponse>('/workspaces/current/plugin/list'),
|
||||
enabled: !disable,
|
||||
initialData: !disable ? undefined : { plugins: [] },
|
||||
})
|
||||
}
|
||||
|
||||
@ -225,6 +227,7 @@ export const useMutationPluginsFromMarketplace = () => {
|
||||
sortOrder,
|
||||
category,
|
||||
tags,
|
||||
exclude,
|
||||
} = pluginsSearchParams
|
||||
return postMarketplace<{ data: PluginsFromMarketplaceResponse }>('/plugins/search/basic', {
|
||||
body: {
|
||||
@ -235,6 +238,7 @@ export const useMutationPluginsFromMarketplace = () => {
|
||||
sort_order: sortOrder,
|
||||
category: category !== 'all' ? category : '',
|
||||
tags,
|
||||
exclude,
|
||||
},
|
||||
})
|
||||
},
|
||||
|
Loading…
Reference in New Issue
Block a user