feat: add @mdi/font and electron-devtools-installer dependencies
- Added @mdi/font for Material Design Icons support. - Included electron-devtools-installer to facilitate Vue DevTools installation in development. refactor: enhance CreateTemplateScreen layout and functionality - Improved layout with a responsive design. - Added functionality for adding directories and files with validation. - Implemented a file content editor dialog for editing file contents. - Updated template save logic to handle changes more effectively. fix: update TemplateListScreen for better UX - Enhanced template list display with improved card layout. - Added action buttons for viewing, executing, editing, and deleting templates. - Improved dialog handling for template details and execution. chore: update vuetify plugin configuration - Removed unused icon set configuration. - Updated locale settings to use simplified Chinese. style: clean up HeaderLayout and vuetify styles - Removed commented-out code and unnecessary styles. - Improved overall styling for better readability and consistency.
This commit is contained in:
1 parent
1aecd5f4b6
commit
4f859a4933
8 files changed
+653
-394
No files matched your search
@@ -2,13 +2,15 @@
|
||||
<v-container>
|
||||
<v-row>
|
||||
<v-col cols="12">
|
||||
<h2 class="mb-4"> 模板列表 </h2>
|
||||
<div class="d-flex align-center mb-4 justify-space-between flex-wrap">
|
||||
<h2 class="mr-2 mb-2"> 模板列表 </h2>
|
||||
<v-btn @click="navigateToCreateTemplate" color="primary" prepend-icon="mdi-plus" class="mb-2">
|
||||
创建模板
|
||||
</v-btn>
|
||||
</div>
|
||||
|
||||
<!-- No templates message -->
|
||||
<v-card
|
||||
v-if="templates.length === 0"
|
||||
class="pa-6 mb-4 text-center"
|
||||
>
|
||||
<v-card v-if="templates.length === 0" class="pa-6 mb-4 text-center">
|
||||
<v-card-title class="text-h5 mb-4">
|
||||
暂无模板
|
||||
</v-card-title>
|
||||
@@ -16,12 +18,7 @@
|
||||
<p>还没有创建任何模板。创建您的第一个模板以开始批量生成文件和目录。</p>
|
||||
</v-card-text>
|
||||
<v-card-actions class="justify-center">
|
||||
<v-btn
|
||||
color="primary"
|
||||
size="x-large"
|
||||
@click="navigateToCreateTemplate"
|
||||
prepend-icon="mdi-plus"
|
||||
>
|
||||
<v-btn color="primary" size="default" @click="navigateToCreateTemplate" prepend-icon="mdi-plus">
|
||||
创建模板
|
||||
</v-btn>
|
||||
</v-card-actions>
|
||||
@@ -30,38 +27,61 @@
|
||||
<!-- Template list -->
|
||||
<div v-else>
|
||||
<v-row>
|
||||
<v-col
|
||||
v-for="template in templates"
|
||||
:key="template.id"
|
||||
cols="12"
|
||||
md="6"
|
||||
lg="4"
|
||||
>
|
||||
<v-card
|
||||
class="d-flex flex-column"
|
||||
height="100%"
|
||||
>
|
||||
<v-card-title>{{ template.name }}</v-card-title>
|
||||
<v-card-subtitle>{{ template.description }}</v-card-subtitle>
|
||||
<v-card-text class="flex-grow-1">
|
||||
<p>文件数量: {{ template.files.length }}</p>
|
||||
<p>目录数量: {{ template.directories.length }}</p>
|
||||
<v-col v-for="template in templates" :key="template.id" cols="12" sm="6" md="4" lg="3">
|
||||
<v-card class="d-flex flex-column" height="100%">
|
||||
<v-card-item>
|
||||
<v-card-title>{{ template.name }}</v-card-title>
|
||||
<v-card-subtitle>{{ template.description }}</v-card-subtitle>
|
||||
</v-card-item>
|
||||
|
||||
<v-card-text class="flex-grow-1 py-2">
|
||||
<v-chip-group column>
|
||||
<v-chip size="small" color="primary" variant="tonal">
|
||||
文件: {{ template.files.length }}
|
||||
</v-chip>
|
||||
<v-chip size="small" color="success" variant="tonal">
|
||||
目录: {{ template.directories.length }}
|
||||
</v-chip>
|
||||
</v-chip-group>
|
||||
</v-card-text>
|
||||
<v-card-actions>
|
||||
<v-btn
|
||||
color="primary"
|
||||
variant="outlined"
|
||||
@click="viewTemplate(template)"
|
||||
>
|
||||
查看
|
||||
</v-btn>
|
||||
<v-btn
|
||||
color="success"
|
||||
variant="outlined"
|
||||
@click="executeTemplate(template)"
|
||||
>
|
||||
执行
|
||||
</v-btn>
|
||||
|
||||
<v-divider class="mt-auto"></v-divider>
|
||||
|
||||
<v-card-actions class="pa-2 justify-space-between">
|
||||
<div>
|
||||
<v-btn color="primary" variant="text" size="small" @click="viewTemplate(template)">
|
||||
查看
|
||||
</v-btn>
|
||||
<v-btn color="success" variant="text" size="small" @click="executeTemplate(template)">
|
||||
执行
|
||||
</v-btn>
|
||||
</div>
|
||||
|
||||
<v-menu location="bottom end">
|
||||
<template v-slot:activator="{ props }">
|
||||
<v-btn v-bind="props" icon variant="text" size="small" density="comfortable">
|
||||
<v-icon>mdi-dots-vertical</v-icon>
|
||||
</v-btn>
|
||||
</template>
|
||||
|
||||
<v-list density="compact">
|
||||
<v-list-item @click="editTemplate(template)">
|
||||
<template v-slot:prepend>
|
||||
<v-icon>mdi-pencil</v-icon>
|
||||
</template>
|
||||
<v-list-item-title>修改</v-list-item-title>
|
||||
</v-list-item>
|
||||
|
||||
<v-divider></v-divider>
|
||||
|
||||
<v-list-item @click="deleteTemplate(template)">
|
||||
<template v-slot:prepend>
|
||||
<v-icon color="error">mdi-delete</v-icon>
|
||||
</template>
|
||||
<v-list-item-title class="text-error">删除</v-list-item-title>
|
||||
</v-list-item>
|
||||
</v-list>
|
||||
</v-menu>
|
||||
</v-card-actions>
|
||||
</v-card>
|
||||
</v-col>
|
||||
@@ -71,37 +91,20 @@
|
||||
</v-row>
|
||||
|
||||
<!-- Template detail dialog -->
|
||||
<v-dialog
|
||||
v-model="showTemplateDetail"
|
||||
max-width="800"
|
||||
>
|
||||
<v-dialog v-model="showTemplateDetail" max-width="800">
|
||||
<v-card>
|
||||
<v-card-title>
|
||||
<span>模板详情: {{ selectedTemplate?.name }}</span>
|
||||
<v-spacer />
|
||||
<v-btn
|
||||
icon
|
||||
@click="showTemplateDetail = false"
|
||||
>
|
||||
<v-icon>mdi-close</v-icon>
|
||||
</v-btn>
|
||||
</v-card-title>
|
||||
<v-card-text>
|
||||
<v-treeview
|
||||
:items="templateTree"
|
||||
item-title="name"
|
||||
item-key="id"
|
||||
item-children="children"
|
||||
activatable
|
||||
open-all
|
||||
>
|
||||
<template v-slot:prepend="{ item, open }">
|
||||
<v-treeview :items="templateTree" item-title="name" item-key="id" item-children="children" activatable
|
||||
open-all>
|
||||
<template v-slot:prepend="{ item }">
|
||||
<v-icon>
|
||||
{{
|
||||
item.type === 'directory'
|
||||
? open
|
||||
? 'mdi-folder-open'
|
||||
: 'mdi-folder'
|
||||
? 'mdi-folder'
|
||||
: 'mdi-file'
|
||||
}}
|
||||
</v-icon>
|
||||
@@ -112,63 +115,27 @@
|
||||
</v-dialog>
|
||||
|
||||
<!-- Execute template dialog -->
|
||||
<v-dialog
|
||||
v-model="showExecuteDialog"
|
||||
max-width="600"
|
||||
>
|
||||
<v-dialog v-model="showExecuteDialog" max-width="600">
|
||||
<v-card>
|
||||
<v-card-title>执行模板</v-card-title>
|
||||
<v-card-text>
|
||||
<v-form v-model="executeFormValid">
|
||||
<v-text-field
|
||||
v-model="executePath"
|
||||
label="选择目录"
|
||||
readonly
|
||||
@click="selectDirectory"
|
||||
prepend-inner-icon="mdi-folder"
|
||||
:rules="[(v) => !!v || '请选择目录']"
|
||||
/>
|
||||
<v-textarea
|
||||
v-model="baseDirNames"
|
||||
label="基础目录名 (每行一个,支持批量)"
|
||||
placeholder="输入基础目录名,每行一个"
|
||||
:rules="[(v) => !!v || '请输入基础目录名']"
|
||||
/>
|
||||
<v-text-field v-model="executePath" label="选择目录" readonly @click="selectDirectory"
|
||||
prepend-inner-icon="mdi-folder" :rules="[(v) => !!v || '请选择目录']" />
|
||||
<v-textarea v-model="baseDirNames" label="基础目录名 (每行一个,支持批量)" placeholder="输入基础目录名,每行一个"
|
||||
:rules="[(v) => !!v || '请输入基础目录名']" />
|
||||
</v-form>
|
||||
</v-card-text>
|
||||
<v-card-actions>
|
||||
<v-spacer />
|
||||
<v-btn @click="showExecuteDialog = false"> 取消 </v-btn>
|
||||
<v-btn
|
||||
color="success"
|
||||
@click="confirmExecuteTemplate"
|
||||
:disabled="!executeFormValid"
|
||||
>
|
||||
<v-btn color="success" @click="confirmExecuteTemplate" :disabled="!executeFormValid">
|
||||
确认执行
|
||||
</v-btn>
|
||||
</v-card-actions>
|
||||
</v-card>
|
||||
</v-dialog>
|
||||
|
||||
<!-- Floating Action Button for creating templates -->
|
||||
<v-btn
|
||||
v-if="templates.length > 0"
|
||||
color="primary"
|
||||
size="x-large"
|
||||
icon="mdi-plus"
|
||||
fixed
|
||||
location="bottom end"
|
||||
class="mb-8 mr-8"
|
||||
style="z-index: 1000;"
|
||||
@click="navigateToCreateTemplate"
|
||||
>
|
||||
<v-tooltip
|
||||
activator="parent"
|
||||
location="top"
|
||||
>
|
||||
创建模板
|
||||
</v-tooltip>
|
||||
</v-btn>
|
||||
|
||||
</v-container>
|
||||
</template>
|
||||
|
||||
@@ -176,6 +143,7 @@
|
||||
import { ref, computed, onMounted } from 'vue'
|
||||
import { useRouter } from 'vue-router'
|
||||
import { useTemplateStore } from '@/renderer/store/template'
|
||||
import { Template } from '@/renderer/store/template'
|
||||
|
||||
const router = useRouter()
|
||||
const templateStore = useTemplateStore()
|
||||
@@ -185,11 +153,13 @@ onMounted(async () => {
|
||||
await templateStore.loadTemplates()
|
||||
})
|
||||
|
||||
const { deleteTemplate: storeDeleteTemplate } = templateStore
|
||||
|
||||
const templates = computed(() => templateStore.templates)
|
||||
|
||||
// Template detail view
|
||||
const showTemplateDetail = ref(false)
|
||||
const selectedTemplate = ref(null as any)
|
||||
const selectedTemplate = ref<Template | null>(null)
|
||||
|
||||
// Execute template
|
||||
const showExecuteDialog = ref(false)
|
||||
@@ -197,13 +167,21 @@ const executePath = ref('')
|
||||
const baseDirNames = ref('')
|
||||
const executeFormValid = ref(false)
|
||||
|
||||
const templateTree = computed(() => {
|
||||
// Define item type for the tree view
|
||||
interface TreeNode {
|
||||
id: string
|
||||
name: string
|
||||
type: 'directory' | 'file'
|
||||
children?: TreeNode[]
|
||||
}
|
||||
|
||||
const templateTree = computed<TreeNode[]>(() => {
|
||||
if (!selectedTemplate.value) return []
|
||||
|
||||
const items = []
|
||||
const items: TreeNode[] = []
|
||||
|
||||
// Add directories
|
||||
selectedTemplate.value.directories.forEach((dir: any) => {
|
||||
selectedTemplate.value.directories.forEach((dir) => {
|
||||
items.push({
|
||||
id: `dir-${dir.path}`,
|
||||
name: dir.path,
|
||||
@@ -213,7 +191,7 @@ const templateTree = computed(() => {
|
||||
})
|
||||
|
||||
// Add files
|
||||
selectedTemplate.value.files.forEach((file: any) => {
|
||||
selectedTemplate.value.files.forEach((file) => {
|
||||
items.push({
|
||||
id: `file-${file.path}`,
|
||||
name: file.path,
|
||||
@@ -228,12 +206,22 @@ const navigateToCreateTemplate = () => {
|
||||
router.push('/create-template')
|
||||
}
|
||||
|
||||
const viewTemplate = (template: any) => {
|
||||
const viewTemplate = (template: Template) => {
|
||||
selectedTemplate.value = template
|
||||
showTemplateDetail.value = true
|
||||
}
|
||||
|
||||
const executeTemplate = (template: any) => {
|
||||
const editTemplate = (template: Template) => {
|
||||
router.push(`/create-template/${template.id}`)
|
||||
}
|
||||
|
||||
const deleteTemplate = (template: Template) => {
|
||||
if (confirm(`确定要删除模板 "${template.name}" 吗?此操作不可撤销。`)) {
|
||||
storeDeleteTemplate(template.id)
|
||||
}
|
||||
}
|
||||
|
||||
const executeTemplate = (template: Template) => {
|
||||
selectedTemplate.value = template
|
||||
executePath.value = ''
|
||||
baseDirNames.value = ''
|
||||
@@ -248,7 +236,7 @@ const selectDirectory = async () => {
|
||||
}
|
||||
|
||||
const confirmExecuteTemplate = () => {
|
||||
if (!executePath.value || !baseDirNames.value.trim()) return
|
||||
if (!executePath.value || !baseDirNames.value.trim() || !selectedTemplate.value) return
|
||||
|
||||
const dirNames = baseDirNames.value.split('\n').filter((name) => name.trim())
|
||||
|
||||
|
||||
Reference in new issue
Block a user