Merge branch 'feat/plugins' of github.com:langgenius/dify into feat/plugins
commit
495d86fd96
@ -0,0 +1,47 @@
|
||||
'use client'
|
||||
import type { FC } from 'react'
|
||||
import React, { useEffect } from 'react'
|
||||
import type { Dependency, Plugin } from '../../../types'
|
||||
import { pluginManifestToCardPluginProps } from '../../utils'
|
||||
import { useUploadGitHub } from '@/service/use-plugins'
|
||||
import Loading from './loading'
|
||||
import LoadedItem from './loaded-item'
|
||||
|
||||
type Props = {
|
||||
checked: boolean
|
||||
onCheckedChange: (plugin: Plugin) => void
|
||||
dependency: Dependency
|
||||
onFetchedPayload: (payload: Plugin) => void
|
||||
}
|
||||
|
||||
const Item: FC<Props> = ({
|
||||
checked,
|
||||
onCheckedChange,
|
||||
dependency,
|
||||
onFetchedPayload,
|
||||
}) => {
|
||||
const info = dependency.value
|
||||
const { data } = useUploadGitHub({
|
||||
repo: info.repo!,
|
||||
version: info.version!,
|
||||
package: info.package!,
|
||||
})
|
||||
const [payload, setPayload] = React.useState<Plugin | null>(null)
|
||||
useEffect(() => {
|
||||
if (data) {
|
||||
const payload = pluginManifestToCardPluginProps(data.manifest)
|
||||
onFetchedPayload(payload)
|
||||
setPayload(payload)
|
||||
}
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [data])
|
||||
if (!payload) return <Loading />
|
||||
return (
|
||||
<LoadedItem
|
||||
payload={payload}
|
||||
checked={checked}
|
||||
onCheckedChange={onCheckedChange}
|
||||
/>
|
||||
)
|
||||
}
|
||||
export default React.memo(Item)
|
||||
@ -0,0 +1,36 @@
|
||||
'use client'
|
||||
import type { FC } from 'react'
|
||||
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'
|
||||
|
||||
type Props = {
|
||||
checked: boolean
|
||||
onCheckedChange: (plugin: Plugin) => void
|
||||
payload: Plugin
|
||||
}
|
||||
|
||||
const LoadedItem: FC<Props> = ({
|
||||
checked,
|
||||
onCheckedChange,
|
||||
payload,
|
||||
}) => {
|
||||
return (
|
||||
<div className='flex items-center space-x-2'>
|
||||
<Checkbox
|
||||
className='shrink-0'
|
||||
checked={checked}
|
||||
onCheck={() => onCheckedChange(payload)}
|
||||
/>
|
||||
<Card
|
||||
className='grow'
|
||||
payload={payload}
|
||||
titleLeft={<Badge className='mx-1' size="s" state={BadgeState.Default}>{payload.version}</Badge>}
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default React.memo(LoadedItem)
|
||||
@ -0,0 +1,12 @@
|
||||
'use client'
|
||||
import React from 'react'
|
||||
|
||||
const Loading = () => {
|
||||
return (
|
||||
<div>
|
||||
Loading...
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default React.memo(Loading)
|
||||
@ -0,0 +1,29 @@
|
||||
'use client'
|
||||
import type { FC } from 'react'
|
||||
import React from 'react'
|
||||
import type { Plugin } from '../../../types'
|
||||
import Loading from './loading'
|
||||
import LoadedItem from './loaded-item'
|
||||
|
||||
type Props = {
|
||||
checked: boolean
|
||||
onCheckedChange: (plugin: Plugin) => void
|
||||
payload?: Plugin
|
||||
}
|
||||
|
||||
const MarketPlaceItem: FC<Props> = ({
|
||||
checked,
|
||||
onCheckedChange,
|
||||
payload,
|
||||
}) => {
|
||||
if (!payload) return <Loading />
|
||||
return (
|
||||
<LoadedItem
|
||||
checked={checked}
|
||||
onCheckedChange={onCheckedChange}
|
||||
payload={payload}
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
||||
export default React.memo(MarketPlaceItem)
|
||||
@ -0,0 +1,83 @@
|
||||
'use client'
|
||||
import type { FC } from 'react'
|
||||
import React, { useCallback, useEffect, useMemo } from 'react'
|
||||
import type { Dependency, Plugin } from '../../../types'
|
||||
import MarketplaceItem from '../item/marketplace-item'
|
||||
import GithubItem from '../item/github-item'
|
||||
import { useFetchPluginsInMarketPlaceByIds } from '@/service/use-plugins'
|
||||
import produce from 'immer'
|
||||
import { useGetState } from 'ahooks'
|
||||
|
||||
type Props = {
|
||||
fromDSLPayload: Dependency[]
|
||||
selectedPlugins: Plugin[]
|
||||
handleSelect: (plugin: Plugin) => void
|
||||
onLoadedAllPlugin: () => void
|
||||
}
|
||||
|
||||
const InstallByDSLList: FC<Props> = ({
|
||||
fromDSLPayload,
|
||||
selectedPlugins,
|
||||
handleSelect,
|
||||
onLoadedAllPlugin,
|
||||
}) => {
|
||||
const { isLoading: isFetchingMarketplaceData, data: marketplaceRes } = useFetchPluginsInMarketPlaceByIds(fromDSLPayload.filter(d => d.type === 'marketplace').map(d => d.value.plugin_unique_identifier!))
|
||||
const [plugins, setPlugins, getPlugins] = useGetState<Plugin[]>([])
|
||||
const handlePlugInFetched = useCallback((index: number) => {
|
||||
return (p: Plugin) => {
|
||||
setPlugins(plugins.map((item, i) => i === index ? p : item))
|
||||
}
|
||||
}, [plugins])
|
||||
|
||||
const marketPlaceInDSLIndex = useMemo(() => {
|
||||
const res: number[] = []
|
||||
fromDSLPayload.forEach((d, index) => {
|
||||
if (d.type === 'marketplace')
|
||||
res.push(index)
|
||||
})
|
||||
return res
|
||||
}, [fromDSLPayload])
|
||||
|
||||
useEffect(() => {
|
||||
if (!isFetchingMarketplaceData && marketplaceRes?.data.plugins && marketplaceRes?.data.plugins.length > 0) {
|
||||
const payloads = marketplaceRes?.data.plugins
|
||||
|
||||
const nextPlugins = produce(getPlugins(), (draft) => {
|
||||
marketPlaceInDSLIndex.forEach((index, i) => {
|
||||
draft[index] = payloads[i]
|
||||
})
|
||||
})
|
||||
setPlugins(nextPlugins)
|
||||
// marketplaceRes?.data.plugins
|
||||
}
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [isFetchingMarketplaceData])
|
||||
|
||||
const isLoadedAllData = fromDSLPayload.length === plugins.length && plugins.every(p => !!p)
|
||||
useEffect(() => {
|
||||
if (isLoadedAllData)
|
||||
onLoadedAllPlugin()
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [isLoadedAllData])
|
||||
return (
|
||||
<>
|
||||
{fromDSLPayload.map((d, index) => (
|
||||
d.type === 'github'
|
||||
? <GithubItem
|
||||
key={index}
|
||||
checked={!!selectedPlugins.find(p => p.plugin_id === d.value.plugin_unique_identifier)}
|
||||
onCheckedChange={handleSelect}
|
||||
dependency={d}
|
||||
onFetchedPayload={handlePlugInFetched(index)}
|
||||
/>
|
||||
: <MarketplaceItem
|
||||
key={index}
|
||||
checked={!!selectedPlugins.find(p => p.plugin_id === d.value.plugin_unique_identifier)}
|
||||
onCheckedChange={handleSelect}
|
||||
payload={plugins[index] as Plugin}
|
||||
/>
|
||||
))}
|
||||
</>
|
||||
)
|
||||
}
|
||||
export default React.memo(InstallByDSLList)
|
||||
Loading…
Reference in New Issue