feat: marketplace list

This commit is contained in:
StyleZhang 2024-10-29 14:44:30 +08:00
parent 36c01d89c9
commit e65a47cff7
6 changed files with 102 additions and 54 deletions

View File

@ -13,6 +13,7 @@ import { useDebounceFn } from 'ahooks'
import { PLUGIN_TYPE_SEARCH_MAP } from './plugin-type-switch'
import type { Plugin } from '../types'
import type { PluginsSearchParams } from './types'
import { getMarketplacePlugins } from './utils'
export type MarketplaceContextValue = {
intersected: boolean
@ -57,31 +58,10 @@ export const MarketplaceContextProvider = ({
const [activePluginType, setActivePluginType] = useState(PLUGIN_TYPE_SEARCH_MAP.all)
const [plugins, setPlugins] = useState<Plugin[]>()
const handleUpdatePlugins = useCallback((query: PluginsSearchParams) => {
const fetchPlugins = async () => {
const response = await fetch(
'https://marketplace.dify.dev/api/v1/plugins/search/basic',
{
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
query: query.query,
page: 1,
page_size: 10,
sort_by: query.sortBy,
sort_order: query.sortOrder,
category: query.category,
tag: query.tag,
}),
},
)
const data = await response.json()
setPlugins(data.data.plugins)
}
const handleUpdatePlugins = useCallback(async (query: PluginsSearchParams) => {
const { marketplacePlugins } = await getMarketplacePlugins(query)
fetchPlugins()
setPlugins(marketplacePlugins)
}, [])
const { run: handleUpdatePluginsWithDebounced } = useDebounceFn(handleUpdatePlugins, {

View File

@ -1,24 +1,13 @@
import type { Plugin } from '../types'
import { MarketplaceContextProvider } from './context'
import Description from './description'
import IntersectionLine from './intersection-line'
import SearchBox from './search-box'
import PluginTypeSwitch from './plugin-type-switch'
import ListWrapper from './list/list-wrapper'
import type { MarketplaceCollection } from './types'
import { getMarketplaceCollectionsAndPlugins } from './utils'
const Marketplace = async () => {
const marketplaceCollectionsData = await globalThis.fetch('https://marketplace.dify.dev/api/v1/collections')
const marketplaceCollectionsDataJson = await marketplaceCollectionsData.json()
const marketplaceCollections = marketplaceCollectionsDataJson.data.collections
const marketplaceCollectionPluginsMap = {} as Record<string, Plugin[]>
await Promise.all(marketplaceCollections.map(async (collection: MarketplaceCollection) => {
const marketplaceCollectionPluginsData = await globalThis.fetch(`https://marketplace.dify.dev/api/v1/collections/${collection.name}/plugins`)
const marketplaceCollectionPluginsDataJson = await marketplaceCollectionPluginsData.json()
const plugins = marketplaceCollectionPluginsDataJson.data.plugins
marketplaceCollectionPluginsMap[collection.name] = plugins
}))
const { marketplaceCollections, marketplaceCollectionPluginsMap } = await getMarketplaceCollectionsAndPlugins()
return (
<MarketplaceContextProvider>

View File

@ -27,7 +27,7 @@ const List = ({
}
{
plugins && (
<div className='grid grid-cols-4 gap-3 mt-2'>
<div className='grid grid-cols-4 gap-3'>
{
plugins.map(plugin => (
<Card

View File

@ -0,0 +1,67 @@
import type { Plugin } from '@/app/components/plugins/types'
import type {
MarketplaceCollection,
PluginsSearchParams,
} from '@/app/components/plugins/marketplace/types'
const MARKETPLACE_API_URL = 'https://marketplace.dify.dev/api/v1'
export const getMarketplaceCollectionsAndPlugins = async () => {
let marketplaceCollections = [] as MarketplaceCollection[]
let marketplaceCollectionPluginsMap = {} as Record<string, Plugin[]>
try {
const marketplaceCollectionsData = await globalThis.fetch(`${MARKETPLACE_API_URL}/collections`)
const marketplaceCollectionsDataJson = await marketplaceCollectionsData.json()
marketplaceCollections = marketplaceCollectionsDataJson.data.collections
await Promise.all(marketplaceCollections.map(async (collection: MarketplaceCollection) => {
const marketplaceCollectionPluginsData = await globalThis.fetch(`${MARKETPLACE_API_URL}/collections/${collection.name}/plugins`)
const marketplaceCollectionPluginsDataJson = await marketplaceCollectionPluginsData.json()
const plugins = marketplaceCollectionPluginsDataJson.data.plugins
marketplaceCollectionPluginsMap[collection.name] = plugins
}))
}
// eslint-disable-next-line unused-imports/no-unused-vars
catch (e) {
marketplaceCollections = []
marketplaceCollectionPluginsMap = {}
}
return {
marketplaceCollections,
marketplaceCollectionPluginsMap,
}
}
export const getMarketplacePlugins = async (query: PluginsSearchParams) => {
let marketplacePlugins = [] as Plugin[]
try {
const marketplacePluginsData = await globalThis.fetch(
`${MARKETPLACE_API_URL}/plugins`,
{
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,
tag: query.tag,
}),
},
)
const marketplacePluginsDataJson = await marketplacePluginsData.json()
marketplacePlugins = marketplacePluginsDataJson.data.plugins
}
// eslint-disable-next-line unused-imports/no-unused-vars
catch (e) {
marketplacePlugins = []
}
return {
marketplacePlugins,
}
}

View File

@ -5,22 +5,16 @@ import {
} from 'react'
import type { Plugin } from '@/app/components/plugins/types'
import type { MarketplaceCollection } from '@/app/components/plugins/marketplace/types'
import { getMarketplaceCollectionsAndPlugins } from '@/app/components/plugins/marketplace/utils'
export const useMarketplace = () => {
const [marketplaceCollections, setMarketplaceCollections] = useState<MarketplaceCollection[]>([])
const [marketplaceCollectionPluginsMap, setMarketplaceCollectionPluginsMap] = useState<Record<string, Plugin[]>>({})
const [isLoading, setIsLoading] = useState(true)
const getMarketplaceCollections = useCallback(async () => {
const marketplaceCollectionsData = await globalThis.fetch('https://marketplace.dify.dev/api/v1/collections')
const marketplaceCollectionsDataJson = await marketplaceCollectionsData.json()
const marketplaceCollections = marketplaceCollectionsDataJson.data.collections
const marketplaceCollectionPluginsMap = {} as Record<string, Plugin[]>
await Promise.all(marketplaceCollections.map(async (collection: MarketplaceCollection) => {
const marketplaceCollectionPluginsData = await globalThis.fetch(`https://marketplace.dify.dev/api/v1/collections/${collection.name}/plugins`)
const marketplaceCollectionPluginsDataJson = await marketplaceCollectionPluginsData.json()
const plugins = marketplaceCollectionPluginsDataJson.data.plugins
marketplaceCollectionPluginsMap[collection.name] = plugins
}))
setIsLoading(true)
const { marketplaceCollections, marketplaceCollectionPluginsMap } = await getMarketplaceCollectionsAndPlugins()
setIsLoading(false)
setMarketplaceCollections(marketplaceCollections)
setMarketplaceCollectionPluginsMap(marketplaceCollectionPluginsMap)
}, [])
@ -29,6 +23,7 @@ export const useMarketplace = () => {
}, [getMarketplaceCollections])
return {
isLoading,
marketplaceCollections,
marketplaceCollectionPluginsMap,
}

View File

@ -1,6 +1,7 @@
import { RiArrowUpDoubleLine } from '@remixicon/react'
import { useMarketplace } from './hooks'
import List from '@/app/components/plugins/marketplace/list'
import Loading from '@/app/components/base/loading'
type MarketplaceProps = {
onMarketplaceScroll: () => void
@ -8,7 +9,12 @@ type MarketplaceProps = {
const Marketplace = ({
onMarketplaceScroll,
}: MarketplaceProps) => {
const { marketplaceCollections, marketplaceCollectionPluginsMap } = useMarketplace()
const {
isLoading,
marketplaceCollections,
marketplaceCollectionPluginsMap,
} = useMarketplace()
return (
<div className='shrink-0 sticky -bottom-[442px] h-[530px] overflow-y-auto px-12 py-2 pt-0 bg-background-default-subtle'>
<RiArrowUpDoubleLine
@ -37,10 +43,21 @@ const Marketplace = ({
in Dify Marketplace
</div>
</div>
<List
marketplaceCollections={marketplaceCollections}
marketplaceCollectionPluginsMap={marketplaceCollectionPluginsMap}
/>
{
isLoading && (
<div className='absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2'>
<Loading />
</div>
)
}
{
!isLoading && (
<List
marketplaceCollections={marketplaceCollections}
marketplaceCollectionPluginsMap={marketplaceCollectionPluginsMap}
/>
)
}
</div>
)
}