From 7c2ab21c9c37eff3fd21057188b5196038b80986 Mon Sep 17 00:00:00 2001 From: StyleZhang Date: Wed, 6 Nov 2024 11:55:19 +0800 Subject: [PATCH 01/11] i18n --- web/app/components/plugins/hooks.ts | 6 +- .../plugins/marketplace/description/index.tsx | 19 ++++-- .../components/plugins/marketplace/hooks.ts | 13 ++++ .../components/plugins/marketplace/index.tsx | 9 ++- .../plugins/marketplace/list/card-wrapper.tsx | 6 +- .../plugins/marketplace/list/index.tsx | 3 + .../plugins/marketplace/list/list-wrapper.tsx | 3 + .../marketplace/plugin-type-switch.tsx | 65 ++++++++++--------- .../plugins/marketplace/search-box/index.tsx | 5 +- .../search-box/search-box-wrapper.tsx | 11 +++- .../marketplace/search-box/tags-filter.tsx | 8 ++- .../components/tools/marketplace/index.tsx | 13 ++-- web/i18n/en-US/plugin.ts | 7 ++ web/i18n/zh-Hans/plugin.ts | 7 ++ 14 files changed, 125 insertions(+), 50 deletions(-) diff --git a/web/app/components/plugins/hooks.ts b/web/app/components/plugins/hooks.ts index 0abadd7a90..484a7fbb5a 100644 --- a/web/app/components/plugins/hooks.ts +++ b/web/app/components/plugins/hooks.ts @@ -1,12 +1,14 @@ import { useTranslation } from 'react-i18next' +import type { TFunction } from 'i18next' type Tag = { name: string label: string } -export const useTags = () => { - const { t } = useTranslation() +export const useTags = (translateFromOut?: TFunction) => { + const { t: translation } = useTranslation() + const t = translateFromOut || translation const tags = [ { diff --git a/web/app/components/plugins/marketplace/description/index.tsx b/web/app/components/plugins/marketplace/description/index.tsx index 754a4b12a9..41888d3dbe 100644 --- a/web/app/components/plugins/marketplace/description/index.tsx +++ b/web/app/components/plugins/marketplace/description/index.tsx @@ -1,4 +1,13 @@ -const Description = () => { +import { useTranslation as translate } from '@/i18n/server' + +type DescriptionProps = { + locale?: string +} +const Description = async ({ + locale = 'en-US', +}: DescriptionProps) => { + const { t } = await translate(locale, 'plugin') + return ( <>

@@ -7,19 +16,19 @@ const Description = () => {

Discover - models + {t('category.models')} , - tools + {t('category.tools')} , - extensions + {t('category.extensions')} and - bundles + {t('category.bundles')} in Dify Marketplace

diff --git a/web/app/components/plugins/marketplace/hooks.ts b/web/app/components/plugins/marketplace/hooks.ts index 83b7ee5435..254e506912 100644 --- a/web/app/components/plugins/marketplace/hooks.ts +++ b/web/app/components/plugins/marketplace/hooks.ts @@ -2,6 +2,8 @@ import { useCallback, useState, } from 'react' +import i18n from 'i18next' +import { useTranslation } from 'react-i18next' import { useDebounceFn } from 'ahooks' import type { Plugin } from '../types' import type { @@ -63,3 +65,14 @@ export const useMarketplacePlugins = () => { setIsLoading, } } + +export const useMixedTranslation = (localeFromOuter?: string) => { + let t = useTranslation().t + + if (localeFromOuter) + t = i18n.getFixedT(localeFromOuter) + + return { + t, + } +} diff --git a/web/app/components/plugins/marketplace/index.tsx b/web/app/components/plugins/marketplace/index.tsx index 0c87cce924..742df86ea0 100644 --- a/web/app/components/plugins/marketplace/index.tsx +++ b/web/app/components/plugins/marketplace/index.tsx @@ -7,20 +7,23 @@ import ListWrapper from './list/list-wrapper' import { getMarketplaceCollectionsAndPlugins } from './utils' type MarketplaceProps = { + locale?: string showInstallButton?: boolean } const Marketplace = async ({ + locale, showInstallButton = true, }: MarketplaceProps) => { const { marketplaceCollections, marketplaceCollectionPluginsMap } = await getMarketplaceCollectionsAndPlugins() return ( - + - - + + { - const { t } = useTranslation() + const { t } = useMixedTranslation(locale) return (
plugins?: Plugin[] showInstallButton?: boolean + locale?: string } const List = ({ marketplaceCollections, marketplaceCollectionPluginsMap, plugins, showInstallButton, + locale, }: ListProps) => { return ( <> @@ -37,6 +39,7 @@ const List = ({ key={plugin.name} plugin={plugin} showInstallButton={showInstallButton} + locale={locale} /> )) } diff --git a/web/app/components/plugins/marketplace/list/list-wrapper.tsx b/web/app/components/plugins/marketplace/list/list-wrapper.tsx index bcb929ca2f..443b9ef516 100644 --- a/web/app/components/plugins/marketplace/list/list-wrapper.tsx +++ b/web/app/components/plugins/marketplace/list/list-wrapper.tsx @@ -9,11 +9,13 @@ type ListWrapperProps = { marketplaceCollections: MarketplaceCollection[] marketplaceCollectionPluginsMap: Record showInstallButton?: boolean + locale?: string } const ListWrapper = ({ marketplaceCollections, marketplaceCollectionPluginsMap, showInstallButton, + locale, }: ListWrapperProps) => { const plugins = useMarketplaceContext(v => v.plugins) const marketplaceCollectionsFromClient = useMarketplaceContext(v => v.marketplaceCollectionsFromClient) @@ -35,6 +37,7 @@ const ListWrapper = ({ marketplaceCollectionPluginsMap={marketplaceCollectionPluginsMapFromClient || marketplaceCollectionPluginsMap} plugins={plugins} showInstallButton={showInstallButton} + locale={locale} />
) diff --git a/web/app/components/plugins/marketplace/plugin-type-switch.tsx b/web/app/components/plugins/marketplace/plugin-type-switch.tsx index 35f5349343..c1469cf6bf 100644 --- a/web/app/components/plugins/marketplace/plugin-type-switch.tsx +++ b/web/app/components/plugins/marketplace/plugin-type-switch.tsx @@ -1,5 +1,4 @@ 'use client' - import { RiArchive2Line, RiBrain2Line, @@ -8,6 +7,7 @@ import { } from '@remixicon/react' import { PluginType } from '../types' import { useMarketplaceContext } from './context' +import { useMixedTranslation } from './hooks' import cn from '@/utils/classnames' export const PLUGIN_TYPE_SEARCH_MAP = { @@ -17,37 +17,44 @@ export const PLUGIN_TYPE_SEARCH_MAP = { extension: PluginType.extension, bundle: 'bundle', } -const options = [ - { - value: PLUGIN_TYPE_SEARCH_MAP.all, - text: 'All', - icon: null, - }, - { - value: PLUGIN_TYPE_SEARCH_MAP.model, - text: 'Models', - icon: , - }, - { - value: PLUGIN_TYPE_SEARCH_MAP.tool, - text: 'Tools', - icon: , - }, - { - value: PLUGIN_TYPE_SEARCH_MAP.extension, - text: 'Extensions', - icon: , - }, - { - value: PLUGIN_TYPE_SEARCH_MAP.bundle, - text: 'Bundles', - icon: , - }, -] -const PluginTypeSwitch = () => { +type PluginTypeSwitchProps = { + locale?: string +} +const PluginTypeSwitch = ({ + locale, +}: PluginTypeSwitchProps) => { + const { t } = useMixedTranslation(locale) const activePluginType = useMarketplaceContext(s => s.activePluginType) const handleActivePluginTypeChange = useMarketplaceContext(s => s.handleActivePluginTypeChange) + const options = [ + { + value: PLUGIN_TYPE_SEARCH_MAP.all, + text: 'All', + icon: null, + }, + { + value: PLUGIN_TYPE_SEARCH_MAP.model, + text: t('plugin.category.models'), + icon: , + }, + { + value: PLUGIN_TYPE_SEARCH_MAP.tool, + text: t('plugin.category.tools'), + icon: , + }, + { + value: PLUGIN_TYPE_SEARCH_MAP.extension, + text: t('plugin.category.extensions'), + icon: , + }, + { + value: PLUGIN_TYPE_SEARCH_MAP.bundle, + text: t('plugin.category.bundles'), + icon: , + }, + ] + return (
void size?: 'small' | 'large' placeholder?: string + locale?: string } const SearchBox = ({ search, @@ -20,7 +21,8 @@ const SearchBox = ({ tags, onTagsChange, size = 'small', - placeholder = 'Search tools...', + placeholder = '', + locale, }: SearchBoxProps) => { return (
diff --git a/web/app/components/plugins/marketplace/search-box/search-box-wrapper.tsx b/web/app/components/plugins/marketplace/search-box/search-box-wrapper.tsx index a124d93eb4..dfdc699958 100644 --- a/web/app/components/plugins/marketplace/search-box/search-box-wrapper.tsx +++ b/web/app/components/plugins/marketplace/search-box/search-box-wrapper.tsx @@ -1,9 +1,16 @@ 'use client' import { useMarketplaceContext } from '../context' +import { useMixedTranslation } from '../hooks' import SearchBox from './index' import cn from '@/utils/classnames' -const SearchBoxWrapper = () => { +type SearchBoxWrapperProps = { + locale?: string +} +const SearchBoxWrapper = ({ + locale, +}: SearchBoxWrapperProps) => { + const { t } = useMixedTranslation(locale) const intersected = useMarketplaceContext(v => v.intersected) const searchPluginText = useMarketplaceContext(v => v.searchPluginText) const handleSearchPluginTextChange = useMarketplaceContext(v => v.handleSearchPluginTextChange) @@ -21,6 +28,8 @@ const SearchBoxWrapper = () => { tags={filterPluginTags} onTagsChange={handleFilterPluginTagsChange} size='large' + locale={locale} + placeholder={t('plugin.searchPlugins')} /> ) } diff --git a/web/app/components/plugins/marketplace/search-box/tags-filter.tsx b/web/app/components/plugins/marketplace/search-box/tags-filter.tsx index 670d7af6ed..416cc99b91 100644 --- a/web/app/components/plugins/marketplace/search-box/tags-filter.tsx +++ b/web/app/components/plugins/marketplace/search-box/tags-filter.tsx @@ -1,7 +1,6 @@ 'use client' import { useState } from 'react' -import { useTranslation } from 'react-i18next' import { RiArrowDownSLine, RiCloseCircleFill, @@ -16,21 +15,24 @@ import Checkbox from '@/app/components/base/checkbox' import cn from '@/utils/classnames' import Input from '@/app/components/base/input' import { useTags } from '@/app/components/plugins/hooks' +import { useMixedTranslation } from '@/app/components/plugins/marketplace/hooks' type TagsFilterProps = { tags: string[] onTagsChange: (tags: string[]) => void size: 'small' | 'large' + locale?: string } const TagsFilter = ({ tags, onTagsChange, size, + locale, }: TagsFilterProps) => { - const { t } = useTranslation() + const { t } = useMixedTranslation(locale) const [open, setOpen] = useState(false) const [searchText, setSearchText] = useState('') - const { tags: options, tagsMap } = useTags() + const { tags: options, tagsMap } = useTags(t) const filteredOptions = options.filter(option => option.label.toLowerCase().includes(searchText.toLowerCase())) const handleCheck = (id: string) => { if (tags.includes(id)) diff --git a/web/app/components/tools/marketplace/index.tsx b/web/app/components/tools/marketplace/index.tsx index fff22fedc5..f2092227a0 100644 --- a/web/app/components/tools/marketplace/index.tsx +++ b/web/app/components/tools/marketplace/index.tsx @@ -1,7 +1,9 @@ import { RiArrowUpDoubleLine } from '@remixicon/react' +import { useTranslation } from 'react-i18next' import { useMarketplace } from './hooks' import List from '@/app/components/plugins/marketplace/list' import Loading from '@/app/components/base/loading' +import { getLocaleOnClient } from '@/i18n' type MarketplaceProps = { searchPluginText: string @@ -13,6 +15,8 @@ const Marketplace = ({ filterPluginTags, onMarketplaceScroll, }: MarketplaceProps) => { + const locale = getLocaleOnClient() + const { t } = useTranslation() const { isLoading, marketplaceCollections, @@ -31,19 +35,19 @@ const Marketplace = ({
Discover - models + {t('plugin.category.models')} , - tools + {t('plugin.category.tools')} , - extensions + {t('plugin.category.extensions')} and - bundles + {t('plugin.category.bundles')} in Dify Marketplace
@@ -62,6 +66,7 @@ const Marketplace = ({ marketplaceCollectionPluginsMap={marketplaceCollectionPluginsMap || {}} plugins={plugins} showInstallButton + locale={locale} /> ) } diff --git a/web/i18n/en-US/plugin.ts b/web/i18n/en-US/plugin.ts index 5ee95468b9..6fbe49a5b7 100644 --- a/web/i18n/en-US/plugin.ts +++ b/web/i18n/en-US/plugin.ts @@ -1,4 +1,11 @@ const translation = { + category: { + models: 'models', + tools: 'tools', + extensions: 'extensions', + bundles: 'bundles', + }, + searchPlugins: 'Search plugins', from: 'From', findMoreInMarketplace: 'Find more in Marketplace', searchInMarketplace: 'Search in Marketplace', diff --git a/web/i18n/zh-Hans/plugin.ts b/web/i18n/zh-Hans/plugin.ts index a9acc1e0e3..a7d146181b 100644 --- a/web/i18n/zh-Hans/plugin.ts +++ b/web/i18n/zh-Hans/plugin.ts @@ -1,4 +1,11 @@ const translation = { + category: { + models: '模型', + tools: '工具', + extensions: '扩展', + bundles: '捆绑包', + }, + searchPlugins: '搜索插件', from: '来自', findMoreInMarketplace: '在 Marketplace 中查找更多', searchInMarketplace: '在 Marketplace 中搜索', From 319a54aa2fedb89dd5412bc11da1b6f05f4b9864 Mon Sep 17 00:00:00 2001 From: StyleZhang Date: Wed, 6 Nov 2024 14:37:20 +0800 Subject: [PATCH 02/11] i18n --- web/app/components/plugins/marketplace/hooks.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/web/app/components/plugins/marketplace/hooks.ts b/web/app/components/plugins/marketplace/hooks.ts index 254e506912..47ad603276 100644 --- a/web/app/components/plugins/marketplace/hooks.ts +++ b/web/app/components/plugins/marketplace/hooks.ts @@ -2,7 +2,6 @@ import { useCallback, useState, } from 'react' -import i18n from 'i18next' import { useTranslation } from 'react-i18next' import { useDebounceFn } from 'ahooks' import type { Plugin } from '../types' @@ -15,6 +14,7 @@ import { getMarketplaceCollectionsAndPlugins, getMarketplacePlugins, } from './utils' +import i18n from '@/i18n/i18next-config' export const useMarketplaceCollectionsAndPlugins = () => { const [isLoading, setIsLoading] = useState(false) From bc43e3a9fe6340c81bb79487945fe10005f03241 Mon Sep 17 00:00:00 2001 From: StyleZhang Date: Wed, 6 Nov 2024 14:52:47 +0800 Subject: [PATCH 03/11] card locale --- web/app/components/plugins/card/index.tsx | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/web/app/components/plugins/card/index.tsx b/web/app/components/plugins/card/index.tsx index b9ff8ecfda..c7acfbe428 100644 --- a/web/app/components/plugins/card/index.tsx +++ b/web/app/components/plugins/card/index.tsx @@ -22,6 +22,7 @@ export type Props = { footer?: React.ReactNode isLoading?: boolean loadingFileName?: string + locale?: string } const Card = ({ @@ -35,8 +36,10 @@ const Card = ({ footer, isLoading = false, loadingFileName, + locale: localeFromProps, }: Props) => { - const locale = useGetLanguage() + const defaultLocale = useGetLanguage() + const locale = localeFromProps || defaultLocale const { type, name, org, label, brief, icon, verified } = payload From 9025e85ca55919b46bfed85b19ae054582398989 Mon Sep 17 00:00:00 2001 From: StyleZhang Date: Wed, 6 Nov 2024 15:00:37 +0800 Subject: [PATCH 04/11] locale --- web/app/components/plugins/marketplace/list/card-wrapper.tsx | 1 + web/app/components/plugins/marketplace/list/index.tsx | 1 + .../plugins/marketplace/list/list-with-collection.tsx | 3 +++ 3 files changed, 5 insertions(+) diff --git a/web/app/components/plugins/marketplace/list/card-wrapper.tsx b/web/app/components/plugins/marketplace/list/card-wrapper.tsx index 2ebeeeb7d0..8fdb3034b5 100644 --- a/web/app/components/plugins/marketplace/list/card-wrapper.tsx +++ b/web/app/components/plugins/marketplace/list/card-wrapper.tsx @@ -23,6 +23,7 @@ const CardWrapper = ({ ) } 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 6d56380c52..57b087d1f5 100644 --- a/web/app/components/plugins/marketplace/list/list-with-collection.tsx +++ b/web/app/components/plugins/marketplace/list/list-with-collection.tsx @@ -7,11 +7,13 @@ type ListWithCollectionProps = { marketplaceCollections: MarketplaceCollection[] marketplaceCollectionPluginsMap: Record showInstallButton?: boolean + locale?: string } const ListWithCollection = ({ marketplaceCollections, marketplaceCollectionPluginsMap, showInstallButton, + locale, }: ListWithCollectionProps) => { return ( <> @@ -30,6 +32,7 @@ const ListWithCollection = ({ key={plugin.name} plugin={plugin} showInstallButton={showInstallButton} + locale={locale} /> )) } From 21b3703bd87ed0c2e2ec089e1a893fbec94d28bb Mon Sep 17 00:00:00 2001 From: StyleZhang Date: Wed, 6 Nov 2024 15:23:38 +0800 Subject: [PATCH 05/11] fix: i18n --- web/app/components/plugins/card/index.tsx | 3 ++- .../plugins/marketplace/description/index.tsx | 10 +++++++--- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/web/app/components/plugins/card/index.tsx b/web/app/components/plugins/card/index.tsx index c7acfbe428..b262727506 100644 --- a/web/app/components/plugins/card/index.tsx +++ b/web/app/components/plugins/card/index.tsx @@ -10,6 +10,7 @@ import Description from './base/description' import Placeholder from './base/placeholder' import cn from '@/utils/classnames' import { useGetLanguage } from '@/context/i18n' +import { getLanguage } from '@/i18n/language' export type Props = { className?: string @@ -39,7 +40,7 @@ const Card = ({ locale: localeFromProps, }: Props) => { const defaultLocale = useGetLanguage() - const locale = localeFromProps || defaultLocale + const locale = localeFromProps ? getLanguage(localeFromProps) : defaultLocale const { type, name, org, label, brief, icon, verified } = payload diff --git a/web/app/components/plugins/marketplace/description/index.tsx b/web/app/components/plugins/marketplace/description/index.tsx index 41888d3dbe..403478dfc7 100644 --- a/web/app/components/plugins/marketplace/description/index.tsx +++ b/web/app/components/plugins/marketplace/description/index.tsx @@ -1,12 +1,16 @@ -import { useTranslation as translate } from '@/i18n/server' +import { + getLocaleOnServer, + useTranslation as translate, +} from '@/i18n/server' type DescriptionProps = { locale?: string } const Description = async ({ - locale = 'en-US', + locale: localeFromProps, }: DescriptionProps) => { - const { t } = await translate(locale, 'plugin') + const localeDefault = getLocaleOnServer() + const { t } = await translate(localeFromProps || localeDefault, 'plugin') return ( <> From fcde5b5c9eb217a8af3376de273ce7272ad7f28c Mon Sep 17 00:00:00 2001 From: StyleZhang Date: Wed, 6 Nov 2024 15:37:12 +0800 Subject: [PATCH 06/11] fix: detail --- .../components/plugins/marketplace/list/card-wrapper.tsx | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/web/app/components/plugins/marketplace/list/card-wrapper.tsx b/web/app/components/plugins/marketplace/list/card-wrapper.tsx index 8fdb3034b5..27891ff1e6 100644 --- a/web/app/components/plugins/marketplace/list/card-wrapper.tsx +++ b/web/app/components/plugins/marketplace/list/card-wrapper.tsx @@ -19,7 +19,13 @@ const CardWrapper = ({ }: CardWrapperProps) => { const { t } = useMixedTranslation(locale) return ( -
+
{ + if (!showInstallButton) + window.open(`${MARKETPLACE_URL_PREFIX}/plugin/${plugin.org}/${plugin.name}`) + }} + > Date: Wed, 6 Nov 2024 15:39:00 +0800 Subject: [PATCH 07/11] feat: add install --- .../plugins/marketplace/list/card-wrapper.tsx | 19 +++++++++++++++++++ web/app/components/plugins/types.ts | 1 + 2 files changed, 20 insertions(+) diff --git a/web/app/components/plugins/marketplace/list/card-wrapper.tsx b/web/app/components/plugins/marketplace/list/card-wrapper.tsx index 27891ff1e6..aff253934e 100644 --- a/web/app/components/plugins/marketplace/list/card-wrapper.tsx +++ b/web/app/components/plugins/marketplace/list/card-wrapper.tsx @@ -6,6 +6,8 @@ import type { Plugin } from '@/app/components/plugins/types' import { MARKETPLACE_URL_PREFIX } from '@/config' import Button from '@/app/components/base/button' import { useMixedTranslation } from '@/app/components/plugins/marketplace/hooks' +import InstallFromMarketplace from '@/app/components/plugins/install-plugin/install-from-marketplace' +import { useBoolean } from 'ahooks' type CardWrapperProps = { plugin: Plugin @@ -18,6 +20,12 @@ const CardWrapper = ({ locale, }: CardWrapperProps) => { const { t } = useMixedTranslation(locale) + const [isShowInstallFromMarketplace, { + setTrue: showInstallFromMarketplace, + setFalse: hideInstallFromMarketplace, + }] = useBoolean(false) + console.log(plugin) + return (
{t('plugin.detailPanel.operation.install')} @@ -57,6 +66,16 @@ const CardWrapper = ({
) } + { + isShowInstallFromMarketplace && ( + + ) + }
) } diff --git a/web/app/components/plugins/types.ts b/web/app/components/plugins/types.ts index 83c3eca39c..7031ec59ca 100644 --- a/web/app/components/plugins/types.ts +++ b/web/app/components/plugins/types.ts @@ -110,6 +110,7 @@ export type Plugin = { plugin_id: string version: string latest_version: string + latest_package_identifier: string icon: string verified: boolean label: Record From 4cf9ff61325869f0258470b533b16da0ffc5cf67 Mon Sep 17 00:00:00 2001 From: Joel Date: Wed, 6 Nov 2024 15:44:49 +0800 Subject: [PATCH 08/11] chore: remove log --- web/app/components/plugins/marketplace/list/card-wrapper.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/web/app/components/plugins/marketplace/list/card-wrapper.tsx b/web/app/components/plugins/marketplace/list/card-wrapper.tsx index aff253934e..3465e095c4 100644 --- a/web/app/components/plugins/marketplace/list/card-wrapper.tsx +++ b/web/app/components/plugins/marketplace/list/card-wrapper.tsx @@ -24,7 +24,6 @@ const CardWrapper = ({ setTrue: showInstallFromMarketplace, setFalse: hideInstallFromMarketplace, }] = useBoolean(false) - console.log(plugin) return (
Date: Wed, 6 Nov 2024 15:57:50 +0800 Subject: [PATCH 09/11] feat: add install model plugin --- .../plugins/install-plugin/base/installed.tsx | 4 ++-- .../install-from-marketplace/index.tsx | 6 +++--- .../install-from-marketplace/steps/install.tsx | 6 +++--- web/app/components/plugins/provider-card.tsx | 17 +++++++++++++++++ 4 files changed, 25 insertions(+), 8 deletions(-) diff --git a/web/app/components/plugins/install-plugin/base/installed.tsx b/web/app/components/plugins/install-plugin/base/installed.tsx index 8322c3e5eb..442a61e372 100644 --- a/web/app/components/plugins/install-plugin/base/installed.tsx +++ b/web/app/components/plugins/install-plugin/base/installed.tsx @@ -1,7 +1,7 @@ 'use client' import type { FC } from 'react' import React from 'react' -import type { PluginDeclaration, PluginManifestInMarket } from '../../types' +import type { Plugin, PluginDeclaration, PluginManifestInMarket } from '../../types' import Card from '../../card' import Button from '@/app/components/base/button' import { pluginManifestInMarketToPluginProps, pluginManifestToCardPluginProps } from '../utils' @@ -9,7 +9,7 @@ import { useTranslation } from 'react-i18next' import Badge, { BadgeState } from '@/app/components/base/badge/index' type Props = { - payload?: PluginDeclaration | PluginManifestInMarket | null + payload?: Plugin | PluginDeclaration | PluginManifestInMarket | null isMarketPayload?: boolean isFailed: boolean errMsg?: string | null diff --git a/web/app/components/plugins/install-plugin/install-from-marketplace/index.tsx b/web/app/components/plugins/install-plugin/install-from-marketplace/index.tsx index 17eca59dc3..b721a84454 100644 --- a/web/app/components/plugins/install-plugin/install-from-marketplace/index.tsx +++ b/web/app/components/plugins/install-plugin/install-from-marketplace/index.tsx @@ -2,7 +2,7 @@ import React, { useCallback, useState } from 'react' import Modal from '@/app/components/base/modal' -import type { PluginManifestInMarket } from '../../types' +import type { Plugin, PluginManifestInMarket } from '../../types' import { InstallStep } from '../../types' import Install from './steps/install' import Installed from '../base/installed' @@ -12,7 +12,7 @@ const i18nPrefix = 'plugin.installModal' type InstallFromMarketplaceProps = { uniqueIdentifier: string - manifest: PluginManifestInMarket + manifest: PluginManifestInMarket | Plugin onSuccess: () => void onClose: () => void } @@ -36,7 +36,7 @@ const InstallFromMarketplace: React.FC = ({ if (step === InstallStep.installFailed) return t(`${i18nPrefix}.installFailed`) return t(`${i18nPrefix}.installPlugin`) - }, [step]) + }, [step, t]) const handleInstalled = useCallback(() => { setStep(InstallStep.installed) diff --git a/web/app/components/plugins/install-plugin/install-from-marketplace/steps/install.tsx b/web/app/components/plugins/install-plugin/install-from-marketplace/steps/install.tsx index f1f5fecf93..bc32e642a5 100644 --- a/web/app/components/plugins/install-plugin/install-from-marketplace/steps/install.tsx +++ b/web/app/components/plugins/install-plugin/install-from-marketplace/steps/install.tsx @@ -2,7 +2,7 @@ import type { FC } from 'react' import React, { useMemo } from 'react' import { RiInformation2Line } from '@remixicon/react' -import type { PluginManifestInMarket } from '../../../types' +import type { Plugin, PluginManifestInMarket } from '../../../types' import Card from '../../../card' import { pluginManifestInMarketToPluginProps } from '../../utils' import Button from '@/app/components/base/button' @@ -16,7 +16,7 @@ const i18nPrefix = 'plugin.installModal' type Props = { uniqueIdentifier: string - payload: PluginManifestInMarket + payload: PluginManifestInMarket | Plugin onCancel: () => void onStartToInstall?: () => void onInstalled: () => void @@ -104,7 +104,7 @@ const Installed: FC = ({
diff --git a/web/app/components/plugins/provider-card.tsx b/web/app/components/plugins/provider-card.tsx index 2a6ab0f132..5c8ab1891e 100644 --- a/web/app/components/plugins/provider-card.tsx +++ b/web/app/components/plugins/provider-card.tsx @@ -12,7 +12,9 @@ import DownloadCount from './card/base/download-count' import Button from '@/app/components/base/button' import { useGetLanguage } from '@/context/i18n' import { MARKETPLACE_URL_PREFIX } from '@/config' +import InstallFromMarketplace from '@/app/components/plugins/install-plugin/install-from-marketplace' import cn from '@/utils/classnames' +import { useBoolean } from 'ahooks' type Props = { className?: string @@ -24,6 +26,10 @@ const ProviderCard: FC = ({ payload, }) => { const { t } = useTranslation() + const [isShowInstallFromMarketplace, { + setTrue: showInstallFromMarketplace, + setFalse: hideInstallFromMarketplace, + }] = useBoolean(false) const language = useGetLanguage() const { org, label } = payload @@ -58,6 +64,7 @@ const ProviderCard: FC = ({ @@ -71,6 +78,16 @@ const ProviderCard: FC = ({
+ { + isShowInstallFromMarketplace && ( + + ) + }
) } From cce39b85e91cd823c3c94c530cc2fc36b4ad4040 Mon Sep 17 00:00:00 2001 From: twwu Date: Wed, 6 Nov 2024 16:18:18 +0800 Subject: [PATCH 10/11] feat: enhance plugin filtering with tags support --- web/app/components/plugins/plugin-item/index.tsx | 1 - web/app/components/plugins/plugin-page/plugins-panel.tsx | 6 +++--- web/app/components/plugins/types.ts | 1 + 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/web/app/components/plugins/plugin-item/index.tsx b/web/app/components/plugins/plugin-item/index.tsx index ad5860801d..c8b3435393 100644 --- a/web/app/components/plugins/plugin-item/index.tsx +++ b/web/app/components/plugins/plugin-item/index.tsx @@ -21,7 +21,6 @@ import Title from '../card/base/title' import Action from './action' import cn from '@/utils/classnames' import I18n from '@/context/i18n' - import { API_PREFIX, MARKETPLACE_URL_PREFIX } from '@/config' type Props = { diff --git a/web/app/components/plugins/plugin-page/plugins-panel.tsx b/web/app/components/plugins/plugin-page/plugins-panel.tsx index 11a8c3d198..6b8d2475fd 100644 --- a/web/app/components/plugins/plugin-page/plugins-panel.tsx +++ b/web/app/components/plugins/plugin-page/plugins-panel.tsx @@ -10,7 +10,7 @@ import { useDebounceFn } from 'ahooks' import Empty from './empty' const PluginsPanel = () => { - const [filters, setFilters] = usePluginPageContext(v => [v.filters, v.setFilters]) + const [filters, setFilters] = usePluginPageContext(v => [v.filters, v.setFilters]) as [FilterState, (filter: FilterState) => void] const pluginList = usePluginPageContext(v => v.installedPluginList) as PluginDetail[] const mutateInstalledPluginList = usePluginPageContext(v => v.mutateInstalledPluginList) @@ -19,11 +19,11 @@ const PluginsPanel = () => { }, { wait: 500 }) const filteredList = useMemo(() => { - // todo: filter by tags - const { categories, searchQuery } = filters + const { categories, searchQuery, tags } = filters const filteredList = pluginList.filter((plugin) => { return ( (categories.length === 0 || categories.includes(plugin.declaration.category)) + && (tags.length === 0 || tags.some(tag => plugin.declaration.tags.includes(tag))) && (searchQuery === '' || plugin.plugin_id.toLowerCase().includes(searchQuery.toLowerCase())) ) }) diff --git a/web/app/components/plugins/types.ts b/web/app/components/plugins/types.ts index 7031ec59ca..f0f80a3e57 100644 --- a/web/app/components/plugins/types.ts +++ b/web/app/components/plugins/types.ts @@ -69,6 +69,7 @@ export type PluginDeclaration = { endpoint: PluginEndpointDeclaration tool: PluginToolDeclaration model: any // TODO + tags: string[] } export type PluginManifestInMarket = { From 306843fe6af14dcfe499eecab5ff86a4227eca4e Mon Sep 17 00:00:00 2001 From: Joel Date: Wed, 6 Nov 2024 16:42:04 +0800 Subject: [PATCH 11/11] chore: plugin info --- .../plugins/plugin-detail-panel/detail-header.tsx | 5 +++-- .../components/plugins/plugin-page/plugin-info.tsx | 12 ++++++------ 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/web/app/components/plugins/plugin-detail-panel/detail-header.tsx b/web/app/components/plugins/plugin-detail-panel/detail-header.tsx index 37831368e2..2f8ec889f4 100644 --- a/web/app/components/plugins/plugin-detail-panel/detail-header.tsx +++ b/web/app/components/plugins/plugin-detail-panel/detail-header.tsx @@ -52,13 +52,14 @@ const DetailHeader = ({ meta, } = detail const { author, name, label, description, icon, verified } = detail.declaration + const isFromGitHub = source === PluginSource.github // Only plugin installed from GitHub need to check if it's the new version const hasNewVersion = useMemo(() => { return source === PluginSource.github && latest_version !== version }, [source, latest_version, version]) // #plugin TODO# update plugin - const handleUpdate = () => {} + const handleUpdate = () => { } const [isShowPluginInfo, { setTrue: showPluginInfo, @@ -151,7 +152,7 @@ const DetailHeader = ({ {isShowPluginInfo && ( void } @@ -30,9 +30,9 @@ const PlugInfo: FC = ({ closable >
- - - + {repository && } + {release && } + {packageName && }
)