diff --git a/web/app/(commonLayout)/layout.tsx b/web/app/(commonLayout)/layout.tsx index ef07732997..f0f7e0321d 100644 --- a/web/app/(commonLayout)/layout.tsx +++ b/web/app/(commonLayout)/layout.tsx @@ -15,20 +15,20 @@ const Layout = ({ children }: { children: ReactNode }) => { <> - - - - - -
- - + + + + + + +
+ {children} - - - - - + + + + + ) diff --git a/web/app/components/plugins/marketplace/context.tsx b/web/app/components/plugins/marketplace/context.tsx index 0c87e32919..4c5752d45b 100644 --- a/web/app/components/plugins/marketplace/context.tsx +++ b/web/app/components/plugins/marketplace/context.tsx @@ -34,7 +34,7 @@ export type MarketplaceContextValue = { activePluginType: string handleActivePluginTypeChange: (type: string) => void plugins?: Plugin[] - setPlugins: (plugins: Plugin[]) => void + resetPlugins: () => void sort: PluginsSort handleSortChange: (sort: PluginsSort) => void marketplaceCollectionsFromClient?: MarketplaceCollection[] @@ -53,7 +53,7 @@ export const MarketplaceContext = createContext({ activePluginType: PLUGIN_TYPE_SEARCH_MAP.all, handleActivePluginTypeChange: () => {}, plugins: undefined, - setPlugins: () => {}, + resetPlugins: () => {}, sort: DEFAULT_SORT, handleSortChange: () => {}, marketplaceCollectionsFromClient: [], @@ -91,7 +91,7 @@ export const MarketplaceContextProvider = ({ } = useMarketplaceCollectionsAndPlugins() const { plugins, - setPlugins, + resetPlugins, queryPlugins, queryPluginsWithDebounced, } = useMarketplacePlugins() @@ -104,7 +104,7 @@ export const MarketplaceContextProvider = ({ queryMarketplaceCollectionsAndPlugins({ category: activePluginTypeRef.current === PLUGIN_TYPE_SEARCH_MAP.all ? undefined : activePluginTypeRef.current, }) - setPlugins(undefined) + resetPlugins() return } @@ -116,7 +116,7 @@ export const MarketplaceContextProvider = ({ sortBy: sortRef.current.sortBy, sortOrder: sortRef.current.sortOrder, }) - }, [queryPluginsWithDebounced, queryMarketplaceCollectionsAndPlugins, setPlugins]) + }, [queryPluginsWithDebounced, queryMarketplaceCollectionsAndPlugins, resetPlugins]) const handleFilterPluginTagsChange = useCallback((tags: string[]) => { setFilterPluginTags(tags) @@ -126,7 +126,7 @@ export const MarketplaceContextProvider = ({ queryMarketplaceCollectionsAndPlugins({ category: activePluginTypeRef.current === PLUGIN_TYPE_SEARCH_MAP.all ? undefined : activePluginTypeRef.current, }) - setPlugins(undefined) + resetPlugins() return } @@ -138,7 +138,7 @@ export const MarketplaceContextProvider = ({ sortBy: sortRef.current.sortBy, sortOrder: sortRef.current.sortOrder, }) - }, [queryPlugins, setPlugins, queryMarketplaceCollectionsAndPlugins]) + }, [queryPlugins, resetPlugins, queryMarketplaceCollectionsAndPlugins]) const handleActivePluginTypeChange = useCallback((type: string) => { setActivePluginType(type) @@ -148,7 +148,7 @@ export const MarketplaceContextProvider = ({ queryMarketplaceCollectionsAndPlugins({ category: type === PLUGIN_TYPE_SEARCH_MAP.all ? undefined : type, }) - setPlugins(undefined) + resetPlugins() return } @@ -160,7 +160,7 @@ export const MarketplaceContextProvider = ({ sortBy: sortRef.current.sortBy, sortOrder: sortRef.current.sortOrder, }) - }, [queryPlugins, setPlugins, queryMarketplaceCollectionsAndPlugins]) + }, [queryPlugins, resetPlugins, queryMarketplaceCollectionsAndPlugins]) const handleSortChange = useCallback((sort: PluginsSort) => { setSort(sort) @@ -187,7 +187,7 @@ export const MarketplaceContextProvider = ({ activePluginType, handleActivePluginTypeChange, plugins, - setPlugins, + resetPlugins, sort, handleSortChange, marketplaceCollectionsFromClient, diff --git a/web/app/components/plugins/marketplace/hooks.ts b/web/app/components/plugins/marketplace/hooks.ts index 47ad603276..1cbc035972 100644 --- a/web/app/components/plugins/marketplace/hooks.ts +++ b/web/app/components/plugins/marketplace/hooks.ts @@ -4,7 +4,9 @@ import { } from 'react' import { useTranslation } from 'react-i18next' import { useDebounceFn } from 'ahooks' -import type { Plugin } from '../types' +import type { + Plugin, +} from '../types' import type { CollectionsAndPluginsSearchParams, MarketplaceCollection, @@ -12,9 +14,9 @@ import type { } from './types' import { getMarketplaceCollectionsAndPlugins, - getMarketplacePlugins, } from './utils' import i18n from '@/i18n/i18next-config' +import { useMutationPluginsFromMarketplace } from '@/service/use-plugins' export const useMarketplaceCollectionsAndPlugins = () => { const [isLoading, setIsLoading] = useState(false) @@ -41,28 +43,29 @@ export const useMarketplaceCollectionsAndPlugins = () => { } export const useMarketplacePlugins = () => { - const [isLoading, setIsLoading] = useState(false) - const [plugins, setPlugins] = useState() + const { + data, + mutate, + reset, + isPending, + } = useMutationPluginsFromMarketplace() - const queryPlugins = useCallback(async (query: PluginsSearchParams) => { - setIsLoading(true) - const { marketplacePlugins } = await getMarketplacePlugins(query) - setIsLoading(false) + const queryPlugins = useCallback((pluginsSearchParams: PluginsSearchParams) => { + mutate(pluginsSearchParams) + }, [mutate]) - setPlugins(marketplacePlugins) - }, []) - - const { run: queryPluginsWithDebounced } = useDebounceFn(queryPlugins, { + const { run: queryPluginsWithDebounced } = useDebounceFn((pluginsSearchParams) => { + mutate(pluginsSearchParams) + }, { wait: 500, }) return { - plugins, - setPlugins, + plugins: data?.data?.plugins, + resetPlugins: reset, queryPlugins, queryPluginsWithDebounced, - isLoading, - setIsLoading, + isLoading: isPending, } } diff --git a/web/app/components/plugins/marketplace/index.tsx b/web/app/components/plugins/marketplace/index.tsx index 742df86ea0..10e623710e 100644 --- a/web/app/components/plugins/marketplace/index.tsx +++ b/web/app/components/plugins/marketplace/index.tsx @@ -5,6 +5,7 @@ import SearchBoxWrapper from './search-box/search-box-wrapper' import PluginTypeSwitch from './plugin-type-switch' import ListWrapper from './list/list-wrapper' import { getMarketplaceCollectionsAndPlugins } from './utils' +import { TanstackQueryIniter } from '@/context/query-client' type MarketplaceProps = { locale?: string @@ -17,18 +18,20 @@ const Marketplace = async ({ const { marketplaceCollections, marketplaceCollectionPluginsMap } = await getMarketplaceCollectionsAndPlugins() return ( - - - - - - - + + + + + + + + + ) } diff --git a/web/app/components/plugins/types.ts b/web/app/components/plugins/types.ts index 95b255de62..629b9b7582 100644 --- a/web/app/components/plugins/types.ts +++ b/web/app/components/plugins/types.ts @@ -301,3 +301,7 @@ export type InstalledPluginListResponse = { export type UninstallPluginResponse = { success: boolean } + +export type PluginsFromMarketplaceResponse = { + plugins: Plugin[] +} diff --git a/web/app/components/tools/marketplace/hooks.ts b/web/app/components/tools/marketplace/hooks.ts index 82f019ef14..5d27e10043 100644 --- a/web/app/components/tools/marketplace/hooks.ts +++ b/web/app/components/tools/marketplace/hooks.ts @@ -15,7 +15,7 @@ export const useMarketplace = (searchPluginText: string, filterPluginTags: strin } = useMarketplaceCollectionsAndPlugins() const { plugins, - setPlugins, + resetPlugins, queryPlugins, queryPluginsWithDebounced, isLoading: isPluginsLoading, @@ -37,9 +37,9 @@ export const useMarketplace = (searchPluginText: string, filterPluginTags: strin } else { queryMarketplaceCollectionsAndPlugins() - setPlugins(undefined) + resetPlugins() } - }, [searchPluginText, filterPluginTags, queryPlugins, queryMarketplaceCollectionsAndPlugins, queryPluginsWithDebounced, setPlugins]) + }, [searchPluginText, filterPluginTags, queryPlugins, queryMarketplaceCollectionsAndPlugins, queryPluginsWithDebounced, resetPlugins]) return { isLoading: isLoading || isPluginsLoading, diff --git a/web/service/base.ts b/web/service/base.ts index 0f9059e617..061e8dcd2c 100644 --- a/web/service/base.ts +++ b/web/service/base.ts @@ -460,6 +460,11 @@ export const post = (url: string, options = {}, otherOptions?: IOtherOptions) return request(url, Object.assign({}, options, { method: 'POST' }), otherOptions) } +// For Marketplace API +export const postMarketplace = (url: string, options = {}, otherOptions?: IOtherOptions) => { + return post(url, options, { ...otherOptions, isMarketplaceAPI: true }) +} + export const postPublic = (url: string, options = {}, otherOptions?: IOtherOptions) => { return post(url, options, { ...otherOptions, isPublicAPI: true }) } diff --git a/web/service/use-plugins.ts b/web/service/use-plugins.ts index 754cd1cc2d..251e3a40cd 100644 --- a/web/service/use-plugins.ts +++ b/web/service/use-plugins.ts @@ -1,12 +1,17 @@ -import type { DebugInfo as DebugInfoTypes, InstalledPluginListResponse, Permissions } from '@/app/components/plugins/types' -import { get, post } from './base' +import type { + DebugInfo as DebugInfoTypes, + InstalledPluginListResponse, + Permissions, + PluginsFromMarketplaceResponse, +} from '@/app/components/plugins/types' +import type { + PluginsSearchParams, +} from '@/app/components/plugins/marketplace/types' +import { get, post, postMarketplace } from './base' import { useMutation, - useQueryClient, -} from '@tanstack/react-query' - -import { useQuery, + useQueryClient, } from '@tanstack/react-query' const NAME_SPACE = 'plugins' @@ -66,3 +71,28 @@ export const useMutationPermissions = ({ onSuccess, }) } + +export const useMutationPluginsFromMarketplace = () => { + return useMutation({ + mutationFn: (pluginsSearchParams: PluginsSearchParams) => { + const { + query, + sortBy, + sortOrder, + category, + tags, + } = pluginsSearchParams + return postMarketplace<{ data: PluginsFromMarketplaceResponse }>('/plugins/search/basic', { + body: { + page: 1, + page_size: 10, + query, + sort_by: sortBy, + sort_order: sortOrder, + category: category !== 'all' ? category : '', + tags, + }, + }) + }, + }) +}