diff --git a/src/renderer/components/FileDialog.vue b/src/renderer/components/FileDialog.vue new file mode 100644 index 0000000..e168156 --- /dev/null +++ b/src/renderer/components/FileDialog.vue @@ -0,0 +1,163 @@ + + + diff --git a/src/renderer/screens/CreateTemplateScreen.vue b/src/renderer/screens/CreateTemplateScreen.vue index b55984a..d29f2c4 100644 --- a/src/renderer/screens/CreateTemplateScreen.vue +++ b/src/renderer/screens/CreateTemplateScreen.vue @@ -160,70 +160,14 @@ @confirm="handleDirectoryDialogConfirm" /> - - + - - - {{ currentEditingItem ? '编辑文件' : '添加文件' }} - - - - - - - - - - -
- 选择文件会直接复制到目标位置 - - 选择文件夹则会自动匹配该文件夹下的文件进行复制并且重命名 - -
-
-
-
- - - 取消 - - {{ currentEditingItem ? '保存' : '添加' }} - - -
-
+ :is-edit-mode="!!currentEditingItem" + :parent-directory="parentDirectoryForNewItems" + :editing-item="currentEditingItem" + @confirm="handleFileDialogConfirm" + /> @@ -238,6 +182,7 @@ import { useTemplateStore, TreeNode } from '@/renderer/store/template' import { useSnackbarStore } from '@/renderer/store/snackbar' import TemplateTree from '@/renderer/components/TemplateTree.vue' import DirectoryDialog from '@/renderer/components/DirectoryDialog.vue' +import FileDialog from '@/renderer/components/FileDialog.vue' import { ConfirmDialogService } from '@/renderer/utils/confirm-dialog-service' const router = useRouter() @@ -256,10 +201,6 @@ const hasChanges = ref(false) // Dialogs const showFileDialog = ref(false) -const fileFormValid = ref(false) - -// Input refs for auto-focus -const fileInputRef = ref(null) // Directory dialog state const showDirectoryDialog = ref(false) @@ -269,9 +210,7 @@ const currentEditingItem = ref(null) -// New item state -const newFilePath = ref('') -const selectedSourcePath = ref('') // Track the selected source file or folder + // Tree state const expandedNodes = ref([]) @@ -370,9 +309,9 @@ const addRootDirectory = () => { } const addRootFile = () => { - newFilePath.value = '' + parentDirectoryForNewItems.value = null + currentEditingItem.value = null showFileDialog.value = true - autoFocusFileInput() } @@ -380,9 +319,8 @@ const addRootFile = () => { // Add a file directly to a specific directory const addFileToDirectory = (directoryItem: TreeItem) => { parentDirectoryForNewItems.value = directoryItem.name // Store the directory as parent - newFilePath.value = '' // Don't pre-fill the path + currentEditingItem.value = null showFileDialog.value = true - autoFocusFileInput() } const addNewItemToCurrentDirectory = (directoryItem: TreeItem) => { @@ -523,26 +461,10 @@ const addChildToNode = ( -const closeFileDialog = () => { - showFileDialog.value = false - newFilePath.value = '' - parentDirectoryForNewItems.value = null - currentEditingItem.value = null - selectedSourcePath.value = '' -} -const selectAndAddFile = async () => { - if (!newFilePath.value.trim()) return - // Construct the full path if there's a parent directory - let fullPath = newFilePath.value - if (parentDirectoryForNewItems.value) { - // Make sure parent directory ends with a slash before appending - const parentPath = parentDirectoryForNewItems.value.endsWith('/') - ? parentDirectoryForNewItems.value - : parentDirectoryForNewItems.value + '/' - fullPath = parentPath + newFilePath.value - } +const handleFileDialogConfirm = (data: { path: string; fullPath: string; sourceFilePath?: string }) => { + const { path, fullPath, sourceFilePath } = data const newId = `file-${Date.now()}-${Math.random()}` @@ -551,10 +473,10 @@ const selectAndAddFile = async () => { // Find and update the existing file in the tree const updatedNode: TreeNode = { id: currentEditingItem.value.id, - name: newFilePath.value, + name: path, path: fullPath, type: 'file', - sourceFilePath: currentEditingItem.value.sourceFilePath + sourceFilePath: sourceFilePath } treeStructure.value = updateNodeInTree( treeStructure.value, @@ -571,7 +493,7 @@ const selectAndAddFile = async () => { ) if (parentNode && parentNode.children) { const duplicateExists = parentNode.children.some( - (child) => child.name === newFilePath.value + (child) => child.name === path ) if (duplicateExists) { snackbar.error('当前目录下已存在同名节点!') @@ -581,7 +503,7 @@ const selectAndAddFile = async () => { } else { // Check at root level for duplicates const duplicateExists = treeStructure.value.some( - (node) => node.name === newFilePath.value + (node) => node.name === path ) if (duplicateExists) { snackbar.error('根目录下已存在同名节点!') @@ -597,86 +519,42 @@ const selectAndAddFile = async () => { } // If we have a selected file, just add it - if (selectedSourcePath.value) { - // Check for duplicate names in the same parent directory - let duplicateNameExists = false + if (sourceFilePath) { + const newFileNode: TreeNode = { + id: newId, + name: path, + path: fullPath, + type: 'file', + sourceFilePath + } + + // Add to tree structure if (parentDirectoryForNewItems.value) { - // In the parent directory, check if a node with the same name already exists - const parentNode = findNodeInTreeByName( + // Add as child to the parent directory + treeStructure.value = addChildToNode( treeStructure.value, - parentDirectoryForNewItems.value + parentDirectoryForNewItems.value, + newFileNode ) - if (parentNode && parentNode.children) { - duplicateNameExists = parentNode.children.some( - (child) => child.name === newFilePath.value - ) - } } else { - // Check at root level for duplicates - duplicateNameExists = treeStructure.value.some( - (node) => node.name === newFilePath.value - ) + // Add as root node + treeStructure.value.push(newFileNode) } - - if (duplicateNameExists) { - snackbar.error('当前目录下已存在同名节点!') - } else { - const newFileNode: TreeNode = { - id: newId, - name: newFilePath.value, - path: fullPath, - type: 'file', - sourceFilePath: selectedSourcePath.value - } - - // Add to tree structure - if (parentDirectoryForNewItems.value) { - // Add as child to the parent directory - treeStructure.value = addChildToNode( - treeStructure.value, - parentDirectoryForNewItems.value, - newFileNode - ) - } else { - // Add as root node - treeStructure.value.push(newFileNode) - } - } - - // Reset selection state - selectedSourcePath.value = '' - - showFileDialog.value = false - parentDirectoryForNewItems.value = null // Clear parent context after creation - currentEditingItem.value = null - - // After adding a new file, expand all nodes to show the new structure - nextTick(() => { - expandAll() - }) - - newFilePath.value = '' + } else { + // Otherwise, show warning + snackbar.warning('请先选择一个文件或文件夹') return } - - // Otherwise, show file selection dialog - snackbar.warning('请先选择一个文件或文件夹') - return } - // Reset selection state after editing - selectedSourcePath.value = '' - showFileDialog.value = false - parentDirectoryForNewItems.value = null + parentDirectoryForNewItems.value = null // Clear parent context after creation currentEditingItem.value = null // After adding a new file, expand all nodes to show the new structure nextTick(() => { expandAll() }) - - newFilePath.value = '' } // 检查树中是否有重复路径的辅助函数 @@ -809,15 +687,8 @@ const showEditDirectoryDialog = (directory: TreeNode) => { const showEditFileDialog = (file: TreeNode) => { // Set up for editing an existing file currentEditingItem.value = file - newFilePath.value = file.path // Set the current path for editing - - // If the file has a source file path, set it in the selection state - if (file.sourceFilePath) { - selectedSourcePath.value = file.sourceFilePath - } - + parentDirectoryForNewItems.value = null showFileDialog.value = true - autoFocusFileInput() } @@ -854,24 +725,11 @@ const removeItemFromTree = (nodes: TreeNode[], itemId: string): TreeNode[] => { -// Methods for file/folder selection -const selectSourceFileOrFolder = async () => { - // 使用现有的主进程API来选择文件或文件夹 - const result = await window.mainApi.invoke('msgSelectFileOrFolder') - - if (result && result.filePath) { - selectedSourcePath.value = result.filePath - } -} -const autoFocusFileInput = async () => { - await nextTick() - if (fileInputRef.value) { - ;(fileInputRef.value as HTMLInputElement).focus() - } -} + + const saveTemplate = () => { if (!formValid.value) return