Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

strategy-detail.tsx 6.3KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166
  1. 'use client'
  2. import type { FC } from 'react'
  3. import React, { useMemo } from 'react'
  4. import { useTranslation } from 'react-i18next'
  5. import {
  6. RiArrowLeftLine,
  7. RiCloseLine,
  8. } from '@remixicon/react'
  9. import Drawer from '@/app/components/base/drawer'
  10. import ActionButton from '@/app/components/base/action-button'
  11. import Icon from '@/app/components/plugins/card/base/card-icon'
  12. import Description from '@/app/components/plugins/card/base/description'
  13. import Divider from '@/app/components/base/divider'
  14. import type {
  15. StrategyDetail as StrategyDetailType,
  16. } from '@/app/components/plugins/types'
  17. import type { Locale } from '@/i18n-config'
  18. import { useRenderI18nObject } from '@/hooks/use-i18n'
  19. import { API_PREFIX } from '@/config'
  20. import cn from '@/utils/classnames'
  21. type Props = {
  22. provider: {
  23. author: string
  24. name: string
  25. description: Record<Locale, string>
  26. tenant_id: string
  27. icon: string
  28. label: Record<Locale, string>
  29. tags: string[]
  30. }
  31. detail: StrategyDetailType
  32. onHide: () => void
  33. }
  34. const StrategyDetail: FC<Props> = ({
  35. provider,
  36. detail,
  37. onHide,
  38. }) => {
  39. const getValueFromI18nObject = useRenderI18nObject()
  40. const { t } = useTranslation()
  41. const outputSchema = useMemo(() => {
  42. const res: any[] = []
  43. if (!detail.output_schema)
  44. return []
  45. Object.keys(detail.output_schema.properties).forEach((outputKey) => {
  46. const output = detail.output_schema.properties[outputKey]
  47. res.push({
  48. name: outputKey,
  49. type: output.type === 'array'
  50. ? `Array[${output.items?.type.slice(0, 1).toLocaleUpperCase()}${output.items?.type.slice(1)}]`
  51. : `${output.type.slice(0, 1).toLocaleUpperCase()}${output.type.slice(1)}`,
  52. description: output.description,
  53. })
  54. })
  55. return res
  56. }, [detail.output_schema])
  57. const getType = (type: string) => {
  58. if (type === 'number-input')
  59. return t('tools.setBuiltInTools.number')
  60. if (type === 'text-input')
  61. return t('tools.setBuiltInTools.string')
  62. if (type === 'checkbox')
  63. return 'boolean'
  64. if (type === 'file')
  65. return t('tools.setBuiltInTools.file')
  66. if (type === 'array[tools]')
  67. return 'multiple-tool-select'
  68. return type
  69. }
  70. return (
  71. <Drawer
  72. isOpen
  73. clickOutsideNotOpen={false}
  74. onClose={onHide}
  75. footer={null}
  76. mask={false}
  77. positionCenter={false}
  78. panelClassName={cn('mb-2 mr-2 mt-[64px] !w-[420px] !max-w-[420px] justify-start rounded-2xl border-[0.5px] border-components-panel-border !bg-components-panel-bg !p-0 shadow-xl')}
  79. >
  80. <>
  81. {/* header */}
  82. <div className='relative border-b border-divider-subtle p-4 pb-3'>
  83. <div className='absolute right-3 top-3'>
  84. <ActionButton onClick={onHide}>
  85. <RiCloseLine className='h-4 w-4' />
  86. </ActionButton>
  87. </div>
  88. <div
  89. className='system-xs-semibold-uppercase mb-2 flex cursor-pointer items-center gap-1 text-text-accent-secondary'
  90. onClick={onHide}
  91. >
  92. <RiArrowLeftLine className='h-4 w-4' />
  93. BACK
  94. </div>
  95. <div className='flex items-center gap-1'>
  96. <Icon size='tiny' className='h-6 w-6' src={`${API_PREFIX}/workspaces/current/plugin/icon?tenant_id=${provider.tenant_id}&filename=${provider.icon}`} />
  97. <div className=''>{getValueFromI18nObject(provider.label)}</div>
  98. </div>
  99. <div className='system-md-semibold mt-1 text-text-primary'>{getValueFromI18nObject(detail.identity.label)}</div>
  100. <Description className='mt-3' text={getValueFromI18nObject(detail.description)} descriptionLineRows={2}></Description>
  101. </div>
  102. {/* form */}
  103. <div className='h-full'>
  104. <div className='flex h-full flex-col overflow-y-auto'>
  105. <div className='system-sm-semibold-uppercase p-4 pb-1 text-text-primary'>{t('tools.setBuiltInTools.parameters')}</div>
  106. <div className='px-4'>
  107. {detail.parameters.length > 0 && (
  108. <div className='space-y-1 py-2'>
  109. {detail.parameters.map((item: any, index) => (
  110. <div key={index} className='py-1'>
  111. <div className='flex items-center gap-2'>
  112. <div className='code-sm-semibold text-text-secondary'>{getValueFromI18nObject(item.label)}</div>
  113. <div className='system-xs-regular text-text-tertiary'>
  114. {getType(item.type)}
  115. </div>
  116. {item.required && (
  117. <div className='system-xs-medium text-text-warning-secondary'>{t('tools.setBuiltInTools.required')}</div>
  118. )}
  119. </div>
  120. {item.human_description && (
  121. <div className='system-xs-regular mt-0.5 text-text-tertiary'>
  122. {getValueFromI18nObject(item.human_description)}
  123. </div>
  124. )}
  125. </div>
  126. ))}
  127. </div>
  128. )}
  129. </div>
  130. {detail.output_schema && (
  131. <>
  132. <div className='px-4'>
  133. <Divider className="!mt-2" />
  134. </div>
  135. <div className='system-sm-semibold-uppercase p-4 pb-1 text-text-primary'>OUTPUT</div>
  136. {outputSchema.length > 0 && (
  137. <div className='space-y-1 px-4 py-2'>
  138. {outputSchema.map((outputItem, index) => (
  139. <div key={index} className='py-1'>
  140. <div className='flex items-center gap-2'>
  141. <div className='code-sm-semibold text-text-secondary'>{outputItem.name}</div>
  142. <div className='system-xs-regular text-text-tertiary'>{outputItem.type}</div>
  143. </div>
  144. {outputItem.description && (
  145. <div className='system-xs-regular mt-0.5 text-text-tertiary'>
  146. {outputItem.description}
  147. </div>
  148. )}
  149. </div>
  150. ))}
  151. </div>
  152. )}
  153. </>
  154. )}
  155. </div>
  156. </div>
  157. </>
  158. </Drawer>
  159. )
  160. }
  161. export default StrategyDetail