You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

install-multi.tsx 7.4KB

Introduce Plugins (#13836) Signed-off-by: yihong0618 <zouzou0208@gmail.com> Signed-off-by: -LAN- <laipz8200@outlook.com> Signed-off-by: xhe <xw897002528@gmail.com> Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: takatost <takatost@gmail.com> Co-authored-by: kurokobo <kuro664@gmail.com> Co-authored-by: Novice Lee <novicelee@NoviPro.local> Co-authored-by: zxhlyh <jasonapring2015@outlook.com> Co-authored-by: AkaraChen <akarachen@outlook.com> Co-authored-by: Yi <yxiaoisme@gmail.com> Co-authored-by: Joel <iamjoel007@gmail.com> Co-authored-by: JzoNg <jzongcode@gmail.com> Co-authored-by: twwu <twwu@dify.ai> Co-authored-by: Hiroshi Fujita <fujita-h@users.noreply.github.com> Co-authored-by: AkaraChen <85140972+AkaraChen@users.noreply.github.com> Co-authored-by: NFish <douxc512@gmail.com> Co-authored-by: Wu Tianwei <30284043+WTW0313@users.noreply.github.com> Co-authored-by: 非法操作 <hjlarry@163.com> Co-authored-by: Novice <857526207@qq.com> Co-authored-by: Hiroki Nagai <82458324+nagaihiroki-git@users.noreply.github.com> Co-authored-by: Gen Sato <52241300+halogen22@users.noreply.github.com> Co-authored-by: eux <euxuuu@gmail.com> Co-authored-by: huangzhuo1949 <167434202+huangzhuo1949@users.noreply.github.com> Co-authored-by: huangzhuo <huangzhuo1@xiaomi.com> Co-authored-by: lotsik <lotsik@mail.ru> Co-authored-by: crazywoola <100913391+crazywoola@users.noreply.github.com> Co-authored-by: nite-knite <nkCoding@gmail.com> Co-authored-by: Jyong <76649700+JohnJyong@users.noreply.github.com> Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Co-authored-by: gakkiyomi <gakkiyomi@aliyun.com> Co-authored-by: CN-P5 <heibai2006@gmail.com> Co-authored-by: CN-P5 <heibai2006@qq.com> Co-authored-by: Chuehnone <1897025+chuehnone@users.noreply.github.com> Co-authored-by: yihong <zouzou0208@gmail.com> Co-authored-by: Kevin9703 <51311316+Kevin9703@users.noreply.github.com> Co-authored-by: -LAN- <laipz8200@outlook.com> Co-authored-by: Boris Feld <lothiraldan@gmail.com> Co-authored-by: mbo <himabo@gmail.com> Co-authored-by: mabo <mabo@aeyes.ai> Co-authored-by: Warren Chen <warren.chen830@gmail.com> Co-authored-by: JzoNgKVO <27049666+JzoNgKVO@users.noreply.github.com> Co-authored-by: jiandanfeng <chenjh3@wangsu.com> Co-authored-by: zhu-an <70234959+xhdd123321@users.noreply.github.com> Co-authored-by: zhaoqingyu.1075 <zhaoqingyu.1075@bytedance.com> Co-authored-by: 海狸大師 <86974027+yenslife@users.noreply.github.com> Co-authored-by: Xu Song <xusong.vip@gmail.com> Co-authored-by: rayshaw001 <396301947@163.com> Co-authored-by: Ding Jiatong <dingjiatong@gmail.com> Co-authored-by: Bowen Liang <liangbowen@gf.com.cn> Co-authored-by: JasonVV <jasonwangiii@outlook.com> Co-authored-by: le0zh <newlight@qq.com> Co-authored-by: zhuxinliang <zhuxinliang@didiglobal.com> Co-authored-by: k-zaku <zaku99@outlook.jp> Co-authored-by: luckylhb90 <luckylhb90@gmail.com> Co-authored-by: hobo.l <hobo.l@binance.com> Co-authored-by: jiangbo721 <365065261@qq.com> Co-authored-by: 刘江波 <jiangbo721@163.com> Co-authored-by: Shun Miyazawa <34241526+miya@users.noreply.github.com> Co-authored-by: EricPan <30651140+Egfly@users.noreply.github.com> Co-authored-by: crazywoola <427733928@qq.com> Co-authored-by: sino <sino2322@gmail.com> Co-authored-by: Jhvcc <37662342+Jhvcc@users.noreply.github.com> Co-authored-by: lowell <lowell.hu@zkteco.in> Co-authored-by: Boris Polonsky <BorisPolonsky@users.noreply.github.com> Co-authored-by: Ademílson Tonato <ademilsonft@outlook.com> Co-authored-by: Ademílson Tonato <ademilson.tonato@refurbed.com> Co-authored-by: IWAI, Masaharu <iwaim.sub@gmail.com> Co-authored-by: Yueh-Po Peng (Yabi) <94939112+y10ab1@users.noreply.github.com> Co-authored-by: Jason <ggbbddjm@gmail.com> Co-authored-by: Xin Zhang <sjhpzx@gmail.com> Co-authored-by: yjc980121 <3898524+yjc980121@users.noreply.github.com> Co-authored-by: heyszt <36215648+hieheihei@users.noreply.github.com> Co-authored-by: Abdullah AlOsaimi <osaimiacc@gmail.com> Co-authored-by: Abdullah AlOsaimi <189027247+osaimi@users.noreply.github.com> Co-authored-by: Yingchun Lai <laiyingchun@apache.org> Co-authored-by: Hash Brown <hi@xzd.me> Co-authored-by: zuodongxu <192560071+zuodongxu@users.noreply.github.com> Co-authored-by: Masashi Tomooka <tmokmss@users.noreply.github.com> Co-authored-by: aplio <ryo.091219@gmail.com> Co-authored-by: Obada Khalili <54270856+obadakhalili@users.noreply.github.com> Co-authored-by: Nam Vu <zuzoovn@gmail.com> Co-authored-by: Kei YAMAZAKI <1715090+kei-yamazaki@users.noreply.github.com> Co-authored-by: TechnoHouse <13776377+deephbz@users.noreply.github.com> Co-authored-by: Riddhimaan-Senapati <114703025+Riddhimaan-Senapati@users.noreply.github.com> Co-authored-by: MaFee921 <31881301+2284730142@users.noreply.github.com> Co-authored-by: te-chan <t-nakanome@sakura-is.co.jp> Co-authored-by: HQidea <HQidea@users.noreply.github.com> Co-authored-by: Joshbly <36315710+Joshbly@users.noreply.github.com> Co-authored-by: xhe <xw897002528@gmail.com> Co-authored-by: weiwenyan-dev <154779315+weiwenyan-dev@users.noreply.github.com> Co-authored-by: ex_wenyan.wei <ex_wenyan.wei@tcl.com> Co-authored-by: engchina <12236799+engchina@users.noreply.github.com> Co-authored-by: engchina <atjapan2015@gmail.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: 呆萌闷油瓶 <253605712@qq.com> Co-authored-by: Kemal <kemalmeler@outlook.com> Co-authored-by: Lazy_Frog <4590648+lazyFrogLOL@users.noreply.github.com> Co-authored-by: Yi Xiao <54782454+YIXIAO0@users.noreply.github.com> Co-authored-by: Steven sun <98230804+Tuyohai@users.noreply.github.com> Co-authored-by: steven <sunzwj@digitalchina.com> Co-authored-by: Kalo Chin <91766386+fdb02983rhy@users.noreply.github.com> Co-authored-by: Katy Tao <34019945+KatyTao@users.noreply.github.com> Co-authored-by: depy <42985524+h4ckdepy@users.noreply.github.com> Co-authored-by: 胡春东 <gycm520@gmail.com> Co-authored-by: Junjie.M <118170653@qq.com> Co-authored-by: MuYu <mr.muzea@gmail.com> Co-authored-by: Naoki Takashima <39912547+takatea@users.noreply.github.com> Co-authored-by: Summer-Gu <37869445+gubinjie@users.noreply.github.com> Co-authored-by: Fei He <droxer.he@gmail.com> Co-authored-by: ybalbert001 <120714773+ybalbert001@users.noreply.github.com> Co-authored-by: Yuanbo Li <ybalbert@amazon.com> Co-authored-by: douxc <7553076+douxc@users.noreply.github.com> Co-authored-by: liuzhenghua <1090179900@qq.com> Co-authored-by: Wu Jiayang <62842862+Wu-Jiayang@users.noreply.github.com> Co-authored-by: Your Name <you@example.com> Co-authored-by: kimjion <45935338+kimjion@users.noreply.github.com> Co-authored-by: AugNSo <song.tiankai@icloud.com> Co-authored-by: llinvokerl <38915183+llinvokerl@users.noreply.github.com> Co-authored-by: liusurong.lsr <liusurong.lsr@alibaba-inc.com> Co-authored-by: Vasu Negi <vasu-negi@users.noreply.github.com> Co-authored-by: Hundredwz <1808096180@qq.com> Co-authored-by: Xiyuan Chen <52963600+GareArc@users.noreply.github.com>
8 months ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221
  1. 'use client'
  2. import type { FC } from 'react'
  3. import React, { useCallback, useEffect, useMemo, useState } from 'react'
  4. import type { Dependency, GitHubItemAndMarketPlaceDependency, PackageDependency, Plugin, VersionInfo } from '../../../types'
  5. import MarketplaceItem from '../item/marketplace-item'
  6. import GithubItem from '../item/github-item'
  7. import { useFetchPluginsInMarketPlaceByIds, useFetchPluginsInMarketPlaceByInfo } from '@/service/use-plugins'
  8. import useCheckInstalled from '@/app/components/plugins/install-plugin/hooks/use-check-installed'
  9. import produce from 'immer'
  10. import PackageItem from '../item/package-item'
  11. import LoadingError from '../../base/loading-error'
  12. type Props = {
  13. allPlugins: Dependency[]
  14. selectedPlugins: Plugin[]
  15. onSelect: (plugin: Plugin, selectedIndex: number) => void
  16. onLoadedAllPlugin: (installedInfo: Record<string, VersionInfo>) => void
  17. isFromMarketPlace?: boolean
  18. }
  19. const InstallByDSLList: FC<Props> = ({
  20. allPlugins,
  21. selectedPlugins,
  22. onSelect,
  23. onLoadedAllPlugin,
  24. isFromMarketPlace,
  25. }) => {
  26. // DSL has id, to get plugin info to show more info
  27. const { isLoading: isFetchingMarketplaceDataById, data: infoGetById, error: infoByIdError } = useFetchPluginsInMarketPlaceByIds(allPlugins.filter(d => d.type === 'marketplace').map(d => (d as GitHubItemAndMarketPlaceDependency).value.marketplace_plugin_unique_identifier!))
  28. // has meta(org,name,version), to get id
  29. const { isLoading: isFetchingDataByMeta, data: infoByMeta, error: infoByMetaError } = useFetchPluginsInMarketPlaceByInfo(allPlugins.filter(d => d.type === 'marketplace').map(d => (d as GitHubItemAndMarketPlaceDependency).value!))
  30. const [plugins, doSetPlugins] = useState<(Plugin | undefined)[]>((() => {
  31. const hasLocalPackage = allPlugins.some(d => d.type === 'package')
  32. if (!hasLocalPackage)
  33. return []
  34. const _plugins = allPlugins.map((d) => {
  35. if (d.type === 'package') {
  36. return {
  37. ...(d as any).value.manifest,
  38. plugin_id: (d as any).value.unique_identifier,
  39. }
  40. }
  41. return undefined
  42. })
  43. return _plugins
  44. })())
  45. const pluginsRef = React.useRef<(Plugin | undefined)[]>(plugins)
  46. const setPlugins = useCallback((p: (Plugin | undefined)[]) => {
  47. doSetPlugins(p)
  48. pluginsRef.current = p
  49. }, [])
  50. const [errorIndexes, setErrorIndexes] = useState<number[]>([])
  51. const handleGitHubPluginFetched = useCallback((index: number) => {
  52. return (p: Plugin) => {
  53. const nextPlugins = produce(pluginsRef.current, (draft) => {
  54. draft[index] = p
  55. })
  56. setPlugins(nextPlugins)
  57. }
  58. }, [setPlugins])
  59. const handleGitHubPluginFetchError = useCallback((index: number) => {
  60. return () => {
  61. setErrorIndexes([...errorIndexes, index])
  62. }
  63. }, [errorIndexes])
  64. const marketPlaceInDSLIndex = useMemo(() => {
  65. const res: number[] = []
  66. allPlugins.forEach((d, index) => {
  67. if (d.type === 'marketplace')
  68. res.push(index)
  69. })
  70. return res
  71. }, [allPlugins])
  72. useEffect(() => {
  73. if (!isFetchingMarketplaceDataById && infoGetById?.data.plugins) {
  74. const payloads = infoGetById?.data.plugins
  75. const failedIndex: number[] = []
  76. const nextPlugins = produce(pluginsRef.current, (draft) => {
  77. marketPlaceInDSLIndex.forEach((index, i) => {
  78. if (payloads[i]) {
  79. draft[index] = {
  80. ...payloads[i],
  81. version: payloads[i].version || payloads[i].latest_version,
  82. }
  83. }
  84. else { failedIndex.push(index) }
  85. })
  86. })
  87. setPlugins(nextPlugins)
  88. if (failedIndex.length > 0)
  89. setErrorIndexes([...errorIndexes, ...failedIndex])
  90. }
  91. // eslint-disable-next-line react-hooks/exhaustive-deps
  92. }, [isFetchingMarketplaceDataById])
  93. useEffect(() => {
  94. if (!isFetchingDataByMeta && infoByMeta?.data.list) {
  95. const payloads = infoByMeta?.data.list
  96. const failedIndex: number[] = []
  97. const nextPlugins = produce(pluginsRef.current, (draft) => {
  98. marketPlaceInDSLIndex.forEach((index, i) => {
  99. if (payloads[i]) {
  100. const item = payloads[i]
  101. draft[index] = {
  102. ...item.plugin,
  103. plugin_id: item.version.unique_identifier,
  104. }
  105. }
  106. else {
  107. failedIndex.push(index)
  108. }
  109. })
  110. })
  111. setPlugins(nextPlugins)
  112. if (failedIndex.length > 0)
  113. setErrorIndexes([...errorIndexes, ...failedIndex])
  114. }
  115. // eslint-disable-next-line react-hooks/exhaustive-deps
  116. }, [isFetchingDataByMeta])
  117. useEffect(() => {
  118. // get info all failed
  119. if (infoByMetaError || infoByIdError)
  120. setErrorIndexes([...errorIndexes, ...marketPlaceInDSLIndex])
  121. // eslint-disable-next-line react-hooks/exhaustive-deps
  122. }, [infoByMetaError, infoByIdError])
  123. const isLoadedAllData = (plugins.filter(p => !!p).length + errorIndexes.length) === allPlugins.length
  124. const { installedInfo } = useCheckInstalled({
  125. pluginIds: plugins?.filter(p => !!p).map((d) => {
  126. return `${d?.org || d?.author}/${d?.name}`
  127. }) || [],
  128. enabled: isLoadedAllData,
  129. })
  130. const getVersionInfo = useCallback((pluginId: string) => {
  131. const pluginDetail = installedInfo?.[pluginId]
  132. const hasInstalled = !!pluginDetail
  133. return {
  134. hasInstalled,
  135. installedVersion: pluginDetail?.installedVersion,
  136. toInstallVersion: '',
  137. }
  138. }, [installedInfo])
  139. useEffect(() => {
  140. if (isLoadedAllData && installedInfo)
  141. onLoadedAllPlugin(installedInfo!)
  142. // eslint-disable-next-line react-hooks/exhaustive-deps
  143. }, [isLoadedAllData, installedInfo])
  144. const handleSelect = useCallback((index: number) => {
  145. return () => {
  146. onSelect(plugins[index]!, index)
  147. }
  148. }, [onSelect, plugins])
  149. return (
  150. <>
  151. {allPlugins.map((d, index) => {
  152. if (errorIndexes.includes(index)) {
  153. return (
  154. <LoadingError key={index} />
  155. )
  156. }
  157. const plugin = plugins[index]
  158. if (d.type === 'github') {
  159. return (<GithubItem
  160. key={index}
  161. checked={!!selectedPlugins.find(p => p.plugin_id === plugins[index]?.plugin_id)}
  162. onCheckedChange={handleSelect(index)}
  163. dependency={d as GitHubItemAndMarketPlaceDependency}
  164. onFetchedPayload={handleGitHubPluginFetched(index)}
  165. onFetchError={handleGitHubPluginFetchError(index)}
  166. versionInfo={getVersionInfo(`${plugin?.org || plugin?.author}/${plugin?.name}`)}
  167. />)
  168. }
  169. if (d.type === 'marketplace') {
  170. return (
  171. <MarketplaceItem
  172. key={index}
  173. checked={!!selectedPlugins.find(p => p.plugin_id === plugins[index]?.plugin_id)}
  174. onCheckedChange={handleSelect(index)}
  175. payload={plugin}
  176. version={(d as GitHubItemAndMarketPlaceDependency).value.version! || plugin?.version || ''}
  177. versionInfo={getVersionInfo(`${plugin?.org || plugin?.author}/${plugin?.name}`)}
  178. />
  179. )
  180. }
  181. // Local package
  182. return (
  183. <PackageItem
  184. key={index}
  185. checked={!!selectedPlugins.find(p => p.plugin_id === plugins[index]?.plugin_id)}
  186. onCheckedChange={handleSelect(index)}
  187. payload={d as PackageDependency}
  188. isFromMarketPlace={isFromMarketPlace}
  189. versionInfo={getVersionInfo(`${plugin?.org || plugin?.author}/${plugin?.name}`)}
  190. />
  191. )
  192. })
  193. }
  194. </>
  195. )
  196. }
  197. export default React.memo(InstallByDSLList)