mirror of https://github.com/langgenius/dify.git
Merge branch 'feat/plugins' into dev/plugin-deploy
This commit is contained in:
commit
86f45d7e25
|
|
@ -1,6 +1,7 @@
|
|||
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
|
||||
|
||||
|
|
@ -17,31 +18,37 @@ function checkTaskStatus() {
|
|||
taskId,
|
||||
pluginUniqueIdentifier,
|
||||
}: Params) => {
|
||||
if (isStop) return
|
||||
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
|
||||
Promise.reject(new Error('Plugin package not found'))
|
||||
return
|
||||
return {
|
||||
status: TaskStatus.failed,
|
||||
error: 'Plugin package not found',
|
||||
}
|
||||
}
|
||||
nextStatus = plugin.status
|
||||
if (nextStatus === TaskStatus.running) {
|
||||
setTimeout(async () => {
|
||||
await doCheckStatus({
|
||||
taskId,
|
||||
pluginUniqueIdentifier,
|
||||
})
|
||||
}, INTERVAL)
|
||||
return
|
||||
await sleep(INTERVAL)
|
||||
return await doCheckStatus({
|
||||
taskId,
|
||||
pluginUniqueIdentifier,
|
||||
})
|
||||
}
|
||||
if (nextStatus === TaskStatus.failed) {
|
||||
Promise.reject(plugin.message)
|
||||
return
|
||||
return {
|
||||
status: TaskStatus.failed,
|
||||
error: plugin.message,
|
||||
}
|
||||
}
|
||||
return ({
|
||||
status: nextStatus,
|
||||
status: TaskStatus.success,
|
||||
})
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -2,14 +2,9 @@
|
|||
import type { FC } from 'react'
|
||||
import React from 'react'
|
||||
import Badge, { BadgeState } from '@/app/components/base/badge/index'
|
||||
import type { VersionProps } from '../../types'
|
||||
|
||||
type Props = {
|
||||
hasInstalled: boolean
|
||||
installedVersion?: string
|
||||
toInstallVersion: string
|
||||
}
|
||||
|
||||
const Version: FC<Props> = ({
|
||||
const Version: FC<VersionProps> = ({
|
||||
hasInstalled,
|
||||
installedVersion,
|
||||
toInstallVersion,
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
import { useCheckInstalled as useDoCheckInstalled } from '@/service/use-plugins'
|
||||
|
||||
import { useMemo } from 'react'
|
||||
import type { VersionInfo } from '../../types'
|
||||
type Props = {
|
||||
pluginIds: string[],
|
||||
enabled: boolean
|
||||
|
|
@ -12,10 +13,7 @@ const useCheckInstalled = (props: Props) => {
|
|||
if (!data)
|
||||
return undefined
|
||||
|
||||
const res: Record<string, {
|
||||
installedVersion: string,
|
||||
uniqueIdentifier: string
|
||||
}> = {}
|
||||
const res: Record<string, VersionInfo> = {}
|
||||
data?.plugins.forEach((plugin) => {
|
||||
res[plugin.plugin_id] = {
|
||||
installedVersion: plugin.declaration.version,
|
||||
|
|
|
|||
|
|
@ -6,11 +6,13 @@ import { pluginManifestToCardPluginProps } from '../../utils'
|
|||
import { useUploadGitHub } from '@/service/use-plugins'
|
||||
import Loading from '../../base/loading'
|
||||
import LoadedItem from './loaded-item'
|
||||
import type { VersionProps } from '@/app/components/plugins/types'
|
||||
|
||||
type Props = {
|
||||
checked: boolean
|
||||
onCheckedChange: (plugin: Plugin) => void
|
||||
dependency: GitHubItemAndMarketPlaceDependency
|
||||
versionInfo: VersionProps
|
||||
onFetchedPayload: (payload: Plugin) => void
|
||||
onFetchError: () => void
|
||||
}
|
||||
|
|
@ -19,6 +21,7 @@ const Item: FC<Props> = ({
|
|||
checked,
|
||||
onCheckedChange,
|
||||
dependency,
|
||||
versionInfo,
|
||||
onFetchedPayload,
|
||||
onFetchError,
|
||||
}) => {
|
||||
|
|
@ -50,6 +53,7 @@ const Item: FC<Props> = ({
|
|||
return (
|
||||
<LoadedItem
|
||||
payload={payload}
|
||||
versionInfo={versionInfo}
|
||||
checked={checked}
|
||||
onCheckedChange={onCheckedChange}
|
||||
/>
|
||||
|
|
|
|||
|
|
@ -4,15 +4,17 @@ import React from 'react'
|
|||
import type { Plugin } from '../../../types'
|
||||
import Card from '../../../card'
|
||||
import Checkbox from '@/app/components/base/checkbox'
|
||||
import Badge, { BadgeState } from '@/app/components/base/badge/index'
|
||||
import useGetIcon from '../../base/use-get-icon'
|
||||
import { MARKETPLACE_API_PREFIX } from '@/config'
|
||||
import Version from '../../base/version'
|
||||
import type { VersionProps } from '../../../types'
|
||||
|
||||
type Props = {
|
||||
checked: boolean
|
||||
onCheckedChange: (plugin: Plugin) => void
|
||||
payload: Plugin
|
||||
isFromMarketPlace?: boolean
|
||||
versionInfo: VersionProps
|
||||
}
|
||||
|
||||
const LoadedItem: FC<Props> = ({
|
||||
|
|
@ -20,8 +22,13 @@ const LoadedItem: FC<Props> = ({
|
|||
onCheckedChange,
|
||||
payload,
|
||||
isFromMarketPlace,
|
||||
versionInfo: particleVersionInfo,
|
||||
}) => {
|
||||
const { getIconUrl } = useGetIcon()
|
||||
const versionInfo = {
|
||||
...particleVersionInfo,
|
||||
toInstallVersion: payload.version,
|
||||
}
|
||||
return (
|
||||
<div className='flex items-center space-x-2'>
|
||||
<Checkbox
|
||||
|
|
@ -35,7 +42,7 @@ const LoadedItem: FC<Props> = ({
|
|||
...payload,
|
||||
icon: isFromMarketPlace ? `${MARKETPLACE_API_PREFIX}/plugins/${payload.org}/${payload.name}/icon` : getIconUrl(payload.icon),
|
||||
}}
|
||||
titleLeft={payload.version ? <Badge className='mx-1' size="s" state={BadgeState.Default}>{payload.version}</Badge> : null}
|
||||
titleLeft={payload.version ? <Version {...versionInfo} /> : null}
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
|
|
|
|||
|
|
@ -4,25 +4,31 @@ import React from 'react'
|
|||
import type { Plugin } from '../../../types'
|
||||
import Loading from '../../base/loading'
|
||||
import LoadedItem from './loaded-item'
|
||||
import type { VersionProps } from '@/app/components/plugins/types'
|
||||
|
||||
type Props = {
|
||||
checked: boolean
|
||||
onCheckedChange: (plugin: Plugin) => void
|
||||
payload?: Plugin
|
||||
version: string
|
||||
versionInfo: VersionProps
|
||||
}
|
||||
|
||||
const MarketPlaceItem: FC<Props> = ({
|
||||
checked,
|
||||
onCheckedChange,
|
||||
payload,
|
||||
version,
|
||||
versionInfo,
|
||||
}) => {
|
||||
if (!payload) return <Loading />
|
||||
return (
|
||||
<LoadedItem
|
||||
checked={checked}
|
||||
onCheckedChange={onCheckedChange}
|
||||
payload={payload}
|
||||
payload={{ ...payload, version }}
|
||||
isFromMarketPlace
|
||||
versionInfo={versionInfo}
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,12 +6,14 @@ import type { PackageDependency } from '../../../types'
|
|||
import { pluginManifestToCardPluginProps } from '../../utils'
|
||||
import LoadedItem from './loaded-item'
|
||||
import LoadingError from '../../base/loading-error'
|
||||
import type { VersionProps } from '@/app/components/plugins/types'
|
||||
|
||||
type Props = {
|
||||
checked: boolean
|
||||
onCheckedChange: (plugin: Plugin) => void
|
||||
payload: PackageDependency
|
||||
isFromMarketPlace?: boolean
|
||||
versionInfo: VersionProps
|
||||
}
|
||||
|
||||
const PackageItem: FC<Props> = ({
|
||||
|
|
@ -19,6 +21,7 @@ const PackageItem: FC<Props> = ({
|
|||
checked,
|
||||
onCheckedChange,
|
||||
isFromMarketPlace,
|
||||
versionInfo,
|
||||
}) => {
|
||||
if (!payload.value?.manifest)
|
||||
return <LoadingError />
|
||||
|
|
@ -30,6 +33,7 @@ const PackageItem: FC<Props> = ({
|
|||
checked={checked}
|
||||
onCheckedChange={onCheckedChange}
|
||||
isFromMarketPlace={isFromMarketPlace}
|
||||
versionInfo={versionInfo}
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,10 +1,11 @@
|
|||
'use client'
|
||||
import type { FC } from 'react'
|
||||
import React, { useCallback, useEffect, useMemo, useState } from 'react'
|
||||
import type { Dependency, GitHubItemAndMarketPlaceDependency, PackageDependency, Plugin } from '../../../types'
|
||||
import type { Dependency, GitHubItemAndMarketPlaceDependency, PackageDependency, Plugin, VersionInfo } from '../../../types'
|
||||
import MarketplaceItem from '../item/marketplace-item'
|
||||
import GithubItem from '../item/github-item'
|
||||
import { useFetchPluginsInMarketPlaceByIds, useFetchPluginsInMarketPlaceByInfo } from '@/service/use-plugins'
|
||||
import useCheckInstalled from '@/app/components/plugins/install-plugin/hooks/use-check-installed'
|
||||
import produce from 'immer'
|
||||
import PackageItem from '../item/package-item'
|
||||
import LoadingError from '../../base/loading-error'
|
||||
|
|
@ -13,7 +14,7 @@ type Props = {
|
|||
allPlugins: Dependency[]
|
||||
selectedPlugins: Plugin[]
|
||||
onSelect: (plugin: Plugin, selectedIndex: number) => void
|
||||
onLoadedAllPlugin: () => void
|
||||
onLoadedAllPlugin: (installedInfo: Record<string, VersionInfo>) => void
|
||||
isFromMarketPlace?: boolean
|
||||
}
|
||||
|
||||
|
|
@ -28,6 +29,7 @@ const InstallByDSLList: FC<Props> = ({
|
|||
const { isLoading: isFetchingMarketplaceDataById, data: infoGetById, error: infoByIdError } = useFetchPluginsInMarketPlaceByIds(allPlugins.filter(d => d.type === 'marketplace').map(d => (d as GitHubItemAndMarketPlaceDependency).value.plugin_unique_identifier!))
|
||||
// has meta(org,name,version), to get id
|
||||
const { isLoading: isFetchingDataByMeta, data: infoByMeta, error: infoByMetaError } = useFetchPluginsInMarketPlaceByInfo(allPlugins.filter(d => d.type === 'marketplace').map(d => (d as GitHubItemAndMarketPlaceDependency).value!))
|
||||
|
||||
const [plugins, doSetPlugins] = useState<(Plugin | undefined)[]>((() => {
|
||||
const hasLocalPackage = allPlugins.some(d => d.type === 'package')
|
||||
if (!hasLocalPackage)
|
||||
|
|
@ -45,6 +47,7 @@ const InstallByDSLList: FC<Props> = ({
|
|||
})
|
||||
return _plugins
|
||||
})())
|
||||
|
||||
const pluginsRef = React.useRef<(Plugin | undefined)[]>(plugins)
|
||||
|
||||
const setPlugins = useCallback((p: (Plugin | undefined)[]) => {
|
||||
|
|
@ -132,11 +135,30 @@ const InstallByDSLList: FC<Props> = ({
|
|||
}, [infoByMetaError, infoByIdError])
|
||||
|
||||
const isLoadedAllData = (plugins.filter(p => !!p).length + errorIndexes.length) === allPlugins.length
|
||||
|
||||
const { installedInfo } = useCheckInstalled({
|
||||
pluginIds: plugins?.filter(p => !!p).map((d) => {
|
||||
return `${d?.org || d?.author}/${d?.name}`
|
||||
}) || [],
|
||||
enabled: isLoadedAllData,
|
||||
})
|
||||
|
||||
const getVersionInfo = useCallback((pluginId: string) => {
|
||||
const pluginDetail = installedInfo?.[pluginId]
|
||||
const hasInstalled = !!pluginDetail
|
||||
return {
|
||||
hasInstalled,
|
||||
installedVersion: pluginDetail?.installedVersion,
|
||||
toInstallVersion: '',
|
||||
}
|
||||
}, [installedInfo])
|
||||
|
||||
useEffect(() => {
|
||||
if (isLoadedAllData)
|
||||
onLoadedAllPlugin()
|
||||
if (isLoadedAllData && installedInfo)
|
||||
onLoadedAllPlugin(installedInfo!)
|
||||
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [isLoadedAllData])
|
||||
}, [isLoadedAllData, installedInfo])
|
||||
|
||||
const handleSelect = useCallback((index: number) => {
|
||||
return () => {
|
||||
|
|
@ -151,6 +173,7 @@ const InstallByDSLList: FC<Props> = ({
|
|||
<LoadingError key={index} />
|
||||
)
|
||||
}
|
||||
const plugin = plugins[index]
|
||||
if (d.type === 'github') {
|
||||
return (<GithubItem
|
||||
key={index}
|
||||
|
|
@ -159,6 +182,7 @@ const InstallByDSLList: FC<Props> = ({
|
|||
dependency={d as GitHubItemAndMarketPlaceDependency}
|
||||
onFetchedPayload={handleGitHubPluginFetched(index)}
|
||||
onFetchError={handleGitHubPluginFetchError(index)}
|
||||
versionInfo={getVersionInfo(`${plugin?.org || plugin?.author}/${plugin?.name}`)}
|
||||
/>)
|
||||
}
|
||||
|
||||
|
|
@ -169,6 +193,8 @@ const InstallByDSLList: FC<Props> = ({
|
|||
checked={!!selectedPlugins.find(p => p.plugin_id === plugins[index]?.plugin_id)}
|
||||
onCheckedChange={handleSelect(index)}
|
||||
payload={plugins[index] as Plugin}
|
||||
version={(d as GitHubItemAndMarketPlaceDependency).value.version!}
|
||||
versionInfo={getVersionInfo(`${plugin?.org || plugin?.author}/${plugin?.name}`)}
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
|
@ -181,6 +207,7 @@ const InstallByDSLList: FC<Props> = ({
|
|||
onCheckedChange={handleSelect(index)}
|
||||
payload={d as PackageDependency}
|
||||
isFromMarketPlace={isFromMarketPlace}
|
||||
versionInfo={getVersionInfo(`${plugin?.org || plugin?.author}/${plugin?.name}`)}
|
||||
/>
|
||||
)
|
||||
})
|
||||
|
|
|
|||
|
|
@ -1,12 +1,12 @@
|
|||
'use client'
|
||||
import type { FC } from 'react'
|
||||
import React, { useCallback } from 'react'
|
||||
import type { Dependency, InstallStatusResponse, Plugin } from '../../../types'
|
||||
import React, { useCallback, useState } from 'react'
|
||||
import type { Dependency, InstallStatusResponse, Plugin, VersionInfo } from '../../../types'
|
||||
import Button from '@/app/components/base/button'
|
||||
import { RiLoader2Line } from '@remixicon/react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import InstallMulti from './install-multi'
|
||||
import { useInstallFromMarketplaceAndGitHub } from '@/service/use-plugins'
|
||||
import { useInstallOrUpdate } from '@/service/use-plugins'
|
||||
import { useInvalidateInstalledPluginList } from '@/service/use-plugins'
|
||||
const i18nPrefix = 'plugin.installModal'
|
||||
|
||||
|
|
@ -43,12 +43,15 @@ const Install: FC<Props> = ({
|
|||
}
|
||||
|
||||
const [canInstall, setCanInstall] = React.useState(false)
|
||||
const handleLoadedAllPlugin = useCallback(() => {
|
||||
const [installedInfo, setInstalledInfo] = useState<Record<string, VersionInfo> | undefined>(undefined)
|
||||
|
||||
const handleLoadedAllPlugin = useCallback((installedInfo: Record<string, VersionInfo> | undefined) => {
|
||||
setInstalledInfo(installedInfo)
|
||||
setCanInstall(true)
|
||||
}, [])
|
||||
|
||||
// Install from marketplace and github
|
||||
const { mutate: installFromMarketplaceAndGitHub, isPending: isInstalling } = useInstallFromMarketplaceAndGitHub({
|
||||
const { mutate: installOrUpdate, isPending: isInstalling } = useInstallOrUpdate({
|
||||
onSuccess: (res: InstallStatusResponse[]) => {
|
||||
onInstalled(selectedPlugins, res.map((r, i) => {
|
||||
return ({
|
||||
|
|
@ -62,9 +65,10 @@ const Install: FC<Props> = ({
|
|||
},
|
||||
})
|
||||
const handleInstall = () => {
|
||||
installFromMarketplaceAndGitHub({
|
||||
installOrUpdate({
|
||||
payload: allPlugins.filter((_d, index) => selectedIndexes.includes(index)),
|
||||
plugin: selectedPlugins,
|
||||
installedInfo: installedInfo!,
|
||||
})
|
||||
}
|
||||
return (
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
import React from 'react'
|
||||
import Button from '@/app/components/base/button'
|
||||
import type { PluginDeclaration, PluginType, UpdateFromGitHubPayload } from '../../../types'
|
||||
import { type PluginDeclaration, type PluginType, TaskStatus, type UpdateFromGitHubPayload } from '../../../types'
|
||||
import Card from '../../../card'
|
||||
import Badge, { BadgeState } from '@/app/components/base/badge/index'
|
||||
import { pluginManifestToCardPluginProps } from '../../utils'
|
||||
|
|
@ -53,8 +53,9 @@ const Loaded: React.FC<LoadedProps> = ({
|
|||
|
||||
try {
|
||||
const { owner, repo } = parseGitHubUrl(repoUrl)
|
||||
let taskId
|
||||
if (updatePayload) {
|
||||
const { all_installed: isInstalled, task_id: taskId } = await updateFromGitHub(
|
||||
const { all_installed: isInstalled, task_id } = await updateFromGitHub(
|
||||
`${owner}/${repo}`,
|
||||
selectedVersion,
|
||||
selectedPackage,
|
||||
|
|
@ -62,40 +63,42 @@ const Loaded: React.FC<LoadedProps> = ({
|
|||
uniqueIdentifier,
|
||||
)
|
||||
|
||||
taskId = task_id
|
||||
|
||||
if (isInstalled) {
|
||||
onInstalled()
|
||||
return
|
||||
}
|
||||
|
||||
handleRefetch()
|
||||
await check({
|
||||
taskId,
|
||||
pluginUniqueIdentifier: uniqueIdentifier,
|
||||
})
|
||||
|
||||
onInstalled()
|
||||
}
|
||||
else {
|
||||
const { all_installed: isInstalled, task_id: taskId } = await installPackageFromGitHub({
|
||||
const { all_installed: isInstalled, task_id } = await installPackageFromGitHub({
|
||||
repoUrl: `${owner}/${repo}`,
|
||||
selectedVersion,
|
||||
selectedPackage,
|
||||
uniqueIdentifier,
|
||||
})
|
||||
|
||||
taskId = task_id
|
||||
|
||||
if (isInstalled) {
|
||||
onInstalled()
|
||||
return
|
||||
}
|
||||
|
||||
handleRefetch()
|
||||
await check({
|
||||
taskId,
|
||||
pluginUniqueIdentifier: uniqueIdentifier,
|
||||
})
|
||||
|
||||
onInstalled()
|
||||
}
|
||||
|
||||
const { status, error } = await check({
|
||||
taskId,
|
||||
pluginUniqueIdentifier: uniqueIdentifier,
|
||||
})
|
||||
if (status === TaskStatus.failed) {
|
||||
onFailed(error)
|
||||
return
|
||||
}
|
||||
onInstalled()
|
||||
}
|
||||
catch (e) {
|
||||
if (typeof e === 'string') {
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
'use client'
|
||||
import type { FC } from 'react'
|
||||
import React, { useEffect } from 'react'
|
||||
import type { PluginDeclaration } from '../../../types'
|
||||
import { type PluginDeclaration, TaskStatus } from '../../../types'
|
||||
import Card from '../../../card'
|
||||
import { pluginManifestToCardPluginProps } from '../../utils'
|
||||
import Button from '@/app/components/base/button'
|
||||
|
|
@ -43,9 +43,9 @@ const Installed: FC<Props> = ({
|
|||
const hasInstalled = !!installedVersion
|
||||
|
||||
useEffect(() => {
|
||||
if (hasInstalled && toInstallVersion === installedVersion)
|
||||
if (hasInstalled && uniqueIdentifier === installedInfoPayload.uniqueIdentifier)
|
||||
onInstalled()
|
||||
}, [hasInstalled, toInstallVersion, installedVersion])
|
||||
}, [hasInstalled])
|
||||
|
||||
const [isInstalling, setIsInstalling] = React.useState(false)
|
||||
const { mutateAsync: installPackageFromLocal } = useInstallPackageFromLocal()
|
||||
|
|
@ -95,10 +95,14 @@ const Installed: FC<Props> = ({
|
|||
return
|
||||
}
|
||||
handleRefetch()
|
||||
await check({
|
||||
const { status, error } = await check({
|
||||
taskId,
|
||||
pluginUniqueIdentifier: uniqueIdentifier,
|
||||
})
|
||||
if (status === TaskStatus.failed) {
|
||||
onFailed(error)
|
||||
return
|
||||
}
|
||||
onInstalled()
|
||||
}
|
||||
catch (e) {
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
import type { FC } from 'react'
|
||||
import React, { useEffect } from 'react'
|
||||
// import { RiInformation2Line } from '@remixicon/react'
|
||||
import type { Plugin, PluginManifestInMarket } from '../../../types'
|
||||
import { type Plugin, type PluginManifestInMarket, TaskStatus } from '../../../types'
|
||||
import Card from '../../../card'
|
||||
import { pluginManifestInMarketToPluginProps } from '../../utils'
|
||||
import Button from '@/app/components/base/button'
|
||||
|
|
@ -52,9 +52,9 @@ const Installed: FC<Props> = ({
|
|||
} = checkTaskStatus()
|
||||
|
||||
useEffect(() => {
|
||||
if (hasInstalled && toInstallVersion === installedVersion)
|
||||
if (hasInstalled && uniqueIdentifier === installedInfoPayload.uniqueIdentifier)
|
||||
onInstalled()
|
||||
}, [hasInstalled, toInstallVersion, installedVersion])
|
||||
}, [hasInstalled])
|
||||
|
||||
const handleCancel = () => {
|
||||
stop()
|
||||
|
|
@ -93,10 +93,14 @@ const Installed: FC<Props> = ({
|
|||
onInstalled()
|
||||
return
|
||||
}
|
||||
await check({
|
||||
const { status, error } = await check({
|
||||
taskId,
|
||||
pluginUniqueIdentifier: uniqueIdentifier,
|
||||
})
|
||||
if (status === TaskStatus.failed) {
|
||||
onFailed(error)
|
||||
return
|
||||
}
|
||||
onInstalled()
|
||||
}
|
||||
catch (e) {
|
||||
|
|
|
|||
|
|
@ -109,6 +109,7 @@ export type PluginDetail = {
|
|||
export type Plugin = {
|
||||
type: 'plugin' | 'bundle'
|
||||
org: string
|
||||
author?: string
|
||||
name: string
|
||||
plugin_id: string
|
||||
version: string
|
||||
|
|
@ -359,3 +360,14 @@ export type Version = {
|
|||
export type VersionListResponse = {
|
||||
versions: Version[]
|
||||
}
|
||||
|
||||
export type VersionInfo = {
|
||||
installedVersion: string,
|
||||
uniqueIdentifier: string
|
||||
}
|
||||
|
||||
export type VersionProps = {
|
||||
hasInstalled: boolean
|
||||
installedVersion?: string
|
||||
toInstallVersion: string
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,12 +7,13 @@ 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 type { UpdateFromMarketPlacePayload } from '../types'
|
||||
import { TaskStatus, type UpdateFromMarketPlacePayload } from '../types'
|
||||
import { pluginManifestToCardPluginProps } from '@/app/components/plugins/install-plugin/utils'
|
||||
import useGetIcon from '../install-plugin/base/use-get-icon'
|
||||
import { updateFromMarketPlace } from '@/service/plugins'
|
||||
import checkTaskStatus from '@/app/components/plugins/install-plugin/base/check-task-status'
|
||||
import { usePluginTaskList } from '@/service/use-plugins'
|
||||
import Toast from '../../base/toast'
|
||||
|
||||
const i18nPrefix = 'plugin.upgrade'
|
||||
|
||||
|
|
@ -83,10 +84,14 @@ const UpdatePluginModal: FC<Props> = ({
|
|||
return
|
||||
}
|
||||
handleRefetch()
|
||||
await check({
|
||||
const { status, error } = await check({
|
||||
taskId,
|
||||
pluginUniqueIdentifier: targetPackageInfo.id,
|
||||
})
|
||||
if (status === TaskStatus.failed) {
|
||||
Toast.notify({ type: 'error', message: error! })
|
||||
return
|
||||
}
|
||||
onSave()
|
||||
}
|
||||
// eslint-disable-next-line unused-imports/no-unused-vars
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@ import type {
|
|||
PluginTask,
|
||||
PluginsFromMarketplaceByInfoResponse,
|
||||
PluginsFromMarketplaceResponse,
|
||||
VersionInfo,
|
||||
VersionListResponse,
|
||||
uploadGitHubResponse,
|
||||
} from '@/app/components/plugins/types'
|
||||
|
|
@ -145,22 +146,30 @@ export const useUploadGitHub = (payload: {
|
|||
})
|
||||
}
|
||||
|
||||
export const useInstallFromMarketplaceAndGitHub = ({
|
||||
export const useInstallOrUpdate = ({
|
||||
onSuccess,
|
||||
}: {
|
||||
onSuccess?: (res: { success: boolean }[]) => void
|
||||
}) => {
|
||||
const { mutateAsync: updatePackageFromMarketPlace } = useUpdatePackageFromMarketPlace()
|
||||
|
||||
return useMutation({
|
||||
mutationFn: (data: {
|
||||
payload: Dependency[],
|
||||
plugin: Plugin[],
|
||||
installedInfo: Record<string, VersionInfo>
|
||||
}) => {
|
||||
const { payload, plugin } = data
|
||||
const { payload, plugin, installedInfo } = data
|
||||
|
||||
return Promise.all(payload.map(async (item, i) => {
|
||||
try {
|
||||
const orgAndName = `${plugin[i]?.org || plugin[i]?.author}/${plugin[i]?.name}`
|
||||
const installedPayload = installedInfo[orgAndName]
|
||||
const isInstalled = !!installedPayload
|
||||
let uniqueIdentifier = ''
|
||||
|
||||
if (item.type === 'github') {
|
||||
const data = item as GitHubItemAndMarketPlaceDependency
|
||||
let pluginId = ''
|
||||
// From local bundle don't have data.value.github_plugin_unique_identifier
|
||||
if (!data.value.github_plugin_unique_identifier) {
|
||||
const { unique_identifier } = await post<uploadGitHubResponse>('/workspaces/current/plugin/upload/github', {
|
||||
|
|
@ -170,32 +179,61 @@ export const useInstallFromMarketplaceAndGitHub = ({
|
|||
package: data.value.packages! || data.value.package!,
|
||||
},
|
||||
})
|
||||
pluginId = unique_identifier
|
||||
uniqueIdentifier = data.value.github_plugin_unique_identifier! || unique_identifier
|
||||
// has the same version, but not installed
|
||||
if (uniqueIdentifier === installedPayload?.uniqueIdentifier) {
|
||||
return {
|
||||
success: true,
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!isInstalled) {
|
||||
await post<InstallPackageResponse>('/workspaces/current/plugin/install/github', {
|
||||
body: {
|
||||
repo: data.value.repo!,
|
||||
version: data.value.release! || data.value.version!,
|
||||
package: data.value.packages! || data.value.package!,
|
||||
plugin_unique_identifier: uniqueIdentifier,
|
||||
},
|
||||
})
|
||||
}
|
||||
await post<InstallPackageResponse>('/workspaces/current/plugin/install/github', {
|
||||
body: {
|
||||
repo: data.value.repo!,
|
||||
version: data.value.release! || data.value.version!,
|
||||
package: data.value.packages! || data.value.package!,
|
||||
plugin_unique_identifier: data.value.github_plugin_unique_identifier! || pluginId,
|
||||
},
|
||||
})
|
||||
}
|
||||
if (item.type === 'marketplace') {
|
||||
const data = item as GitHubItemAndMarketPlaceDependency
|
||||
|
||||
await post<InstallPackageResponse>('/workspaces/current/plugin/install/marketplace', {
|
||||
body: {
|
||||
plugin_unique_identifiers: [data.value.plugin_unique_identifier! || plugin[i]?.plugin_id],
|
||||
},
|
||||
})
|
||||
uniqueIdentifier = data.value.plugin_unique_identifier! || plugin[i]?.plugin_id
|
||||
if (uniqueIdentifier === installedPayload?.uniqueIdentifier) {
|
||||
return {
|
||||
success: true,
|
||||
}
|
||||
}
|
||||
if (!isInstalled) {
|
||||
await post<InstallPackageResponse>('/workspaces/current/plugin/install/marketplace', {
|
||||
body: {
|
||||
plugin_unique_identifiers: [uniqueIdentifier],
|
||||
},
|
||||
})
|
||||
}
|
||||
}
|
||||
if (item.type === 'package') {
|
||||
const data = item as PackageDependency
|
||||
await post<InstallPackageResponse>('/workspaces/current/plugin/install/pkg', {
|
||||
body: {
|
||||
plugin_unique_identifiers: [data.value.unique_identifier],
|
||||
},
|
||||
uniqueIdentifier = data.value.unique_identifier
|
||||
if (uniqueIdentifier === installedPayload?.uniqueIdentifier) {
|
||||
return {
|
||||
success: true,
|
||||
}
|
||||
}
|
||||
if (!isInstalled) {
|
||||
await post<InstallPackageResponse>('/workspaces/current/plugin/install/pkg', {
|
||||
body: {
|
||||
plugin_unique_identifiers: [uniqueIdentifier],
|
||||
},
|
||||
})
|
||||
}
|
||||
}
|
||||
if (isInstalled) {
|
||||
await updatePackageFromMarketPlace({
|
||||
original_plugin_unique_identifier: installedPayload?.uniqueIdentifier,
|
||||
new_plugin_unique_identifier: uniqueIdentifier,
|
||||
})
|
||||
}
|
||||
return ({ success: true })
|
||||
|
|
|
|||
Loading…
Reference in New Issue