feat: 优化模板创建界面,添加右键菜单功能以支持目录和文件的快速添加
This commit is contained in:
1 parent
4f859a4933
commit
02610224a1
1 file changed
+207
-250
@@ -8,215 +8,154 @@
|
|||||||
{{ isEditMode ? '编辑模板' : '创建模板' }}
|
{{ isEditMode ? '编辑模板' : '创建模板' }}
|
||||||
</h2>
|
</h2>
|
||||||
<v-spacer />
|
<v-spacer />
|
||||||
<v-btn
|
<v-btn icon variant="text" @click="goBack">
|
||||||
icon
|
|
||||||
variant="text"
|
|
||||||
@click="goBack"
|
|
||||||
>
|
|
||||||
<v-icon>mdi-close</v-icon>
|
<v-icon>mdi-close</v-icon>
|
||||||
<v-tooltip
|
<v-tooltip activator="parent" location="bottom">
|
||||||
activator="parent"
|
|
||||||
location="bottom"
|
|
||||||
>
|
|
||||||
关闭
|
关闭
|
||||||
</v-tooltip>
|
</v-tooltip>
|
||||||
</v-btn>
|
</v-btn>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<v-form v-model="formValid" class="mb-4">
|
<v-form v-model="formValid" class="mb-4">
|
||||||
<v-text-field
|
<v-text-field v-model="templateName" label="模板名称 *" placeholder="输入模板名称" :rules="[requiredRule]" required
|
||||||
v-model="templateName"
|
clearable density="comfortable" />
|
||||||
label="模板名称 *"
|
|
||||||
placeholder="输入模板名称"
|
<v-textarea v-model="templateDescription" label="模板描述" placeholder="描述这个模板的用途..." rows="2" auto-grow clearable
|
||||||
:rules="[requiredRule]"
|
density="comfortable" />
|
||||||
required
|
|
||||||
clearable
|
|
||||||
density="comfortable"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<v-textarea
|
|
||||||
v-model="templateDescription"
|
|
||||||
label="模板描述"
|
|
||||||
placeholder="描述这个模板的用途..."
|
|
||||||
rows="2"
|
|
||||||
auto-grow
|
|
||||||
clearable
|
|
||||||
density="comfortable"
|
|
||||||
/>
|
|
||||||
</v-form>
|
</v-form>
|
||||||
|
|
||||||
<v-divider class="my-4" />
|
<v-divider class="my-4" />
|
||||||
|
|
||||||
<!-- File Operations -->
|
|
||||||
<div class="mb-4">
|
|
||||||
<h3 class="text-subtitle-1 mb-2">添加项</h3>
|
|
||||||
<div class="d-flex flex-column ga-2">
|
|
||||||
<v-btn
|
|
||||||
color="primary"
|
|
||||||
variant="outlined"
|
|
||||||
prepend-icon="mdi-folder-plus"
|
|
||||||
@click="showAddDirectoryDialog"
|
|
||||||
block
|
|
||||||
>
|
|
||||||
添加目录
|
|
||||||
</v-btn>
|
|
||||||
<v-btn
|
|
||||||
color="success"
|
|
||||||
variant="outlined"
|
|
||||||
prepend-icon="mdi-file-plus"
|
|
||||||
@click="showAddFileDialog"
|
|
||||||
block
|
|
||||||
>
|
|
||||||
添加文件
|
|
||||||
</v-btn>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<v-divider class="my-4" />
|
|
||||||
|
|
||||||
<!-- Template Actions -->
|
<!-- Template Actions -->
|
||||||
<div class="d-flex ga-2">
|
<div class="d-flex ga-2">
|
||||||
<v-btn
|
<v-btn color="primary" @click="saveTemplate" :disabled="!formValid || !hasChanges"
|
||||||
color="primary"
|
prepend-icon="mdi-content-save" block>
|
||||||
@click="saveTemplate"
|
|
||||||
:disabled="!formValid || !hasChanges"
|
|
||||||
prepend-icon="mdi-content-save"
|
|
||||||
block
|
|
||||||
>
|
|
||||||
保存模板
|
保存模板
|
||||||
</v-btn>
|
</v-btn>
|
||||||
</div>
|
</div>
|
||||||
</v-col>
|
</v-col>
|
||||||
|
|
||||||
<!-- Right Panel - Tree Structure -->
|
<!-- Right Panel - Tree Structure -->
|
||||||
<v-col cols="12" md="8" class="pa-4">
|
<v-col cols="12" md="8" class="pa-4">
|
||||||
<div class="d-flex align-center mb-4">
|
<div class="d-flex align-center mb-4">
|
||||||
<h3 class="text-h6 mr-2">模板结构</h3>
|
<h3 class="text-h6 mr-2">模板结构</h3>
|
||||||
<v-spacer />
|
<v-spacer />
|
||||||
<v-btn
|
<v-btn icon variant="text" @click="addRootDirectory" size="small">
|
||||||
icon
|
<v-icon>mdi-folder-plus</v-icon>
|
||||||
variant="text"
|
<v-tooltip activator="parent" location="bottom">
|
||||||
@click="expandAll"
|
添加根目录
|
||||||
size="small"
|
</v-tooltip>
|
||||||
>
|
</v-btn>
|
||||||
|
<v-btn icon variant="text" @click="addRootFile" size="small">
|
||||||
|
<v-icon>mdi-file-plus</v-icon>
|
||||||
|
<v-tooltip activator="parent" location="bottom">
|
||||||
|
添加根文件
|
||||||
|
</v-tooltip>
|
||||||
|
</v-btn>
|
||||||
|
<v-btn icon variant="text" @click="expandAll" size="small">
|
||||||
<v-icon>mdi-arrow-expand-down</v-icon>
|
<v-icon>mdi-arrow-expand-down</v-icon>
|
||||||
<v-tooltip
|
<v-tooltip activator="parent" location="bottom">
|
||||||
activator="parent"
|
|
||||||
location="bottom"
|
|
||||||
>
|
|
||||||
展开全部
|
展开全部
|
||||||
</v-tooltip>
|
</v-tooltip>
|
||||||
</v-btn>
|
</v-btn>
|
||||||
<v-btn
|
<v-btn icon variant="text" @click="collapseAll" size="small">
|
||||||
icon
|
|
||||||
variant="text"
|
|
||||||
@click="collapseAll"
|
|
||||||
size="small"
|
|
||||||
>
|
|
||||||
<v-icon>mdi-arrow-collapse-up</v-icon>
|
<v-icon>mdi-arrow-collapse-up</v-icon>
|
||||||
<v-tooltip
|
<v-tooltip activator="parent" location="bottom">
|
||||||
activator="parent"
|
|
||||||
location="bottom"
|
|
||||||
>
|
|
||||||
收起全部
|
收起全部
|
||||||
</v-tooltip>
|
</v-tooltip>
|
||||||
</v-btn>
|
</v-btn>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<v-card
|
<v-card variant="outlined" class="pa-2" :height="treeHeight"
|
||||||
variant="outlined"
|
@contextmenu.prevent="showContextMenu($event, null)">
|
||||||
class="pa-2"
|
<v-treeview v-model:expanded="expandedNodes" :items="treeItems" item-title="name" item-key="id"
|
||||||
:height="treeHeight"
|
item-children="children" activatable open-on-click :return-object="false">
|
||||||
>
|
|
||||||
<v-treeview
|
|
||||||
v-model:expanded="expandedNodes"
|
|
||||||
:items="treeItems"
|
|
||||||
item-title="name"
|
|
||||||
item-key="id"
|
|
||||||
item-children="children"
|
|
||||||
activatable
|
|
||||||
open-on-click
|
|
||||||
:return-object="false"
|
|
||||||
>
|
|
||||||
<template v-slot:prepend="{ item }">
|
<template v-slot:prepend="{ item }">
|
||||||
<v-icon
|
<v-icon :color="item.type === 'directory' ? 'warning' : 'info'" size="large">
|
||||||
:color="item.type === 'directory' ? 'warning' : 'info'"
|
{{
|
||||||
size="large"
|
item.type === 'directory'
|
||||||
>
|
? 'mdi-folder-outline'
|
||||||
{{
|
: 'mdi-file-document-outline'
|
||||||
item.type === 'directory'
|
|
||||||
? 'mdi-folder-outline'
|
|
||||||
: 'mdi-file-document-outline'
|
|
||||||
}}
|
}}
|
||||||
</v-icon>
|
</v-icon>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
<template v-slot:title="{ item }">
|
||||||
|
<span @contextmenu.prevent="showContextMenu($event, item)" class="cursor-pointer d-flex align-center">
|
||||||
|
{{ item.name }}
|
||||||
|
<v-btn v-if="item.type === 'directory'" icon variant="text" size="small" class="ml-2"
|
||||||
|
@click.stop="addNewItemToCurrentDirectory(item)">
|
||||||
|
<v-icon size="small">mdi-plus</v-icon>
|
||||||
|
<v-tooltip activator="parent" location="top">
|
||||||
|
添加到目录
|
||||||
|
</v-tooltip>
|
||||||
|
</v-btn>
|
||||||
|
</span>
|
||||||
|
</template>
|
||||||
|
|
||||||
<template v-slot:append="{ item }">
|
<template v-slot:append="{ item }">
|
||||||
<div class="d-flex align-center ga-1">
|
<div class="d-flex align-center ga-1">
|
||||||
<v-btn
|
<v-btn v-if="item.type === 'file'" icon variant="text" size="small" @click.stop="editFile(item)">
|
||||||
v-if="item.type === 'file'"
|
|
||||||
icon
|
|
||||||
variant="text"
|
|
||||||
size="small"
|
|
||||||
@click.stop="editFile(item)"
|
|
||||||
>
|
|
||||||
<v-icon size="small">mdi-pencil</v-icon>
|
<v-icon size="small">mdi-pencil</v-icon>
|
||||||
<v-tooltip
|
<v-tooltip activator="parent" location="top">
|
||||||
activator="parent"
|
|
||||||
location="top"
|
|
||||||
>
|
|
||||||
编辑内容
|
编辑内容
|
||||||
</v-tooltip>
|
</v-tooltip>
|
||||||
</v-btn>
|
</v-btn>
|
||||||
|
|
||||||
<v-btn
|
<v-btn icon variant="text" size="small" @click.stop="deleteItem(item)">
|
||||||
icon
|
<v-icon size="small" color="error">
|
||||||
variant="text"
|
|
||||||
size="small"
|
|
||||||
@click.stop="deleteItem(item)"
|
|
||||||
>
|
|
||||||
<v-icon
|
|
||||||
size="small"
|
|
||||||
color="error"
|
|
||||||
>
|
|
||||||
mdi-delete
|
mdi-delete
|
||||||
</v-icon>
|
</v-icon>
|
||||||
<v-tooltip
|
<v-tooltip activator="parent" location="top">
|
||||||
activator="parent"
|
|
||||||
location="top"
|
|
||||||
>
|
|
||||||
删除
|
删除
|
||||||
</v-tooltip>
|
</v-tooltip>
|
||||||
</v-btn>
|
</v-btn>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<template v-slot:no-data>
|
<template v-slot:no-data>
|
||||||
<div class="text-center pa-4">
|
<div class="text-center pa-4">
|
||||||
<v-icon size="48" color="grey-lighten-1">mdi-folder-open-outline</v-icon>
|
<v-icon size="48" color="grey-lighten-1">mdi-folder-open-outline</v-icon>
|
||||||
<p class="text-body-2 mt-2">暂无文件或目录</p>
|
<p class="text-body-2 mt-2">暂无文件或目录</p>
|
||||||
<p class="text-caption">点击左侧"添加目录"或"添加文件"开始创建</p>
|
<p class="text-caption">右键点击空白区域添加根目录或文件</p>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
</v-treeview>
|
</v-treeview>
|
||||||
</v-card>
|
</v-card>
|
||||||
|
|
||||||
|
<!-- Context Menu -->
|
||||||
|
<v-menu v-model="showContextMenuVar" :position-x="contextMenuX" :position-y="contextMenuY" absolute>
|
||||||
|
<v-list density="compact">
|
||||||
|
<v-list-item @click="addDirectory(currentContextItem)">
|
||||||
|
<template v-slot: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="addFile(currentContextItem)">
|
||||||
|
<template v-slot: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>
|
||||||
</v-col>
|
</v-col>
|
||||||
</v-row>
|
</v-row>
|
||||||
|
|
||||||
<!-- Add Directory Dialog -->
|
<!-- Add Directory Dialog -->
|
||||||
<v-dialog v-model="showDirectoryDialog" max-width="500">
|
<v-dialog v-model="showDirectoryDialog" max-width="500">
|
||||||
<v-card>
|
<v-card>
|
||||||
<v-card-title>添加目录</v-card-title>
|
<v-card-title>添加目录</v-card-title>
|
||||||
<v-card-text>
|
<v-card-text>
|
||||||
<v-form v-model="directoryFormValid">
|
<v-form v-model="directoryFormValid">
|
||||||
<v-text-field
|
<v-text-field v-model="newDirectoryPath" label="目录路径 *" placeholder="例如: src/components"
|
||||||
v-model="newDirectoryPath"
|
:rules="[requiredRule]" required density="comfortable" />
|
||||||
label="目录路径 *"
|
|
||||||
placeholder="例如: src/components"
|
|
||||||
:rules="[requiredRule]"
|
|
||||||
required
|
|
||||||
density="comfortable"
|
|
||||||
/>
|
|
||||||
</v-form>
|
</v-form>
|
||||||
</v-card-text>
|
</v-card-text>
|
||||||
<v-card-actions>
|
<v-card-actions>
|
||||||
@@ -224,31 +163,21 @@
|
|||||||
<v-btn @click="showDirectoryDialog = false">
|
<v-btn @click="showDirectoryDialog = false">
|
||||||
取消
|
取消
|
||||||
</v-btn>
|
</v-btn>
|
||||||
<v-btn
|
<v-btn color="primary" @click="confirmAddDirectory" :disabled="!directoryFormValid">
|
||||||
color="primary"
|
|
||||||
@click="addDirectory"
|
|
||||||
:disabled="!directoryFormValid"
|
|
||||||
>
|
|
||||||
添加
|
添加
|
||||||
</v-btn>
|
</v-btn>
|
||||||
</v-card-actions>
|
</v-card-actions>
|
||||||
</v-card>
|
</v-card>
|
||||||
</v-dialog>
|
</v-dialog>
|
||||||
|
|
||||||
<!-- Add File Dialog -->
|
<!-- Add File Dialog -->
|
||||||
<v-dialog v-model="showFileDialog" max-width="500">
|
<v-dialog v-model="showFileDialog" max-width="500">
|
||||||
<v-card>
|
<v-card>
|
||||||
<v-card-title>添加文件</v-card-title>
|
<v-card-title>添加文件</v-card-title>
|
||||||
<v-card-text>
|
<v-card-text>
|
||||||
<v-form v-model="fileFormValid">
|
<v-form v-model="fileFormValid">
|
||||||
<v-text-field
|
<v-text-field v-model="newFilePath" label="文件路径 *" placeholder="例如: src/index.js" :rules="[requiredRule]"
|
||||||
v-model="newFilePath"
|
required density="comfortable" />
|
||||||
label="文件路径 *"
|
|
||||||
placeholder="例如: src/index.js"
|
|
||||||
:rules="[requiredRule]"
|
|
||||||
required
|
|
||||||
density="comfortable"
|
|
||||||
/>
|
|
||||||
</v-form>
|
</v-form>
|
||||||
</v-card-text>
|
</v-card-text>
|
||||||
<v-card-actions>
|
<v-card-actions>
|
||||||
@@ -256,17 +185,13 @@
|
|||||||
<v-btn @click="showFileDialog = false">
|
<v-btn @click="showFileDialog = false">
|
||||||
取消
|
取消
|
||||||
</v-btn>
|
</v-btn>
|
||||||
<v-btn
|
<v-btn color="primary" @click="confirmAddFile" :disabled="!fileFormValid">
|
||||||
color="primary"
|
|
||||||
@click="addFile"
|
|
||||||
:disabled="!fileFormValid"
|
|
||||||
>
|
|
||||||
添加并编辑
|
添加并编辑
|
||||||
</v-btn>
|
</v-btn>
|
||||||
</v-card-actions>
|
</v-card-actions>
|
||||||
</v-card>
|
</v-card>
|
||||||
</v-dialog>
|
</v-dialog>
|
||||||
|
|
||||||
<!-- File Content Editor Dialog -->
|
<!-- File Content Editor Dialog -->
|
||||||
<v-dialog v-model="showEditorDialog" fullscreen>
|
<v-dialog v-model="showEditorDialog" fullscreen>
|
||||||
<v-card>
|
<v-card>
|
||||||
@@ -278,25 +203,14 @@
|
|||||||
编辑文件: {{ editingFile?.path }}
|
编辑文件: {{ editingFile?.path }}
|
||||||
</v-toolbar-title>
|
</v-toolbar-title>
|
||||||
<v-spacer />
|
<v-spacer />
|
||||||
<v-btn
|
<v-btn variant="text" @click="saveFileContent">
|
||||||
variant="text"
|
|
||||||
@click="saveFileContent"
|
|
||||||
>
|
|
||||||
保存
|
保存
|
||||||
</v-btn>
|
</v-btn>
|
||||||
</v-toolbar>
|
</v-toolbar>
|
||||||
|
|
||||||
<v-card-text class="pa-0 fill-height">
|
<v-card-text class="pa-0 fill-height">
|
||||||
<v-textarea
|
<v-textarea v-model="editingFileContent" class="fill-height" style="height: calc(100vh - 120px);" no-resize
|
||||||
v-model="editingFileContent"
|
spellcheck="false" placeholder="在此输入文件内容..." variant="solo-filled" density="comfortable" />
|
||||||
class="fill-height"
|
|
||||||
style="height: calc(100vh - 120px);"
|
|
||||||
no-resize
|
|
||||||
spellcheck="false"
|
|
||||||
placeholder="在此输入文件内容..."
|
|
||||||
variant="solo-filled"
|
|
||||||
density="comfortable"
|
|
||||||
/>
|
|
||||||
</v-card-text>
|
</v-card-text>
|
||||||
</v-card>
|
</v-card>
|
||||||
</v-dialog>
|
</v-dialog>
|
||||||
@@ -304,7 +218,7 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { ref, computed, onMounted, onUnmounted, watch } from 'vue'
|
import { ref, computed, onMounted, onUnmounted, watch, nextTick } from 'vue'
|
||||||
import { useRoute, useRouter } from 'vue-router'
|
import { useRoute, useRouter } from 'vue-router'
|
||||||
import { useTemplateStore } from '@/renderer/store/template'
|
import { useTemplateStore } from '@/renderer/store/template'
|
||||||
import { Template } from '@/renderer/store/template'
|
import { Template } from '@/renderer/store/template'
|
||||||
@@ -329,6 +243,12 @@ const showEditorDialog = ref(false)
|
|||||||
const directoryFormValid = ref(false)
|
const directoryFormValid = ref(false)
|
||||||
const fileFormValid = ref(false)
|
const fileFormValid = ref(false)
|
||||||
|
|
||||||
|
// Context menu
|
||||||
|
const showContextMenuVar = ref(false)
|
||||||
|
const contextMenuX = ref(0)
|
||||||
|
const contextMenuY = ref(0)
|
||||||
|
const currentContextItem = ref<any>(null)
|
||||||
|
|
||||||
// New item state
|
// New item state
|
||||||
const newDirectoryPath = ref('')
|
const newDirectoryPath = ref('')
|
||||||
const newFilePath = ref('')
|
const newFilePath = ref('')
|
||||||
@@ -347,7 +267,7 @@ const files = ref<{ path: string; content: string }[]>([])
|
|||||||
const isEditMode = computed(() => !!route.params.id)
|
const isEditMode = computed(() => !!route.params.id)
|
||||||
const treeItems = computed(() => {
|
const treeItems = computed(() => {
|
||||||
const items = []
|
const items = []
|
||||||
|
|
||||||
// Add directories
|
// Add directories
|
||||||
directories.value.forEach(dir => {
|
directories.value.forEach(dir => {
|
||||||
items.push({
|
items.push({
|
||||||
@@ -357,7 +277,7 @@ const treeItems = computed(() => {
|
|||||||
children: []
|
children: []
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
// Add files
|
// Add files
|
||||||
files.value.forEach(file => {
|
files.value.forEach(file => {
|
||||||
items.push({
|
items.push({
|
||||||
@@ -366,7 +286,7 @@ const treeItems = computed(() => {
|
|||||||
type: 'file'
|
type: 'file'
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
return items
|
return items
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -381,18 +301,18 @@ watch([templateName, templateDescription, directories, files], () => {
|
|||||||
// Lifecycle
|
// Lifecycle
|
||||||
onMounted(async () => {
|
onMounted(async () => {
|
||||||
await templateStore.loadTemplates()
|
await templateStore.loadTemplates()
|
||||||
|
|
||||||
// Set tree height based on window height
|
// Set tree height based on window height
|
||||||
updateTreeHeight()
|
updateTreeHeight()
|
||||||
|
|
||||||
// Add resize listener
|
// Add resize listener
|
||||||
window.addEventListener('resize', updateTreeHeight)
|
window.addEventListener('resize', updateTreeHeight)
|
||||||
|
|
||||||
// Handle edit mode
|
// Handle edit mode
|
||||||
if (isEditMode.value) {
|
if (isEditMode.value) {
|
||||||
const templateId = route.params.id as string
|
const templateId = route.params.id as string
|
||||||
const template = getTemplateById(templateId)
|
const template = getTemplateById(templateId)
|
||||||
|
|
||||||
if (template) {
|
if (template) {
|
||||||
templateName.value = template.name
|
templateName.value = template.name
|
||||||
templateDescription.value = template.description
|
templateDescription.value = template.description
|
||||||
@@ -403,7 +323,7 @@ onMounted(async () => {
|
|||||||
router.push('/templates')
|
router.push('/templates')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Expand all nodes by default
|
// Expand all nodes by default
|
||||||
expandAll()
|
expandAll()
|
||||||
})
|
})
|
||||||
@@ -417,7 +337,92 @@ const updateTreeHeight = () => {
|
|||||||
treeHeight.value = window.innerHeight - 200
|
treeHeight.value = window.innerHeight - 200
|
||||||
}
|
}
|
||||||
|
|
||||||
// Methods
|
const showContextMenu = (event: MouseEvent, item: any) => {
|
||||||
|
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 = () => {
|
||||||
|
newDirectoryPath.value = ''
|
||||||
|
showDirectoryDialog.value = true
|
||||||
|
}
|
||||||
|
|
||||||
|
const addRootFile = () => {
|
||||||
|
newFilePath.value = ''
|
||||||
|
showFileDialog.value = true
|
||||||
|
}
|
||||||
|
|
||||||
|
const addDirectory = (parentItem: any = null) => {
|
||||||
|
showContextMenuVar.value = false
|
||||||
|
currentContextItem.value = parentItem
|
||||||
|
newDirectoryPath.value = parentItem ? `${parentItem.name}/` : ''
|
||||||
|
showDirectoryDialog.value = true
|
||||||
|
}
|
||||||
|
|
||||||
|
const addFile = (parentItem: any = null) => {
|
||||||
|
showContextMenuVar.value = false
|
||||||
|
newFilePath.value = parentItem ? `${parentItem.name}/` : ''
|
||||||
|
showFileDialog.value = true
|
||||||
|
}
|
||||||
|
|
||||||
|
const addNewItemToCurrentDirectory = (directoryItem: any) => {
|
||||||
|
currentContextItem.value = directoryItem
|
||||||
|
newDirectoryPath.value = directoryItem ? `${directoryItem.name}/` : ''
|
||||||
|
showDirectoryDialog.value = true
|
||||||
|
}
|
||||||
|
|
||||||
|
const confirmAddDirectory = () => {
|
||||||
|
if (!newDirectoryPath.value.trim()) return
|
||||||
|
|
||||||
|
// Check for duplicates
|
||||||
|
const exists = directories.value.some(d => d.path === newDirectoryPath.value)
|
||||||
|
if (exists) {
|
||||||
|
alert('该目录路径已存在!')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
directories.value.push({
|
||||||
|
path: newDirectoryPath.value
|
||||||
|
})
|
||||||
|
|
||||||
|
showDirectoryDialog.value = false
|
||||||
|
newDirectoryPath.value = ''
|
||||||
|
currentContextItem.value = null
|
||||||
|
}
|
||||||
|
|
||||||
|
const confirmAddFile = () => {
|
||||||
|
if (!newFilePath.value.trim()) return
|
||||||
|
|
||||||
|
// Check for duplicates
|
||||||
|
const exists = files.value.some(f => f.path === newFilePath.value)
|
||||||
|
if (exists) {
|
||||||
|
alert('该文件路径已存在!')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
const newFile = {
|
||||||
|
path: newFilePath.value,
|
||||||
|
content: ''
|
||||||
|
}
|
||||||
|
|
||||||
|
files.value.push(newFile)
|
||||||
|
|
||||||
|
// Open editor for the new file
|
||||||
|
editFileContent(newFile)
|
||||||
|
|
||||||
|
showFileDialog.value = false
|
||||||
|
newFilePath.value = ''
|
||||||
|
currentContextItem.value = null
|
||||||
|
}
|
||||||
|
|
||||||
const goBack = () => {
|
const goBack = () => {
|
||||||
if (hasChanges.value) {
|
if (hasChanges.value) {
|
||||||
if (confirm('您有未保存的更改,确定要离开吗?')) {
|
if (confirm('您有未保存的更改,确定要离开吗?')) {
|
||||||
@@ -436,58 +441,6 @@ const collapseAll = () => {
|
|||||||
expandedNodes.value = []
|
expandedNodes.value = []
|
||||||
}
|
}
|
||||||
|
|
||||||
const showAddDirectoryDialog = () => {
|
|
||||||
newDirectoryPath.value = ''
|
|
||||||
showDirectoryDialog.value = true
|
|
||||||
}
|
|
||||||
|
|
||||||
const showAddFileDialog = () => {
|
|
||||||
newFilePath.value = ''
|
|
||||||
showFileDialog.value = true
|
|
||||||
}
|
|
||||||
|
|
||||||
const addDirectory = () => {
|
|
||||||
if (!newDirectoryPath.value.trim()) return
|
|
||||||
|
|
||||||
// Check for duplicates
|
|
||||||
const exists = directories.value.some(d => d.path === newDirectoryPath.value)
|
|
||||||
if (exists) {
|
|
||||||
alert('该目录路径已存在!')
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
directories.value.push({
|
|
||||||
path: newDirectoryPath.value
|
|
||||||
})
|
|
||||||
|
|
||||||
showDirectoryDialog.value = false
|
|
||||||
newDirectoryPath.value = ''
|
|
||||||
}
|
|
||||||
|
|
||||||
const addFile = () => {
|
|
||||||
if (!newFilePath.value.trim()) return
|
|
||||||
|
|
||||||
// Check for duplicates
|
|
||||||
const exists = files.value.some(f => f.path === newFilePath.value)
|
|
||||||
if (exists) {
|
|
||||||
alert('该文件路径已存在!')
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
const newFile = {
|
|
||||||
path: newFilePath.value,
|
|
||||||
content: ''
|
|
||||||
}
|
|
||||||
|
|
||||||
files.value.push(newFile)
|
|
||||||
|
|
||||||
// Open editor for the new file
|
|
||||||
editFileContent(newFile)
|
|
||||||
|
|
||||||
showFileDialog.value = false
|
|
||||||
newFilePath.value = ''
|
|
||||||
}
|
|
||||||
|
|
||||||
const editFile = (item: any) => {
|
const editFile = (item: any) => {
|
||||||
const file = files.value.find(f => `file-${f.path}` === item.id)
|
const file = files.value.find(f => `file-${f.path}` === item.id)
|
||||||
if (file) {
|
if (file) {
|
||||||
@@ -513,7 +466,7 @@ const saveFileContent = () => {
|
|||||||
|
|
||||||
const deleteItem = (item: any) => {
|
const deleteItem = (item: any) => {
|
||||||
if (!confirm('确定要删除此项吗?')) return
|
if (!confirm('确定要删除此项吗?')) return
|
||||||
|
|
||||||
if (item.type === 'directory') {
|
if (item.type === 'directory') {
|
||||||
directories.value = directories.value.filter(d => `dir-${d.path}` !== item.id)
|
directories.value = directories.value.filter(d => `dir-${d.path}` !== item.id)
|
||||||
} else {
|
} else {
|
||||||
@@ -523,14 +476,14 @@ const deleteItem = (item: any) => {
|
|||||||
|
|
||||||
const saveTemplate = () => {
|
const saveTemplate = () => {
|
||||||
if (!formValid.value) return
|
if (!formValid.value) return
|
||||||
|
|
||||||
const templateData = {
|
const templateData = {
|
||||||
name: templateName.value,
|
name: templateName.value,
|
||||||
description: templateDescription.value,
|
description: templateDescription.value,
|
||||||
files: files.value,
|
files: files.value,
|
||||||
directories: directories.value
|
directories: directories.value
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isEditMode.value) {
|
if (isEditMode.value) {
|
||||||
const templateId = route.params.id as string
|
const templateId = route.params.id as string
|
||||||
templateStore.updateTemplate({
|
templateStore.updateTemplate({
|
||||||
@@ -540,7 +493,7 @@ const saveTemplate = () => {
|
|||||||
} else {
|
} else {
|
||||||
templateStore.addTemplate(templateData)
|
templateStore.addTemplate(templateData)
|
||||||
}
|
}
|
||||||
|
|
||||||
hasChanges.value = false
|
hasChanges.value = false
|
||||||
router.push('/templates')
|
router.push('/templates')
|
||||||
}
|
}
|
||||||
@@ -554,4 +507,8 @@ const saveTemplate = () => {
|
|||||||
.fill-height {
|
.fill-height {
|
||||||
height: 100%;
|
height: 100%;
|
||||||
}
|
}
|
||||||
</style>
|
|
||||||
|
.cursor-pointer {
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
Reference in new issue
Block a user