diff --git a/web/app/components/plugins/marketplace/context.tsx b/web/app/components/plugins/marketplace/context.tsx index 79618c6c9e..e484f1e275 100644 --- a/web/app/components/plugins/marketplace/context.tsx +++ b/web/app/components/plugins/marketplace/context.tsx @@ -24,6 +24,7 @@ import type { MarketplaceCollection, PluginsSort, SearchParams, + SearchParamsFromCollection, } from './types' import { DEFAULT_SORT } from './constants' import { @@ -49,10 +50,12 @@ export type MarketplaceContextValue = { page: number handlePageChange: (page: number) => void plugins?: Plugin[] + pluginsTotal?: number resetPlugins: () => void sort: PluginsSort handleSortChange: (sort: PluginsSort) => void handleQueryPlugins: () => void + handleMoreClick: (searchParams: SearchParamsFromCollection) => void marketplaceCollectionsFromClient?: MarketplaceCollection[] setMarketplaceCollectionsFromClient: (collections: MarketplaceCollection[]) => void marketplaceCollectionPluginsMapFromClient?: Record @@ -73,10 +76,12 @@ export const MarketplaceContext = createContext({ page: 1, handlePageChange: () => {}, plugins: undefined, + pluginsTotal: 0, resetPlugins: () => {}, sort: DEFAULT_SORT, handleSortChange: () => {}, handleQueryPlugins: () => {}, + handleMoreClick: () => {}, marketplaceCollectionsFromClient: [], setMarketplaceCollectionsFromClient: () => {}, marketplaceCollectionPluginsMapFromClient: {}, @@ -248,7 +253,7 @@ export const MarketplaceContextProvider = ({ }, [handleQueryPlugins]) const handlePageChange = useCallback(() => { - if (pluginsTotal && plugins && pluginsTotal > plugins.length && (!!searchPluginTextRef.current || !!filterPluginTagsRef.current.length)) { + if (pluginsTotal && plugins && pluginsTotal > plugins.length) { setPage(pageRef.current + 1) pageRef.current++ @@ -256,6 +261,23 @@ export const MarketplaceContextProvider = ({ } }, [handleQueryPlugins, plugins, pluginsTotal]) + const handleMoreClick = useCallback((searchParams: SearchParamsFromCollection) => { + setSearchPluginText(searchParams?.query || '') + searchPluginTextRef.current = searchParams?.query || '' + setSort({ + sortBy: searchParams?.sort_by || DEFAULT_SORT.sortBy, + sortOrder: searchParams?.sort_order || DEFAULT_SORT.sortOrder, + }) + sortRef.current = { + sortBy: searchParams?.sort_by || DEFAULT_SORT.sortBy, + sortOrder: searchParams?.sort_order || DEFAULT_SORT.sortOrder, + } + setPage(1) + pageRef.current = 1 + + handleQueryPlugins() + }, [handleQueryPlugins]) + useMarketplaceContainerScroll(handlePageChange, scrollContainerId) return ( @@ -272,10 +294,12 @@ export const MarketplaceContextProvider = ({ page, handlePageChange, plugins, + pluginsTotal, resetPlugins, sort, handleSortChange, handleQueryPlugins, + handleMoreClick, marketplaceCollectionsFromClient, setMarketplaceCollectionsFromClient, marketplaceCollectionPluginsMapFromClient, diff --git a/web/app/components/plugins/marketplace/list/list-with-collection.tsx b/web/app/components/plugins/marketplace/list/list-with-collection.tsx index 4bb22ad4dc..4195280351 100644 --- a/web/app/components/plugins/marketplace/list/list-with-collection.tsx +++ b/web/app/components/plugins/marketplace/list/list-with-collection.tsx @@ -1,9 +1,13 @@ 'use client' + +import { useTranslation } from 'react-i18next' +import { RiArrowRightSLine } from '@remixicon/react' import type { MarketplaceCollection } from '../types' import CardWrapper from './card-wrapper' import type { Plugin } from '@/app/components/plugins/types' import { getLanguage } from '@/i18n/language' import cn from '@/utils/classnames' +import type { SearchParamsFromCollection } from '@/app/components/plugins/marketplace/types' type ListWithCollectionProps = { marketplaceCollections: MarketplaceCollection[] @@ -12,7 +16,7 @@ type ListWithCollectionProps = { locale: string cardContainerClassName?: string cardRender?: (plugin: Plugin) => JSX.Element | null - onMoreClick?: () => void + onMoreClick?: (searchParams?: SearchParamsFromCollection) => void } const ListWithCollection = ({ marketplaceCollections, @@ -21,8 +25,10 @@ const ListWithCollection = ({ locale, cardContainerClassName, cardRender, - // onMoreClick, + onMoreClick, }: ListWithCollectionProps) => { + const { t } = useTranslation() + return ( <> { @@ -31,15 +37,22 @@ const ListWithCollection = ({ key={collection.name} className='py-3' > -
+
{collection.label[getLanguage(locale)]}
{collection.description[getLanguage(locale)]}
- {/*
onMoreClick?.()} - >more
*/} + { + collection.searchable && onMoreClick && ( +
onMoreClick?.(collection.search_params)} + > + {t('plugin.marketplace.viewMore')} + +
+ ) + }
{ const { t } = useTranslation() const plugins = useMarketplaceContext(v => v.plugins) + const pluginsTotal = useMarketplaceContext(v => v.pluginsTotal) const marketplaceCollectionsFromClient = useMarketplaceContext(v => v.marketplaceCollectionsFromClient) const marketplaceCollectionPluginsMapFromClient = useMarketplaceContext(v => v.marketplaceCollectionPluginsMapFromClient) const isLoading = useMarketplaceContext(v => v.isLoading) const isSuccessCollections = useMarketplaceContext(v => v.isSuccessCollections) const handleQueryPlugins = useMarketplaceContext(v => v.handleQueryPlugins) const page = useMarketplaceContext(v => v.page) + const handleMoreClick = useMarketplaceContext(v => v.handleMoreClick) useEffect(() => { if (!marketplaceCollectionsFromClient?.length && isSuccessCollections) @@ -39,7 +41,7 @@ const ListWrapper = ({ { plugins && (
-
{t('plugin.marketplace.pluginsResult', { num: plugins.length })}
+
{t('plugin.marketplace.pluginsResult', { num: pluginsTotal })}
@@ -60,6 +62,7 @@ const ListWrapper = ({ plugins={plugins} showInstallButton={showInstallButton} locale={locale} + onMoreClick={handleMoreClick} /> ) } diff --git a/web/app/components/plugins/marketplace/types.ts b/web/app/components/plugins/marketplace/types.ts index 2baee5b98b..4145f69248 100644 --- a/web/app/components/plugins/marketplace/types.ts +++ b/web/app/components/plugins/marketplace/types.ts @@ -1,5 +1,11 @@ import type { Plugin } from '../types' +export type SearchParamsFromCollection = { + query?: string + sort_by?: string + sort_order?: string +} + export type MarketplaceCollection = { name: string label: Record @@ -7,6 +13,8 @@ export type MarketplaceCollection = { rule: string created_at: string updated_at: string + searchable?: boolean + search_params?: SearchParamsFromCollection } export type MarketplaceCollectionsResponse = { diff --git a/web/i18n/en-US/plugin.ts b/web/i18n/en-US/plugin.ts index 3ab1110440..b6b90ba44d 100644 --- a/web/i18n/en-US/plugin.ts +++ b/web/i18n/en-US/plugin.ts @@ -161,6 +161,7 @@ const translation = { newlyReleased: 'Newly Released', firstReleased: 'First Released', }, + viewMore: 'View more', }, task: { installing: 'Installing {{installingLength}} plugins, 0 done.', diff --git a/web/i18n/zh-Hans/plugin.ts b/web/i18n/zh-Hans/plugin.ts index 59ce344b3f..d1af323ddd 100644 --- a/web/i18n/zh-Hans/plugin.ts +++ b/web/i18n/zh-Hans/plugin.ts @@ -161,6 +161,7 @@ const translation = { newlyReleased: '最新发布', firstReleased: '首次发布', }, + viewMore: '查看更多', }, task: { installing: '{{installingLength}} 个插件安装中,0 已完成',