fix: add view file action to file context menu

* fix: add view file context menu action

* Address PR review feedback (#4620)

- Localize the View File context menu label

- Update file explorer virtual row test fixture

* test: cover view file context menu visibility

---------

Co-authored-by: Jinjing <6427696+AmethystLiang@users.noreply.github.com>
This commit is contained in:
Trevin Chow 2026-07-06 10:03:43 -07:00 committed by GitHub
parent 9d9ebe69af
commit cd3d0e99db
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
11 changed files with 92 additions and 6 deletions

View File

@ -19,7 +19,8 @@ import {
shouldShowFindInFolderAction,
shouldShowCopyFileAction,
shouldShowOpenInTerminalAction,
shouldShowRemoteDownloadAction
shouldShowRemoteDownloadAction,
shouldShowViewFileAction
} from './FileExplorerRow'
import { FileExplorerVirtualRows } from './FileExplorerVirtualRows'
import type { TreeNode } from './file-explorer-types'
@ -581,6 +582,11 @@ describe('FileExplorerRow collapse folder action', () => {
expect(shouldShowOpenInTerminalAction(fileNode)).toBe(false)
})
it('only shows view file for files', () => {
expect(shouldShowViewFileAction(fileNode)).toBe(true)
expect(shouldShowViewFileAction(directoryNode)).toBe(false)
})
it('shows remote download only for desktop SSH or Remote Host file-like rows', () => {
const runtimeContext = {
settings: { activeRuntimeEnvironmentId: 'runtime-1' },
@ -775,6 +781,7 @@ describe('FileExplorerRow collapse folder action', () => {
deleteShortcutLabel: 'Del',
onClick: vi.fn(),
onDoubleClick: vi.fn(),
onViewFile: vi.fn(),
onContextMenuSelect: vi.fn(),
onCopyPaths: vi.fn(),
onStartNew: vi.fn(),
@ -827,6 +834,7 @@ describe('FileExplorerRow collapse folder action', () => {
deleteShortcutLabel: 'Del',
onClick: vi.fn(),
onDoubleClick: vi.fn(),
onViewFile: vi.fn(),
onContextMenuSelect: vi.fn(),
onCopyPaths: vi.fn(),
onStartNew: vi.fn(),
@ -879,6 +887,7 @@ describe('FileExplorerRow collapse folder action', () => {
connectionId: 'ssh-1',
onClick: vi.fn(),
onDoubleClick: vi.fn(),
onViewFile: vi.fn(),
onContextMenuSelect: vi.fn(),
onCopyPaths: vi.fn(),
onStartNew: vi.fn(),
@ -930,6 +939,7 @@ describe('FileExplorerRow collapse folder action', () => {
deleteShortcutLabel: 'Del',
onClick: vi.fn(),
onDoubleClick: vi.fn(),
onViewFile: vi.fn(),
onContextMenuSelect: vi.fn(),
onCopyPaths: vi.fn(),
onStartNew: vi.fn(),
@ -957,4 +967,57 @@ describe('FileExplorerRow collapse folder action', () => {
expect(onOpenInTerminal).toHaveBeenCalledWith(directoryNode)
})
it('passes the row node to the view file handler', () => {
const onViewFile = vi.fn()
const element = FileExplorerVirtualRows({
virtualizer: {
getTotalSize: () => 26,
getVirtualItems: () => [{ index: 0, key: 'src', start: 0 }],
measureElement: vi.fn()
} as never,
inlineInputIndex: -1,
rowProjection: createFileExplorerRowProjection([fileNode]),
inlineInput: null,
handleInlineSubmit: vi.fn(),
dismissInlineInput: vi.fn(),
folderStatusByRelativePath: new Map(),
statusByRelativePath: new Map(),
ignoredByRelativePath: new Set(),
expanded: new Set(),
dirCache: {},
selectedPaths: new Set(),
activeFileId: null,
flashingPath: null,
deleteShortcutLabel: 'Del',
onClick: vi.fn(),
onDoubleClick: vi.fn(),
onViewFile,
onContextMenuSelect: vi.fn(),
onCopyPaths: vi.fn(),
onStartNew: vi.fn(),
onStartRename: vi.fn(),
onDuplicate: vi.fn(),
onAddFolderAsProject: vi.fn(),
canAddFolderAsProject: () => false,
onOpenInTerminal: vi.fn(),
onRequestDelete: vi.fn(),
onCollapseFolderSubtree: vi.fn(),
onFindInFolder: vi.fn(),
onMoveDrop: vi.fn(),
onDragTargetChange: vi.fn(),
onDragSourceChange: vi.fn(),
onDragExpandDir: vi.fn(),
onNativeDragTargetChange: vi.fn(),
onNativeDragExpandDir: vi.fn(),
dropTargetDir: null,
dragSourcePath: null,
nativeDropTargetDir: null
})
const row = findFileExplorerRow(element)
;(row.props.onViewFile as () => void)()
expect(onViewFile).toHaveBeenCalledWith(fileNode)
})
})

View File

@ -746,6 +746,7 @@ function FileExplorerFiles(): React.JSX.Element {
runtimeDownloadContext={runtimeDownloadContext}
onClick={handleRowClick}
onDoubleClick={handleDoubleClick}
onViewFile={handleClick}
onContextMenuSelect={preserveSelectionForContextMenu}
onCopyPaths={copyPathsForNode}
onStartNew={startNew}

View File

@ -279,6 +279,7 @@ type FileExplorerRowProps = {
selectionSize: number
onClick: (event: React.MouseEvent<HTMLButtonElement>) => void
onDoubleClick: () => void
onViewFile: () => void
onContextMenuSelect: () => void
onCopyPaths: (pathKind: 'absolute' | 'relative') => void
onStartNew: (type: 'file' | 'folder', dir: string, depth: number) => void
@ -310,6 +311,10 @@ export function shouldShowOpenInTerminalAction(node: TreeNode): boolean {
return node.isDirectory
}
export function shouldShowViewFileAction(node: TreeNode): boolean {
return !node.isDirectory
}
export function shouldShowRemoteDownloadAction(
node: TreeNode,
connectionId?: string | null,
@ -421,6 +426,7 @@ export function FileExplorerRow({
selectionSize,
onClick,
onDoubleClick,
onViewFile,
onContextMenuSelect,
onCopyPaths,
onStartNew,
@ -712,6 +718,12 @@ export function FileExplorerRow({
)}
</ContextMenuItem>
)}
{shouldShowViewFileAction(node) && (
<ContextMenuItem onSelect={onViewFile}>
<File />
{translate('auto.components.right.sidebar.FileExplorerRow.1d8e182c32', 'View File')}
</ContextMenuItem>
)}
{!node.isDirectory && activeWorktreeId && (
<ContextMenuItem onSelect={handleOpenInOrcaBrowser}>
<Globe />

View File

@ -30,6 +30,7 @@ type FileExplorerVirtualRowsProps = {
runtimeDownloadContext?: RuntimeFileOperationArgs | null
onClick: (node: TreeNode, event: React.MouseEvent<HTMLButtonElement>) => void
onDoubleClick: (node: TreeNode) => void
onViewFile: (node: TreeNode) => void
onContextMenuSelect: (node: TreeNode) => void
onCopyPaths: (node: TreeNode, pathKind: 'absolute' | 'relative') => void
onStartNew: (type: 'file' | 'folder', parentPath: string, depth: number) => void
@ -74,6 +75,7 @@ export function FileExplorerVirtualRows(props: FileExplorerVirtualRowsProps): Re
runtimeDownloadContext,
onClick,
onDoubleClick,
onViewFile,
onContextMenuSelect,
onCopyPaths,
onStartNew,
@ -180,6 +182,7 @@ export function FileExplorerVirtualRows(props: FileExplorerVirtualRowsProps): Re
selectionSize={selectedPaths.has(n.path) ? visibleSelectionCount : 1}
onClick={(event) => onClick(n, event)}
onDoubleClick={() => onDoubleClick(n)}
onViewFile={() => onViewFile(n)}
onContextMenuSelect={() => onContextMenuSelect(n)}
onCopyPaths={(pathKind) => onCopyPaths(n, pathKind)}
onStartNew={onStartNew}

View File

@ -70,6 +70,7 @@ describe('FileExplorerVirtualRows add-as-project action', () => {
deleteShortcutLabel: 'Del',
onClick: vi.fn(),
onDoubleClick: vi.fn(),
onViewFile: vi.fn(),
onContextMenuSelect: vi.fn(),
onCopyPaths: vi.fn(),
onStartNew: vi.fn(),

View File

@ -73,6 +73,7 @@ function virtualRowsElement(nodes: TreeNode[]): React.JSX.Element {
onDoubleClick: vi.fn(),
onContextMenuSelect: vi.fn(),
onCopyPaths: vi.fn(),
onViewFile: vi.fn(),
onStartNew: vi.fn(),
onStartRename: vi.fn(),
onDuplicate: vi.fn(),

View File

@ -8893,7 +8893,8 @@
"b234ab25b4": "Could not copy the file to the clipboard",
"f9d7ca753d": "Copy Paths",
"3161c4e425": "folder",
"e887fa4b2e": "Open in Terminal"
"e887fa4b2e": "Open in Terminal",
"1d8e182c32": "View File"
},
"FileExplorerToolbar": {
"d238264654": "Show Git Ignored Files",

View File

@ -8893,7 +8893,8 @@
"b234ab25b4": "No se pudo copiar el archivo en el portapapeles",
"f9d7ca753d": "Copiar rutas",
"3161c4e425": "carpeta",
"e887fa4b2e": "Abrir en terminal"
"e887fa4b2e": "Abrir en terminal",
"1d8e182c32": "Ver archivo"
},
"FileExplorerToolbar": {
"d238264654": "Mostrar archivos ignorados por Git",

View File

@ -8893,7 +8893,8 @@
"b234ab25b4": "ファイルをクリップボードにコピーできませんでした",
"f9d7ca753d": "パスのコピー",
"3161c4e425": "フォルダ",
"e887fa4b2e": "ターミナルで開く"
"e887fa4b2e": "ターミナルで開く",
"1d8e182c32": "ファイルを表示"
},
"FileExplorerToolbar": {
"d238264654": "Git で無視されたファイルを表示",

View File

@ -8893,7 +8893,8 @@
"b234ab25b4": "파일을 클립보드에 복사하지 못했습니다",
"f9d7ca753d": "경로 복사",
"3161c4e425": "폴더",
"e887fa4b2e": "터미널에서 열기"
"e887fa4b2e": "터미널에서 열기",
"1d8e182c32": "파일 보기"
},
"FileExplorerToolbar": {
"d238264654": "Git이 무시한 파일 표시",

View File

@ -8893,7 +8893,8 @@
"b234ab25b4": "无法将文件复制到剪贴板",
"f9d7ca753d": "复制路径",
"3161c4e425": "文件夹",
"e887fa4b2e": "在终端中打开"
"e887fa4b2e": "在终端中打开",
"1d8e182c32": "查看文件"
},
"FileExplorerToolbar": {
"d238264654": "显示 Git 忽略的文件",