Skip to content

Commit c1bf0f2

Browse files
committed
feat(ui): 为模板编辑器添加全屏编辑功能
- 在简单模板和高级模板消息编辑区域添加全屏编辑按钮 - 新增全屏编辑器模态框,提供更大的编辑空间 - 添加字符计数显示功能 - 优化文本域自动高度调整(minRows/maxRows) - 使用 NSpace、NText 等 Naive UI 组件替换原生 HTML 标签 - 添加中英繁三语翻译支持
1 parent 261370f commit c1bf0f2

File tree

4 files changed

+161
-32
lines changed

4 files changed

+161
-32
lines changed

packages/ui/src/components/TemplateManager.vue

Lines changed: 146 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -323,31 +323,47 @@
323323
</div>
324324

325325
<!-- Simple Template Editor -->
326-
<div v-if="!form.isAdvanced">
327-
<label class="block text-sm font-medium mb-1.5">
328-
{{ t('template.content') }}
329-
<span class="text-xs ml-2 opacity-70">
330-
{{ t('templateManager.simpleTemplateHint') }}
331-
</span>
332-
</label>
326+
<NSpace v-if="!form.isAdvanced" vertical :size="8">
327+
<NSpace justify="space-between" align="center">
328+
<NText>
329+
{{ t('template.content') }}
330+
<NText depth="3" style="font-size: 12px; margin-left: 8px;">
331+
{{ t('templateManager.simpleTemplateHint') }}
332+
</NText>
333+
</NText>
334+
<NButton
335+
v-if="!viewingTemplate"
336+
size="tiny"
337+
quaternary
338+
@click="openFullscreenEditor('simple')"
339+
:title="t('templateManager.fullscreenEdit')"
340+
>
341+
<template #icon>
342+
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-4 h-4">
343+
<path stroke-linecap="round" stroke-linejoin="round" d="M3.75 3.75v4.5m0-4.5h4.5m-4.5 0L9 9M3.75 20.25v-4.5m0 4.5h4.5m-4.5 0L9 15M20.25 3.75h-4.5m4.5 0v4.5m0-4.5L15 9m5.25 11.25h-4.5m4.5 0v-4.5m0 4.5L15 15" />
344+
</svg>
345+
</template>
346+
{{ t('templateManager.fullscreen') }}
347+
</NButton>
348+
</NSpace>
333349
<NInput
334350
v-model:value="form.content"
335351
type="textarea"
336352
:placeholder="t('template.contentPlaceholder')"
337-
:rows="15"
353+
:autosize="{ minRows: 15, maxRows: 30 }"
338354
:readonly="!!viewingTemplate"
339355
/>
340-
</div>
356+
</NSpace>
341357

342358
<!-- Advanced Template Editor -->
343-
<div v-else>
344-
<div class="flex items-center justify-between mb-3">
345-
<label class="block text-sm font-medium">
359+
<NSpace v-else vertical :size="12">
360+
<NSpace justify="space-between" align="center">
361+
<NText>
346362
{{ t('templateManager.messageTemplates') }}
347-
<span class="text-xs ml-2 opacity-70">
363+
<NText depth="3" style="font-size: 12px; margin-left: 8px;">
348364
{{ t('templateManager.advancedTemplateHint') }}
349-
</span>
350-
</label>
365+
</NText>
366+
</NText>
351367
<NButton
352368
v-if="!viewingTemplate"
353369
@click="addMessage"
@@ -361,7 +377,7 @@
361377
</template>
362378
{{ t('templateManager.addMessage') }}
363379
</NButton>
364-
</div>
380+
</NSpace>
365381

366382
<!-- Message List -->
367383
<NScrollbar style="max-height: 500px;">
@@ -384,19 +400,35 @@
384400
{ label: t('templateManager.roleAssistant'), value: 'assistant' }
385401
]"
386402
/>
387-
403+
388404
<!-- Message Content -->
389-
<NInput
390-
v-model:value="message.content"
391-
type="textarea"
392-
:placeholder="t('templateManager.messageContentPlaceholder')"
393-
:rows="3"
394-
:readonly="!!viewingTemplate"
395-
class="flex-1"
396-
/>
397-
405+
<NSpace vertical :size="4" style="flex: 1;">
406+
<NInput
407+
v-model:value="message.content"
408+
type="textarea"
409+
:placeholder="t('templateManager.messageContentPlaceholder')"
410+
:autosize="{ minRows: 3, maxRows: 20 }"
411+
:readonly="!!viewingTemplate"
412+
/>
413+
<NButton
414+
v-if="!viewingTemplate"
415+
size="tiny"
416+
quaternary
417+
@click="openFullscreenEditor('advanced', index)"
418+
:title="t('templateManager.fullscreenEdit')"
419+
style="align-self: flex-end;"
420+
>
421+
<template #icon>
422+
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-3 h-3">
423+
<path stroke-linecap="round" stroke-linejoin="round" d="M3.75 3.75v4.5m0-4.5h4.5m-4.5 0L9 9M3.75 20.25v-4.5m0 4.5h4.5m-4.5 0L9 15M20.25 3.75h-4.5m4.5 0v4.5m0-4.5L15 9m5.25 11.25h-4.5m4.5 0v-4.5m0 4.5L15 15" />
424+
</svg>
425+
</template>
426+
{{ t('templateManager.fullscreen') }}
427+
</NButton>
428+
</NSpace>
429+
398430
<!-- Message Controls -->
399-
<div v-if="!viewingTemplate" class="flex flex-col gap-1 flex-shrink-0">
431+
<NSpace v-if="!viewingTemplate" vertical :size="4" style="flex-shrink: 0;">
400432
<NButton
401433
quaternary
402434
size="tiny"
@@ -433,12 +465,12 @@
433465
</svg>
434466
</template>
435467
</NButton>
436-
</div>
468+
</NSpace>
437469
</div>
438470
</NCard>
439471
</NSpace>
440472
</NScrollbar>
441-
</div>
473+
</NSpace>
442474

443475
<!-- Template Preview -->
444476
<div v-if="form.isAdvanced && form.messages.length > 0">
@@ -553,17 +585,57 @@
553585
</NSpace>
554586
</template>
555587
</NModal>
588+
589+
<!-- Fullscreen Editor Modal -->
590+
<NModal
591+
:show="fullscreenEditor.show"
592+
preset="card"
593+
:style="{ width: '95vw', height: '90vh', maxWidth: '1400px' }"
594+
:title="t('templateManager.fullscreenEdit')"
595+
size="large"
596+
:bordered="false"
597+
:segmented="true"
598+
@update:show="(value: boolean) => !value && closeFullscreenEditor()"
599+
>
600+
<NEl style="height: calc(90vh - 140px);">
601+
<NInput
602+
v-model:value="fullscreenEditor.content"
603+
type="textarea"
604+
:placeholder="fullscreenEditor.type === 'simple'
605+
? t('template.contentPlaceholder')
606+
: t('templateManager.messageContentPlaceholder')"
607+
style="height: 100%;"
608+
:autosize="false"
609+
/>
610+
</NEl>
611+
612+
<template #action>
613+
<NSpace justify="space-between" style="width: 100%;">
614+
<NText depth="3" style="font-size: 12px;">
615+
{{ t('templateManager.characterCount', { count: fullscreenEditor.content.length }) }}
616+
</NText>
617+
<NSpace>
618+
<NButton @click="closeFullscreenEditor()">
619+
{{ t('common.cancel') }}
620+
</NButton>
621+
<NButton type="primary" @click="saveFullscreenEditor">
622+
{{ t('common.save') }}
623+
</NButton>
624+
</NSpace>
625+
</NSpace>
626+
</template>
627+
</NModal>
556628
</NModal>
557629
</template>
558630

559631
<script setup lang="ts">
560632
import { ref, onMounted, computed, watch, nextTick, inject } from 'vue'
561633
import { useI18n } from 'vue-i18n'
562-
import {
563-
NModal, NCard, NTabs, NTabPane, NButton, NTag, NInput, NInputGroup,
634+
import {
635+
NModal, NCard, NTabs, NTabPane, NButton, NTag, NInput, NInputGroup,
564636
NSelect, NSpace, NText, NH3, NH4, NDivider, NScrollbar,
565637
NButtonGroup, NIcon, NCode, NSwitch, NMessageProvider,
566-
NGrid, NGridItem
638+
NGrid, NGridItem, NEl
567639
} from 'naive-ui'
568640
import { TemplateProcessor, type Template, type MessageTemplate } from '@prompt-optimizer/core'
569641
import { useToast } from '../composables/useToast'
@@ -643,6 +715,18 @@ const migrationDialog = ref<{
643715
converted: []
644716
})
645717
718+
const fullscreenEditor = ref<{
719+
show: boolean
720+
type: 'simple' | 'advanced'
721+
messageIndex: number
722+
content: string
723+
}>({
724+
show: false,
725+
type: 'simple',
726+
messageIndex: -1,
727+
content: ''
728+
})
729+
646730
// 添加计算属性
647731
const selectedTemplate = computed(() => {
648732
switch (props.templateType) {
@@ -983,6 +1067,36 @@ const applyMigration = async () => {
9831067
}
9841068
}
9851069
1070+
// 打开全屏编辑器
1071+
const openFullscreenEditor = (type: 'simple' | 'advanced', messageIndex = -1) => {
1072+
fullscreenEditor.value = {
1073+
show: true,
1074+
type,
1075+
messageIndex,
1076+
content: type === 'simple' ? form.value.content : form.value.messages[messageIndex]?.content || ''
1077+
}
1078+
}
1079+
1080+
// 关闭全屏编辑器
1081+
const closeFullscreenEditor = () => {
1082+
fullscreenEditor.value = {
1083+
show: false,
1084+
type: 'simple',
1085+
messageIndex: -1,
1086+
content: ''
1087+
}
1088+
}
1089+
1090+
// 保存全屏编辑器内容
1091+
const saveFullscreenEditor = () => {
1092+
if (fullscreenEditor.value.type === 'simple') {
1093+
form.value.content = fullscreenEditor.value.content
1094+
} else if (fullscreenEditor.value.messageIndex >= 0) {
1095+
form.value.messages[fullscreenEditor.value.messageIndex].content = fullscreenEditor.value.content
1096+
}
1097+
closeFullscreenEditor()
1098+
}
1099+
9861100
// 提交表单
9871101
const handleSubmit = async () => {
9881102
try {

packages/ui/src/i18n/locales/en-US.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -531,6 +531,11 @@ export default {
531531
// Preview
532532
preview: 'Preview',
533533

534+
// Fullscreen Edit
535+
fullscreen: 'Fullscreen',
536+
fullscreenEdit: 'Fullscreen Edit',
537+
characterCount: '{count} characters',
538+
534539
// Migration
535540
convertToAdvanced: 'Convert to Advanced Format',
536541
migrationDescription: 'Convert simple template to advanced message format for more flexible control.',

packages/ui/src/i18n/locales/zh-CN.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -531,6 +531,11 @@
531531
// 预览
532532
preview: '预览',
533533

534+
// 全屏编辑
535+
fullscreen: '全屏',
536+
fullscreenEdit: '全屏编辑',
537+
characterCount: '{count} 个字符',
538+
534539
// 迁移
535540
convertToAdvanced: '转换为高级格式',
536541
migrationDescription: '将简单模板转换为高级消息格式,提供更灵活的控制能力。',

packages/ui/src/i18n/locales/zh-TW.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -531,6 +531,11 @@ export default {
531531
// 預覽
532532
preview: '預覽',
533533

534+
// 全螢幕編輯
535+
fullscreen: '全螢幕',
536+
fullscreenEdit: '全螢幕編輯',
537+
characterCount: '{count} 個字符',
538+
534539
// 遷移
535540
convertToAdvanced: '轉換為進階格式',
536541
migrationDescription: '將簡單範本轉換為進階訊息格式,提供更靈活的控制能力。',

0 commit comments

Comments
 (0)