From 18f5f9cc3776e1d862c3a46f4ca0a1906366dada Mon Sep 17 00:00:00 2001 From: Joel Date: Wed, 16 Oct 2024 18:05:55 +0800 Subject: [PATCH 1/2] feat: plugin upgrade --- .../(commonLayout)/plugins/test/card/page.tsx | 2 + .../plugins/test/other/page.tsx | 20 ++++ .../plugins/update-plugin/index.tsx | 101 ++++++++++++++++++ web/i18n/en-US/plugin.ts | 9 ++ web/i18n/zh-Hans/plugin.ts | 9 ++ 5 files changed, 141 insertions(+) create mode 100644 web/app/(commonLayout)/plugins/test/other/page.tsx create mode 100644 web/app/components/plugins/update-plugin/index.tsx diff --git a/web/app/(commonLayout)/plugins/test/card/page.tsx b/web/app/(commonLayout)/plugins/test/card/page.tsx index eea1d32bec..6316f40e64 100644 --- a/web/app/(commonLayout)/plugins/test/card/page.tsx +++ b/web/app/(commonLayout)/plugins/test/card/page.tsx @@ -8,10 +8,12 @@ import ProviderCard from '@/app/components/plugins/provider-card' import PluginDetailPanel from '@/app/components/plugins/plugin-detail-panel' import { getLocaleOnServer, useTranslation as translate } from '@/i18n/server' import Badge from '@/app/components/base/badge' + const PluginList = async () => { const locale = getLocaleOnServer() const pluginList = [toolNotion, extensionDallE, modelGPT4, customTool] const { t: pluginI8n } = await translate(locale, 'plugin') + return (
diff --git a/web/app/(commonLayout)/plugins/test/other/page.tsx b/web/app/(commonLayout)/plugins/test/other/page.tsx new file mode 100644 index 0000000000..3166e34ba3 --- /dev/null +++ b/web/app/(commonLayout)/plugins/test/other/page.tsx @@ -0,0 +1,20 @@ +'use client' +import { useBoolean } from 'ahooks' +import UpdatePlugin from '@/app/components/plugins/update-plugin' + +const Page = () => { + const [isShowUpdateModal, { + setTrue: showUpdateModal, + setFalse: hideUpdateModal, + }] = useBoolean(false) + return ( +
+
Show Upgrade
+ {isShowUpdateModal && ( + + )} +
+ ) +} + +export default Page diff --git a/web/app/components/plugins/update-plugin/index.tsx b/web/app/components/plugins/update-plugin/index.tsx new file mode 100644 index 0000000000..d0abd21e0c --- /dev/null +++ b/web/app/components/plugins/update-plugin/index.tsx @@ -0,0 +1,101 @@ +'use client' +import type { FC } from 'react' +import React, { useCallback, useMemo, useState } from 'react' +import { useContext } from 'use-context-selector' +import { RiInformation2Line } from '@remixicon/react' +import { useTranslation } from 'react-i18next' +import Card from '@/app/components/plugins/card' +import Modal from '@/app/components/base/modal' +import Button from '@/app/components/base/button' +import Badge, { BadgeState } from '@/app/components/base/badge/index' +import I18n from '@/context/i18n' +import { toolNotion } from '@/app/components/plugins/card/card-mock' + +const i18nPrefix = 'plugin.upgrade' + +type Props = { + onHide: () => void +} + +enum UploadStep { + notStarted = 'notStarted', + upgrading = 'upgrading', + installed = 'installed', +} + +const UpdatePluginModal: FC = ({ + onHide, +}) => { + const { locale } = useContext(I18n) + const { t } = useTranslation() + const [uploadStep, setUploadStep] = useState(UploadStep.notStarted) + const configBtnText = useMemo(() => { + return ({ + [UploadStep.notStarted]: t(`${i18nPrefix}.upgrade`), + [UploadStep.upgrading]: t(`${i18nPrefix}.upgrading`), + [UploadStep.installed]: t(`${i18nPrefix}.close`), + })[uploadStep] + }, [uploadStep]) + const handleConfirm = useCallback(() => { + if (uploadStep === UploadStep.notStarted) { + setUploadStep(UploadStep.upgrading) + setTimeout(() => { + setUploadStep(UploadStep.installed) + }, 1500) + return + } + if (uploadStep === UploadStep.installed) + onHide() + }, [uploadStep]) + return ( + +
+ {t(`${i18nPrefix}.description`)} +
+
+ + + {'1.2.0 -> 1.3.2'} + +
+
{t(`${i18nPrefix}.usedInApps`, { num: 3 })}
+ {/* show the used apps */} + +
+ + } + /> +
+
+ {uploadStep === UploadStep.notStarted && ( + + )} + +
+
+ ) +} +export default React.memo(UpdatePluginModal) diff --git a/web/i18n/en-US/plugin.ts b/web/i18n/en-US/plugin.ts index 73361f9fe1..9d94549d64 100644 --- a/web/i18n/en-US/plugin.ts +++ b/web/i18n/en-US/plugin.ts @@ -47,6 +47,15 @@ const translation = { deleteContentRight: ' plugin?', usedInApps: 'This plugin is being used in {{num}} apps.', }, + upgrade: { + title: 'Upgrade Plugin', + successfulTitle: 'Upgrade successful', + description: 'About to upgrade the following plugin', + usedInApps: 'Used in {{num}} apps', + upgrade: 'Upgrade', + upgrading: 'Upgrading...', + close: 'Close', + }, } export default translation diff --git a/web/i18n/zh-Hans/plugin.ts b/web/i18n/zh-Hans/plugin.ts index 2549533865..30f6032261 100644 --- a/web/i18n/zh-Hans/plugin.ts +++ b/web/i18n/zh-Hans/plugin.ts @@ -47,6 +47,15 @@ const translation = { deleteContentRight: ' 插件?', usedInApps: '此插件正在 {{num}} 个应用中使用。', }, + upgrade: { + title: '升级插件', + successfulTitle: '升级成功', + description: '即将升级以下插件', + usedInApps: '在 {{num}} 个应用中使用', + upgrade: '升级', + upgrading: '升级中...', + close: '关闭', + }, } export default translation From cac04c5f3caeefca28b6437f88a19dfd4e487bb5 Mon Sep 17 00:00:00 2001 From: Joel Date: Thu, 17 Oct 2024 15:06:06 +0800 Subject: [PATCH 2/2] refactor: chagne card to client component --- .../(commonLayout)/plugins/test/card/page.tsx | 13 ++------- .../plugins/test/card/test-client-plugin.tsx | 21 -------------- .../model-provider-page/index.tsx | 4 +-- web/app/components/plugins/card/index.tsx | 11 +++---- .../install-from-local-package/index.tsx | 3 +- .../install-from-marketplace/index.tsx | 8 ++--- .../plugins/marketplace/list/index.tsx | 29 ------------------- .../components/plugins/plugin-item/index.tsx | 20 ++++++------- web/app/components/plugins/provider-card.tsx | 7 +++-- .../plugins/update-plugin/index.tsx | 4 --- web/app/components/tools/marketplace.tsx | 29 ------------------- web/app/components/tools/provider-list.tsx | 1 - 12 files changed, 26 insertions(+), 124 deletions(-) delete mode 100644 web/app/(commonLayout)/plugins/test/card/test-client-plugin.tsx diff --git a/web/app/(commonLayout)/plugins/test/card/page.tsx b/web/app/(commonLayout)/plugins/test/card/page.tsx index 6316f40e64..a2ec11e223 100644 --- a/web/app/(commonLayout)/plugins/test/card/page.tsx +++ b/web/app/(commonLayout)/plugins/test/card/page.tsx @@ -1,18 +1,16 @@ import { handleDelete } from './actions' -import TestClientPlugin from './test-client-plugin' import Card from '@/app/components/plugins/card' import { customTool, extensionDallE, modelGPT4, toolNotion } from '@/app/components/plugins/card/card-mock' import PluginItem from '@/app/components/plugins/plugin-item' import CardMoreInfo from '@/app/components/plugins/card/card-more-info' import ProviderCard from '@/app/components/plugins/provider-card' import PluginDetailPanel from '@/app/components/plugins/plugin-detail-panel' -import { getLocaleOnServer, useTranslation as translate } from '@/i18n/server' +import { getLocaleOnServer } from '@/i18n/server' import Badge from '@/app/components/base/badge' const PluginList = async () => { const locale = getLocaleOnServer() const pluginList = [toolNotion, extensionDallE, modelGPT4, customTool] - const { t: pluginI8n } = await translate(locale, 'plugin') return (
@@ -24,19 +22,14 @@ const PluginList = async () => { key={index} payload={plugin as any} onDelete={handleDelete} - pluginI8n={pluginI8n} - locale={locale} /> ))}
-

Client plugin item

-

Install Plugin / Package under bundle

@@ -47,7 +40,6 @@ const PluginList = async () => {
@@ -56,7 +48,7 @@ const PluginList = async () => {

Install model provide

{pluginList.map((plugin, index) => ( - + ))}
@@ -67,7 +59,6 @@ const PluginList = async () => { } diff --git a/web/app/(commonLayout)/plugins/test/card/test-client-plugin.tsx b/web/app/(commonLayout)/plugins/test/card/test-client-plugin.tsx deleted file mode 100644 index 8187428d9c..0000000000 --- a/web/app/(commonLayout)/plugins/test/card/test-client-plugin.tsx +++ /dev/null @@ -1,21 +0,0 @@ -'use client' -import React from 'react' -import { useTranslation } from 'react-i18next' -import { useContext } from 'use-context-selector' -import { extensionDallE } from '@/app/components/plugins/card/card-mock' -import PluginItem from '@/app/components/plugins/plugin-item' -import I18n from '@/context/i18n' - -const TestClientPlugin = () => { - const { locale } = useContext(I18n) - const { t } = useTranslation() - return ( - { }} - pluginI8n={t} - locale={locale} - /> - ) -} -export default React.memo(TestClientPlugin) diff --git a/web/app/components/header/account-setting/model-provider-page/index.tsx b/web/app/components/header/account-setting/model-provider-page/index.tsx index 70965c0b6b..6e441c3dc9 100644 --- a/web/app/components/header/account-setting/model-provider-page/index.tsx +++ b/web/app/components/header/account-setting/model-provider-page/index.tsx @@ -115,7 +115,7 @@ const ModelProviderPage = () => { 'shrink-0 relative flex items-center justify-end gap-2 p-0.5 rounded-lg border border-transparent', defaultModelNotConfigured && 'pl-2 bg-components-panel-bg-blur border-components-panel-border shadow-xs', )}> - {defaultModelNotConfigured &&
} + {defaultModelNotConfigured &&
} {defaultModelNotConfigured && (
@@ -185,7 +185,7 @@ const ModelProviderPage = () => { {!collapse && (
{pluginList.map((plugin, index) => ( - + ))}
)} diff --git a/web/app/components/plugins/card/index.tsx b/web/app/components/plugins/card/index.tsx index d68c410a49..ef0c146512 100644 --- a/web/app/components/plugins/card/index.tsx +++ b/web/app/components/plugins/card/index.tsx @@ -1,4 +1,6 @@ +'use client' import React from 'react' +import { useContext } from 'use-context-selector' import { RiVerifiedBadgeLine } from '@remixicon/react' import type { Plugin } from '../types' import Icon from '../card/base/card-icon' @@ -8,18 +10,16 @@ import OrgInfo from './base/org-info' import Description from './base/description' import Placeholder from './base/placeholder' import cn from '@/utils/classnames' -import type { Locale } from '@/i18n' +import I18n from '@/context/i18n' type Props = { className?: string payload: Plugin - locale: Locale // The component is used in both client and server side, so we can't get the locale from both side(getLocaleOnServer and useContext) titleLeft?: React.ReactNode installed?: boolean hideCornerMark?: boolean descriptionLineRows?: number footer?: React.ReactNode - serverLocale?: Locale isLoading?: boolean loadingFileName?: string } @@ -32,10 +32,11 @@ const Card = ({ hideCornerMark, descriptionLineRows = 2, footer, - locale, isLoading = false, loadingFileName, }: Props) => { + const { locale } = useContext(I18n) + const { type, name, org, label, brief, icon } = payload const getLocalizedText = (obj: Record | undefined) => @@ -80,4 +81,4 @@ const Card = ({ ) } -export default Card +export default React.memo(Card) diff --git a/web/app/components/plugins/install-plugin/install-from-local-package/index.tsx b/web/app/components/plugins/install-plugin/install-from-local-package/index.tsx index 87e470584e..6fd0feead9 100644 --- a/web/app/components/plugins/install-plugin/install-from-local-package/index.tsx +++ b/web/app/components/plugins/install-plugin/install-from-local-package/index.tsx @@ -69,7 +69,6 @@ const InstallFromLocalPackage: React.FC = ({ onClo
= ({ onClo : ( <> )} diff --git a/web/app/components/plugins/marketplace/list/index.tsx b/web/app/components/plugins/marketplace/list/index.tsx index fa5975bb5a..c3d7ff1d24 100644 --- a/web/app/components/plugins/marketplace/list/index.tsx +++ b/web/app/components/plugins/marketplace/list/index.tsx @@ -13,35 +13,30 @@ const List = () => {
Our top picks to get you started
} /> } /> } /> } /> @@ -54,168 +49,144 @@ const List = () => {
Explore the library and discover the incredible work of our community
} /> } /> } /> } /> } /> } /> } /> } /> } /> } /> } /> } /> } /> } /> } /> } /> } /> } /> } /> } /> } /> } /> } /> diff --git a/web/app/components/plugins/plugin-item/index.tsx b/web/app/components/plugins/plugin-item/index.tsx index 452796c27b..08e4bf1419 100644 --- a/web/app/components/plugins/plugin-item/index.tsx +++ b/web/app/components/plugins/plugin-item/index.tsx @@ -1,6 +1,9 @@ +'use client' import type { FC } from 'react' import React from 'react' +import { useContext } from 'use-context-selector' import { RiArrowRightUpLine, RiLoginCircleLine, RiVerifiedBadgeLine } from '@remixicon/react' +import { useTranslation } from 'react-i18next' import { Github } from '../../base/icons/src/public/common' import Badge from '../../base/badge' import type { Plugin } from '../types' @@ -11,26 +14,21 @@ import OrgInfo from '../card/base/org-info' import Title from '../card/base/title' import Action from './action' import cn from '@/utils/classnames' -import type { Locale } from '@/i18n' +import I18n from '@/context/i18n' type Props = { className?: string payload: Plugin - locale: Locale onDelete: () => void - pluginI8n: any - isClient?: boolean } const PluginItem: FC = ({ className, payload, onDelete, - locale, - pluginI8n, - isClient, }) => { - const t = (key: string, param?: object) => pluginI8n(`${isClient ? 'plugin.' : ''}${key}`, param) + const { locale } = useContext(I18n) + const { t } = useTranslation() const { type, name, org, label } = payload const hasNewVersion = payload.latest_version !== payload.version @@ -74,12 +72,12 @@ const PluginItem: FC = ({
·
- {t('endpointsEnabled', { num: 2 })} + {t('plugin.endpointsEnabled', { num: 2 })}
- {t('from')} + {t('plugin.from')}
GitHub
@@ -91,4 +89,4 @@ const PluginItem: FC = ({ ) } -export default PluginItem +export default React.memo(PluginItem) diff --git a/web/app/components/plugins/provider-card.tsx b/web/app/components/plugins/provider-card.tsx index 2445c4b9ab..7d9f21ea43 100644 --- a/web/app/components/plugins/provider-card.tsx +++ b/web/app/components/plugins/provider-card.tsx @@ -1,4 +1,6 @@ +'use client' import React from 'react' +import { useContext } from 'use-context-selector' import type { FC } from 'react' import Link from 'next/link' import { RiArrowRightUpLine, RiVerifiedBadgeLine } from '@remixicon/react' @@ -9,22 +11,21 @@ import Icon from './card/base/card-icon' import Title from './card/base/title' import DownloadCount from './card/base/download-count' import Button from '@/app/components/base/button' -import type { Locale } from '@/i18n' import cn from '@/utils/classnames' +import I18n from '@/context/i18n' type Props = { className?: string - locale: Locale // The component is used in both client and server side, so we can't get the locale from both side(getLocaleOnServer and useContext) payload: Plugin installed?: boolean } const ProviderCard: FC = ({ className, - locale, payload, installed = true, }) => { + const { locale } = useContext(I18n) const { org, label } = payload return ( diff --git a/web/app/components/plugins/update-plugin/index.tsx b/web/app/components/plugins/update-plugin/index.tsx index d0abd21e0c..0a358debac 100644 --- a/web/app/components/plugins/update-plugin/index.tsx +++ b/web/app/components/plugins/update-plugin/index.tsx @@ -1,14 +1,12 @@ 'use client' import type { FC } from 'react' import React, { useCallback, useMemo, useState } from 'react' -import { useContext } from 'use-context-selector' import { RiInformation2Line } from '@remixicon/react' import { useTranslation } from 'react-i18next' import Card from '@/app/components/plugins/card' import Modal from '@/app/components/base/modal' import Button from '@/app/components/base/button' import Badge, { BadgeState } from '@/app/components/base/badge/index' -import I18n from '@/context/i18n' import { toolNotion } from '@/app/components/plugins/card/card-mock' const i18nPrefix = 'plugin.upgrade' @@ -26,7 +24,6 @@ enum UploadStep { const UpdatePluginModal: FC = ({ onHide, }) => { - const { locale } = useContext(I18n) const { t } = useTranslation() const [uploadStep, setUploadStep] = useState(UploadStep.notStarted) const configBtnText = useMemo(() => { @@ -62,7 +59,6 @@ const UpdatePluginModal: FC = ({ diff --git a/web/app/components/tools/marketplace.tsx b/web/app/components/tools/marketplace.tsx index 56f85d447d..9608f4ac69 100644 --- a/web/app/components/tools/marketplace.tsx +++ b/web/app/components/tools/marketplace.tsx @@ -45,35 +45,30 @@ const Marketplace = ({
Our top picks to get you started
} /> } /> } /> } /> @@ -86,168 +81,144 @@ const Marketplace = ({
Explore the library and discover the incredible work of our community
} /> } /> } /> } /> } /> } /> } /> } /> } /> } /> } /> } /> } /> } /> } /> } /> } /> } /> } /> } /> } /> } /> } /> diff --git a/web/app/components/tools/provider-list.tsx b/web/app/components/tools/provider-list.tsx index e0ee954e62..6f8fbc76bf 100644 --- a/web/app/components/tools/provider-list.tsx +++ b/web/app/components/tools/provider-list.tsx @@ -112,7 +112,6 @@ const ProviderList = () => { currentProvider?.id === collection.id && 'border-components-option-card-option-selected-border', )} hideCornerMark - locale={language} payload={{ ...collection, brief: collection.description,