您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符

display-content.tsx 4.8KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  1. import React, { useMemo, useState } from 'react'
  2. import { useTranslation } from 'react-i18next'
  3. import { RiBracesLine, RiEyeLine } from '@remixicon/react'
  4. import Textarea from '@/app/components/base/textarea'
  5. import { Markdown } from '@/app/components/base/markdown'
  6. import SchemaEditor from '@/app/components/workflow/nodes/llm/components/json-schema-config-modal/schema-editor'
  7. import { SegmentedControl } from '@/app/components/base/segmented-control'
  8. import cn from '@/utils/classnames'
  9. import { ChunkCardList } from '@/app/components/rag-pipeline/components/chunk-card-list'
  10. import type { ChunkInfo } from '@/app/components/rag-pipeline/components/chunk-card-list/types'
  11. import type { ParentMode } from '@/models/datasets'
  12. import { ChunkingMode } from '@/models/datasets'
  13. import { PreviewType, ViewMode } from './types'
  14. import type { VarType } from '../types'
  15. type DisplayContentProps = {
  16. previewType: PreviewType
  17. varType: VarType
  18. schemaType?: string
  19. mdString?: string
  20. jsonString?: string
  21. readonly: boolean
  22. handleTextChange?: (value: string) => void
  23. handleEditorChange?: (value: string) => void
  24. }
  25. const DisplayContent = (props: DisplayContentProps) => {
  26. const { previewType, varType, schemaType, mdString, jsonString, readonly, handleTextChange, handleEditorChange } = props
  27. const [viewMode, setViewMode] = useState<ViewMode>(ViewMode.Code)
  28. const [isFocused, setIsFocused] = useState(false)
  29. const { t } = useTranslation()
  30. const chunkType = useMemo(() => {
  31. if (previewType !== PreviewType.Chunks || !schemaType)
  32. return undefined
  33. if (schemaType === 'general_structure')
  34. return ChunkingMode.text
  35. if (schemaType === 'parent_child_structure')
  36. return ChunkingMode.parentChild
  37. if (schemaType === 'qa_structure')
  38. return ChunkingMode.qa
  39. }, [previewType, schemaType])
  40. const parentMode = useMemo(() => {
  41. if (previewType !== PreviewType.Chunks || !schemaType || !jsonString)
  42. return undefined
  43. if (schemaType === 'parent_child_structure')
  44. return JSON.parse(jsonString!)?.parent_mode as ParentMode
  45. return undefined
  46. }, [previewType, schemaType, jsonString])
  47. return (
  48. <div className={cn('flex h-full flex-col rounded-[10px] bg-components-input-bg-normal', isFocused && 'bg-components-input-bg-active outline outline-1 outline-components-input-border-active')}>
  49. <div className='flex shrink-0 items-center justify-end p-1'>
  50. {previewType === PreviewType.Markdown && (
  51. <div className='system-xs-semibold-uppercase flex grow items-center px-2 py-0.5 text-text-secondary'>
  52. {previewType.toUpperCase()}
  53. </div>
  54. )}
  55. {previewType === PreviewType.Chunks && (
  56. <div className='system-xs-semibold-uppercase flex grow items-center px-2 py-0.5 text-text-secondary'>
  57. {varType.toUpperCase()}{schemaType ? `(${schemaType})` : ''}
  58. </div>
  59. )}
  60. <SegmentedControl
  61. options={[
  62. { value: ViewMode.Code, text: t('workflow.nodes.templateTransform.code'), Icon: RiBracesLine },
  63. { value: ViewMode.Preview, text: t('workflow.common.preview'), Icon: RiEyeLine },
  64. ]}
  65. value={viewMode}
  66. onChange={setViewMode}
  67. size='small'
  68. padding='with'
  69. activeClassName='!text-text-accent-light-mode-only'
  70. btnClassName='!pl-1.5 !pr-0.5 gap-[3px]'
  71. className='shrink-0'
  72. />
  73. </div>
  74. <div className='flex flex-1 overflow-auto rounded-b-[10px] pl-3 pr-1'>
  75. {viewMode === ViewMode.Code && (
  76. previewType === PreviewType.Markdown
  77. ? <Textarea
  78. readOnly={readonly}
  79. disabled={readonly}
  80. className='h-full border-none bg-transparent p-0 text-text-secondary hover:bg-transparent focus:bg-transparent focus:shadow-none'
  81. value={mdString as any}
  82. onChange={e => handleTextChange?.(e.target.value)}
  83. onFocus={() => setIsFocused(true)}
  84. onBlur={() => setIsFocused(false)}
  85. />
  86. : <SchemaEditor
  87. readonly={readonly}
  88. className='overflow-y-auto bg-transparent'
  89. hideTopMenu
  90. schema={jsonString!}
  91. onUpdate={handleEditorChange!}
  92. onFocus={() => setIsFocused(true)}
  93. onBlur={() => setIsFocused(false)}
  94. />
  95. )}
  96. {viewMode === ViewMode.Preview && (
  97. previewType === PreviewType.Markdown
  98. ? <Markdown className='grow overflow-auto rounded-lg !bg-white px-4 py-3' content={(mdString ?? '') as string} />
  99. : <ChunkCardList
  100. chunkType={chunkType!}
  101. parentMode={parentMode}
  102. chunkInfo={JSON.parse(jsonString!) as ChunkInfo}
  103. />
  104. )}
  105. </div>
  106. </div>
  107. )
  108. }
  109. export default React.memo(DisplayContent)