選択できるのは25トピックまでです。 トピックは、先頭が英数字で、英数字とダッシュ('-')を使用した35文字以内のものにしてください。

index.tsx 3.1KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798
  1. 'use client'
  2. import { useMemo, useState } from 'react'
  3. import NewMCPCard from './create-card'
  4. import MCPCard from './provider-card'
  5. import MCPDetailPanel from './detail/provider-detail'
  6. import {
  7. useAllToolProviders,
  8. } from '@/service/use-tools'
  9. import type { ToolWithProvider } from '@/app/components/workflow/types'
  10. import cn from '@/utils/classnames'
  11. type Props = {
  12. searchText: string
  13. }
  14. function renderDefaultCard() {
  15. const defaultCards = Array.from({ length: 36 }, (_, index) => (
  16. <div
  17. key={index}
  18. className={cn(
  19. 'inline-flex h-[111px] rounded-xl bg-background-default-lighter opacity-10',
  20. index < 4 && 'opacity-60',
  21. index >= 4 && index < 8 && 'opacity-50',
  22. index >= 8 && index < 12 && 'opacity-40',
  23. index >= 12 && index < 16 && 'opacity-30',
  24. index >= 16 && index < 20 && 'opacity-25',
  25. index >= 20 && index < 24 && 'opacity-20',
  26. )}
  27. ></div>
  28. ))
  29. return defaultCards
  30. }
  31. const MCPList = ({
  32. searchText,
  33. }: Props) => {
  34. const { data: list = [] as ToolWithProvider[], refetch } = useAllToolProviders()
  35. const [isTriggerAuthorize, setIsTriggerAuthorize] = useState<boolean>(false)
  36. const filteredList = useMemo(() => {
  37. return list.filter((collection) => {
  38. if (searchText)
  39. return Object.values(collection.name).some(value => (value as string).toLowerCase().includes(searchText.toLowerCase()))
  40. return collection.type === 'mcp'
  41. }) as ToolWithProvider[]
  42. }, [list, searchText])
  43. const [currentProviderID, setCurrentProviderID] = useState<string>()
  44. const currentProvider = useMemo(() => {
  45. return list.find(provider => provider.id === currentProviderID)
  46. }, [list, currentProviderID])
  47. const handleCreate = async (provider: ToolWithProvider) => {
  48. await refetch() // update list
  49. setCurrentProviderID(provider.id)
  50. setIsTriggerAuthorize(true)
  51. }
  52. const handleUpdate = async (providerID: string) => {
  53. await refetch() // update list
  54. setCurrentProviderID(providerID)
  55. setIsTriggerAuthorize(true)
  56. }
  57. return (
  58. <>
  59. <div
  60. className={cn(
  61. 'relative grid shrink-0 grid-cols-1 content-start gap-4 px-12 pb-4 pt-2 sm:grid-cols-1 md:grid-cols-2 xl:grid-cols-4 2xl:grid-cols-5 2k:grid-cols-6',
  62. !list.length && 'h-[calc(100vh_-_136px)] overflow-hidden',
  63. )}
  64. >
  65. <NewMCPCard handleCreate={handleCreate} />
  66. {filteredList.map(provider => (
  67. <MCPCard
  68. key={provider.id}
  69. data={provider}
  70. currentProvider={currentProvider as ToolWithProvider}
  71. handleSelect={setCurrentProviderID}
  72. onUpdate={handleUpdate}
  73. onDeleted={refetch}
  74. />
  75. ))}
  76. {!list.length && renderDefaultCard()}
  77. </div>
  78. {currentProvider && (
  79. <MCPDetailPanel
  80. detail={currentProvider as ToolWithProvider}
  81. onHide={() => setCurrentProviderID(undefined)}
  82. onUpdate={refetch}
  83. isTriggerAuthorize={isTriggerAuthorize}
  84. onFirstCreate={() => setIsTriggerAuthorize(false)}
  85. />
  86. )}
  87. </>
  88. )
  89. }
  90. export default MCPList