diff --git a/web/app/components/plugins/card/base/card-icon.tsx b/web/app/components/plugins/card/base/card-icon.tsx index 4c0335c248..a30267bc43 100644 --- a/web/app/components/plugins/card/base/card-icon.tsx +++ b/web/app/components/plugins/card/base/card-icon.tsx @@ -1,4 +1,4 @@ -import { RiCheckLine } from '@remixicon/react' +import { RiCheckLine, RiCloseLine } from '@remixicon/react' import AppIcon from '@/app/components/base/app-icon' import cn from '@/utils/classnames' @@ -6,14 +6,17 @@ const Icon = ({ className, src, installed = false, + installFailed = false, }: { className?: string src: string | { - 'content': string - 'background': string + content: string + background: string } installed?: boolean + installFailed?: boolean }) => { + const iconClassName = 'flex justify-center items-center gap-2 absolute bottom-[-4px] right-[-4px] w-[18px] h-[18px] rounded-full border-2 border-components-panel-bg' if (typeof src === 'object') { return (
@@ -34,11 +37,18 @@ const Icon = ({ backgroundImage: `url(${src})`, }} > - {installed - &&
+ { + installed + &&
} + { + installFailed + &&
+ +
+ }
) } diff --git a/web/app/components/plugins/card/index.tsx b/web/app/components/plugins/card/index.tsx index 14dffe8f37..be68ab0ae1 100644 --- a/web/app/components/plugins/card/index.tsx +++ b/web/app/components/plugins/card/index.tsx @@ -16,6 +16,7 @@ export type Props = { payload: Plugin titleLeft?: React.ReactNode installed?: boolean + installFailed?: boolean hideCornerMark?: boolean descriptionLineRows?: number footer?: React.ReactNode @@ -28,6 +29,7 @@ const Card = ({ payload, titleLeft, installed, + installFailed, hideCornerMark, descriptionLineRows = 2, footer, @@ -56,7 +58,7 @@ const Card = ({ {!hideCornerMark && } {/* Header */}
- +
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 50478bddb4..3d18625839 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 @@ -23,7 +23,7 @@ const InstallFromLocalPackage: React.FC<InstallFromLocalPackageProps> = ({ onClose, }) => { const { t } = useTranslation() - // uploading -> readyToInstall -> installed + // uploading -> readyToInstall -> installed/failed const [step, setStep] = useState<InstallStep>(InstallStep.uploading) const [uniqueIdentifier, setUniqueIdentifier] = useState<string | null>(null) @@ -31,6 +31,8 @@ const InstallFromLocalPackage: React.FC<InstallFromLocalPackageProps> = ({ const getTitle = useCallback(() => { if (step === InstallStep.installed) return t(`${i18nPrefix}.installedSuccessfully`) + if (step === InstallStep.installFailed) + return t(`${i18nPrefix}.installFailed`) return t(`${i18nPrefix}.installPlugin`) }, []) const [manifest, setManifest] = useState<PluginDeclaration | null>(toolNotionManifest) @@ -48,6 +50,10 @@ const InstallFromLocalPackage: React.FC<InstallFromLocalPackageProps> = ({ setStep(InstallStep.installed) }, []) + const handleFailed = useCallback(() => { + setStep(InstallStep.installFailed) + }, []) + return ( <Modal isShow={true} @@ -73,13 +79,15 @@ const InstallFromLocalPackage: React.FC<InstallFromLocalPackageProps> = ({ payload={manifest!} onCancel={onClose} onInstalled={handleInstalled} + onFailed={handleFailed} /> ) } { - step === InstallStep.installed && ( + ([InstallStep.installed, InstallStep.installFailed].includes(step)) && ( <Installed payload={manifest!} + isFailed={step === InstallStep.installFailed} onCancel={onClose} /> ) diff --git a/web/app/components/plugins/install-plugin/install-from-local-package/steps/install.tsx b/web/app/components/plugins/install-plugin/install-from-local-package/steps/install.tsx index 5067dff908..8572d96a3a 100644 --- a/web/app/components/plugins/install-plugin/install-from-local-package/steps/install.tsx +++ b/web/app/components/plugins/install-plugin/install-from-local-package/steps/install.tsx @@ -15,12 +15,14 @@ type Props = { payload: PluginDeclaration onCancel: () => void onInstalled: () => void + onFailed: () => void } const Installed: FC<Props> = ({ payload, onCancel, onInstalled, + onFailed, }) => { const { t } = useTranslation() const [isInstalling, setIsInstalling] = React.useState(false) @@ -29,7 +31,8 @@ const Installed: FC<Props> = ({ if (isInstalling) return setIsInstalling(true) await sleep(1500) - onInstalled() + // onInstalled() + onFailed() } return ( diff --git a/web/app/components/plugins/install-plugin/install-from-local-package/steps/installed.tsx b/web/app/components/plugins/install-plugin/install-from-local-package/steps/installed.tsx index 34fad51691..2288371b7d 100644 --- a/web/app/components/plugins/install-plugin/install-from-local-package/steps/installed.tsx +++ b/web/app/components/plugins/install-plugin/install-from-local-package/steps/installed.tsx @@ -9,24 +9,26 @@ import { useTranslation } from 'react-i18next' type Props = { payload: PluginDeclaration + isFailed: boolean onCancel: () => void - } const Installed: FC<Props> = ({ payload, + isFailed, onCancel, }) => { const { t } = useTranslation() return ( <> <div className='flex flex-col px-6 py-3 justify-center items-start gap-4 self-stretch'> - <p className='text-text-secondary system-md-regular'>The plugin has been installed successfully.</p> + <p className='text-text-secondary system-md-regular'>{t(`plugin.installModal.${isFailed ? 'installFailedDesc' : 'installedSuccessfullyDesc'}`)}</p> <div className='flex p-2 items-start content-start gap-1 self-stretch flex-wrap rounded-2xl bg-background-section-burn'> <Card className='w-full' payload={pluginManifestToCardPluginProps(payload)} - installed + installed={!isFailed} + installFailed={isFailed} /> </div> </div> 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 411e2cf1f1..86c0150b5d 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 @@ -24,7 +24,7 @@ const InstallFromMarketplace: React.FC<InstallFromMarketplaceProps> = ({ onClose, }) => { const { t } = useTranslation() - // readyToInstall -> check installed -> installed + // readyToInstall -> check installed -> installed/failed const [step, setStep] = useState<InstallStep>(InstallStep.readyToInstall) // TODO: check installed in beta version. @@ -32,13 +32,19 @@ const InstallFromMarketplace: React.FC<InstallFromMarketplaceProps> = ({ const getTitle = useCallback(() => { if (step === InstallStep.installed) return t(`${i18nPrefix}.installedSuccessfully`) + if (step === InstallStep.installFailed) + return t(`${i18nPrefix}.installFailed`) return t(`${i18nPrefix}.installPlugin`) }, []) - const handleInstalled = useCallback(async () => { + const handleInstalled = useCallback(() => { setStep(InstallStep.installed) }, []) + const handleFailed = useCallback(() => { + setStep(InstallStep.installFailed) + }, []) + return ( <Modal isShow={true} @@ -57,13 +63,15 @@ const InstallFromMarketplace: React.FC<InstallFromMarketplaceProps> = ({ payload={manifest!} onCancel={onClose} onInstalled={handleInstalled} + onFailed={handleFailed} /> ) } { - step === InstallStep.installed && ( + ([InstallStep.installed, InstallStep.installFailed].includes(step)) && ( <Installed payload={manifest!} + isFailed={step === InstallStep.installFailed} onCancel={onSuccess} /> ) 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 eb5072b7e3..df5a551339 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 @@ -17,12 +17,14 @@ type Props = { payload: PluginDeclaration onCancel: () => void onInstalled: () => void + onFailed: () => void } const Installed: FC<Props> = ({ payload, onCancel, onInstalled, + onFailed, }) => { const { t } = useTranslation() const [isInstalling, setIsInstalling] = React.useState(false) @@ -32,6 +34,7 @@ const Installed: FC<Props> = ({ setIsInstalling(true) await sleep(1500) onInstalled() + // onFailed() } const toInstallVersion = '1.3.0' diff --git a/web/app/components/plugins/install-plugin/install-from-marketplace/steps/installed.tsx b/web/app/components/plugins/install-plugin/install-from-marketplace/steps/installed.tsx index 34fad51691..2288371b7d 100644 --- a/web/app/components/plugins/install-plugin/install-from-marketplace/steps/installed.tsx +++ b/web/app/components/plugins/install-plugin/install-from-marketplace/steps/installed.tsx @@ -9,24 +9,26 @@ import { useTranslation } from 'react-i18next' type Props = { payload: PluginDeclaration + isFailed: boolean onCancel: () => void - } const Installed: FC<Props> = ({ payload, + isFailed, onCancel, }) => { const { t } = useTranslation() return ( <> <div className='flex flex-col px-6 py-3 justify-center items-start gap-4 self-stretch'> - <p className='text-text-secondary system-md-regular'>The plugin has been installed successfully.</p> + <p className='text-text-secondary system-md-regular'>{t(`plugin.installModal.${isFailed ? 'installFailedDesc' : 'installedSuccessfullyDesc'}`)}</p> <div className='flex p-2 items-start content-start gap-1 self-stretch flex-wrap rounded-2xl bg-background-section-burn'> <Card className='w-full' payload={pluginManifestToCardPluginProps(payload)} - installed + installed={!isFailed} + installFailed={isFailed} /> </div> </div> diff --git a/web/app/components/plugins/types.ts b/web/app/components/plugins/types.ts index 465f131ed0..8fdea20406 100644 --- a/web/app/components/plugins/types.ts +++ b/web/app/components/plugins/types.ts @@ -171,6 +171,7 @@ export enum InstallStep { readyToInstall = 'readyToInstall', installing = 'installing', installed = 'installed', + installFailed = 'failed', } export type GitHubAsset = { diff --git a/web/i18n/en-US/plugin.ts b/web/i18n/en-US/plugin.ts index cf426e2b4e..1be0398331 100644 --- a/web/i18n/en-US/plugin.ts +++ b/web/i18n/en-US/plugin.ts @@ -61,7 +61,10 @@ const translation = { }, installModal: { installPlugin: 'Install Plugin', - installedSuccessfully: 'Install successful', + installedSuccessfully: 'Installation successful', + installedSuccessfullyDesc: 'The plugin has been installed successfully.', + installFailed: 'Installation failed', + installFailedDesc: 'The plugin has been installed failed.', install: 'Install', installing: 'Installing...', uploadingPackage: 'Uploading {{packageName}}...', diff --git a/web/i18n/zh-Hans/plugin.ts b/web/i18n/zh-Hans/plugin.ts index 2d5a39b7df..91f7a998eb 100644 --- a/web/i18n/zh-Hans/plugin.ts +++ b/web/i18n/zh-Hans/plugin.ts @@ -62,6 +62,9 @@ const translation = { installModal: { installPlugin: '安装插件', installedSuccessfully: '安装成功', + installedSuccessfullyDesc: '插件已成功安装。', + installFailed: '安装失败', + installFailedDesc: '插件安装失败。', install: '安装', installing: '安装中...', uploadingPackage: '上传 {{packageName}} 中...',