feat: 添加 TypeScript 类型检查命令,优化模板创建流程,移除不必要的上下文菜单逻辑
This commit is contained in:
1 parent
562e4f5b9e
commit
157bc47f3c
4 files changed
+70
-144
No files matched your search
@@ -64,6 +64,9 @@ pnpm dev:debug
|
|||||||
|
|
||||||
# Force reinstall dependencies and start development
|
# Force reinstall dependencies and start development
|
||||||
pnpm dev:debug:force
|
pnpm dev:debug:force
|
||||||
|
|
||||||
|
# run Typescript Type check
|
||||||
|
pnpm typecheck
|
||||||
```
|
```
|
||||||
|
|
||||||
### Building
|
### Building
|
||||||
@@ -103,11 +106,6 @@ pnpm lint
|
|||||||
# Fix linting issues automatically
|
# Fix linting issues automatically
|
||||||
pnpm lint:fix
|
pnpm lint:fix
|
||||||
|
|
||||||
# Format code with Prettier
|
|
||||||
pnpm format
|
|
||||||
|
|
||||||
# Format and fix code automatically
|
|
||||||
pnpm format:fix
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## Key Features
|
## Key Features
|
||||||
@@ -231,4 +229,6 @@ Building creates different distribution formats based on the platform:
|
|||||||
|
|
||||||
Artifacts are named with the format `${productName} ${version}_${arch}.${ext}` and stored in the `release/${version}` directory.
|
Artifacts are named with the format `${productName} ${version}_${arch}.${ext}` and stored in the `release/${version}` directory.
|
||||||
|
|
||||||
|
run `pnpm typecheck` before finish the task
|
||||||
|
|
||||||
Always respond in 中文
|
Always respond in 中文
|
||||||
+1
-2
@@ -24,6 +24,7 @@
|
|||||||
"dev": "vite",
|
"dev": "vite",
|
||||||
"dev:debug": "vite -d",
|
"dev:debug": "vite -d",
|
||||||
"dev:debug:force": "vite -d --force",
|
"dev:debug:force": "vite -d --force",
|
||||||
|
"typecheck": "vue-tsc --noEmit",
|
||||||
"build": "npm run build:pre && electron-builder --config=buildAssets/builder/config.js",
|
"build": "npm run build:pre && electron-builder --config=buildAssets/builder/config.js",
|
||||||
"build:pre": "vue-tsc --noEmit && vite build",
|
"build:pre": "vue-tsc --noEmit && vite build",
|
||||||
"build:all": "npm run build:pre && electron-builder --config=buildAssets/builder/config.js -wml",
|
"build:all": "npm run build:pre && electron-builder --config=buildAssets/builder/config.js -wml",
|
||||||
@@ -33,8 +34,6 @@
|
|||||||
"build:win": "npm run build:pre && electron-builder --config=buildAssets/builder/config.js --windows",
|
"build:win": "npm run build:pre && electron-builder --config=buildAssets/builder/config.js --windows",
|
||||||
"lint": "eslint . --ext .js,.ts,.vue .",
|
"lint": "eslint . --ext .js,.ts,.vue .",
|
||||||
"lint:fix": "eslint . --ext .js,.ts,.vue --fix .",
|
"lint:fix": "eslint . --ext .js,.ts,.vue --fix .",
|
||||||
"format": "prettier .",
|
|
||||||
"format:fix": "prettier . --write",
|
|
||||||
"test": "npm run build:pre && playwright test",
|
"test": "npm run build:pre && playwright test",
|
||||||
"test:linux": "npm run build:pre && xvfb-run --auto-servernum --server-args='-screen 0, 1280x960x24' -- playwright test"
|
"test:linux": "npm run build:pre && xvfb-run --auto-servernum --server-args='-screen 0, 1280x960x24' -- playwright test"
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -3,7 +3,6 @@
|
|||||||
variant="outlined"
|
variant="outlined"
|
||||||
class="pa-2"
|
class="pa-2"
|
||||||
:height="height"
|
:height="height"
|
||||||
@contextmenu.prevent="emit('showContextMenu', $event, null)"
|
|
||||||
>
|
>
|
||||||
<v-treeview
|
<v-treeview
|
||||||
v-model:expanded="localExpanded"
|
v-model:expanded="localExpanded"
|
||||||
@@ -31,27 +30,9 @@
|
|||||||
|
|
||||||
<template #title="{ item }">
|
<template #title="{ item }">
|
||||||
<span
|
<span
|
||||||
@contextmenu.prevent="emit('showContextMenu', $event, item)"
|
|
||||||
class="cursor-pointer d-flex align-center"
|
class="cursor-pointer d-flex align-center"
|
||||||
>
|
>
|
||||||
{{ item.name }}
|
{{ item.name }}
|
||||||
<v-btn
|
|
||||||
v-if="!readOnly && item.type === 'directory'"
|
|
||||||
icon
|
|
||||||
variant="text"
|
|
||||||
size="small"
|
|
||||||
class="ml-2"
|
|
||||||
@click.stop="emit('addNewItemToCurrentDirectory', item)"
|
|
||||||
>
|
|
||||||
<v-icon size="small">mdi-plus</v-icon>
|
|
||||||
<v-tooltip
|
|
||||||
v-if="!readOnly"
|
|
||||||
activator="parent"
|
|
||||||
location="top"
|
|
||||||
>
|
|
||||||
添加到目录
|
|
||||||
</v-tooltip>
|
|
||||||
</v-btn>
|
|
||||||
</span>
|
</span>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@@ -61,23 +42,24 @@
|
|||||||
class="d-flex align-center ga-1"
|
class="d-flex align-center ga-1"
|
||||||
>
|
>
|
||||||
<v-btn
|
<v-btn
|
||||||
v-if="!readOnly"
|
v-if="!readOnly && item.type === 'directory'"
|
||||||
icon
|
icon
|
||||||
variant="text"
|
variant="text"
|
||||||
size="small"
|
size="small"
|
||||||
@click.stop="emit('editItem', item)"
|
class="ml-2"
|
||||||
|
@click.stop="emit('addNewItemToCurrentDirectory', item)"
|
||||||
>
|
>
|
||||||
<v-icon size="small"> mdi-pencil </v-icon>
|
<v-icon size="small">mdi-folder-plus</v-icon>
|
||||||
<v-tooltip
|
<v-tooltip
|
||||||
activator="parent"
|
activator="parent"
|
||||||
location="top"
|
location="top"
|
||||||
>
|
>
|
||||||
{{ item.type === 'file' ? '编辑文件' : '编辑目录' }}
|
添加到目录
|
||||||
</v-tooltip>
|
</v-tooltip>
|
||||||
</v-btn>
|
</v-btn>
|
||||||
|
|
||||||
<v-btn
|
<v-btn
|
||||||
v-if="item.type === 'directory' && !readOnly"
|
v-if="item.type === 'directory'"
|
||||||
icon
|
icon
|
||||||
variant="text"
|
variant="text"
|
||||||
size="small"
|
size="small"
|
||||||
@@ -92,6 +74,21 @@
|
|||||||
</v-tooltip>
|
</v-tooltip>
|
||||||
</v-btn>
|
</v-btn>
|
||||||
|
|
||||||
|
<v-btn
|
||||||
|
icon
|
||||||
|
variant="text"
|
||||||
|
size="small"
|
||||||
|
@click.stop="emit('editItem', item)"
|
||||||
|
>
|
||||||
|
<v-icon size="small"> mdi-pencil </v-icon>
|
||||||
|
<v-tooltip
|
||||||
|
activator="parent"
|
||||||
|
location="top"
|
||||||
|
>
|
||||||
|
{{ item.type === 'file' ? '编辑文件' : '编辑目录' }}
|
||||||
|
</v-tooltip>
|
||||||
|
</v-btn>
|
||||||
|
|
||||||
<v-btn
|
<v-btn
|
||||||
icon
|
icon
|
||||||
variant="text"
|
variant="text"
|
||||||
@@ -99,7 +96,6 @@
|
|||||||
@click.stop="emit('deleteItem', item)"
|
@click.stop="emit('deleteItem', item)"
|
||||||
>
|
>
|
||||||
<v-icon
|
<v-icon
|
||||||
v-if="!readOnly"
|
|
||||||
size="small"
|
size="small"
|
||||||
color="error"
|
color="error"
|
||||||
>
|
>
|
||||||
@@ -133,39 +129,12 @@
|
|||||||
v-if="!readOnly"
|
v-if="!readOnly"
|
||||||
class="text-caption"
|
class="text-caption"
|
||||||
>
|
>
|
||||||
右键点击空白区域添加根目录或文件
|
点击上方按钮添加根目录或文件
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</v-card>
|
</v-card>
|
||||||
|
|
||||||
<!-- Context Menu -->
|
|
||||||
<v-menu
|
|
||||||
v-if="!readOnly"
|
|
||||||
v-model="localShowContextMenuVar"
|
|
||||||
:position-x="contextMenuX"
|
|
||||||
:position-y="contextMenuY"
|
|
||||||
absolute
|
|
||||||
>
|
|
||||||
<v-list density="compact">
|
|
||||||
<v-list-item @click="emit('addDirectory', currentContextItem)">
|
|
||||||
<template #prepend>
|
|
||||||
<v-icon>mdi-folder-plus</v-icon>
|
|
||||||
</template>
|
|
||||||
<v-list-item-title>
|
|
||||||
{{ currentContextItem ? '添加子目录' : '添加根目录' }}
|
|
||||||
</v-list-item-title>
|
|
||||||
</v-list-item>
|
|
||||||
|
|
||||||
<v-list-item @click="emit('addFile', currentContextItem)">
|
|
||||||
<template #prepend>
|
|
||||||
<v-icon>mdi-file-plus</v-icon>
|
|
||||||
</template>
|
|
||||||
<v-list-item-title>
|
|
||||||
{{ currentContextItem ? '添加子文件' : '添加根文件' }}
|
|
||||||
</v-list-item-title>
|
|
||||||
</v-list-item>
|
|
||||||
</v-list>
|
|
||||||
</v-menu>
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
@@ -182,18 +151,12 @@ interface Props {
|
|||||||
height?: number
|
height?: number
|
||||||
readOnly?: boolean
|
readOnly?: boolean
|
||||||
emptyText?: string
|
emptyText?: string
|
||||||
contextMenuX?: number
|
|
||||||
contextMenuY?: number
|
|
||||||
currentContextItem?: TreeItem | null
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const props = withDefaults(defineProps<Props>(), {
|
const props = withDefaults(defineProps<Props>(), {
|
||||||
height: 600,
|
height: 600,
|
||||||
readOnly: false,
|
readOnly: false,
|
||||||
emptyText: '暂无文件或目录',
|
emptyText: '暂无文件或目录'
|
||||||
contextMenuX: 0,
|
|
||||||
contextMenuY: 0,
|
|
||||||
currentContextItem: null
|
|
||||||
})
|
})
|
||||||
|
|
||||||
const localExpanded = defineModel<string[]>('expanded', {
|
const localExpanded = defineModel<string[]>('expanded', {
|
||||||
@@ -205,13 +168,10 @@ const localShowContextMenuVar = defineModel<boolean>('showContextMenuVar', {
|
|||||||
})
|
})
|
||||||
|
|
||||||
const emit = defineEmits([
|
const emit = defineEmits([
|
||||||
'showContextMenu',
|
|
||||||
'addNewItemToCurrentDirectory',
|
'addNewItemToCurrentDirectory',
|
||||||
'editFile',
|
'editFile',
|
||||||
'editItem',
|
'editItem',
|
||||||
'deleteItem',
|
'deleteItem',
|
||||||
'addDirectory',
|
|
||||||
'addFile',
|
|
||||||
'addFileToDirectory'
|
'addFileToDirectory'
|
||||||
])
|
])
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -142,19 +142,12 @@
|
|||||||
:items="treeItems"
|
:items="treeItems"
|
||||||
:height="treeHeight"
|
:height="treeHeight"
|
||||||
v-model:expanded="expandedNodes"
|
v-model:expanded="expandedNodes"
|
||||||
v-model:showContextMenuVar="showContextMenuVar"
|
|
||||||
:context-menu-x="contextMenuX"
|
|
||||||
:context-menu-y="contextMenuY"
|
|
||||||
:current-context-item="currentContextItem"
|
|
||||||
:empty-text="'暂无文件或目录'"
|
:empty-text="'暂无文件或目录'"
|
||||||
:read-only="false"
|
:read-only="false"
|
||||||
@showContextMenu="showContextMenu"
|
|
||||||
@add-new-item-to-current-directory="addNewItemToCurrentDirectory"
|
@add-new-item-to-current-directory="addNewItemToCurrentDirectory"
|
||||||
@edit-file="editFile"
|
@edit-file="editFile"
|
||||||
@edit-item="editItem"
|
@edit-item="editItem"
|
||||||
@delete-item="deleteItem"
|
@delete-item="deleteItem"
|
||||||
@add-directory="addDirectory"
|
|
||||||
@add-file="addFile"
|
|
||||||
@add-file-to-directory="addFileToDirectory"
|
@add-file-to-directory="addFileToDirectory"
|
||||||
/>
|
/>
|
||||||
</v-col>
|
</v-col>
|
||||||
@@ -183,10 +176,10 @@
|
|||||||
</v-card-text>
|
</v-card-text>
|
||||||
<v-card-actions>
|
<v-card-actions>
|
||||||
<v-spacer />
|
<v-spacer />
|
||||||
<v-btn
|
<v-btn
|
||||||
@click="closeDirectoryDialog"
|
@click="closeDirectoryDialog"
|
||||||
>
|
>
|
||||||
取消
|
取消
|
||||||
</v-btn>
|
</v-btn>
|
||||||
<v-btn
|
<v-btn
|
||||||
color="primary"
|
color="primary"
|
||||||
@@ -218,7 +211,7 @@
|
|||||||
ref="fileInputRef"
|
ref="fileInputRef"
|
||||||
@keydown.enter="selectAndAddFile"
|
@keydown.enter="selectAndAddFile"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<div class="d-flex align-center my-4">
|
<div class="d-flex align-center my-4">
|
||||||
<v-btn
|
<v-btn
|
||||||
@click="selectSourceFile"
|
@click="selectSourceFile"
|
||||||
@@ -237,7 +230,7 @@
|
|||||||
选择文件夹
|
选择文件夹
|
||||||
</v-btn>
|
</v-btn>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Display selected source -->
|
<!-- Display selected source -->
|
||||||
<div v-if="selectedSourcePath" class="d-flex align-center">
|
<div v-if="selectedSourcePath" class="d-flex align-center">
|
||||||
<v-icon :color="isAutoFindMode ? 'warning' : 'info'" class="mr-2">
|
<v-icon :color="isAutoFindMode ? 'warning' : 'info'" class="mr-2">
|
||||||
@@ -245,7 +238,7 @@
|
|||||||
</v-icon>
|
</v-icon>
|
||||||
<span class="text-truncate">{{ selectedSourcePath }}</span>
|
<span class="text-truncate">{{ selectedSourcePath }}</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Auto-find indicator -->
|
<!-- Auto-find indicator -->
|
||||||
<v-alert
|
<v-alert
|
||||||
v-if="isAutoFindMode"
|
v-if="isAutoFindMode"
|
||||||
@@ -258,7 +251,7 @@
|
|||||||
<span>自动寻找文件夹内的文件</span>
|
<span>自动寻找文件夹内的文件</span>
|
||||||
</div>
|
</div>
|
||||||
</v-alert>
|
</v-alert>
|
||||||
|
|
||||||
<!-- Note when editing -->
|
<!-- Note when editing -->
|
||||||
<v-alert
|
<v-alert
|
||||||
v-if="currentEditingItem"
|
v-if="currentEditingItem"
|
||||||
@@ -275,10 +268,10 @@
|
|||||||
</v-card-text>
|
</v-card-text>
|
||||||
<v-card-actions>
|
<v-card-actions>
|
||||||
<v-spacer />
|
<v-spacer />
|
||||||
<v-btn
|
<v-btn
|
||||||
@click="closeFileDialog"
|
@click="closeFileDialog"
|
||||||
>
|
>
|
||||||
取消
|
取消
|
||||||
</v-btn>
|
</v-btn>
|
||||||
<v-btn
|
<v-btn
|
||||||
color="primary"
|
color="primary"
|
||||||
@@ -384,11 +377,7 @@ const fileFormValid = ref(false)
|
|||||||
const directoryInputRef = ref<HTMLInputElement | null>(null)
|
const directoryInputRef = ref<HTMLInputElement | null>(null)
|
||||||
const fileInputRef = ref<HTMLInputElement | null>(null)
|
const fileInputRef = ref<HTMLInputElement | null>(null)
|
||||||
|
|
||||||
// Context menu
|
|
||||||
const showContextMenuVar = ref(false)
|
|
||||||
const contextMenuX = ref(0)
|
|
||||||
const contextMenuY = ref(0)
|
|
||||||
const currentContextItem = ref<TreeItem | null>(null)
|
|
||||||
|
|
||||||
// Snackbar variables
|
// Snackbar variables
|
||||||
const snackbarVisible = ref(false)
|
const snackbarVisible = ref(false)
|
||||||
@@ -440,10 +429,10 @@ const treeItems = computed<TreeItem[]>(() => {
|
|||||||
for (let i = 0; i < pathParts.length; i++) {
|
for (let i = 0; i < pathParts.length; i++) {
|
||||||
const part = pathParts[i]
|
const part = pathParts[i]
|
||||||
const isLastPart = i === pathParts.length - 1
|
const isLastPart = i === pathParts.length - 1
|
||||||
|
|
||||||
// Check if this part already exists in the current level
|
// Check if this part already exists in the current level
|
||||||
let existingItem = currentLevel.find(item => item.name === part)
|
let existingItem = currentLevel.find(item => item.name === part)
|
||||||
|
|
||||||
if (!existingItem) {
|
if (!existingItem) {
|
||||||
// Create new directory item
|
// Create new directory item
|
||||||
const newDir: TreeItem = {
|
const newDir: TreeItem = {
|
||||||
@@ -455,7 +444,7 @@ const treeItems = computed<TreeItem[]>(() => {
|
|||||||
currentLevel.push(newDir)
|
currentLevel.push(newDir)
|
||||||
existingItem = newDir
|
existingItem = newDir
|
||||||
}
|
}
|
||||||
|
|
||||||
// Move to the next level if not the last part
|
// Move to the next level if not the last part
|
||||||
if (!isLastPart && existingItem.children) {
|
if (!isLastPart && existingItem.children) {
|
||||||
currentLevel = existingItem.children
|
currentLevel = existingItem.children
|
||||||
@@ -467,16 +456,16 @@ const treeItems = computed<TreeItem[]>(() => {
|
|||||||
files.value.forEach((file) => {
|
files.value.forEach((file) => {
|
||||||
const pathParts = file.path.split('/').filter(part => part !== '')
|
const pathParts = file.path.split('/').filter(part => part !== '')
|
||||||
const fileName = pathParts.pop() // Get the last part as filename
|
const fileName = pathParts.pop() // Get the last part as filename
|
||||||
|
|
||||||
if (!fileName) return // Skip if no filename
|
if (!fileName) return // Skip if no filename
|
||||||
|
|
||||||
let currentLevel = root.children || []
|
let currentLevel = root.children || []
|
||||||
|
|
||||||
// Navigate to the appropriate directory for the file
|
// Navigate to the appropriate directory for the file
|
||||||
for (let i = 0; i < pathParts.length; i++) {
|
for (let i = 0; i < pathParts.length; i++) {
|
||||||
const part = pathParts[i]
|
const part = pathParts[i]
|
||||||
const dirItem = currentLevel.find(item => item.name === part && item.type === 'directory')
|
const dirItem = currentLevel.find(item => item.name === part && item.type === 'directory')
|
||||||
|
|
||||||
if (dirItem && dirItem.children) {
|
if (dirItem && dirItem.children) {
|
||||||
currentLevel = dirItem.children
|
currentLevel = dirItem.children
|
||||||
} else {
|
} else {
|
||||||
@@ -491,7 +480,7 @@ const treeItems = computed<TreeItem[]>(() => {
|
|||||||
currentLevel = newDir.children || []
|
currentLevel = newDir.children || []
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add the file to the current level
|
// Add the file to the current level
|
||||||
currentLevel.push({
|
currentLevel.push({
|
||||||
id: `file-${fileName}-${Date.now()}-${Math.random()}`,
|
id: `file-${fileName}-${Date.now()}-${Math.random()}`,
|
||||||
@@ -554,18 +543,7 @@ const updateTreeHeight = () => {
|
|||||||
treeHeight.value = window.innerHeight - 200
|
treeHeight.value = window.innerHeight - 200
|
||||||
}
|
}
|
||||||
|
|
||||||
const showContextMenu = (event: MouseEvent, item: TreeItem | null) => {
|
|
||||||
event.preventDefault()
|
|
||||||
contextMenuX.value = event.clientX
|
|
||||||
contextMenuY.value = event.clientY
|
|
||||||
currentContextItem.value = item
|
|
||||||
showContextMenuVar.value = false // Close first to reset position
|
|
||||||
nextTick(() => {
|
|
||||||
contextMenuX.value = event.clientX
|
|
||||||
contextMenuY.value = event.clientY
|
|
||||||
showContextMenuVar.value = true
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
const addRootDirectory = () => {
|
const addRootDirectory = () => {
|
||||||
newDirectoryPath.value = ''
|
newDirectoryPath.value = ''
|
||||||
@@ -580,8 +558,6 @@ const addRootFile = () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const addDirectory = (parentItem: TreeItem | null = null) => {
|
const addDirectory = (parentItem: TreeItem | null = null) => {
|
||||||
showContextMenuVar.value = false
|
|
||||||
currentContextItem.value = parentItem
|
|
||||||
parentDirectoryForNewItems.value = parentItem ? parentItem.name : null // Store parent context
|
parentDirectoryForNewItems.value = parentItem ? parentItem.name : null // Store parent context
|
||||||
newDirectoryPath.value = '' // Don't pre-fill the path
|
newDirectoryPath.value = '' // Don't pre-fill the path
|
||||||
showDirectoryDialog.value = true
|
showDirectoryDialog.value = true
|
||||||
@@ -589,7 +565,6 @@ const addDirectory = (parentItem: TreeItem | null = null) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const addFile = (parentItem: TreeItem | null = null) => {
|
const addFile = (parentItem: TreeItem | null = null) => {
|
||||||
showContextMenuVar.value = false
|
|
||||||
parentDirectoryForNewItems.value = parentItem ? parentItem.name : null // Store parent context
|
parentDirectoryForNewItems.value = parentItem ? parentItem.name : null // Store parent context
|
||||||
newFilePath.value = '' // Don't pre-fill the path
|
newFilePath.value = '' // Don't pre-fill the path
|
||||||
showFileDialog.value = true
|
showFileDialog.value = true
|
||||||
@@ -598,7 +573,6 @@ const addFile = (parentItem: TreeItem | null = null) => {
|
|||||||
|
|
||||||
// Add a file directly to a specific directory
|
// Add a file directly to a specific directory
|
||||||
const addFileToDirectory = (directoryItem: TreeItem) => {
|
const addFileToDirectory = (directoryItem: TreeItem) => {
|
||||||
showContextMenuVar.value = false
|
|
||||||
parentDirectoryForNewItems.value = directoryItem.name // Store the directory as parent
|
parentDirectoryForNewItems.value = directoryItem.name // Store the directory as parent
|
||||||
newFilePath.value = '' // Don't pre-fill the path
|
newFilePath.value = '' // Don't pre-fill the path
|
||||||
showFileDialog.value = true
|
showFileDialog.value = true
|
||||||
@@ -606,7 +580,6 @@ const addFileToDirectory = (directoryItem: TreeItem) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const addNewItemToCurrentDirectory = (directoryItem: TreeItem) => {
|
const addNewItemToCurrentDirectory = (directoryItem: TreeItem) => {
|
||||||
currentContextItem.value = directoryItem
|
|
||||||
parentDirectoryForNewItems.value = directoryItem.name // Store parent context
|
parentDirectoryForNewItems.value = directoryItem.name // Store parent context
|
||||||
newDirectoryPath.value = '' // Don't pre-fill the path
|
newDirectoryPath.value = '' // Don't pre-fill the path
|
||||||
showDirectoryDialog.value = true
|
showDirectoryDialog.value = true
|
||||||
@@ -620,8 +593,8 @@ const confirmAddDirectory = () => {
|
|||||||
let fullPath = newDirectoryPath.value
|
let fullPath = newDirectoryPath.value
|
||||||
if (parentDirectoryForNewItems.value) {
|
if (parentDirectoryForNewItems.value) {
|
||||||
// Make sure parent directory ends with a slash before appending
|
// Make sure parent directory ends with a slash before appending
|
||||||
const parentPath = parentDirectoryForNewItems.value.endsWith('/')
|
const parentPath = parentDirectoryForNewItems.value.endsWith('/')
|
||||||
? parentDirectoryForNewItems.value
|
? parentDirectoryForNewItems.value
|
||||||
: parentDirectoryForNewItems.value + '/'
|
: parentDirectoryForNewItems.value + '/'
|
||||||
fullPath = parentPath + newDirectoryPath.value
|
fullPath = parentPath + newDirectoryPath.value
|
||||||
}
|
}
|
||||||
@@ -632,7 +605,7 @@ const confirmAddDirectory = () => {
|
|||||||
if (index !== -1) {
|
if (index !== -1) {
|
||||||
// Update the existing directory path
|
// Update the existing directory path
|
||||||
directories.value[index].path = fullPath
|
directories.value[index].path = fullPath
|
||||||
|
|
||||||
// If the directory path changes, update any files/dirs that were inside it
|
// If the directory path changes, update any files/dirs that were inside it
|
||||||
updatePathsForRenamedDirectory(currentEditingItem.value.path, fullPath)
|
updatePathsForRenamedDirectory(currentEditingItem.value.path, fullPath)
|
||||||
}
|
}
|
||||||
@@ -654,9 +627,8 @@ const confirmAddDirectory = () => {
|
|||||||
showDirectoryDialog.value = false
|
showDirectoryDialog.value = false
|
||||||
newDirectoryPath.value = ''
|
newDirectoryPath.value = ''
|
||||||
parentDirectoryForNewItems.value = null // Clear parent context after creation
|
parentDirectoryForNewItems.value = null // Clear parent context after creation
|
||||||
currentContextItem.value = null
|
|
||||||
currentEditingItem.value = null
|
currentEditingItem.value = null
|
||||||
|
|
||||||
// If we added to a parent directory, make sure it's expanded
|
// If we added to a parent directory, make sure it's expanded
|
||||||
if (parentDirectoryForNewItems.value) {
|
if (parentDirectoryForNewItems.value) {
|
||||||
if (!expandedNodes.value.includes(`dir-${parentDirectoryForNewItems.value}`)) {
|
if (!expandedNodes.value.includes(`dir-${parentDirectoryForNewItems.value}`)) {
|
||||||
@@ -677,7 +649,7 @@ const updatePathsForRenamedDirectory = (oldPath: string, newPath: string) => {
|
|||||||
}
|
}
|
||||||
return file
|
return file
|
||||||
})
|
})
|
||||||
|
|
||||||
// Update all directories that were under the old directory
|
// Update all directories that were under the old directory
|
||||||
directories.value = directories.value.map(dir => {
|
directories.value = directories.value.map(dir => {
|
||||||
if (dir.path.startsWith(oldPath + '/') || dir.path === oldPath) {
|
if (dir.path.startsWith(oldPath + '/') || dir.path === oldPath) {
|
||||||
@@ -695,7 +667,6 @@ const closeDirectoryDialog = () => {
|
|||||||
showDirectoryDialog.value = false
|
showDirectoryDialog.value = false
|
||||||
newDirectoryPath.value = ''
|
newDirectoryPath.value = ''
|
||||||
parentDirectoryForNewItems.value = null
|
parentDirectoryForNewItems.value = null
|
||||||
currentContextItem.value = null
|
|
||||||
currentEditingItem.value = null
|
currentEditingItem.value = null
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -703,7 +674,6 @@ const closeFileDialog = () => {
|
|||||||
showFileDialog.value = false
|
showFileDialog.value = false
|
||||||
newFilePath.value = ''
|
newFilePath.value = ''
|
||||||
parentDirectoryForNewItems.value = null
|
parentDirectoryForNewItems.value = null
|
||||||
currentContextItem.value = null
|
|
||||||
currentEditingItem.value = null
|
currentEditingItem.value = null
|
||||||
selectedSourcePath.value = ''
|
selectedSourcePath.value = ''
|
||||||
isAutoFindMode.value = false
|
isAutoFindMode.value = false
|
||||||
@@ -716,8 +686,8 @@ const selectAndAddFile = async () => {
|
|||||||
let fullPath = newFilePath.value
|
let fullPath = newFilePath.value
|
||||||
if (parentDirectoryForNewItems.value) {
|
if (parentDirectoryForNewItems.value) {
|
||||||
// Make sure parent directory ends with a slash before appending
|
// Make sure parent directory ends with a slash before appending
|
||||||
const parentPath = parentDirectoryForNewItems.value.endsWith('/')
|
const parentPath = parentDirectoryForNewItems.value.endsWith('/')
|
||||||
? parentDirectoryForNewItems.value
|
? parentDirectoryForNewItems.value
|
||||||
: parentDirectoryForNewItems.value + '/'
|
: parentDirectoryForNewItems.value + '/'
|
||||||
fullPath = parentPath + newFilePath.value
|
fullPath = parentPath + newFilePath.value
|
||||||
}
|
}
|
||||||
@@ -744,13 +714,13 @@ const selectAndAddFile = async () => {
|
|||||||
if (isAutoFindMode.value && selectedSourcePath.value) {
|
if (isAutoFindMode.value && selectedSourcePath.value) {
|
||||||
// Auto-find files in the selected folder
|
// Auto-find files in the selected folder
|
||||||
const foundFiles = await window.mainApi.invoke('msgFindFilesInFolder', selectedSourcePath.value)
|
const foundFiles = await window.mainApi.invoke('msgFindFilesInFolder', selectedSourcePath.value)
|
||||||
|
|
||||||
// Add all found files as template files
|
// Add all found files as template files
|
||||||
for (const foundFile of foundFiles) {
|
for (const foundFile of foundFiles) {
|
||||||
// Calculate relative path from selected folder to the found file
|
// Calculate relative path from selected folder to the found file
|
||||||
const relativePath = foundFile.replace(selectedSourcePath.value, '').substring(1) // Remove leading slash
|
const relativePath = foundFile.replace(selectedSourcePath.value, '').substring(1) // Remove leading slash
|
||||||
const fullTargetPath = fullPath ? `${fullPath}/${relativePath}` : relativePath
|
const fullTargetPath = fullPath ? `${fullPath}/${relativePath}` : relativePath
|
||||||
|
|
||||||
// Check for duplicates
|
// Check for duplicates
|
||||||
const duplicate = files.value.some(f => f.path === fullTargetPath)
|
const duplicate = files.value.some(f => f.path === fullTargetPath)
|
||||||
if (!duplicate) {
|
if (!duplicate) {
|
||||||
@@ -761,19 +731,18 @@ const selectAndAddFile = async () => {
|
|||||||
files.value.push(newFile)
|
files.value.push(newFile)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reset selection state
|
// Reset selection state
|
||||||
selectedSourcePath.value = ''
|
selectedSourcePath.value = ''
|
||||||
isAutoFindMode.value = false
|
isAutoFindMode.value = false
|
||||||
|
|
||||||
showFileDialog.value = false
|
showFileDialog.value = false
|
||||||
newFilePath.value = ''
|
newFilePath.value = ''
|
||||||
parentDirectoryForNewItems.value = null // Clear parent context after creation
|
parentDirectoryForNewItems.value = null // Clear parent context after creation
|
||||||
currentContextItem.value = null
|
|
||||||
currentEditingItem.value = null
|
currentEditingItem.value = null
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// If we have a selected file, just add it
|
// If we have a selected file, just add it
|
||||||
if (selectedSourcePath.value) {
|
if (selectedSourcePath.value) {
|
||||||
const newFile = {
|
const newFile = {
|
||||||
@@ -790,11 +759,10 @@ const selectAndAddFile = async () => {
|
|||||||
showFileDialog.value = false
|
showFileDialog.value = false
|
||||||
newFilePath.value = ''
|
newFilePath.value = ''
|
||||||
parentDirectoryForNewItems.value = null // Clear parent context after creation
|
parentDirectoryForNewItems.value = null // Clear parent context after creation
|
||||||
currentContextItem.value = null
|
|
||||||
currentEditingItem.value = null
|
currentEditingItem.value = null
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Otherwise, show file selection dialog
|
// Otherwise, show file selection dialog
|
||||||
showSnackbar('请先选择一个文件或文件夹', 'warning')
|
showSnackbar('请先选择一个文件或文件夹', 'warning')
|
||||||
return
|
return
|
||||||
@@ -803,11 +771,10 @@ const selectAndAddFile = async () => {
|
|||||||
// Reset selection state after editing
|
// Reset selection state after editing
|
||||||
selectedSourcePath.value = ''
|
selectedSourcePath.value = ''
|
||||||
isAutoFindMode.value = false
|
isAutoFindMode.value = false
|
||||||
|
|
||||||
showFileDialog.value = false
|
showFileDialog.value = false
|
||||||
newFilePath.value = ''
|
newFilePath.value = ''
|
||||||
parentDirectoryForNewItems.value = null
|
parentDirectoryForNewItems.value = null
|
||||||
currentContextItem.value = null
|
|
||||||
currentEditingItem.value = null
|
currentEditingItem.value = null
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -820,7 +787,7 @@ const goBack = async () => {
|
|||||||
cancelText: '取消',
|
cancelText: '取消',
|
||||||
confirmColor: 'warning'
|
confirmColor: 'warning'
|
||||||
})
|
})
|
||||||
|
|
||||||
if (confirmed) {
|
if (confirmed) {
|
||||||
router.push('/templates')
|
router.push('/templates')
|
||||||
}
|
}
|
||||||
@@ -831,7 +798,7 @@ const goBack = async () => {
|
|||||||
|
|
||||||
const expandAll = () => {
|
const expandAll = () => {
|
||||||
const allIds: string[] = []
|
const allIds: string[] = []
|
||||||
|
|
||||||
const collectIds = (items: TreeItem[]) => {
|
const collectIds = (items: TreeItem[]) => {
|
||||||
items.forEach(item => {
|
items.forEach(item => {
|
||||||
if (item.children && item.children.length > 0) {
|
if (item.children && item.children.length > 0) {
|
||||||
@@ -840,7 +807,7 @@ const expandAll = () => {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
collectIds(treeItems.value)
|
collectIds(treeItems.value)
|
||||||
expandedNodes.value = allIds
|
expandedNodes.value = allIds
|
||||||
}
|
}
|
||||||
@@ -899,13 +866,13 @@ const showEditFileDialog = (file: { path: string; content?: string; sourceFilePa
|
|||||||
// Set up for editing an existing file
|
// Set up for editing an existing file
|
||||||
currentEditingItem.value = { ...file, type: 'file' }
|
currentEditingItem.value = { ...file, type: 'file' }
|
||||||
newFilePath.value = file.path // Set the current path for editing
|
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 the file has a source file path, set it in the selection state
|
||||||
if (file.sourceFilePath) {
|
if (file.sourceFilePath) {
|
||||||
selectedSourcePath.value = file.sourceFilePath
|
selectedSourcePath.value = file.sourceFilePath
|
||||||
isAutoFindMode.value = false
|
isAutoFindMode.value = false
|
||||||
}
|
}
|
||||||
|
|
||||||
showFileDialog.value = true
|
showFileDialog.value = true
|
||||||
autoFocusFileInput()
|
autoFocusFileInput()
|
||||||
}
|
}
|
||||||
@@ -921,7 +888,7 @@ const deleteItem = async (item: TreeItem) => {
|
|||||||
cancelText: '取消',
|
cancelText: '取消',
|
||||||
confirmColor: 'error'
|
confirmColor: 'error'
|
||||||
})
|
})
|
||||||
|
|
||||||
if (!confirmed) return
|
if (!confirmed) return
|
||||||
|
|
||||||
if (item.type === 'directory') {
|
if (item.type === 'directory') {
|
||||||
@@ -931,7 +898,7 @@ const deleteItem = async (item: TreeItem) => {
|
|||||||
// Exclude if exact match or it's a subdirectory
|
// Exclude if exact match or it's a subdirectory
|
||||||
return !isSubPath(d.path, item.name);
|
return !isSubPath(d.path, item.name);
|
||||||
});
|
});
|
||||||
|
|
||||||
// Also remove files that are inside this directory
|
// Also remove files that are inside this directory
|
||||||
files.value = files.value.filter(f => {
|
files.value = files.value.filter(f => {
|
||||||
// Exclude if it's inside the directory being deleted
|
// Exclude if it's inside the directory being deleted
|
||||||
|
|||||||
Reference in new issue
Block a user