dify/web/app/components/plugins/marketplace/view.tsx
CodingOnStar a4a57ec662 fix(web): address marketplace review follow-ups on assets, locale and a11y
- resample the 3MB trending background to a 97KB webp and serve a frozen
  recommend banner from the E2E stub so the benchmark covers the carousel
- show the on-page filtered count in template search and redirect
  out-of-range pages to the last available page
- localize the carousel controls across all 24 locales and replace the
  i18n type casts with typed selectors
- surface Marketplace API failures with a retry action instead of
  rendering them as empty results
- use iconify marks for the hero decorations, share the carousel
  page-size hook to avoid a hydration mismatch, move banner types into
  @dify/contracts, scope the Cmd+K shortcut to the standalone platform,
  point the embedded logo at /marketplace, pass resolvedTheme to the
  detail dialogs, and reveal the detail iframe after a loading timeout

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-16 13:48:34 +08:00

76 lines
2.5 KiB
TypeScript

import type { PluginBanner } from '@dify/contracts/marketplace'
import type { ActivePluginType } from './constants'
import type { HomeCatalogTabLabels } from './home/home-catalog-tabs'
import { PluginInstallPermissionProviderGuard } from '@/app/components/plugins/install-plugin/components/plugin-install-permission-provider'
import Description from './description'
import MarketplaceHome from './home'
import ListWrapper from './list/list-wrapper'
import StickySearchAndSwitchWrapper from './sticky-search-and-switch-wrapper'
type MarketplaceVariant = 'default' | 'home'
export type MarketplaceViewProps = {
banners: PluginBanner[]
showInstallButton?: boolean
linkToMarketplaceDetail?: boolean
pluginTypeSwitchClassName?: string
isMarketplacePlatform?: boolean
marketplaceNav?: React.ReactNode
variant?: MarketplaceVariant
homeHeaderActions?: React.ReactNode
homeCatalogLabels?: HomeCatalogTabLabels
homeCatalogCategories?: React.ReactNode
homeActivePluginType?: ActivePluginType
homeSearch?: React.ReactNode
language?: string
}
export function MarketplaceView({
banners,
showInstallButton = false,
linkToMarketplaceDetail = false,
pluginTypeSwitchClassName,
isMarketplacePlatform = false,
marketplaceNav,
variant = 'default',
homeHeaderActions,
homeCatalogLabels,
homeCatalogCategories,
homeActivePluginType,
homeSearch,
language,
}: MarketplaceViewProps) {
return (
<PluginInstallPermissionProviderGuard canInstallPlugin={showInstallButton}>
{variant === 'home' ? (
<MarketplaceHome
actions={homeHeaderActions}
activePluginType={homeActivePluginType}
banners={banners}
catalogCategories={homeCatalogCategories}
catalogLabels={homeCatalogLabels}
search={homeSearch}
isMarketplacePlatform={isMarketplacePlatform}
language={language}
linkToMarketplaceDetail={linkToMarketplaceDetail}
showInstallButton={showInstallButton}
/>
) : (
<>
<Description
isMarketplacePlatform={isMarketplacePlatform}
marketplaceNav={marketplaceNav}
/>
{!isMarketplacePlatform && (
<StickySearchAndSwitchWrapper pluginTypeSwitchClassName={pluginTypeSwitchClassName} />
)}
<ListWrapper
showInstallButton={showInstallButton}
linkToMarketplaceDetail={linkToMarketplaceDetail}
/>
</>
)}
</PluginInstallPermissionProviderGuard>
)
}