feat: support install failed

This commit is contained in:
Joel 2024-10-23 17:52:39 +08:00
parent 474cedf653
commit d357f359ab
11 changed files with 64 additions and 19 deletions

View File

@ -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 (
<div className={cn('relative', className)}>
@ -34,11 +37,18 @@ const Icon = ({
backgroundImage: `url(${src})`,
}}
>
{installed
&& <div className='flex justify-center items-center gap-2 absolute bottom-[-4px] right-[-4px] w-[18px] h-[18px] rounded-full border-2 border-components-panel-bg bg-state-success-solid'>
{
installed
&& <div className={cn(iconClassName, 'bg-state-success-solid')}>
<RiCheckLine className='w-3 h-3 text-text-primary-on-surface' />
</div>
}
{
installFailed
&& <div className={cn(iconClassName, 'bg-state-destructive-solid')}>
<RiCloseLine className='w-3 h-3 text-text-primary-on-surface' />
</div>
}
</div>
)
}

View File

@ -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 && <CornerMark text={type} />}
{/* Header */}
<div className="flex">
<Icon src={icon} installed={installed} />
<Icon src={icon} installed={installed} installFailed={installFailed} />
<div className="ml-3 grow">
<div className="flex items-center h-5">
<Title title={getLocalizedText(label)} />

View File

@ -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}
/>
)

View File

@ -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 (

View File

@ -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>

View File

@ -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}
/>
)

View File

@ -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'

View File

@ -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>

View File

@ -171,6 +171,7 @@ export enum InstallStep {
readyToInstall = 'readyToInstall',
installing = 'installing',
installed = 'installed',
installFailed = 'failed',
}
export type GitHubAsset = {

View File

@ -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}}...',

View File

@ -62,6 +62,9 @@ const translation = {
installModal: {
installPlugin: '安装插件',
installedSuccessfully: '安装成功',
installedSuccessfullyDesc: '插件已成功安装。',
installFailed: '安装失败',
installFailedDesc: '插件安装失败。',
install: '安装',
installing: '安装中...',
uploadingPackage: '上传 {{packageName}} 中...',