refactor(skill)!: add file node view-state flow and mode-based file data hook

- introduce resolving/ready/missing node view-state to avoid unsupported flicker

- switch useSkillFileData to explicit mode: none/content/download

- add hook tests for view-state transitions and mode query gating

BREAKING CHANGE: useSkillFileData signature changed from (appId, nodeId, isEditable) to (appId, nodeId, mode).
This commit is contained in:
yyh
2026-02-06 15:34:27 +08:00
parent f1100b82f9
commit dc213ca76c
5 changed files with 334 additions and 9 deletions

View File

@ -1,5 +1,7 @@
import { useGetAppAssetFileContent, useGetAppAssetFileDownloadUrl } from '@/service/use-app-asset'
export type SkillFileDataMode = 'none' | 'content' | 'download'
export type SkillFileDataResult = {
fileContent: ReturnType<typeof useGetAppAssetFileContent>['data']
downloadUrlData: ReturnType<typeof useGetAppAssetFileDownloadUrl>['data']
@ -9,19 +11,22 @@ export type SkillFileDataResult = {
/**
* Hook to fetch file data for skill documents.
* Fetches content for editable files and download URL for non-editable files.
* Uses explicit mode to control data fetching:
* - 'content': fetch editable file content
* - 'download': fetch non-editable file download URL
* - 'none': skip file-related requests while node metadata is unresolved
*/
export function useSkillFileData(
appId: string,
nodeId: string | null | undefined,
isEditable: boolean,
mode: SkillFileDataMode,
): SkillFileDataResult {
const {
data: fileContent,
isLoading: isContentLoading,
error: contentError,
} = useGetAppAssetFileContent(appId, nodeId || '', {
enabled: isEditable,
enabled: mode === 'content',
})
const {
@ -29,11 +34,19 @@ export function useSkillFileData(
isLoading: isDownloadUrlLoading,
error: downloadUrlError,
} = useGetAppAssetFileDownloadUrl(appId, nodeId || '', {
enabled: !isEditable && !!nodeId,
enabled: mode === 'download' && !!nodeId,
})
const isLoading = isEditable ? isContentLoading : isDownloadUrlLoading
const error = isEditable ? contentError : downloadUrlError
const isLoading = mode === 'content'
? isContentLoading
: mode === 'download'
? isDownloadUrlLoading
: false
const error = mode === 'content'
? contentError
: mode === 'download'
? downloadUrlError
: null
return {
fileContent,