mirror of
https://github.com/langgenius/dify.git
synced 2026-05-04 17:38:04 +08:00
refactor(skill): remove React.FC type annotations from all components
Replace FC<Props> pattern with direct props typing in function parameters for better TypeScript inference and modern React best practices.
This commit is contained in:
@ -1,9 +1,9 @@
|
||||
import type { FC, PropsWithChildren } from 'react'
|
||||
import type { PropsWithChildren } from 'react'
|
||||
import * as React from 'react'
|
||||
|
||||
type ContentAreaProps = PropsWithChildren
|
||||
|
||||
const ContentArea: FC<ContentAreaProps> = ({ children }) => {
|
||||
const ContentArea = ({ children }: ContentAreaProps) => {
|
||||
return (
|
||||
<section className="flex min-h-0 min-w-0 flex-1 flex-col rounded-lg">
|
||||
{children}
|
||||
|
||||
@ -1,9 +1,9 @@
|
||||
import type { FC, PropsWithChildren } from 'react'
|
||||
import type { PropsWithChildren } from 'react'
|
||||
import * as React from 'react'
|
||||
|
||||
type ContentBodyProps = PropsWithChildren
|
||||
|
||||
const ContentBody: FC<ContentBodyProps> = ({ children }) => {
|
||||
const ContentBody = ({ children }: ContentBodyProps) => {
|
||||
return (
|
||||
<div className="flex min-h-0 min-w-0 flex-1">
|
||||
{children}
|
||||
|
||||
@ -1,4 +1,3 @@
|
||||
import type { FC } from 'react'
|
||||
import Editor from '@monaco-editor/react'
|
||||
import * as React from 'react'
|
||||
import Loading from '@/app/components/base/loading'
|
||||
@ -11,7 +10,7 @@ type CodeFileEditorProps = {
|
||||
onMount: (editor: any, monaco: any) => void
|
||||
}
|
||||
|
||||
const CodeFileEditor: FC<CodeFileEditorProps> = ({ language, theme, value, onChange, onMount }) => {
|
||||
const CodeFileEditor = ({ language, theme, value, onChange, onMount }: CodeFileEditorProps) => {
|
||||
return (
|
||||
<Editor
|
||||
language={language}
|
||||
|
||||
@ -1,4 +1,3 @@
|
||||
import type { FC } from 'react'
|
||||
import * as React from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import SkillEditor from './skill-editor'
|
||||
@ -10,12 +9,12 @@ type MarkdownFileEditorProps = {
|
||||
collaborationEnabled?: boolean
|
||||
}
|
||||
|
||||
const MarkdownFileEditor: FC<MarkdownFileEditorProps> = ({
|
||||
const MarkdownFileEditor = ({
|
||||
instanceId,
|
||||
value,
|
||||
onChange,
|
||||
collaborationEnabled,
|
||||
}) => {
|
||||
}: MarkdownFileEditorProps) => {
|
||||
const { t } = useTranslation()
|
||||
const handleChange = React.useCallback((val: string) => {
|
||||
if (val !== value) {
|
||||
|
||||
@ -1,7 +1,6 @@
|
||||
'use client'
|
||||
|
||||
import type { EditorState } from 'lexical'
|
||||
import type { FC } from 'react'
|
||||
import { CodeNode } from '@lexical/code'
|
||||
import { LexicalComposer } from '@lexical/react/LexicalComposer'
|
||||
import { ContentEditable } from '@lexical/react/LexicalContentEditable'
|
||||
@ -52,7 +51,7 @@ export type SkillEditorProps = {
|
||||
toolPickerScope?: string
|
||||
}
|
||||
|
||||
const SkillEditor: FC<SkillEditorProps> = ({
|
||||
const SkillEditor = ({
|
||||
instanceId,
|
||||
compact,
|
||||
wrapperClassName,
|
||||
@ -68,7 +67,7 @@ const SkillEditor: FC<SkillEditorProps> = ({
|
||||
onBlur,
|
||||
onFocus,
|
||||
toolPickerScope = 'all',
|
||||
}) => {
|
||||
}: SkillEditorProps) => {
|
||||
const initialConfig = {
|
||||
namespace: 'skill-editor',
|
||||
nodes: [
|
||||
|
||||
@ -1,5 +1,4 @@
|
||||
import type { LexicalNode } from 'lexical'
|
||||
import type { FC } from 'react'
|
||||
import { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext'
|
||||
import { LexicalTypeaheadMenuPlugin, MenuOption } from '@lexical/react/LexicalTypeaheadMenuPlugin'
|
||||
import {
|
||||
@ -24,7 +23,7 @@ class FilePickerMenuOption extends MenuOption {
|
||||
}
|
||||
}
|
||||
|
||||
const FilePickerBlock: FC = () => {
|
||||
const FilePickerBlock = () => {
|
||||
const [editor] = useLexicalComposerContext()
|
||||
const checkForTriggerMatch = useBasicTypeaheadTriggerMatch('/', {
|
||||
minLength: 0,
|
||||
|
||||
@ -1,4 +1,3 @@
|
||||
import type { FC } from 'react'
|
||||
import type { NodeRendererProps } from 'react-arborist'
|
||||
import type { FileAppearanceType } from '@/app/components/base/file-uploader/types'
|
||||
import type { TreeNodeData } from '@/app/components/workflow/skill/type'
|
||||
@ -20,7 +19,7 @@ type FilePickerTreeNodeProps = NodeRendererProps<TreeNodeData> & {
|
||||
onSelectNode: (node: TreeNodeData) => void
|
||||
}
|
||||
|
||||
const FilePickerTreeNode: FC<FilePickerTreeNodeProps> = ({ node, style, dragHandle, onSelectNode }) => {
|
||||
const FilePickerTreeNode = ({ node, style, dragHandle, onSelectNode }: FilePickerTreeNodeProps) => {
|
||||
const { t } = useTranslation('workflow')
|
||||
const isFolder = node.data.node_type === 'folder'
|
||||
const isSelected = node.isSelected
|
||||
@ -114,13 +113,13 @@ type FilePickerPanelProps = {
|
||||
showHeader?: boolean
|
||||
}
|
||||
|
||||
const FilePickerPanel: FC<FilePickerPanelProps> = ({
|
||||
const FilePickerPanel = ({
|
||||
onSelectNode,
|
||||
focusNodeId,
|
||||
className,
|
||||
contentClassName,
|
||||
showHeader = true,
|
||||
}) => {
|
||||
}: FilePickerPanelProps) => {
|
||||
const { t } = useTranslation('workflow')
|
||||
const { data: treeData, isLoading, error } = useSkillAssetTreeData()
|
||||
const containerRef = useRef<HTMLDivElement>(null)
|
||||
|
||||
@ -1,5 +1,4 @@
|
||||
import type { LexicalNode } from 'lexical'
|
||||
import type { FC } from 'react'
|
||||
import type { FileAppearanceType } from '@/app/components/base/file-uploader/types'
|
||||
import type { TreeNodeData } from '@/app/components/workflow/skill/type'
|
||||
import { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext'
|
||||
@ -24,7 +23,7 @@ type FileReferenceBlockProps = {
|
||||
resourceId: string
|
||||
}
|
||||
|
||||
const FileReferenceBlock: FC<FileReferenceBlockProps> = ({ nodeKey, resourceId }) => {
|
||||
const FileReferenceBlock = ({ nodeKey, resourceId }: FileReferenceBlockProps) => {
|
||||
const [editor] = useLexicalComposerContext()
|
||||
const [ref, isSelected] = useSelectOrDelete(nodeKey)
|
||||
const { data: nodeMap } = useSkillAssetNodeMap()
|
||||
|
||||
@ -1,6 +1,5 @@
|
||||
'use client'
|
||||
import type { RangeSelection, TextNode } from 'lexical'
|
||||
import type { FC } from 'react'
|
||||
import type { OnlineUser } from '@/app/components/workflow/collaboration/types'
|
||||
import { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext'
|
||||
import {
|
||||
@ -316,10 +315,12 @@ const getSelectionRects = (
|
||||
return rects
|
||||
}
|
||||
|
||||
export const LocalCursorPlugin: FC<{
|
||||
type LocalCursorPluginProps = {
|
||||
fileId?: string
|
||||
enabled?: boolean
|
||||
}> = ({ fileId, enabled }) => {
|
||||
}
|
||||
|
||||
export const LocalCursorPlugin = ({ fileId, enabled }: LocalCursorPluginProps) => {
|
||||
const [editor] = useLexicalComposerContext()
|
||||
const lastEmittedCursorRef = useRef<{ start: number, end: number } | null>(null)
|
||||
const lastEmitRef = useRef(0)
|
||||
@ -461,10 +462,12 @@ export const LocalCursorPlugin: FC<{
|
||||
return null
|
||||
}
|
||||
|
||||
export const SkillRemoteCursors: FC<{
|
||||
type SkillRemoteCursorsProps = {
|
||||
fileId?: string
|
||||
enabled?: boolean
|
||||
}> = ({ fileId, enabled }) => {
|
||||
}
|
||||
|
||||
export const SkillRemoteCursors = ({ fileId, enabled }: SkillRemoteCursorsProps) => {
|
||||
const [editor] = useLexicalComposerContext()
|
||||
const { userProfile } = useAppContext()
|
||||
const myUserId = userProfile?.id || null
|
||||
|
||||
@ -1,4 +1,3 @@
|
||||
import type { FC } from 'react'
|
||||
import type { PluginDetail } from '@/app/components/plugins/types'
|
||||
import type { Emoji } from '@/app/components/tools/types'
|
||||
import type { ToolValue } from '@/app/components/workflow/block-selector/types'
|
||||
@ -107,7 +106,7 @@ type ToolConfigValueItem = {
|
||||
|
||||
type ToolConfigValueMap = Record<string, ToolConfigValueItem>
|
||||
|
||||
const ToolBlockComponent: FC<ToolBlockComponentProps> = ({
|
||||
const ToolBlockComponent = ({
|
||||
nodeKey,
|
||||
provider,
|
||||
tool,
|
||||
@ -115,7 +114,7 @@ const ToolBlockComponent: FC<ToolBlockComponentProps> = ({
|
||||
label,
|
||||
icon,
|
||||
iconDark,
|
||||
}) => {
|
||||
}: ToolBlockComponentProps) => {
|
||||
const [ref, isSelected] = useSelectOrDelete(nodeKey, DELETE_TOOL_BLOCK_COMMAND)
|
||||
const language = useGetLanguage()
|
||||
const { t } = useTranslation()
|
||||
|
||||
@ -1,4 +1,3 @@
|
||||
import type { FC } from 'react'
|
||||
import type { ToolToken } from './utils'
|
||||
import type { PluginDetail } from '@/app/components/plugins/types'
|
||||
import type { ToolParameter } from '@/app/components/tools/types'
|
||||
@ -102,10 +101,10 @@ const normalizeProviderIcon = (icon?: ToolWithProvider['icon']) => {
|
||||
return icon
|
||||
}
|
||||
|
||||
const ToolGroupBlockComponent: FC<ToolGroupBlockComponentProps> = ({
|
||||
const ToolGroupBlockComponent = ({
|
||||
nodeKey,
|
||||
tools,
|
||||
}) => {
|
||||
}: ToolGroupBlockComponentProps) => {
|
||||
const [ref, isSelected] = useSelectOrDelete(nodeKey, DELETE_TOOL_BLOCK_COMMAND)
|
||||
const { t } = useTranslation()
|
||||
const authBadgeLabel = t('skillEditor.authorizationBadge', { ns: 'workflow' })
|
||||
|
||||
@ -1,6 +1,5 @@
|
||||
'use client'
|
||||
|
||||
import type { FC } from 'react'
|
||||
import type { Emoji } from '@/app/components/tools/types'
|
||||
import { RiArrowLeftSLine, RiCloseLine } from '@remixicon/react'
|
||||
import AppIcon from '@/app/components/base/app-icon'
|
||||
@ -15,7 +14,7 @@ type ToolHeaderProps = {
|
||||
backLabel?: string
|
||||
}
|
||||
|
||||
const ToolHeader: FC<ToolHeaderProps> = ({
|
||||
const ToolHeader = ({
|
||||
icon,
|
||||
providerLabel,
|
||||
toolLabel,
|
||||
@ -23,7 +22,7 @@ const ToolHeader: FC<ToolHeaderProps> = ({
|
||||
onClose,
|
||||
onBack,
|
||||
backLabel,
|
||||
}) => {
|
||||
}: ToolHeaderProps) => {
|
||||
const renderHeaderIcon = () => {
|
||||
if (!icon)
|
||||
return null
|
||||
|
||||
@ -1,5 +1,4 @@
|
||||
import type { LexicalNode } from 'lexical'
|
||||
import type { FC } from 'react'
|
||||
import type { ToolParameter } from '@/app/components/tools/types'
|
||||
import type { ToolDefaultValue } from '@/app/components/workflow/block-selector/types'
|
||||
import { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext'
|
||||
@ -32,7 +31,7 @@ type ToolPickerBlockProps = {
|
||||
scope?: string
|
||||
}
|
||||
|
||||
const ToolPickerBlock: FC<ToolPickerBlockProps> = ({ scope = 'all' }) => {
|
||||
const ToolPickerBlock = ({ scope = 'all' }: ToolPickerBlockProps) => {
|
||||
const [editor] = useLexicalComposerContext()
|
||||
const checkForTriggerMatch = useBasicTypeaheadTriggerMatch('@', {
|
||||
minLength: 0,
|
||||
|
||||
@ -1,6 +1,5 @@
|
||||
'use client'
|
||||
|
||||
import type { FC } from 'react'
|
||||
import type { Tool } from '@/app/components/tools/types'
|
||||
import type { ToolValue } from '@/app/components/workflow/block-selector/types'
|
||||
import type { ToolWithProvider } from '@/app/components/workflow/types'
|
||||
@ -38,13 +37,13 @@ type ToolSettingsSectionProps = {
|
||||
onChange?: (value: ToolValue) => void
|
||||
}
|
||||
|
||||
const ToolSettingsSection: FC<ToolSettingsSectionProps> = ({
|
||||
const ToolSettingsSection = ({
|
||||
currentProvider,
|
||||
currentTool,
|
||||
value,
|
||||
nodeId,
|
||||
onChange,
|
||||
}) => {
|
||||
}: ToolSettingsSectionProps) => {
|
||||
const { t } = useTranslation()
|
||||
const safeNodeId = nodeId ?? ''
|
||||
|
||||
|
||||
@ -1,7 +1,6 @@
|
||||
'use client'
|
||||
|
||||
import type { OnMount } from '@monaco-editor/react'
|
||||
import type { FC } from 'react'
|
||||
import { loader } from '@monaco-editor/react'
|
||||
import dynamic from 'next/dynamic'
|
||||
import * as React from 'react'
|
||||
@ -34,7 +33,7 @@ const SQLiteFilePreview = dynamic(
|
||||
if (typeof window !== 'undefined')
|
||||
loader.config({ paths: { vs: `${window.location.origin}${basePath}/vs` } })
|
||||
|
||||
const FileContentPanel: FC = () => {
|
||||
const FileContentPanel = () => {
|
||||
const { t } = useTranslation('workflow')
|
||||
const { theme: appTheme } = useTheme()
|
||||
const [isMounted, setIsMounted] = useState(false)
|
||||
|
||||
@ -1,6 +1,5 @@
|
||||
'use client'
|
||||
|
||||
import type { FC } from 'react'
|
||||
import type { FileAppearanceType } from '@/app/components/base/file-uploader/types'
|
||||
import { RiCloseLine } from '@remixicon/react'
|
||||
import * as React from 'react'
|
||||
@ -22,7 +21,7 @@ type FileTabItemProps = {
|
||||
onDoubleClick: (fileId: string) => void
|
||||
}
|
||||
|
||||
const FileTabItem: FC<FileTabItemProps> = ({
|
||||
const FileTabItem = ({
|
||||
fileId,
|
||||
name,
|
||||
extension,
|
||||
@ -32,7 +31,7 @@ const FileTabItem: FC<FileTabItemProps> = ({
|
||||
onClick,
|
||||
onClose,
|
||||
onDoubleClick,
|
||||
}) => {
|
||||
}: FileTabItemProps) => {
|
||||
const { t } = useTranslation()
|
||||
const iconType = getFileIconType(name, extension)
|
||||
|
||||
|
||||
@ -1,6 +1,5 @@
|
||||
'use client'
|
||||
|
||||
import type { FC } from 'react'
|
||||
import * as React from 'react'
|
||||
import { useCallback, useState } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
@ -12,7 +11,7 @@ import FileTabItem from './file-tab-item'
|
||||
import { useSkillAssetNodeMap } from './hooks/use-skill-asset-tree'
|
||||
import StartTabItem from './start-tab-item'
|
||||
|
||||
const FileTabs: FC = () => {
|
||||
const FileTabs = () => {
|
||||
const { t } = useTranslation('workflow')
|
||||
const openTabIds = useStore(s => s.openTabIds)
|
||||
const activeTabId = useStore(s => s.activeTabId)
|
||||
|
||||
@ -1,6 +1,5 @@
|
||||
'use client'
|
||||
|
||||
import type { FC } from 'react'
|
||||
import type { SandboxFileTreeNode } from '@/types/sandbox-file'
|
||||
import { RiArrowDownSLine, RiArrowRightSLine, RiLoader2Line } from '@remixicon/react'
|
||||
import * as React from 'react'
|
||||
@ -16,7 +15,7 @@ type ArtifactsSectionProps = {
|
||||
className?: string
|
||||
}
|
||||
|
||||
const ArtifactsSection: FC<ArtifactsSectionProps> = ({ className }) => {
|
||||
const ArtifactsSection = ({ className }: ArtifactsSectionProps) => {
|
||||
const { t } = useTranslation('workflow')
|
||||
const { userProfile } = useAppContext()
|
||||
const sandboxId = userProfile?.id
|
||||
|
||||
@ -1,6 +1,5 @@
|
||||
'use client'
|
||||
|
||||
import type { FC } from 'react'
|
||||
import type { FileAppearanceType } from '@/app/components/base/file-uploader/types'
|
||||
import type { SandboxFileTreeNode } from '@/types/sandbox-file'
|
||||
import { RiDownloadLine, RiFolderLine, RiFolderOpenLine } from '@remixicon/react'
|
||||
@ -30,14 +29,14 @@ type ArtifactsTreeNodeProps = {
|
||||
isDownloading?: boolean
|
||||
}
|
||||
|
||||
const ArtifactsTreeNode: FC<ArtifactsTreeNodeProps> = ({
|
||||
const ArtifactsTreeNode = ({
|
||||
node,
|
||||
depth,
|
||||
onDownload,
|
||||
onSelect,
|
||||
selectedPath,
|
||||
isDownloading,
|
||||
}) => {
|
||||
}: ArtifactsTreeNodeProps) => {
|
||||
const [isExpanded, setIsExpanded] = useState(false)
|
||||
const isFolder = node.node_type === 'folder'
|
||||
const hasChildren = isFolder && node.children.length > 0
|
||||
@ -132,13 +131,13 @@ const ArtifactsTreeNode: FC<ArtifactsTreeNodeProps> = ({
|
||||
)
|
||||
}
|
||||
|
||||
const ArtifactsTree: FC<ArtifactsTreeProps> = ({
|
||||
const ArtifactsTree = ({
|
||||
data,
|
||||
onDownload,
|
||||
onSelect,
|
||||
selectedPath,
|
||||
isDownloading,
|
||||
}) => {
|
||||
}: ArtifactsTreeProps) => {
|
||||
if (!data || data.length === 0)
|
||||
return null
|
||||
|
||||
|
||||
@ -1,6 +1,5 @@
|
||||
'use client'
|
||||
|
||||
import type { FC } from 'react'
|
||||
import * as React from 'react'
|
||||
import { useMemo } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
@ -14,7 +13,7 @@ type DragActionTooltipProps = {
|
||||
action: DragAction
|
||||
}
|
||||
|
||||
const DragActionTooltip: FC<DragActionTooltipProps> = ({ action }) => {
|
||||
const DragActionTooltip = ({ action }: DragActionTooltipProps) => {
|
||||
const { t } = useTranslation('workflow')
|
||||
const dragOverFolderId = useStore(s => s.dragOverFolderId)
|
||||
const { data: nodeMap } = useSkillAssetNodeMap()
|
||||
|
||||
@ -88,7 +88,7 @@ const DropTip = () => {
|
||||
)
|
||||
}
|
||||
|
||||
const FileTree: React.FC<FileTreeProps> = ({ className }) => {
|
||||
const FileTree = ({ className }: FileTreeProps) => {
|
||||
const { t } = useTranslation('workflow')
|
||||
const treeRef = useRef<TreeApi<TreeNodeData>>(null)
|
||||
const containerRef = useRef<HTMLDivElement>(null)
|
||||
|
||||
@ -1,7 +1,6 @@
|
||||
'use client'
|
||||
|
||||
import type { VariantProps } from 'class-variance-authority'
|
||||
import type { FC } from 'react'
|
||||
import { cva } from 'class-variance-authority'
|
||||
import * as React from 'react'
|
||||
import ShortcutsName from '@/app/components/workflow/shortcuts-name'
|
||||
@ -58,7 +57,7 @@ export type MenuItemProps = {
|
||||
disabled?: boolean
|
||||
} & VariantProps<typeof menuItemVariants>
|
||||
|
||||
const MenuItem: FC<MenuItemProps> = ({ icon: Icon, label, kbd, onClick, disabled, variant }) => {
|
||||
const MenuItem = ({ icon: Icon, label, kbd, onClick, disabled, variant }: MenuItemProps) => {
|
||||
const handleClick = React.useCallback((event: React.MouseEvent<HTMLButtonElement>) => {
|
||||
event.stopPropagation()
|
||||
onClick(event)
|
||||
|
||||
@ -1,6 +1,5 @@
|
||||
'use client'
|
||||
|
||||
import type { FC } from 'react'
|
||||
import type { NodeApi, TreeApi } from 'react-arborist'
|
||||
import type { NodeMenuType } from '../constants'
|
||||
import type { TreeNodeData } from '../type'
|
||||
@ -42,14 +41,14 @@ type NodeMenuProps = {
|
||||
node?: NodeApi<TreeNodeData>
|
||||
}
|
||||
|
||||
const NodeMenu: FC<NodeMenuProps> = ({
|
||||
const NodeMenu = ({
|
||||
type,
|
||||
nodeId,
|
||||
onClose,
|
||||
className,
|
||||
treeRef,
|
||||
node,
|
||||
}) => {
|
||||
}: NodeMenuProps) => {
|
||||
const { t } = useTranslation('workflow')
|
||||
const storeApi = useWorkflowStore()
|
||||
const selectedNodeIds = useStore(s => s.selectedNodeIds)
|
||||
|
||||
@ -1,6 +1,5 @@
|
||||
'use client'
|
||||
|
||||
import type { FC } from 'react'
|
||||
import type { TreeApi } from 'react-arborist'
|
||||
import type { TreeNodeData } from '../type'
|
||||
import { useClickAway } from 'ahooks'
|
||||
@ -14,7 +13,7 @@ type TreeContextMenuProps = {
|
||||
treeRef: React.RefObject<TreeApi<TreeNodeData> | null>
|
||||
}
|
||||
|
||||
const TreeContextMenu: FC<TreeContextMenuProps> = ({ treeRef }) => {
|
||||
const TreeContextMenu = ({ treeRef }: TreeContextMenuProps) => {
|
||||
const ref = useRef<HTMLDivElement>(null)
|
||||
const contextMenu = useStore(s => s.contextMenu)
|
||||
const storeApi = useWorkflowStore()
|
||||
|
||||
@ -10,7 +10,7 @@ type TreeEditInputProps = {
|
||||
node: NodeApi<TreeNodeData>
|
||||
}
|
||||
|
||||
const TreeEditInput: React.FC<TreeEditInputProps> = ({ node }) => {
|
||||
const TreeEditInput = ({ node }: TreeEditInputProps) => {
|
||||
const { t } = useTranslation('workflow')
|
||||
const inputRef = useRef<HTMLInputElement>(null)
|
||||
const isFolder = node.data.node_type === 'folder'
|
||||
|
||||
@ -12,11 +12,11 @@ type TreeGuideLinesProps = {
|
||||
const INDENT_SIZE = 20
|
||||
const DEFAULT_LINE_OFFSET = 10
|
||||
|
||||
const TreeGuideLines: React.FC<TreeGuideLinesProps> = ({
|
||||
const TreeGuideLines = ({
|
||||
level,
|
||||
indentSize = INDENT_SIZE,
|
||||
lineOffset = DEFAULT_LINE_OFFSET,
|
||||
}) => {
|
||||
}: TreeGuideLinesProps) => {
|
||||
const guides = useMemo(() => {
|
||||
if (level === 0)
|
||||
return null
|
||||
|
||||
@ -2,7 +2,6 @@
|
||||
|
||||
// Icon rendering for tree nodes (folder/file icons with dirty indicator)
|
||||
|
||||
import type { FC } from 'react'
|
||||
import type { FileAppearanceType } from '@/app/components/base/file-uploader/types'
|
||||
import { RiFolderLine, RiFolderOpenLine } from '@remixicon/react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
@ -19,14 +18,14 @@ type TreeNodeIconProps = {
|
||||
onToggle?: (e: React.MouseEvent) => void
|
||||
}
|
||||
|
||||
export const TreeNodeIcon: FC<TreeNodeIconProps> = ({
|
||||
export const TreeNodeIcon = ({
|
||||
isFolder,
|
||||
isOpen,
|
||||
fileName,
|
||||
extension,
|
||||
isDirty,
|
||||
onToggle,
|
||||
}) => {
|
||||
}: TreeNodeIconProps) => {
|
||||
const { t } = useTranslation('workflow')
|
||||
|
||||
if (isFolder) {
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
'use client'
|
||||
|
||||
import type { FC, ReactNode } from 'react'
|
||||
import type { ReactNode } from 'react'
|
||||
import {
|
||||
RiAlertFill,
|
||||
RiCheckboxCircleFill,
|
||||
@ -18,7 +18,7 @@ type UploadStatusTooltipProps = {
|
||||
|
||||
const SUCCESS_DISPLAY_MS = 2000
|
||||
|
||||
const UploadStatusTooltip: FC<UploadStatusTooltipProps> = ({ fallback }) => {
|
||||
const UploadStatusTooltip = ({ fallback }: UploadStatusTooltipProps) => {
|
||||
const { t } = useTranslation('workflow')
|
||||
const storeApi = useWorkflowStore()
|
||||
const uploadStatus = useStore(s => s.uploadStatus)
|
||||
|
||||
@ -1,6 +1,5 @@
|
||||
'use client'
|
||||
|
||||
import type { FC } from 'react'
|
||||
import * as React from 'react'
|
||||
import { useStore as useAppStore } from '@/app/components/app/store'
|
||||
import ContentArea from './content-area'
|
||||
@ -15,12 +14,12 @@ import Sidebar from './sidebar'
|
||||
import SidebarSearchAdd from './sidebar-search-add'
|
||||
import SkillPageLayout from './skill-page-layout'
|
||||
|
||||
const SkillAutoSaveManager: FC = () => {
|
||||
const SkillAutoSaveManager = () => {
|
||||
useSkillAutoSave()
|
||||
return null
|
||||
}
|
||||
|
||||
const SkillMain: FC = () => {
|
||||
const SkillMain = () => {
|
||||
const appDetail = useAppStore(s => s.appDetail)
|
||||
const appId = appDetail?.id || ''
|
||||
|
||||
|
||||
@ -1,6 +1,5 @@
|
||||
'use client'
|
||||
|
||||
import type { FC } from 'react'
|
||||
import {
|
||||
RiAddLine,
|
||||
RiFileAddLine,
|
||||
@ -32,7 +31,7 @@ type MenuItemProps = {
|
||||
disabled?: boolean
|
||||
}
|
||||
|
||||
const MenuItem: React.FC<MenuItemProps> = ({ icon: Icon, label, onClick, disabled }) => (
|
||||
const MenuItem = ({ icon: Icon, label, onClick, disabled }: MenuItemProps) => (
|
||||
<button
|
||||
type="button"
|
||||
onClick={onClick}
|
||||
@ -50,7 +49,7 @@ const MenuItem: React.FC<MenuItemProps> = ({ icon: Icon, label, onClick, disable
|
||||
</button>
|
||||
)
|
||||
|
||||
const SidebarSearchAdd: FC = () => {
|
||||
const SidebarSearchAdd = () => {
|
||||
const { t } = useTranslation('workflow')
|
||||
const searchValue = useStore(s => s.fileTreeSearchTerm)
|
||||
const storeApi = useWorkflowStore()
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
'use client'
|
||||
|
||||
import type { FC, PropsWithChildren } from 'react'
|
||||
import type { PropsWithChildren } from 'react'
|
||||
import { useDebounceFn } from 'ahooks'
|
||||
import * as React from 'react'
|
||||
import { useCallback } from 'react'
|
||||
@ -11,7 +11,7 @@ import { SIDEBAR_DEFAULT_WIDTH, SIDEBAR_MAX_WIDTH, SIDEBAR_MIN_WIDTH } from './c
|
||||
|
||||
type SidebarProps = PropsWithChildren
|
||||
|
||||
const Sidebar: FC<SidebarProps> = ({ children }) => {
|
||||
const Sidebar = ({ children }: SidebarProps) => {
|
||||
const { run: persistWidth } = useDebounceFn(
|
||||
(width: number) => storage.set(STORAGE_KEYS.SKILL.SIDEBAR_WIDTH, width),
|
||||
{ wait: 200 },
|
||||
|
||||
@ -1,9 +1,9 @@
|
||||
import type { FC, PropsWithChildren } from 'react'
|
||||
import type { PropsWithChildren } from 'react'
|
||||
import * as React from 'react'
|
||||
|
||||
type SkillPageLayoutProps = PropsWithChildren
|
||||
|
||||
const SkillPageLayout: FC<SkillPageLayoutProps> = ({ children }) => {
|
||||
const SkillPageLayout = ({ children }: SkillPageLayoutProps) => {
|
||||
return (
|
||||
<div className="flex h-full gap-3 overflow-hidden">
|
||||
{children}
|
||||
|
||||
@ -1,6 +1,5 @@
|
||||
'use client'
|
||||
|
||||
import type { FC } from 'react'
|
||||
import * as React from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import Home from '@/app/components/base/icons/src/vender/workflow/Home'
|
||||
@ -11,10 +10,10 @@ type StartTabItemProps = {
|
||||
onClick: () => void
|
||||
}
|
||||
|
||||
const StartTabItem: FC<StartTabItemProps> = ({
|
||||
const StartTabItem = ({
|
||||
isActive,
|
||||
onClick,
|
||||
}) => {
|
||||
}: StartTabItemProps) => {
|
||||
const { t } = useTranslation('workflow')
|
||||
|
||||
return (
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
'use client'
|
||||
|
||||
import type { FC, ReactNode } from 'react'
|
||||
import type { ReactNode } from 'react'
|
||||
import { memo } from 'react'
|
||||
import { cn } from '@/utils/classnames'
|
||||
|
||||
@ -11,12 +11,12 @@ type ActionCardProps = {
|
||||
onClick?: () => void
|
||||
}
|
||||
|
||||
const ActionCard: FC<ActionCardProps> = ({
|
||||
const ActionCard = ({
|
||||
icon,
|
||||
title,
|
||||
description,
|
||||
onClick,
|
||||
}) => {
|
||||
}: ActionCardProps) => {
|
||||
return (
|
||||
<button
|
||||
type="button"
|
||||
|
||||
@ -1,6 +1,5 @@
|
||||
'use client'
|
||||
|
||||
import type { FC } from 'react'
|
||||
import { memo } from 'react'
|
||||
import TabItem from './tab-item'
|
||||
|
||||
@ -24,11 +23,11 @@ type CategoryTabsProps = {
|
||||
onCategoryChange: (categoryId: string) => void
|
||||
}
|
||||
|
||||
const CategoryTabs: FC<CategoryTabsProps> = ({
|
||||
const CategoryTabs = ({
|
||||
categories = MOCK_CATEGORIES,
|
||||
activeCategory,
|
||||
onCategoryChange,
|
||||
}) => {
|
||||
}: CategoryTabsProps) => {
|
||||
return (
|
||||
<div className="flex flex-1 items-center gap-1">
|
||||
{categories.map(category => (
|
||||
|
||||
@ -1,6 +1,5 @@
|
||||
'use client'
|
||||
|
||||
import type { FC } from 'react'
|
||||
import { memo } from 'react'
|
||||
import { cn } from '@/utils/classnames'
|
||||
|
||||
@ -10,11 +9,11 @@ type TabItemProps = {
|
||||
onClick: () => void
|
||||
}
|
||||
|
||||
const TabItem: FC<TabItemProps> = ({
|
||||
const TabItem = ({
|
||||
label,
|
||||
isActive,
|
||||
onClick,
|
||||
}) => {
|
||||
}: TabItemProps) => {
|
||||
return (
|
||||
<button
|
||||
type="button"
|
||||
|
||||
@ -1,12 +1,11 @@
|
||||
'use client'
|
||||
|
||||
import type { FC } from 'react'
|
||||
import { RiAddCircleFill, RiUploadLine } from '@remixicon/react'
|
||||
import { memo } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import ActionCard from './action-card'
|
||||
|
||||
const CreateImportSection: FC = () => {
|
||||
const CreateImportSection = () => {
|
||||
const { t } = useTranslation('workflow')
|
||||
|
||||
return (
|
||||
|
||||
@ -1,11 +1,10 @@
|
||||
'use client'
|
||||
|
||||
import type { FC } from 'react'
|
||||
import { memo } from 'react'
|
||||
import CreateImportSection from './create-import-section'
|
||||
import SkillTemplatesSection from './skill-templates-section'
|
||||
|
||||
const StartTabContent: FC = () => {
|
||||
const StartTabContent = () => {
|
||||
return (
|
||||
<div className="h-full w-full overflow-auto bg-components-panel-bg">
|
||||
<CreateImportSection />
|
||||
|
||||
@ -1,6 +1,5 @@
|
||||
'use client'
|
||||
|
||||
import type { FC } from 'react'
|
||||
import { memo } from 'react'
|
||||
|
||||
type SectionHeaderProps = {
|
||||
@ -9,11 +8,11 @@ type SectionHeaderProps = {
|
||||
className?: string
|
||||
}
|
||||
|
||||
const SectionHeader: FC<SectionHeaderProps> = ({
|
||||
const SectionHeader = ({
|
||||
title,
|
||||
description,
|
||||
className,
|
||||
}) => {
|
||||
}: SectionHeaderProps) => {
|
||||
return (
|
||||
<header className={className}>
|
||||
<h2 className="title-xl-semi-bold text-text-primary">
|
||||
|
||||
@ -1,13 +1,12 @@
|
||||
'use client'
|
||||
|
||||
import type { FC } from 'react'
|
||||
import { memo, useState } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import CategoryTabs from './category-tabs'
|
||||
import SectionHeader from './section-header'
|
||||
import TemplateSearch from './template-search'
|
||||
|
||||
const SkillTemplatesSection: FC = () => {
|
||||
const SkillTemplatesSection = () => {
|
||||
const { t } = useTranslation('workflow')
|
||||
const [activeCategory, setActiveCategory] = useState('all')
|
||||
const [searchValue, setSearchValue] = useState('')
|
||||
|
||||
@ -1,6 +1,5 @@
|
||||
'use client'
|
||||
|
||||
import type { FC } from 'react'
|
||||
import { RiSearchLine } from '@remixicon/react'
|
||||
import { memo } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
@ -10,10 +9,10 @@ type TemplateSearchProps = {
|
||||
onChange: (value: string) => void
|
||||
}
|
||||
|
||||
const TemplateSearch: FC<TemplateSearchProps> = ({
|
||||
const TemplateSearch = ({
|
||||
value,
|
||||
onChange,
|
||||
}) => {
|
||||
}: TemplateSearchProps) => {
|
||||
const { t } = useTranslation('workflow')
|
||||
|
||||
return (
|
||||
|
||||
@ -1,4 +1,3 @@
|
||||
import type { FC } from 'react'
|
||||
import * as React from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
|
||||
@ -7,7 +6,7 @@ type MediaFilePreviewProps = {
|
||||
src: string
|
||||
}
|
||||
|
||||
const MediaFilePreview: FC<MediaFilePreviewProps> = ({ type, src }) => {
|
||||
const MediaFilePreview = ({ type, src }: MediaFilePreviewProps) => {
|
||||
const { t } = useTranslation('workflow')
|
||||
|
||||
if (!src) {
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
import type { TFunction } from 'i18next'
|
||||
import type { FC, RefObject } from 'react'
|
||||
import type { RefObject } from 'react'
|
||||
import type { SQLiteValue } from '../../hooks/use-sqlite-database'
|
||||
import { useVirtualizer } from '@tanstack/react-virtual'
|
||||
import * as React from 'react'
|
||||
@ -32,7 +32,7 @@ const truncateValue = (value: string): string => {
|
||||
return `${value.slice(0, MAX_CELL_LENGTH)}…`
|
||||
}
|
||||
|
||||
const DataTable: FC<DataTableProps> = ({ columns, values, scrollRef, isTruncated = false }) => {
|
||||
const DataTable = ({ columns, values, scrollRef, isTruncated = false }: DataTableProps) => {
|
||||
const { t } = useTranslation('workflow')
|
||||
const keyColumnIndex = useMemo(() => {
|
||||
const candidates = new Set(['id', 'rowid', 'uuid'])
|
||||
|
||||
@ -1,4 +1,3 @@
|
||||
import type { FC } from 'react'
|
||||
import * as React from 'react'
|
||||
import { useMemo, useRef, useState } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
@ -13,9 +12,9 @@ type SQLiteFilePreviewProps = {
|
||||
downloadUrl: string
|
||||
}
|
||||
|
||||
const SQLiteFilePreview: FC<SQLiteFilePreviewProps> = ({
|
||||
const SQLiteFilePreview = ({
|
||||
downloadUrl,
|
||||
}) => {
|
||||
}: SQLiteFilePreviewProps) => {
|
||||
const { t } = useTranslation('workflow')
|
||||
const { tables, isLoading, error, queryTable } = useSQLiteDatabase(downloadUrl)
|
||||
const [selectedTableId, setSelectedTableId] = useState<string>('')
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import type { FC, RefObject } from 'react'
|
||||
import type { RefObject } from 'react'
|
||||
import type { SQLiteQueryResult } from '../../hooks/sqlite/types'
|
||||
import * as React from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
@ -13,13 +13,13 @@ type TablePanelProps = {
|
||||
isTruncated?: boolean
|
||||
}
|
||||
|
||||
const TablePanel: FC<TablePanelProps> = ({
|
||||
const TablePanel = ({
|
||||
data,
|
||||
isLoading,
|
||||
error,
|
||||
scrollRef,
|
||||
isTruncated = false,
|
||||
}) => {
|
||||
}: TablePanelProps) => {
|
||||
const { t } = useTranslation('workflow')
|
||||
|
||||
return (
|
||||
|
||||
@ -1,4 +1,3 @@
|
||||
import type { FC } from 'react'
|
||||
import { RiArrowDownSLine } from '@remixicon/react'
|
||||
import * as React from 'react'
|
||||
import { useMemo, useState } from 'react'
|
||||
@ -19,12 +18,12 @@ type TableSelectorProps = {
|
||||
onTableChange: (tableName: string) => void
|
||||
}
|
||||
|
||||
const TableSelector: FC<TableSelectorProps> = ({
|
||||
const TableSelector = ({
|
||||
tables,
|
||||
selectedTable,
|
||||
isLoading = false,
|
||||
onTableChange,
|
||||
}) => {
|
||||
}: TableSelectorProps) => {
|
||||
const { t } = useTranslation('workflow')
|
||||
const [open, setOpen] = useState(false)
|
||||
const items = useMemo(() => {
|
||||
|
||||
@ -1,4 +1,3 @@
|
||||
import type { FC } from 'react'
|
||||
import * as React from 'react'
|
||||
import { useCallback } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
@ -13,7 +12,7 @@ type UnsupportedFileDownloadProps = {
|
||||
downloadUrl?: string
|
||||
}
|
||||
|
||||
const UnsupportedFileDownload: FC<UnsupportedFileDownloadProps> = ({ name, size, downloadUrl }) => {
|
||||
const UnsupportedFileDownload = ({ name, size, downloadUrl }: UnsupportedFileDownloadProps) => {
|
||||
const { t } = useTranslation('workflow')
|
||||
const fileSize = size ? formatFileSize(size) : ''
|
||||
|
||||
|
||||
Reference in New Issue
Block a user