Skip to content

Commit 727ab7d

Browse files
committed
feat (core): 添加语言 Logo
1 parent 597d9c2 commit 727ab7d

4 files changed

Lines changed: 173 additions & 107 deletions

File tree

public/icons/python.svg

Lines changed: 17 additions & 0 deletions
Loading

src/components/Settings.vue

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
11
<template>
22
<Modal v-model:show="isVisible" title="设置" size="4xl" :close-on-backdrop="false" :close-on-esc="false" @close="closeSettings">
3-
<Tabs v-model="activeTab" type="card" size="md" :tabs="tabsData">
3+
<Tabs v-model="activeTab"
4+
type="card"
5+
size="md"
6+
:nav-class="['w-full']"
7+
:tab-button-class="['flex', 'flex-col']"
8+
:tabs="tabsData">
49
<!-- 通用配置 -->
510
<template #general>
611
<General/>

src/components/setting/Language.vue

Lines changed: 140 additions & 104 deletions
Original file line numberDiff line numberDiff line change
@@ -1,108 +1,118 @@
11
<template>
22
<div class="-mt-2">
3-
<Tabs v-model="activeTab" type="card" size="md" position="left" :tab-button-class="['w-36']" :tabs="tabsData" @change="handleTabChange">
4-
<template #[activeTab]="{ tab }">
3+
<Tabs v-model="activePlugin" type="card" size="md" position="left" :tab-button-class="['w-36']" :tabs="tabsPluginData" @change="handleTabChange">
4+
<template #[activePlugin]="{ tab }">
55
<h3 class="text-lg font-semibold text-gray-900 dark:text-white mb-4 flex items-center">
6-
<Settings2 class="w-5 h-5 mr-2"/>
6+
<LanguagesIcon class="w-5 h-5 mr-2"/>
77
{{ `语言 [ ${ tab.label } ] 配置` }}
88
</h3>
99

10-
<div class="space-y-4">
11-
<div>
12-
<label class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2">
13-
语言环境目录
14-
</label>
15-
<div class="flex gap-2">
16-
<input v-model="pluginConfig.execute_home"
17-
type="text"
18-
placeholder="选择语言环境目录路径"
19-
class="flex-1 px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-md bg-white dark:bg-gray-700 text-gray-900 dark:text-white focus:outline-none focus:ring-1 focus:ring-blue-500 focus:border-transparent text-sm"/>
20-
21-
<Button type="primary"
22-
:icon-only="true"
23-
:icon="Folder"
24-
@click="selectExecuteHome">
25-
</Button>
26-
</div>
27-
</div>
28-
29-
<div>
30-
<label class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2">
31-
文件后缀名
32-
</label>
33-
<div class="flex gap-2">
34-
<input v-model="pluginConfig.extension"
35-
type="text"
36-
placeholder="输入文件后缀名"
37-
class="flex-1 px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-md bg-white dark:bg-gray-700 text-gray-900 dark:text-white focus:outline-none focus:ring-1 focus:ring-blue-500 focus:border-transparent text-sm"/>
38-
</div>
39-
</div>
40-
41-
<div>
42-
<label class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2">
43-
编译前执行的命令
44-
</label>
45-
<div class="flex gap-2">
46-
<input v-model="pluginConfig.before_compile"
47-
type="text"
48-
placeholder="编译前执行的命令"
49-
class="flex-1 px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-md bg-white dark:bg-gray-700 text-gray-900 dark:text-white focus:outline-none focus:ring-1 focus:ring-blue-500 focus:border-transparent text-sm"/>
50-
</div>
51-
</div>
52-
53-
<div>
54-
<label class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2">
55-
执行的命令
56-
</label>
57-
<div class="flex flex-col space-y-1.5">
58-
<input v-model="pluginConfig.run_command"
59-
type="text"
60-
placeholder="执行的命令"
61-
class="flex-1 px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-md bg-white dark:bg-gray-700 text-gray-900 dark:text-white focus:outline-none focus:ring-1 focus:ring-blue-500 focus:border-transparent text-sm"/>
62-
63-
<div class="flex text-sm font-medium text-gray-700 dark:text-gray-300 ml-1 space-x-4">
64-
<div class="font-bold">$filename</div>
65-
<div>执行的源文件或临时生成的文件</div>
10+
<Tabs v-model="activeTab" type="card" size="md" :tabs="tabsData">
11+
<template #general>
12+
<div class="space-y-4">
13+
<div>
14+
<label class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2">
15+
编译前执行的命令
16+
</label>
17+
<div class="flex gap-2">
18+
<input v-model="pluginConfig.before_compile"
19+
type="text"
20+
placeholder="编译前执行的命令"
21+
class="flex-1 px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-md bg-white dark:bg-gray-700 text-gray-900 dark:text-white focus:outline-none focus:ring-1 focus:ring-blue-500 focus:border-transparent text-sm"/>
22+
</div>
23+
</div>
24+
25+
<div>
26+
<label class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2">
27+
执行的命令
28+
</label>
29+
<div class="flex flex-col space-y-1.5">
30+
<input v-model="pluginConfig.run_command"
31+
type="text"
32+
placeholder="执行的命令"
33+
class="flex-1 px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-md bg-white dark:bg-gray-700 text-gray-900 dark:text-white focus:outline-none focus:ring-1 focus:ring-blue-500 focus:border-transparent text-sm"/>
34+
35+
<div class="flex text-sm font-medium text-gray-700 dark:text-gray-300 ml-1 space-x-4">
36+
<div class="font-bold">$filename</div>
37+
<div>执行的源文件或临时生成的文件</div>
38+
</div>
39+
</div>
40+
</div>
41+
42+
<div>
43+
<label class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2">
44+
编译完成后执行的命令
45+
</label>
46+
<div class="flex gap-2">
47+
<input v-model="pluginConfig.after_compile"
48+
type="text"
49+
placeholder="编译完成后执行的命令"
50+
class="flex-1 px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-md bg-white dark:bg-gray-700 text-gray-900 dark:text-white focus:outline-none focus:ring-1 focus:ring-blue-500 focus:border-transparent text-sm"/>
51+
</div>
52+
</div>
53+
54+
<div>
55+
<label class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2">
56+
文件后缀名
57+
</label>
58+
<div class="flex gap-2">
59+
<input v-model="pluginConfig.extension"
60+
type="text"
61+
placeholder="输入文件后缀名"
62+
class="flex-1 px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-md bg-white dark:bg-gray-700 text-gray-900 dark:text-white focus:outline-none focus:ring-1 focus:ring-blue-500 focus:border-transparent text-sm"/>
63+
</div>
6664
</div>
6765
</div>
68-
</div>
69-
70-
<div>
71-
<label class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2">
72-
编译完成后执行的命令
73-
</label>
74-
<div class="flex gap-2">
75-
<input v-model="pluginConfig.after_compile"
76-
type="text"
77-
placeholder="编译完成后执行的命令"
78-
class="flex-1 px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-md bg-white dark:bg-gray-700 text-gray-900 dark:text-white focus:outline-none focus:ring-1 focus:ring-blue-500 focus:border-transparent text-sm"/>
66+
</template>
67+
68+
<template #environment>
69+
<div>
70+
<label class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2">
71+
语言环境目录
72+
</label>
73+
<div class="flex gap-2">
74+
<input v-model="pluginConfig.execute_home"
75+
type="text"
76+
placeholder="选择语言环境目录路径"
77+
class="flex-1 px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-md bg-white dark:bg-gray-700 text-gray-900 dark:text-white focus:outline-none focus:ring-1 focus:ring-blue-500 focus:border-transparent text-sm"/>
78+
79+
<Button type="primary"
80+
:icon-only="true"
81+
:icon="Folder"
82+
@click="selectExecuteHome">
83+
</Button>
84+
</div>
7985
</div>
80-
</div>
81-
82-
<div>
83-
<label class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2">
84-
超时时间(秒)
85-
</label>
86-
<div class="flex gap-2">
87-
<input v-model="pluginConfig.timeout"
88-
type="number"
89-
placeholder="超时时间(秒),默认 30 秒"
90-
class="flex-1 px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-md bg-white dark:bg-gray-700 text-gray-900 dark:text-white focus:outline-none focus:ring-1 focus:ring-blue-500 focus:border-transparent text-sm"/>
86+
</template>
87+
88+
<template #template>
89+
<div>
90+
<label class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2">
91+
文件模板
92+
</label>
93+
<div class="flex">
94+
<textarea v-model="pluginConfig.template"
95+
placeholder="文件模板"
96+
rows="20"
97+
class="flex-1 px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-md bg-white dark:bg-gray-700 text-gray-900 dark:text-white focus:outline-none focus:ring-1 focus:ring-blue-500 focus:border-transparent text-sm"/>
98+
</div>
9199
</div>
92-
</div>
93-
94-
<div>
95-
<label class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2">
96-
文件模板
97-
</label>
98-
<div class="flex">
99-
<textarea v-model="pluginConfig.template"
100-
placeholder="文件模板"
101-
cols="6"
102-
class="flex-1 px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-md bg-white dark:bg-gray-700 text-gray-900 dark:text-white focus:outline-none focus:ring-1 focus:ring-blue-500 focus:border-transparent text-sm"/>
100+
</template>
101+
102+
<template #advanced>
103+
<div>
104+
<label class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2">
105+
超时时间(秒)
106+
</label>
107+
<div class="flex gap-2">
108+
<input v-model="pluginConfig.timeout"
109+
type="number"
110+
placeholder="超时时间(秒),默认 30 秒"
111+
class="flex-1 px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-md bg-white dark:bg-gray-700 text-gray-900 dark:text-white focus:outline-none focus:ring-1 focus:ring-blue-500 focus:border-transparent text-sm"/>
112+
</div>
103113
</div>
104-
</div>
105-
</div>
114+
</template>
115+
</Tabs>
106116
</template>
107117
</Tabs>
108118
</div>
@@ -113,7 +123,7 @@ import { onMounted, ref, watch } from 'vue'
113123
import { invoke } from '@tauri-apps/api/core'
114124
import { debounce } from 'lodash-es'
115125
import { open as openDialog } from '@tauri-apps/plugin-dialog'
116-
import { Folder, Settings2 } from 'lucide-vue-next'
126+
import { ContainerIcon, FileIcon, Folder, LanguagesIcon, PickaxeIcon, Settings2 } from 'lucide-vue-next'
117127
import Button from '../../ui/Button.vue'
118128
import { useToast } from '../../plugins/toast'
119129
import Tabs from '../../ui/Tabs.vue'
@@ -126,8 +136,33 @@ const emit = defineEmits<{
126136
127137
const toast = useToast()
128138
129-
const activeTab = ref('')
130-
const tabsData = ref([] as any[])
139+
const activePlugin = ref('')
140+
const tabsPluginData = ref([] as any[])
141+
142+
const activeTab = ref('general')
143+
const tabsData = [
144+
{
145+
key: 'general',
146+
label: '通用配置',
147+
icon: Settings2
148+
},
149+
{
150+
'key': 'environment',
151+
'label': '环境配置',
152+
'icon': ContainerIcon
153+
},
154+
{
155+
key: 'template',
156+
label: '模板配置',
157+
icon: FileIcon
158+
},
159+
{
160+
key: 'advanced',
161+
label: '高级配置',
162+
icon: PickaxeIcon
163+
}
164+
]
165+
131166
const globalConfig = ref(null as any)
132167
const pluginConfig = ref<PluginConfig>({
133168
enabled: false,
@@ -144,18 +179,19 @@ const pluginConfig = ref<PluginConfig>({
144179
const getSupportedLanguages = async () => {
145180
try {
146181
const languages = await invoke<any[]>('get_supported_languages')
147-
tabsData.value = languages.map((language) => ({
182+
tabsPluginData.value = languages.map((language) => ({
148183
key: language.value,
149-
label: language.name
184+
label: language.name,
185+
svgUrl: `/icons/${ language.value.replace(/\d+$/, '') }.svg`
150186
}))
151187
152-
if (tabsData.value.length > 0 && !activeTab.value) {
153-
activeTab.value = tabsData.value[0].key
188+
if (tabsPluginData.value.length > 0 && !activePlugin.value) {
189+
activePlugin.value = tabsPluginData.value[0].key
154190
}
155191
}
156192
catch (error) {
157193
toast.error('获取支持的语言失败 - 错误信息: ' + error)
158-
tabsData.value = []
194+
tabsPluginData.value = []
159195
}
160196
}
161197
@@ -172,7 +208,7 @@ const getConfigure = async () => {
172208
173209
const handleTabChange = () => {
174210
if (globalConfig.value && globalConfig.value.plugins) {
175-
pluginConfig.value = globalConfig.value.plugins.find((plugin: any) => plugin.language === activeTab.value)
211+
pluginConfig.value = globalConfig.value.plugins.find((plugin: any) => plugin.language === activePlugin.value)
176212
}
177213
}
178214
@@ -209,7 +245,7 @@ const updateGlobalConfig = async (updatedPlugin: PluginConfig) => {
209245
210246
try {
211247
await invoke('update_app_config', { config: globalConfig.value })
212-
toast.success(`${ tabsData.value.find((tab: any) => tab.key === updatedPlugin.language).label } 配置已保存`)
248+
toast.success(`${ tabsPluginData.value.find((tab: any) => tab.key === updatedPlugin.language).label } 配置已保存`)
213249
emit('settings-changed', updatedPlugin)
214250
}
215251
catch (error) {

src/ui/Tabs.vue

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,14 @@
2121
:aria-controls="`tabpanel-${tab.key || tab.name || index}`"
2222
role="tab"
2323
:tabindex="isActiveTab(tab) ? 0 : -1">
24-
<!-- 图标 -->
25-
<component v-if="tab.icon" :is="tab.icon" :class="iconClasses"/>
24+
<!-- 如果是组件图标 -->
25+
<component v-if="tab.icon && !tab.svgIcon" :is="tab.icon" :class="iconClasses"/>
26+
27+
<!-- 如果是SVG字符串 -->
28+
<div v-else-if="tab.svgIcon" v-html="tab.svgIcon" :class="iconClasses"/>
29+
30+
<!-- 如果是SVG URL -->
31+
<img v-else-if="tab.svgUrl" :src="tab.svgUrl" :class="iconClasses" alt="icon"/>
2632

2733
<!-- 文本 -->
2834
<span v-if="tab.label || tab.name" class="tab-text">
@@ -91,6 +97,8 @@ export interface Tab
9197
content?: Component
9298
html?: string
9399
text?: string
100+
svgIcon?: string
101+
svgUrl?: string
94102
95103
[key: string]: any
96104
}

0 commit comments

Comments
 (0)