feat: support open file in new tab

This commit is contained in:
Joel
2026-02-05 16:04:06 +08:00
parent 882ad92c24
commit ce3d2b581b
2 changed files with 21 additions and 8 deletions

View File

@ -2,12 +2,11 @@ import type { FileAppearanceType } from '@/app/components/base/file-uploader/typ
import type { AppAssetTreeView } from '@/types/app-asset'
import { RiCloseLine, RiExternalLinkLine, RiFolderLine } from '@remixicon/react'
import * as React from 'react'
import { useCallback, useContext, useMemo } from 'react'
import { useCallback, useMemo } from 'react'
import { useTranslation } from 'react-i18next'
import { useStore as useAppStore } from '@/app/components/app/store'
import FileTypeIcon from '@/app/components/base/file-uploader/file-type-icon'
import Loading from '@/app/components/base/loading'
import { WorkflowContext } from '@/app/components/workflow/context'
import SkillEditor from '@/app/components/workflow/skill/editor/skill-editor'
import { useFileTypeInfo } from '@/app/components/workflow/skill/hooks/use-file-type-info'
import { getFileIconType } from '@/app/components/workflow/skill/utils/file-utils'
@ -24,7 +23,6 @@ type FilePreviewPanelProps = {
const FilePreviewPanel = ({ resourceId, currentNode, className, style, onClose }: FilePreviewPanelProps) => {
const { t } = useTranslation(['workflow', 'common'])
const workflowStore = useContext(WorkflowContext)
const appId = useAppStore(s => s.appDetail?.id || '')
const isFolder = currentNode?.node_type === 'folder'
@ -58,13 +56,16 @@ const FilePreviewPanel = ({ resourceId, currentNode, className, style, onClose }
? getFileIconType(currentNode.name, currentNode.extension)
: null
const canOpenInEditor = Boolean(resourceId && !isFolder && workflowStore)
const canOpenInEditor = Boolean(resourceId && !isFolder && typeof window !== 'undefined')
const handleOpenInEditor = useCallback(() => {
if (!canOpenInEditor || !workflowStore)
if (!canOpenInEditor)
return
workflowStore.getState().openTab(resourceId)
}, [canOpenInEditor, workflowStore, resourceId])
const nextUrl = new URL(window.location.href)
nextUrl.searchParams.set('view', 'skill')
nextUrl.searchParams.set('fileId', resourceId)
window.open(nextUrl.toString(), '_blank', 'noopener,noreferrer')
}, [canOpenInEditor, resourceId])
return (
<div

View File

@ -1,8 +1,9 @@
'use client'
import { useSearchParams } from 'next/navigation'
import * as React from 'react'
import { useStore as useAppStore } from '@/app/components/app/store'
import { useStore } from '@/app/components/workflow/store'
import { useStore, useWorkflowStore } from '@/app/components/workflow/store'
import ArtifactContentPanel from './artifact-content-panel'
import { isArtifactTab } from './constants'
import ContentArea from './content-area'
@ -32,6 +33,17 @@ const ContentRouter = () => {
const SkillMain = () => {
const appDetail = useAppStore(s => s.appDetail)
const appId = appDetail?.id || ''
const searchParams = useSearchParams()
const storeApi = useWorkflowStore()
const openedFileRef = React.useRef<string | null>(null)
React.useEffect(() => {
const fileId = searchParams.get('fileId')
if (!fileId || openedFileRef.current === fileId)
return
openedFileRef.current = fileId
storeApi.getState().openTab(fileId, { pinned: true })
}, [searchParams, storeApi])
return (
<div className="h-full bg-workflow-canvas-workflow-top-bar-1 pl-3 pt-[52px]">