(node: TreeNode | null)
| 558 | }; |
| 559 | |
| 560 | const getContextMenuItems = (node: TreeNode | null): ContextMenuItem[] => { |
| 561 | if (!node) { |
| 562 | const baseItems: ContextMenuItem[] = [ |
| 563 | { |
| 564 | label: t('fileTree.newFile'), |
| 565 | icon: <FileText size={16} />, |
| 566 | onClick: () => rootPath && handleCreateFileClick(rootPath) |
| 567 | }, |
| 568 | { |
| 569 | label: t('fileTree.newFolder'), |
| 570 | icon: <FolderPlus size={16} />, |
| 571 | onClick: () => rootPath && handleCreateFolderClick(rootPath) |
| 572 | } |
| 573 | ]; |
| 574 | |
| 575 | if (fileActionRegistry && rootPath) { |
| 576 | const templates = fileActionRegistry.getCreationTemplates(); |
| 577 | if (templates.length > 0) { |
| 578 | baseItems.push({ label: '', separator: true, onClick: () => {} }); |
| 579 | for (const template of templates) { |
| 580 | baseItems.push({ |
| 581 | label: template.label, |
| 582 | icon: getIconComponent(template.icon, 16), |
| 583 | onClick: () => handleCreateTemplateFileClick(rootPath, template) |
| 584 | }); |
| 585 | } |
| 586 | } |
| 587 | } |
| 588 | |
| 589 | return baseItems; |
| 590 | } |
| 591 | |
| 592 | const items: ContextMenuItem[] = []; |
| 593 | |
| 594 | if (node.type === 'file') { |
| 595 | items.push({ |
| 596 | label: t('fileTree.openFile'), |
| 597 | icon: <File size={16} />, |
| 598 | onClick: async () => { |
| 599 | try { |
| 600 | await TauriAPI.openFileWithSystemApp(node.path); |
| 601 | } catch (error) { |
| 602 | console.error('Failed to open file:', error); |
| 603 | } |
| 604 | } |
| 605 | }); |
| 606 | |
| 607 | if (fileActionRegistry) { |
| 608 | const handlers = fileActionRegistry.getHandlersForFile(node.path); |
| 609 | for (const handler of handlers) { |
| 610 | if (handler.getContextMenuItems) { |
| 611 | const parentPath = node.path.substring(0, node.path.lastIndexOf('/')); |
| 612 | const pluginItems = handler.getContextMenuItems(node.path, parentPath); |
| 613 | for (const pluginItem of pluginItems) { |
| 614 | items.push({ |
| 615 | label: pluginItem.label, |
| 616 | icon: pluginItem.icon, |
| 617 | onClick: () => pluginItem.onClick(node.path, parentPath), |
no test coverage detected