dify
This commit is contained in:
@@ -0,0 +1,63 @@
|
||||
import { checkTaskStatus as fetchCheckTaskStatus } from '@/service/plugins'
|
||||
import type { PluginStatus } from '../../types'
|
||||
import { TaskStatus } from '../../types'
|
||||
import { sleep } from '@/utils'
|
||||
|
||||
const INTERVAL = 10 * 1000 // 10 seconds
|
||||
|
||||
type Params = {
|
||||
taskId: string
|
||||
pluginUniqueIdentifier: string
|
||||
}
|
||||
|
||||
function checkTaskStatus() {
|
||||
let nextStatus = TaskStatus.running
|
||||
let isStop = false
|
||||
|
||||
const doCheckStatus = async ({
|
||||
taskId,
|
||||
pluginUniqueIdentifier,
|
||||
}: Params) => {
|
||||
if (isStop) {
|
||||
return {
|
||||
status: TaskStatus.success,
|
||||
}
|
||||
}
|
||||
const res = await fetchCheckTaskStatus(taskId)
|
||||
const { plugins } = res.task
|
||||
const plugin = plugins.find((p: PluginStatus) => p.plugin_unique_identifier === pluginUniqueIdentifier)
|
||||
if (!plugin) {
|
||||
nextStatus = TaskStatus.failed
|
||||
return {
|
||||
status: TaskStatus.failed,
|
||||
error: 'Plugin package not found',
|
||||
}
|
||||
}
|
||||
nextStatus = plugin.status
|
||||
if (nextStatus === TaskStatus.running) {
|
||||
await sleep(INTERVAL)
|
||||
return await doCheckStatus({
|
||||
taskId,
|
||||
pluginUniqueIdentifier,
|
||||
})
|
||||
}
|
||||
if (nextStatus === TaskStatus.failed) {
|
||||
return {
|
||||
status: TaskStatus.failed,
|
||||
error: plugin.message,
|
||||
}
|
||||
}
|
||||
return ({
|
||||
status: TaskStatus.success,
|
||||
})
|
||||
}
|
||||
|
||||
return {
|
||||
check: doCheckStatus,
|
||||
stop: () => {
|
||||
isStop = true
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
export default checkTaskStatus
|
||||
@@ -0,0 +1,60 @@
|
||||
'use client'
|
||||
import type { FC } from 'react'
|
||||
import React from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import Card from '../../card'
|
||||
import Button from '@/app/components/base/button'
|
||||
import type { Plugin, PluginDeclaration, PluginManifestInMarket } from '../../types'
|
||||
import { pluginManifestInMarketToPluginProps, pluginManifestToCardPluginProps } from '../utils'
|
||||
import Badge, { BadgeState } from '@/app/components/base/badge/index'
|
||||
|
||||
type Props = {
|
||||
payload?: Plugin | PluginDeclaration | PluginManifestInMarket | null
|
||||
isMarketPayload?: boolean
|
||||
isFailed: boolean
|
||||
errMsg?: string | null
|
||||
onCancel: () => void
|
||||
}
|
||||
|
||||
const Installed: FC<Props> = ({
|
||||
payload,
|
||||
isMarketPayload,
|
||||
isFailed,
|
||||
errMsg,
|
||||
onCancel,
|
||||
}) => {
|
||||
const { t } = useTranslation()
|
||||
|
||||
const handleClose = () => {
|
||||
onCancel()
|
||||
}
|
||||
return (
|
||||
<>
|
||||
<div className='flex flex-col items-start justify-center gap-4 self-stretch px-6 py-3'>
|
||||
<p className='system-md-regular text-text-secondary'>{(isFailed && errMsg) ? errMsg : t(`plugin.installModal.${isFailed ? 'installFailedDesc' : 'installedSuccessfullyDesc'}`)}</p>
|
||||
{payload && (
|
||||
<div className='flex flex-wrap content-start items-start gap-1 self-stretch rounded-2xl bg-background-section-burn p-2'>
|
||||
<Card
|
||||
className='w-full'
|
||||
payload={isMarketPayload ? pluginManifestInMarketToPluginProps(payload as PluginManifestInMarket) : pluginManifestToCardPluginProps(payload as PluginDeclaration)}
|
||||
installed={!isFailed}
|
||||
installFailed={isFailed}
|
||||
titleLeft={<Badge className='mx-1' size="s" state={BadgeState.Default}>{(payload as PluginDeclaration).version || (payload as PluginManifestInMarket).latest_version}</Badge>}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
{/* Action Buttons */}
|
||||
<div className='flex items-center justify-end gap-2 self-stretch p-6 pt-5'>
|
||||
<Button
|
||||
variant='primary'
|
||||
className='min-w-[72px]'
|
||||
onClick={handleClose}
|
||||
>
|
||||
{t('common.operation.close')}
|
||||
</Button>
|
||||
</div>
|
||||
</>
|
||||
)
|
||||
}
|
||||
export default React.memo(Installed)
|
||||
@@ -0,0 +1,45 @@
|
||||
'use client'
|
||||
import type { FC } from 'react'
|
||||
import React from 'react'
|
||||
import { Group } from '../../../base/icons/src/vender/other'
|
||||
import { LoadingPlaceholder } from '@/app/components/plugins/card/base/placeholder'
|
||||
import Checkbox from '@/app/components/base/checkbox'
|
||||
import { RiCloseLine } from '@remixicon/react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
|
||||
const LoadingError: FC = () => {
|
||||
const { t } = useTranslation()
|
||||
return (
|
||||
<div className='flex items-center space-x-2'>
|
||||
<Checkbox
|
||||
className='shrink-0'
|
||||
checked={false}
|
||||
disabled
|
||||
/>
|
||||
<div className='hover-bg-components-panel-on-panel-item-bg relative grow rounded-xl border-[0.5px] border-components-panel-border bg-components-panel-on-panel-item-bg p-4 pb-3 shadow-xs'>
|
||||
<div className="flex">
|
||||
<div
|
||||
className='relative flex h-10 w-10 items-center justify-center gap-2 rounded-[10px] border-[0.5px]
|
||||
border-state-destructive-border bg-state-destructive-hover p-1 backdrop-blur-sm'>
|
||||
<div className='flex h-5 w-5 items-center justify-center'>
|
||||
<Group className='text-text-quaternary' />
|
||||
</div>
|
||||
<div className='absolute bottom-[-4px] right-[-4px] rounded-full border-[2px] border-components-panel-bg bg-state-destructive-solid'>
|
||||
<RiCloseLine className='h-3 w-3 text-text-primary-on-surface' />
|
||||
</div>
|
||||
</div>
|
||||
<div className="ml-3 grow">
|
||||
<div className="system-md-semibold flex h-5 items-center text-text-destructive">
|
||||
{t('plugin.installModal.pluginLoadError')}
|
||||
</div>
|
||||
<div className='system-xs-regular mt-0.5 text-text-tertiary'>
|
||||
{t('plugin.installModal.pluginLoadErrorDesc')}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<LoadingPlaceholder className="mt-3 w-[420px]" />
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
export default React.memo(LoadingError)
|
||||
@@ -0,0 +1,23 @@
|
||||
'use client'
|
||||
import React from 'react'
|
||||
import Placeholder from '../../card/base/placeholder'
|
||||
import Checkbox from '@/app/components/base/checkbox'
|
||||
|
||||
const Loading = () => {
|
||||
return (
|
||||
<div className='flex items-center space-x-2'>
|
||||
<Checkbox
|
||||
className='shrink-0'
|
||||
checked={false}
|
||||
disabled
|
||||
/>
|
||||
<div className='hover-bg-components-panel-on-panel-item-bg relative grow rounded-xl border-[0.5px] border-components-panel-border bg-components-panel-on-panel-item-bg p-4 pb-3 shadow-xs'>
|
||||
<Placeholder
|
||||
wrapClassName='w-full'
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default React.memo(Loading)
|
||||
@@ -0,0 +1,16 @@
|
||||
import { useCallback } from 'react'
|
||||
import { API_PREFIX } from '@/config'
|
||||
import { useSelector } from '@/context/app-context'
|
||||
|
||||
const useGetIcon = () => {
|
||||
const currentWorkspace = useSelector(s => s.currentWorkspace)
|
||||
const getIconUrl = useCallback((fileName: string) => {
|
||||
return `${API_PREFIX}/workspaces/current/plugin/icon?tenant_id=${currentWorkspace.id}&filename=${fileName}`
|
||||
}, [currentWorkspace.id])
|
||||
|
||||
return {
|
||||
getIconUrl,
|
||||
}
|
||||
}
|
||||
|
||||
export default useGetIcon
|
||||
@@ -0,0 +1,34 @@
|
||||
'use client'
|
||||
import type { FC } from 'react'
|
||||
import React from 'react'
|
||||
import Badge, { BadgeState } from '@/app/components/base/badge/index'
|
||||
import type { VersionProps } from '../../types'
|
||||
|
||||
const Version: FC<VersionProps> = ({
|
||||
hasInstalled,
|
||||
installedVersion,
|
||||
toInstallVersion,
|
||||
}) => {
|
||||
return (
|
||||
<>
|
||||
{
|
||||
!hasInstalled
|
||||
? (
|
||||
<Badge className='mx-1' size="s" state={BadgeState.Default}>{toInstallVersion}</Badge>
|
||||
)
|
||||
: (
|
||||
<>
|
||||
<Badge className='mx-1' size="s" state={BadgeState.Warning}>
|
||||
{`${installedVersion} -> ${toInstallVersion}`}
|
||||
</Badge>
|
||||
{/* <div className='flex px-0.5 justify-center items-center gap-0.5'>
|
||||
<div className='text-text-warning system-xs-medium'>Used in 3 apps</div>
|
||||
<RiInformation2Line className='w-4 h-4 text-text-tertiary' />
|
||||
</div> */}
|
||||
</>
|
||||
)
|
||||
}
|
||||
</>
|
||||
)
|
||||
}
|
||||
export default React.memo(Version)
|
||||
Reference in New Issue
Block a user