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.

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164
  1. import type { FC } from 'react'
  2. import {
  3. useMemo,
  4. } from 'react'
  5. import { useTranslation } from 'react-i18next'
  6. import { memo } from 'react'
  7. import type { DataSourceNodeType } from './types'
  8. import { DataSourceClassification } from './types'
  9. import type { NodePanelProps } from '@/app/components/workflow/types'
  10. import {
  11. BoxGroupField,
  12. } from '@/app/components/workflow/nodes/_base/components/layout'
  13. import OutputVars, { VarItem } from '@/app/components/workflow/nodes/_base/components/output-vars'
  14. import StructureOutputItem from '@/app/components/workflow/nodes/_base/components/variable/object-child-tree-panel/show'
  15. import TagInput from '@/app/components/base/tag-input'
  16. import { useNodesReadOnly } from '@/app/components/workflow/hooks'
  17. import { useConfig } from './hooks/use-config'
  18. import {
  19. COMMON_OUTPUT,
  20. LOCAL_FILE_OUTPUT,
  21. } from './constants'
  22. import { useStore } from '@/app/components/workflow/store'
  23. import { toolParametersToFormSchemas } from '@/app/components/tools/utils/to-form-schema'
  24. import ToolForm from '../tool/components/tool-form'
  25. import { wrapStructuredVarItem } from '@/app/components/workflow/utils/tool'
  26. import useMatchSchemaType, { getMatchedSchemaType } from '../_base/components/variable/use-match-schema-type'
  27. const Panel: FC<NodePanelProps<DataSourceNodeType>> = ({ id, data }) => {
  28. const { t } = useTranslation()
  29. const { nodesReadOnly } = useNodesReadOnly()
  30. const dataSourceList = useStore(s => s.dataSourceList)
  31. const {
  32. provider_type,
  33. plugin_id,
  34. fileExtensions = [],
  35. datasource_parameters,
  36. } = data
  37. const {
  38. handleFileExtensionsChange,
  39. handleParametersChange,
  40. outputSchema,
  41. hasObjectOutput,
  42. } = useConfig(id, dataSourceList)
  43. const isLocalFile = provider_type === DataSourceClassification.localFile
  44. const currentDataSource = dataSourceList?.find(ds => ds.plugin_id === plugin_id)
  45. const currentDataSourceItem: any = currentDataSource?.tools?.find((tool: any) => tool.name === data.datasource_name)
  46. const formSchemas = useMemo(() => {
  47. return currentDataSourceItem ? toolParametersToFormSchemas(currentDataSourceItem.parameters) : []
  48. }, [currentDataSourceItem])
  49. const pipelineId = useStore(s => s.pipelineId)
  50. const setShowInputFieldPanel = useStore(s => s.setShowInputFieldPanel)
  51. const { schemaTypeDefinitions } = useMatchSchemaType()
  52. return (
  53. <div >
  54. {
  55. currentDataSource?.is_authorized && !isLocalFile && !!formSchemas?.length && (
  56. <BoxGroupField
  57. boxGroupProps={{
  58. boxProps: { withBorderBottom: true },
  59. }}
  60. fieldProps={{
  61. fieldTitleProps: {
  62. title: t('workflow.nodes.tool.inputVars'),
  63. },
  64. supportCollapse: true,
  65. }}
  66. >
  67. {formSchemas.length > 0 && (
  68. <ToolForm
  69. readOnly={nodesReadOnly}
  70. nodeId={id}
  71. schema={formSchemas as any}
  72. value={datasource_parameters}
  73. onChange={handleParametersChange}
  74. currentProvider={currentDataSource}
  75. currentTool={currentDataSourceItem}
  76. showManageInputField={!!pipelineId}
  77. onManageInputField={() => setShowInputFieldPanel?.(true)}
  78. />
  79. )}
  80. </BoxGroupField>
  81. )
  82. }
  83. {
  84. isLocalFile && (
  85. <BoxGroupField
  86. boxGroupProps={{
  87. boxProps: { withBorderBottom: true },
  88. }}
  89. fieldProps={{
  90. fieldTitleProps: {
  91. title: t('workflow.nodes.dataSource.supportedFileFormats'),
  92. },
  93. }}
  94. >
  95. <div className='rounded-lg bg-components-input-bg-normal p-1 pt-0'>
  96. <TagInput
  97. items={fileExtensions}
  98. onChange={handleFileExtensionsChange}
  99. placeholder={t('workflow.nodes.dataSource.supportedFileFormatsPlaceholder')}
  100. inputClassName='bg-transparent'
  101. disableAdd={nodesReadOnly}
  102. disableRemove={nodesReadOnly}
  103. />
  104. </div>
  105. </BoxGroupField>
  106. )
  107. }
  108. <OutputVars>
  109. {
  110. COMMON_OUTPUT.map((item, index) => (
  111. <VarItem
  112. key={index}
  113. name={item.name}
  114. type={item.type}
  115. description={item.description}
  116. isIndent={hasObjectOutput}
  117. />
  118. ))
  119. }
  120. {
  121. isLocalFile && LOCAL_FILE_OUTPUT.map((item, index) => (
  122. <VarItem
  123. key={index}
  124. name={item.name}
  125. type={item.type}
  126. description={item.description}
  127. subItems={item.subItems.map(item => ({
  128. name: item.name,
  129. type: item.type,
  130. description: item.description,
  131. }))}
  132. />
  133. ))
  134. }
  135. {outputSchema.map((outputItem) => {
  136. const schemaType = getMatchedSchemaType(outputItem.value, schemaTypeDefinitions)
  137. return (
  138. <div key={outputItem.name}>
  139. {outputItem.value?.type === 'object' ? (
  140. <StructureOutputItem
  141. rootClassName='code-sm-semibold text-text-secondary'
  142. payload={wrapStructuredVarItem(outputItem, schemaType)}
  143. />
  144. ) : (
  145. <VarItem
  146. name={outputItem.name}
  147. // eslint-disable-next-line sonarjs/no-nested-template-literals
  148. type={`${outputItem.type.toLocaleLowerCase()}${schemaType ? ` (${schemaType})` : ''}`}
  149. description={outputItem.description}
  150. isIndent={hasObjectOutput}
  151. />
  152. )}
  153. </div>
  154. )
  155. })}
  156. </OutputVars>
  157. </div>
  158. )
  159. }
  160. export default memo(Panel)