mirror of
https://github.com/langgenius/dify.git
synced 2026-05-03 17:08:03 +08:00
fix(skill): address code review issues for tab management
1. Add confirmation dialog when closing dirty tabs 2. Fix file double-click race condition with useDelayedClick hook 3. Fix previewTabId orphan state in closeTab 4. Remove auto-pin on every keystroke (VS Code behavior) 5. Extract shared MenuItem component to eliminate duplication 6. Make nodeId optional when node is provided (reduce props drilling)
This commit is contained in:
40
web/app/components/workflow/skill/hooks/use-delayed-click.ts
Normal file
40
web/app/components/workflow/skill/hooks/use-delayed-click.ts
Normal file
@ -0,0 +1,40 @@
|
||||
import { useCallback, useRef } from 'react'
|
||||
|
||||
type UseDelayedClickOptions = {
|
||||
delay?: number
|
||||
onSingleClick: () => void
|
||||
onDoubleClick: () => void
|
||||
}
|
||||
|
||||
/**
|
||||
* Hook to distinguish between single-click and double-click events.
|
||||
* Single-click is delayed to allow double-click detection.
|
||||
* Double-click cancels any pending single-click.
|
||||
*/
|
||||
export function useDelayedClick({
|
||||
delay = 200,
|
||||
onSingleClick,
|
||||
onDoubleClick,
|
||||
}: UseDelayedClickOptions) {
|
||||
const timeoutRef = useRef<NodeJS.Timeout | null>(null)
|
||||
|
||||
const handleClick = useCallback(() => {
|
||||
if (timeoutRef.current)
|
||||
clearTimeout(timeoutRef.current)
|
||||
|
||||
timeoutRef.current = setTimeout(() => {
|
||||
onSingleClick()
|
||||
timeoutRef.current = null
|
||||
}, delay)
|
||||
}, [delay, onSingleClick])
|
||||
|
||||
const handleDoubleClick = useCallback(() => {
|
||||
if (timeoutRef.current) {
|
||||
clearTimeout(timeoutRef.current)
|
||||
timeoutRef.current = null
|
||||
}
|
||||
onDoubleClick()
|
||||
}, [onDoubleClick])
|
||||
|
||||
return { handleClick, handleDoubleClick }
|
||||
}
|
||||
@ -16,18 +16,19 @@ import { getAllDescendantFileIds } from '../utils/tree-utils'
|
||||
import { useSkillAssetTreeData } from './use-skill-asset-tree'
|
||||
|
||||
type UseFileOperationsOptions = {
|
||||
nodeId: string
|
||||
nodeId?: string
|
||||
onClose: () => void
|
||||
treeRef?: React.RefObject<TreeApi<TreeNodeData> | null>
|
||||
node?: NodeApi<TreeNodeData>
|
||||
}
|
||||
|
||||
export function useFileOperations({
|
||||
nodeId,
|
||||
nodeId: explicitNodeId,
|
||||
onClose,
|
||||
treeRef,
|
||||
node,
|
||||
}: UseFileOperationsOptions) {
|
||||
const nodeId = node?.data.id ?? explicitNodeId ?? ''
|
||||
const { t } = useTranslation('workflow')
|
||||
const fileInputRef = useRef<HTMLInputElement>(null)
|
||||
const folderInputRef = useRef<HTMLInputElement>(null)
|
||||
|
||||
Reference in New Issue
Block a user