mirror of
https://git.mirrors.martin98.com/https://github.com/langgenius/dify.git
synced 2025-08-18 05:45:59 +08:00
files in log
This commit is contained in:
parent
b491c93b1c
commit
54133dfbde
86
web/app/components/base/file-uploader/file-list-in-log.tsx
Normal file
86
web/app/components/base/file-uploader/file-list-in-log.tsx
Normal file
@ -0,0 +1,86 @@
|
|||||||
|
import React, { useState } from 'react'
|
||||||
|
import { RiArrowRightSLine } from '@remixicon/react'
|
||||||
|
import FileImageRender from './file-image-render'
|
||||||
|
import FileTypeIcon from './file-type-icon'
|
||||||
|
import FileItem from './file-uploader-in-attachment/file-item'
|
||||||
|
import type { FileEntity } from './types'
|
||||||
|
import {
|
||||||
|
getFileAppearanceType,
|
||||||
|
} from './utils'
|
||||||
|
import Tooltip from '@/app/components/base/tooltip'
|
||||||
|
import { SupportUploadFileTypes } from '@/app/components/workflow/types'
|
||||||
|
import cn from '@/utils/classnames'
|
||||||
|
|
||||||
|
type Props = {
|
||||||
|
fileList: FileEntity[]
|
||||||
|
}
|
||||||
|
|
||||||
|
const FileListInLog = ({ fileList }: Props) => {
|
||||||
|
const [expanded, setExpanded] = useState(false)
|
||||||
|
|
||||||
|
if (!fileList.length)
|
||||||
|
return null
|
||||||
|
return (
|
||||||
|
<div className={cn('border-t border-divider-subtle px-3 py-2', expanded && 'py-3')}>
|
||||||
|
<div className='flex justify-between gap-1'>
|
||||||
|
{expanded && (
|
||||||
|
<div></div>
|
||||||
|
)}
|
||||||
|
{!expanded && (
|
||||||
|
<div className='flex'>
|
||||||
|
{fileList.map((file) => {
|
||||||
|
const { id, name, type, supportFileType, base64Url, url } = file
|
||||||
|
const isImageFile = supportFileType === SupportUploadFileTypes.image
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
{isImageFile && (
|
||||||
|
<Tooltip
|
||||||
|
popupContent={name}
|
||||||
|
>
|
||||||
|
<div key={id}>
|
||||||
|
<FileImageRender
|
||||||
|
className='w-8 h-8'
|
||||||
|
imageUrl={base64Url || url || ''}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</Tooltip>
|
||||||
|
)}
|
||||||
|
{!isImageFile && (
|
||||||
|
<Tooltip
|
||||||
|
popupContent={name}
|
||||||
|
>
|
||||||
|
<div key={id} className='p-1.5 rounded-md bg-components-panel-on-panel-item-bg border-[0.5px] border-components-panel-border shadow-xs'>
|
||||||
|
<FileTypeIcon
|
||||||
|
type={getFileAppearanceType(name, type)}
|
||||||
|
size='md'
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</Tooltip>
|
||||||
|
)}
|
||||||
|
</>
|
||||||
|
)
|
||||||
|
})}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
<div className='flex items-center gap-1 cursor-pointer' onClick={() => setExpanded(!expanded)}>
|
||||||
|
{!expanded && <div className='text-text-tertiary system-xs-medium-uppercase'>DETAIL</div>}
|
||||||
|
<RiArrowRightSLine className={cn('w-4 h-4 text-text-tertiary', expanded && 'rotate-90')} />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{expanded && (
|
||||||
|
<div className='flex flex-col gap-1'>
|
||||||
|
{fileList.map(file => (
|
||||||
|
<FileItem
|
||||||
|
key={file.id}
|
||||||
|
file={file}
|
||||||
|
showDeleteAction={false}
|
||||||
|
showDownloadAction
|
||||||
|
/>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default FileListInLog
|
@ -1,4 +1,5 @@
|
|||||||
import mime from 'mime'
|
import mime from 'mime'
|
||||||
|
import { flatten } from 'lodash-es'
|
||||||
import { FileAppearanceTypeEnum } from './types'
|
import { FileAppearanceTypeEnum } from './types'
|
||||||
import type { FileEntity } from './types'
|
import type { FileEntity } from './types'
|
||||||
import { upload } from '@/service/base'
|
import { upload } from '@/service/base'
|
||||||
@ -148,3 +149,12 @@ export const getSupportFileExtensionList = (allowFileTypes: string[], allowFileE
|
|||||||
export const isAllowedFileExtension = (fileName: string, fileMimetype: string, allowFileTypes: string[], allowFileExtensions: string[]) => {
|
export const isAllowedFileExtension = (fileName: string, fileMimetype: string, allowFileTypes: string[], allowFileExtensions: string[]) => {
|
||||||
return getSupportFileExtensionList(allowFileTypes, allowFileExtensions).includes(getFileExtension(fileName, fileMimetype).toUpperCase())
|
return getSupportFileExtensionList(allowFileTypes, allowFileExtensions).includes(getFileExtension(fileName, fileMimetype).toUpperCase())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const getFilesInLogs = (rawData: any) => {
|
||||||
|
const originalFiles = flatten(Object.keys(rawData || {}).map((key) => {
|
||||||
|
if (typeof rawData[key] === 'object' || Array.isArray(rawData[key]))
|
||||||
|
return rawData[key]
|
||||||
|
return undefined
|
||||||
|
}).filter(Boolean)).filter(item => item?.model_identity === '__dify__file__')
|
||||||
|
return getProcessedFilesFromResponse(originalFiles)
|
||||||
|
}
|
||||||
|
@ -11,6 +11,8 @@ import {
|
|||||||
} from '@/app/components/base/icons/src/vender/line/files'
|
} from '@/app/components/base/icons/src/vender/line/files'
|
||||||
import ToggleExpandBtn from '@/app/components/workflow/nodes/_base/components/toggle-expand-btn'
|
import ToggleExpandBtn from '@/app/components/workflow/nodes/_base/components/toggle-expand-btn'
|
||||||
import useToggleExpend from '@/app/components/workflow/nodes/_base/hooks/use-toggle-expend'
|
import useToggleExpend from '@/app/components/workflow/nodes/_base/hooks/use-toggle-expend'
|
||||||
|
import type { FileEntity } from '@/app/components/base/file-uploader/types'
|
||||||
|
import FileListInLog from '@/app/components/base/file-uploader/file-list-in-log'
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
className?: string
|
className?: string
|
||||||
@ -21,6 +23,8 @@ type Props = {
|
|||||||
value: string
|
value: string
|
||||||
isFocus: boolean
|
isFocus: boolean
|
||||||
isInNode?: boolean
|
isInNode?: boolean
|
||||||
|
fileList?: FileEntity[]
|
||||||
|
showFileList?: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
const Base: FC<Props> = ({
|
const Base: FC<Props> = ({
|
||||||
@ -32,6 +36,8 @@ const Base: FC<Props> = ({
|
|||||||
value,
|
value,
|
||||||
isFocus,
|
isFocus,
|
||||||
isInNode,
|
isInNode,
|
||||||
|
fileList = [],
|
||||||
|
showFileList,
|
||||||
}) => {
|
}) => {
|
||||||
const ref = useRef<HTMLDivElement>(null)
|
const ref = useRef<HTMLDivElement>(null)
|
||||||
const {
|
const {
|
||||||
@ -87,6 +93,9 @@ const Base: FC<Props> = ({
|
|||||||
{children}
|
{children}
|
||||||
</div>
|
</div>
|
||||||
</PromptEditorHeightResizeWrap>
|
</PromptEditorHeightResizeWrap>
|
||||||
|
{showFileList && fileList.length > 0 && (
|
||||||
|
<FileListInLog fileList={fileList} />
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
</Wrap>
|
</Wrap>
|
||||||
)
|
)
|
||||||
|
@ -1,10 +1,13 @@
|
|||||||
'use client'
|
'use client'
|
||||||
import type { FC } from 'react'
|
import type { FC } from 'react'
|
||||||
import Editor, { loader } from '@monaco-editor/react'
|
import Editor, { loader } from '@monaco-editor/react'
|
||||||
import React, { useEffect, useRef, useState } from 'react'
|
import React, { useEffect, useMemo, useRef, useState } from 'react'
|
||||||
import Base from '../base'
|
import Base from '../base'
|
||||||
import cn from '@/utils/classnames'
|
import cn from '@/utils/classnames'
|
||||||
import { CodeLanguage } from '@/app/components/workflow/nodes/code/types'
|
import { CodeLanguage } from '@/app/components/workflow/nodes/code/types'
|
||||||
|
import {
|
||||||
|
getFilesInLogs,
|
||||||
|
} from '@/app/components/base/file-uploader/utils'
|
||||||
|
|
||||||
import './style.css'
|
import './style.css'
|
||||||
|
|
||||||
@ -27,6 +30,7 @@ export type Props = {
|
|||||||
onMount?: (editor: any, monaco: any) => void
|
onMount?: (editor: any, monaco: any) => void
|
||||||
noWrapper?: boolean
|
noWrapper?: boolean
|
||||||
isExpand?: boolean
|
isExpand?: boolean
|
||||||
|
showFileList?: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
const languageMap = {
|
const languageMap = {
|
||||||
@ -58,6 +62,7 @@ const CodeEditor: FC<Props> = ({
|
|||||||
onMount,
|
onMount,
|
||||||
noWrapper,
|
noWrapper,
|
||||||
isExpand,
|
isExpand,
|
||||||
|
showFileList,
|
||||||
}) => {
|
}) => {
|
||||||
const [isFocus, setIsFocus] = React.useState(false)
|
const [isFocus, setIsFocus] = React.useState(false)
|
||||||
const [isMounted, setIsMounted] = React.useState(false)
|
const [isMounted, setIsMounted] = React.useState(false)
|
||||||
@ -69,6 +74,12 @@ const CodeEditor: FC<Props> = ({
|
|||||||
valueRef.current = value
|
valueRef.current = value
|
||||||
}, [value])
|
}, [value])
|
||||||
|
|
||||||
|
const fileList = useMemo(() => {
|
||||||
|
if (typeof value === 'object')
|
||||||
|
return getFilesInLogs(value)
|
||||||
|
return []
|
||||||
|
}, [value])
|
||||||
|
|
||||||
const editorRef = useRef<any>(null)
|
const editorRef = useRef<any>(null)
|
||||||
const resizeEditorToContent = () => {
|
const resizeEditorToContent = () => {
|
||||||
if (editorRef.current) {
|
if (editorRef.current) {
|
||||||
@ -189,6 +200,8 @@ const CodeEditor: FC<Props> = ({
|
|||||||
isFocus={isFocus && !readOnly}
|
isFocus={isFocus && !readOnly}
|
||||||
minHeight={minHeight}
|
minHeight={minHeight}
|
||||||
isInNode={isInNode}
|
isInNode={isInNode}
|
||||||
|
fileList={fileList}
|
||||||
|
showFileList={showFileList}
|
||||||
>
|
>
|
||||||
{main}
|
{main}
|
||||||
</Base>
|
</Base>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user