feat: marketplace list more link
This commit is contained in:
parent
4f8cdabef0
commit
672843dcab
@ -24,6 +24,7 @@ import type {
|
|||||||
MarketplaceCollection,
|
MarketplaceCollection,
|
||||||
PluginsSort,
|
PluginsSort,
|
||||||
SearchParams,
|
SearchParams,
|
||||||
|
SearchParamsFromCollection,
|
||||||
} from './types'
|
} from './types'
|
||||||
import { DEFAULT_SORT } from './constants'
|
import { DEFAULT_SORT } from './constants'
|
||||||
import {
|
import {
|
||||||
@ -49,10 +50,12 @@ export type MarketplaceContextValue = {
|
|||||||
page: number
|
page: number
|
||||||
handlePageChange: (page: number) => void
|
handlePageChange: (page: number) => void
|
||||||
plugins?: Plugin[]
|
plugins?: Plugin[]
|
||||||
|
pluginsTotal?: number
|
||||||
resetPlugins: () => void
|
resetPlugins: () => void
|
||||||
sort: PluginsSort
|
sort: PluginsSort
|
||||||
handleSortChange: (sort: PluginsSort) => void
|
handleSortChange: (sort: PluginsSort) => void
|
||||||
handleQueryPlugins: () => void
|
handleQueryPlugins: () => void
|
||||||
|
handleMoreClick: (searchParams: SearchParamsFromCollection) => void
|
||||||
marketplaceCollectionsFromClient?: MarketplaceCollection[]
|
marketplaceCollectionsFromClient?: MarketplaceCollection[]
|
||||||
setMarketplaceCollectionsFromClient: (collections: MarketplaceCollection[]) => void
|
setMarketplaceCollectionsFromClient: (collections: MarketplaceCollection[]) => void
|
||||||
marketplaceCollectionPluginsMapFromClient?: Record<string, Plugin[]>
|
marketplaceCollectionPluginsMapFromClient?: Record<string, Plugin[]>
|
||||||
@ -73,10 +76,12 @@ export const MarketplaceContext = createContext<MarketplaceContextValue>({
|
|||||||
page: 1,
|
page: 1,
|
||||||
handlePageChange: () => {},
|
handlePageChange: () => {},
|
||||||
plugins: undefined,
|
plugins: undefined,
|
||||||
|
pluginsTotal: 0,
|
||||||
resetPlugins: () => {},
|
resetPlugins: () => {},
|
||||||
sort: DEFAULT_SORT,
|
sort: DEFAULT_SORT,
|
||||||
handleSortChange: () => {},
|
handleSortChange: () => {},
|
||||||
handleQueryPlugins: () => {},
|
handleQueryPlugins: () => {},
|
||||||
|
handleMoreClick: () => {},
|
||||||
marketplaceCollectionsFromClient: [],
|
marketplaceCollectionsFromClient: [],
|
||||||
setMarketplaceCollectionsFromClient: () => {},
|
setMarketplaceCollectionsFromClient: () => {},
|
||||||
marketplaceCollectionPluginsMapFromClient: {},
|
marketplaceCollectionPluginsMapFromClient: {},
|
||||||
@ -248,7 +253,7 @@ export const MarketplaceContextProvider = ({
|
|||||||
}, [handleQueryPlugins])
|
}, [handleQueryPlugins])
|
||||||
|
|
||||||
const handlePageChange = useCallback(() => {
|
const handlePageChange = useCallback(() => {
|
||||||
if (pluginsTotal && plugins && pluginsTotal > plugins.length && (!!searchPluginTextRef.current || !!filterPluginTagsRef.current.length)) {
|
if (pluginsTotal && plugins && pluginsTotal > plugins.length) {
|
||||||
setPage(pageRef.current + 1)
|
setPage(pageRef.current + 1)
|
||||||
pageRef.current++
|
pageRef.current++
|
||||||
|
|
||||||
@ -256,6 +261,23 @@ export const MarketplaceContextProvider = ({
|
|||||||
}
|
}
|
||||||
}, [handleQueryPlugins, plugins, pluginsTotal])
|
}, [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)
|
useMarketplaceContainerScroll(handlePageChange, scrollContainerId)
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@ -272,10 +294,12 @@ export const MarketplaceContextProvider = ({
|
|||||||
page,
|
page,
|
||||||
handlePageChange,
|
handlePageChange,
|
||||||
plugins,
|
plugins,
|
||||||
|
pluginsTotal,
|
||||||
resetPlugins,
|
resetPlugins,
|
||||||
sort,
|
sort,
|
||||||
handleSortChange,
|
handleSortChange,
|
||||||
handleQueryPlugins,
|
handleQueryPlugins,
|
||||||
|
handleMoreClick,
|
||||||
marketplaceCollectionsFromClient,
|
marketplaceCollectionsFromClient,
|
||||||
setMarketplaceCollectionsFromClient,
|
setMarketplaceCollectionsFromClient,
|
||||||
marketplaceCollectionPluginsMapFromClient,
|
marketplaceCollectionPluginsMapFromClient,
|
||||||
|
@ -1,9 +1,13 @@
|
|||||||
'use client'
|
'use client'
|
||||||
|
|
||||||
|
import { useTranslation } from 'react-i18next'
|
||||||
|
import { RiArrowRightSLine } from '@remixicon/react'
|
||||||
import type { MarketplaceCollection } from '../types'
|
import type { MarketplaceCollection } from '../types'
|
||||||
import CardWrapper from './card-wrapper'
|
import CardWrapper from './card-wrapper'
|
||||||
import type { Plugin } from '@/app/components/plugins/types'
|
import type { Plugin } from '@/app/components/plugins/types'
|
||||||
import { getLanguage } from '@/i18n/language'
|
import { getLanguage } from '@/i18n/language'
|
||||||
import cn from '@/utils/classnames'
|
import cn from '@/utils/classnames'
|
||||||
|
import type { SearchParamsFromCollection } from '@/app/components/plugins/marketplace/types'
|
||||||
|
|
||||||
type ListWithCollectionProps = {
|
type ListWithCollectionProps = {
|
||||||
marketplaceCollections: MarketplaceCollection[]
|
marketplaceCollections: MarketplaceCollection[]
|
||||||
@ -12,7 +16,7 @@ type ListWithCollectionProps = {
|
|||||||
locale: string
|
locale: string
|
||||||
cardContainerClassName?: string
|
cardContainerClassName?: string
|
||||||
cardRender?: (plugin: Plugin) => JSX.Element | null
|
cardRender?: (plugin: Plugin) => JSX.Element | null
|
||||||
onMoreClick?: () => void
|
onMoreClick?: (searchParams?: SearchParamsFromCollection) => void
|
||||||
}
|
}
|
||||||
const ListWithCollection = ({
|
const ListWithCollection = ({
|
||||||
marketplaceCollections,
|
marketplaceCollections,
|
||||||
@ -21,8 +25,10 @@ const ListWithCollection = ({
|
|||||||
locale,
|
locale,
|
||||||
cardContainerClassName,
|
cardContainerClassName,
|
||||||
cardRender,
|
cardRender,
|
||||||
// onMoreClick,
|
onMoreClick,
|
||||||
}: ListWithCollectionProps) => {
|
}: ListWithCollectionProps) => {
|
||||||
|
const { t } = useTranslation()
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
{
|
{
|
||||||
@ -31,15 +37,22 @@ const ListWithCollection = ({
|
|||||||
key={collection.name}
|
key={collection.name}
|
||||||
className='py-3'
|
className='py-3'
|
||||||
>
|
>
|
||||||
<div className='flex justify-between'>
|
<div className='flex justify-between items-end'>
|
||||||
<div>
|
<div>
|
||||||
<div className='title-xl-semi-bold text-text-primary'>{collection.label[getLanguage(locale)]}</div>
|
<div className='title-xl-semi-bold text-text-primary'>{collection.label[getLanguage(locale)]}</div>
|
||||||
<div className='system-xs-regular text-text-tertiary'>{collection.description[getLanguage(locale)]}</div>
|
<div className='system-xs-regular text-text-tertiary'>{collection.description[getLanguage(locale)]}</div>
|
||||||
</div>
|
</div>
|
||||||
{/* <div
|
{
|
||||||
className='system-xs-regular text-text-tertiary cursor-pointer hover:underline'
|
collection.searchable && onMoreClick && (
|
||||||
onClick={() => onMoreClick?.()}
|
<div
|
||||||
>more</div> */}
|
className='flex items-center system-xs-medium text-text-accent cursor-pointer '
|
||||||
|
onClick={() => onMoreClick?.(collection.search_params)}
|
||||||
|
>
|
||||||
|
{t('plugin.marketplace.viewMore')}
|
||||||
|
<RiArrowRightSLine className='w-4 h-4' />
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
</div>
|
</div>
|
||||||
<div className={cn(
|
<div className={cn(
|
||||||
'grid grid-cols-4 gap-3 mt-2',
|
'grid grid-cols-4 gap-3 mt-2',
|
||||||
|
@ -22,12 +22,14 @@ const ListWrapper = ({
|
|||||||
}: ListWrapperProps) => {
|
}: ListWrapperProps) => {
|
||||||
const { t } = useTranslation()
|
const { t } = useTranslation()
|
||||||
const plugins = useMarketplaceContext(v => v.plugins)
|
const plugins = useMarketplaceContext(v => v.plugins)
|
||||||
|
const pluginsTotal = useMarketplaceContext(v => v.pluginsTotal)
|
||||||
const marketplaceCollectionsFromClient = useMarketplaceContext(v => v.marketplaceCollectionsFromClient)
|
const marketplaceCollectionsFromClient = useMarketplaceContext(v => v.marketplaceCollectionsFromClient)
|
||||||
const marketplaceCollectionPluginsMapFromClient = useMarketplaceContext(v => v.marketplaceCollectionPluginsMapFromClient)
|
const marketplaceCollectionPluginsMapFromClient = useMarketplaceContext(v => v.marketplaceCollectionPluginsMapFromClient)
|
||||||
const isLoading = useMarketplaceContext(v => v.isLoading)
|
const isLoading = useMarketplaceContext(v => v.isLoading)
|
||||||
const isSuccessCollections = useMarketplaceContext(v => v.isSuccessCollections)
|
const isSuccessCollections = useMarketplaceContext(v => v.isSuccessCollections)
|
||||||
const handleQueryPlugins = useMarketplaceContext(v => v.handleQueryPlugins)
|
const handleQueryPlugins = useMarketplaceContext(v => v.handleQueryPlugins)
|
||||||
const page = useMarketplaceContext(v => v.page)
|
const page = useMarketplaceContext(v => v.page)
|
||||||
|
const handleMoreClick = useMarketplaceContext(v => v.handleMoreClick)
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!marketplaceCollectionsFromClient?.length && isSuccessCollections)
|
if (!marketplaceCollectionsFromClient?.length && isSuccessCollections)
|
||||||
@ -39,7 +41,7 @@ const ListWrapper = ({
|
|||||||
{
|
{
|
||||||
plugins && (
|
plugins && (
|
||||||
<div className='top-5 flex items-center mb-4 pt-3'>
|
<div className='top-5 flex items-center mb-4 pt-3'>
|
||||||
<div className='title-xl-semi-bold text-text-primary'>{t('plugin.marketplace.pluginsResult', { num: plugins.length })}</div>
|
<div className='title-xl-semi-bold text-text-primary'>{t('plugin.marketplace.pluginsResult', { num: pluginsTotal })}</div>
|
||||||
<div className='mx-3 w-[1px] h-3.5 bg-divider-regular'></div>
|
<div className='mx-3 w-[1px] h-3.5 bg-divider-regular'></div>
|
||||||
<SortDropdown />
|
<SortDropdown />
|
||||||
</div>
|
</div>
|
||||||
@ -60,6 +62,7 @@ const ListWrapper = ({
|
|||||||
plugins={plugins}
|
plugins={plugins}
|
||||||
showInstallButton={showInstallButton}
|
showInstallButton={showInstallButton}
|
||||||
locale={locale}
|
locale={locale}
|
||||||
|
onMoreClick={handleMoreClick}
|
||||||
/>
|
/>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,11 @@
|
|||||||
import type { Plugin } from '../types'
|
import type { Plugin } from '../types'
|
||||||
|
|
||||||
|
export type SearchParamsFromCollection = {
|
||||||
|
query?: string
|
||||||
|
sort_by?: string
|
||||||
|
sort_order?: string
|
||||||
|
}
|
||||||
|
|
||||||
export type MarketplaceCollection = {
|
export type MarketplaceCollection = {
|
||||||
name: string
|
name: string
|
||||||
label: Record<string, string>
|
label: Record<string, string>
|
||||||
@ -7,6 +13,8 @@ export type MarketplaceCollection = {
|
|||||||
rule: string
|
rule: string
|
||||||
created_at: string
|
created_at: string
|
||||||
updated_at: string
|
updated_at: string
|
||||||
|
searchable?: boolean
|
||||||
|
search_params?: SearchParamsFromCollection
|
||||||
}
|
}
|
||||||
|
|
||||||
export type MarketplaceCollectionsResponse = {
|
export type MarketplaceCollectionsResponse = {
|
||||||
|
@ -161,6 +161,7 @@ const translation = {
|
|||||||
newlyReleased: 'Newly Released',
|
newlyReleased: 'Newly Released',
|
||||||
firstReleased: 'First Released',
|
firstReleased: 'First Released',
|
||||||
},
|
},
|
||||||
|
viewMore: 'View more',
|
||||||
},
|
},
|
||||||
task: {
|
task: {
|
||||||
installing: 'Installing {{installingLength}} plugins, 0 done.',
|
installing: 'Installing {{installingLength}} plugins, 0 done.',
|
||||||
|
@ -161,6 +161,7 @@ const translation = {
|
|||||||
newlyReleased: '最新发布',
|
newlyReleased: '最新发布',
|
||||||
firstReleased: '首次发布',
|
firstReleased: '首次发布',
|
||||||
},
|
},
|
||||||
|
viewMore: '查看更多',
|
||||||
},
|
},
|
||||||
task: {
|
task: {
|
||||||
installing: '{{installingLength}} 个插件安装中,0 已完成',
|
installing: '{{installingLength}} 个插件安装中,0 已完成',
|
||||||
|
Loading…
Reference in New Issue
Block a user