diff --git a/web/app/(commonLayout)/plugins/page.tsx b/web/app/(commonLayout)/plugins/page.tsx index f28944ebbd..516cc138a2 100644 --- a/web/app/(commonLayout)/plugins/page.tsx +++ b/web/app/(commonLayout)/plugins/page.tsx @@ -1,12 +1,14 @@ import PluginPage from '@/app/components/plugins/plugin-page' import PluginsPanel from '@/app/components/plugins/plugin-page/plugins-panel' import Marketplace from '@/app/components/plugins/marketplace' +import { getLocaleOnServer } from '@/i18n/server' const PluginList = async () => { + const locale = await getLocaleOnServer() return ( } - marketplace={} + marketplace={} /> ) } diff --git a/web/app/components/plugins/install-plugin/install-bundle/index.tsx b/web/app/components/plugins/install-plugin/install-bundle/index.tsx index 89323de3a0..da5a9fbd6a 100644 --- a/web/app/components/plugins/install-plugin/install-bundle/index.tsx +++ b/web/app/components/plugins/install-plugin/install-bundle/index.tsx @@ -56,7 +56,7 @@ const InstallBundle: FC = ({ diff --git a/web/app/components/plugins/install-plugin/install-bundle/item/github-item.tsx b/web/app/components/plugins/install-plugin/install-bundle/item/github-item.tsx index 49f7e448aa..cfbe05ca5d 100644 --- a/web/app/components/plugins/install-plugin/install-bundle/item/github-item.tsx +++ b/web/app/components/plugins/install-plugin/install-bundle/item/github-item.tsx @@ -1,7 +1,7 @@ 'use client' import type { FC } from 'react' import React, { useEffect } from 'react' -import type { Dependency, Plugin } from '../../../types' +import type { GitHubItemAndMarketPlaceDependency, Plugin } from '../../../types' import { pluginManifestToCardPluginProps } from '../../utils' import { useUploadGitHub } from '@/service/use-plugins' import Loading from './loading' @@ -10,8 +10,9 @@ import LoadedItem from './loaded-item' type Props = { checked: boolean onCheckedChange: (plugin: Plugin) => void - dependency: Dependency + dependency: GitHubItemAndMarketPlaceDependency onFetchedPayload: (payload: Plugin) => void + onFetchError: () => void } const Item: FC = ({ @@ -19,9 +20,10 @@ const Item: FC = ({ onCheckedChange, dependency, onFetchedPayload, + onFetchError, }) => { const info = dependency.value - const { data } = useUploadGitHub({ + const { data, error } = useUploadGitHub({ repo: info.repo!, version: info.version!, package: info.package!, @@ -38,6 +40,12 @@ const Item: FC = ({ } // eslint-disable-next-line react-hooks/exhaustive-deps }, [data]) + useEffect(() => { + if (error) + onFetchError() + + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [error]) if (!payload) return return ( void + payload: PackageDependency +} + +const PackageItem: FC = ({ + payload, + checked, + onCheckedChange, +}) => { + const plugin = pluginManifestToCardPluginProps(payload.value.manifest) + return ( + + ) +} + +export default React.memo(PackageItem) diff --git a/web/app/components/plugins/install-plugin/install-bundle/ready-to-install.tsx b/web/app/components/plugins/install-plugin/install-bundle/ready-to-install.tsx index e9f89cb5c6..0f5dda2395 100644 --- a/web/app/components/plugins/install-plugin/install-bundle/ready-to-install.tsx +++ b/web/app/components/plugins/install-plugin/install-bundle/ready-to-install.tsx @@ -9,14 +9,14 @@ import type { Dependency, InstallStatusResponse, Plugin } from '../../types' type Props = { step: InstallStep onStepChange: (step: InstallStep) => void, - dependencies: Dependency[] + allPlugins: Dependency[] onClose: () => void } const ReadyToInstall: FC = ({ step, onStepChange, - dependencies, + allPlugins, onClose, }) => { const [installedPlugins, setInstalledPlugins] = useState([]) @@ -30,7 +30,7 @@ const ReadyToInstall: FC = ({ <> {step === InstallStep.readyToInstall && ( diff --git a/web/app/components/plugins/install-plugin/install-bundle/steps/install-by-dsl-list.tsx b/web/app/components/plugins/install-plugin/install-bundle/steps/install-multi.tsx similarity index 56% rename from web/app/components/plugins/install-plugin/install-bundle/steps/install-by-dsl-list.tsx rename to web/app/components/plugins/install-plugin/install-bundle/steps/install-multi.tsx index aeafa8f18f..b70a481b74 100644 --- a/web/app/components/plugins/install-plugin/install-bundle/steps/install-by-dsl-list.tsx +++ b/web/app/components/plugins/install-plugin/install-bundle/steps/install-multi.tsx @@ -1,30 +1,34 @@ 'use client' import type { FC } from 'react' -import React, { useCallback, useEffect, useMemo } from 'react' -import type { Dependency, Plugin } from '../../../types' +import React, { useCallback, useEffect, useMemo, useState } from 'react' +import type { Dependency, GitHubItemAndMarketPlaceDependency, PackageDependency, Plugin } from '../../../types' import MarketplaceItem from '../item/marketplace-item' import GithubItem from '../item/github-item' import { useFetchPluginsInMarketPlaceByIds } from '@/service/use-plugins' import produce from 'immer' import { useGetState } from 'ahooks' +import PackageItem from '../item/package-item' type Props = { - fromDSLPayload: Dependency[] + allPlugins: Dependency[] selectedPlugins: Plugin[] onSelect: (plugin: Plugin, selectedIndex: number) => void onLoadedAllPlugin: () => void } const InstallByDSLList: FC = ({ - fromDSLPayload, + allPlugins, selectedPlugins, onSelect, onLoadedAllPlugin, }) => { - const { isLoading: isFetchingMarketplaceData, data: marketplaceRes } = useFetchPluginsInMarketPlaceByIds(fromDSLPayload.filter(d => d.type === 'marketplace').map(d => d.value.plugin_unique_identifier!)) + const { isLoading: isFetchingMarketplaceData, data: marketplaceRes } = useFetchPluginsInMarketPlaceByIds(allPlugins.filter(d => d.type === 'marketplace').map(d => d.value.plugin_unique_identifier!)) const [plugins, setPlugins, getPlugins] = useGetState([]) - const handlePlugInFetched = useCallback((index: number) => { + + const [errorIndexes, setErrorIndexes] = useState([]) + + const handleGitHubPluginFetched = useCallback((index: number) => { return (p: Plugin) => { const nextPlugins = produce(getPlugins(), (draft) => { draft[index] = p @@ -33,14 +37,20 @@ const InstallByDSLList: FC = ({ } }, [getPlugins, setPlugins]) + const handleGitHubPluginFetchError = useCallback((index: number) => { + return () => { + setErrorIndexes([...errorIndexes, index]) + } + }, [errorIndexes]) + const marketPlaceInDSLIndex = useMemo(() => { const res: number[] = [] - fromDSLPayload.forEach((d, index) => { + allPlugins.forEach((d, index) => { if (d.type === 'marketplace') res.push(index) }) return res - }, [fromDSLPayload]) + }, [allPlugins]) useEffect(() => { if (!isFetchingMarketplaceData && marketplaceRes?.data.plugins && marketplaceRes?.data.plugins.length > 0) { @@ -57,7 +67,7 @@ const InstallByDSLList: FC = ({ // eslint-disable-next-line react-hooks/exhaustive-deps }, [isFetchingMarketplaceData]) - const isLoadedAllData = fromDSLPayload.length === plugins.length && plugins.every(p => !!p) + const isLoadedAllData = allPlugins.length === plugins.length && plugins.every(p => !!p) useEffect(() => { if (isLoadedAllData) onLoadedAllPlugin() @@ -71,22 +81,44 @@ const InstallByDSLList: FC = ({ }, [onSelect, plugins]) return ( <> - {fromDSLPayload.map((d, index) => ( - d.type === 'github' - ? { + if (errorIndexes.includes(index)) { + return ( +
error
+ ) + } + if (d.type === 'github') { + return ( p.plugin_id === plugins[index]?.plugin_id)} onCheckedChange={handleSelect(index)} - dependency={d} - onFetchedPayload={handlePlugInFetched(index)} - /> - : ) + } + + if (d.type === 'marketplace') { + return ( + p.plugin_id === plugins[index]?.plugin_id)} + onCheckedChange={handleSelect(index)} + payload={plugins[index] as Plugin} + /> + ) + } + + return ( + p.plugin_id === plugins[index]?.plugin_id)} onCheckedChange={handleSelect(index)} - payload={plugins[index] as Plugin} + payload={d as PackageDependency} /> - ))} + ) + }) + } ) } diff --git a/web/app/components/plugins/install-plugin/install-bundle/steps/install.tsx b/web/app/components/plugins/install-plugin/install-bundle/steps/install.tsx index 6cb1bf5a21..9c361d4e4b 100644 --- a/web/app/components/plugins/install-plugin/install-bundle/steps/install.tsx +++ b/web/app/components/plugins/install-plugin/install-bundle/steps/install.tsx @@ -5,19 +5,19 @@ import type { Dependency, InstallStatusResponse, Plugin } from '../../../types' import Button from '@/app/components/base/button' import { RiLoader2Line } from '@remixicon/react' import { useTranslation } from 'react-i18next' -import InstallByDSLList from './install-by-dsl-list' +import InstallByDSLList from './install-multi' import { useInstallFromMarketplaceAndGitHub } from '@/service/use-plugins' import { useInvalidateInstalledPluginList } from '@/service/use-plugins' const i18nPrefix = 'plugin.installModal' type Props = { - fromDSLPayload: Dependency[] + allPlugins: Dependency[] onInstalled: (plugins: Plugin[], installStatus: InstallStatusResponse[]) => void onCancel: () => void } const Install: FC = ({ - fromDSLPayload, + allPlugins, onInstalled, onCancel, }) => { @@ -49,7 +49,7 @@ const Install: FC = ({ onInstalled(selectedPlugins, res.map((r, i) => { return ({ ...r, - isFromMarketPlace: fromDSLPayload[selectedIndexes[i]].type === 'marketplace', + isFromMarketPlace: allPlugins[selectedIndexes[i]].type === 'marketplace', }) })) const hasInstallSuccess = res.some(r => r.success) @@ -58,7 +58,7 @@ const Install: FC = ({ }, }) const handleInstall = () => { - installFromMarketplaceAndGitHub(fromDSLPayload.filter((_d, index) => selectedIndexes.includes(index))) + installFromMarketplaceAndGitHub(allPlugins.filter((_d, index) => selectedIndexes.includes(index))) } return ( <> @@ -68,7 +68,7 @@ const Install: FC = ({
= ({ step={step} onStepChange={setStep} onClose={onClose} - dependencies={dependencies} + allPlugins={dependencies} /> ) : ( { }) return { - plugins: data?.data?.plugins, + plugins: data?.data?.plugins.map(plugin => ({ + ...plugin, + icon: getPluginIconInMarketplace(plugin), + })), resetPlugins: reset, queryPlugins, queryPluginsWithDebounced, diff --git a/web/app/components/plugins/marketplace/index.tsx b/web/app/components/plugins/marketplace/index.tsx index 0ffe94a048..5afb8c31ae 100644 --- a/web/app/components/plugins/marketplace/index.tsx +++ b/web/app/components/plugins/marketplace/index.tsx @@ -9,7 +9,7 @@ import { getMarketplaceCollectionsAndPlugins } from './utils' import { TanstackQueryIniter } from '@/context/query-client' type MarketplaceProps = { - locale?: string + locale: string showInstallButton?: boolean searchParams?: SearchParams } diff --git a/web/app/components/plugins/marketplace/list/index.tsx b/web/app/components/plugins/marketplace/list/index.tsx index 1fe1e7306b..9dec49fc70 100644 --- a/web/app/components/plugins/marketplace/list/index.tsx +++ b/web/app/components/plugins/marketplace/list/index.tsx @@ -10,7 +10,7 @@ type ListProps = { marketplaceCollectionPluginsMap: Record plugins?: Plugin[] showInstallButton?: boolean - locale?: string + locale: string } const List = ({ marketplaceCollections, 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 57b087d1f5..f60e056ed2 100644 --- a/web/app/components/plugins/marketplace/list/list-with-collection.tsx +++ b/web/app/components/plugins/marketplace/list/list-with-collection.tsx @@ -2,12 +2,13 @@ import type { MarketplaceCollection } from '../types' import CardWrapper from './card-wrapper' import type { Plugin } from '@/app/components/plugins/types' +import { getLanguage } from '@/i18n/language' type ListWithCollectionProps = { marketplaceCollections: MarketplaceCollection[] marketplaceCollectionPluginsMap: Record showInstallButton?: boolean - locale?: string + locale: string } const ListWithCollection = ({ marketplaceCollections, @@ -23,8 +24,8 @@ const ListWithCollection = ({ key={collection.name} className='py-3' > -
{collection.name}
-
{collection.description}
+
{collection.label[getLanguage(locale)]}
+
{collection.description[getLanguage(locale)]}
{ marketplaceCollectionPluginsMap[collection.name].map(plugin => ( diff --git a/web/app/components/plugins/marketplace/list/list-wrapper.tsx b/web/app/components/plugins/marketplace/list/list-wrapper.tsx index cf31bf9dee..124049f70f 100644 --- a/web/app/components/plugins/marketplace/list/list-wrapper.tsx +++ b/web/app/components/plugins/marketplace/list/list-wrapper.tsx @@ -11,7 +11,7 @@ type ListWrapperProps = { marketplaceCollections: MarketplaceCollection[] marketplaceCollectionPluginsMap: Record showInstallButton?: boolean - locale?: string + locale: string } const ListWrapper = ({ marketplaceCollections, diff --git a/web/app/components/plugins/marketplace/types.ts b/web/app/components/plugins/marketplace/types.ts index e2c4315f3d..fbe4595322 100644 --- a/web/app/components/plugins/marketplace/types.ts +++ b/web/app/components/plugins/marketplace/types.ts @@ -2,7 +2,8 @@ import type { Plugin } from '../types' export type MarketplaceCollection = { name: string - description: string + label: Record + description: Record rule: string created_at: string updated_at: string diff --git a/web/app/components/plugins/provider-card.tsx b/web/app/components/plugins/provider-card.tsx index e2a45fc24d..3f2d889bc0 100644 --- a/web/app/components/plugins/provider-card.tsx +++ b/web/app/components/plugins/provider-card.tsx @@ -64,17 +64,17 @@ const ProviderCard: FC = ({ className='hidden group-hover:flex items-center gap-2 absolute bottom-0 left-0 right-0 p-4 pt-8 rounded-xl bg-gradient-to-tr from-[#f9fafb] to-[rgba(249,250,251,0)]' >