feat: Refactor PromptPanel with Modal and dynamic template selection

- Replace inline iterate input with Modal component
- Add dynamic template type and title text computation
- Improve template selection and iteration UI
- Enhance component flexibility and reusability
- Update z-index for TemplateManager modal
This commit is contained in:
linshen committed 2025-02-11 20:41:59 +08:00
1 parent 8959812149
commit 3f2ddc3e61
4 files changed
+137 -27

No files matched your search

+84
View File
@@ -0,0 +1,84 @@
<template>
<Teleport to="body">
<Transition
enter-active-class="transition duration-200 ease-out"
enter-from-class="transform scale-95 opacity-0"
enter-to-class="transform scale-100 opacity-100"
leave-active-class="transition duration-200 ease-in"
leave-from-class="transform scale-100 opacity-100"
leave-to-class="transform scale-95 opacity-0"
>
<div v-if="modelValue" class="fixed inset-0 z-30 overflow-y-auto" @click="handleBackdropClick">
<div class="flex min-h-full items-center justify-center p-4">
<!-- 背景遮罩 -->
<div class="fixed inset-0 bg-black/60 transition-opacity"></div>
<!-- 弹窗内容 -->
<div
class="relative bg-gray-900 rounded-xl border border-purple-600/50 w-full max-w-lg transform transition-all"
@click.stop
>
<!-- 标题栏 -->
<div class="flex items-center justify-between p-4 border-b border-purple-600/30">
<h3 class="text-lg font-semibold text-white/90">
<slot name="title">标题</slot>
</h3>
<button
@click="$emit('update:modelValue', false)"
class="text-white/70 hover:text-white/90 transition-colors"
>
<svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12" />
</svg>
</button>
</div>
<!-- 内容区域 -->
<div class="p-4">
<slot></slot>
</div>
<!-- 按钮区域 -->
<div class="flex justify-end space-x-3 px-4 py-3 border-t border-purple-600/30">
<slot name="footer">
<button
@click="$emit('update:modelValue', false)"
class="px-4 py-2 text-sm text-white/70 hover:text-white/90 transition-colors"
>
取消
</button>
<button
@click="$emit('confirm')"
class="px-4 py-2 text-sm bg-purple-600 hover:bg-purple-500 text-white rounded-lg transition-colors"
>
确认
</button>
</slot>
</div>
</div>
</div>
</div>
</Transition>
</Teleport>
</template>
<script setup>
import { defineProps, defineEmits } from 'vue'
defineProps({
modelValue: {
type: Boolean,
required: true
}
})
defineEmits(['update:modelValue', 'confirm'])
const handleBackdropClick = (event) => {
if (event.target === event.currentTarget) {
event.stopPropagation()
event.preventDefault()
emit('update:modelValue', false)
}
}
</script>
+47 -25
View File
@@ -35,50 +35,61 @@
</div>
</div>
<!-- 迭代优化输入框 -->
<div v-if="showIterateInput" class="mt-4">
<div class="bg-black/20 rounded-xl border border-purple-600/50 p-4">
<h4 class="text-sm font-medium text-white/90 mb-2">请输入需要优化的方向:</h4>
<div class="mb-3">
<!-- 迭代优化弹窗 -->
<Modal
v-model="showIterateInput"
@confirm="submitIterate"
>
<template #title>
{{ templateTitleText }}
</template>
<div class="space-y-4">
<div>
<h4 class="text-sm font-medium text-white/90 mb-2">{{ templateSelectText }}</h4>
<TemplateSelect
:modelValue="selectedIterateTemplate"
@update:modelValue="$emit('update:selectedIterateTemplate', $event)"
type="iterate"
@manage="$emit('openTemplateManager', 'iterate')"
:type="templateType"
@manage="$emit('openTemplateManager', templateType)"
/>
</div>
<div class="flex flex-col space-y-3">
<div>
<h4 class="text-sm font-medium text-white/90 mb-2">请输入需要优化的方向:</h4>
<textarea
v-model="iterateInput"
class="w-full bg-black/30 border-none rounded-lg p-3 text-white/90 placeholder-gray-400 text-sm resize-none focus:ring-2 focus:ring-purple-500/50"
placeholder="例如:使提示词更简洁、增加特定功能描述等..."
rows="3"
></textarea>
<div class="flex justify-end space-x-3">
<button
@click="cancelIterate"
class="px-4 py-2 text-sm text-white/70 hover:text-white/90 transition-colors"
>
取消
</button>
<button
@click="submitIterate"
class="px-4 py-2 text-sm bg-purple-600 hover:bg-purple-500 text-white rounded-lg transition-colors disabled:opacity-50 disabled:cursor-not-allowed"
:disabled="!iterateInput.trim() || isIterating"
>
{{ isIterating ? '优化中...' : '确认优化' }}
</button>
</div>
</div>
</div>
</div>
<template #footer>
<button
@click="cancelIterate"
class="px-4 py-2 text-sm text-white/70 hover:text-white/90 transition-colors"
>
取消
</button>
<button
@click="submitIterate"
class="px-4 py-2 text-sm bg-purple-600 hover:bg-purple-500 text-white rounded-lg transition-colors disabled:opacity-50 disabled:cursor-not-allowed"
:disabled="!iterateInput.trim() || isIterating"
>
{{ isIterating ? '优化中...' : '确认优化' }}
</button>
</template>
</Modal>
</div>
</template>
<script setup>
import { ref, defineProps, defineEmits } from 'vue'
import { ref, defineProps, defineEmits, computed } from 'vue'
import { useToast } from '../composables/useToast'
import TemplateSelect from './TemplateSelect.vue'
import Modal from './Modal.vue'
const toast = useToast()
const promptTextarea = ref(null)
@@ -102,6 +113,17 @@ const emit = defineEmits(['update:optimizedPrompt', 'iterate', 'openTemplateMana
const showIterateInput = ref(false)
const iterateInput = ref('')
const templateType = ref('iterate')
// 计算标题文本
const templateTitleText = computed(() => {
return '迭代功能提示词'
})
// 计算模板选择标题
const templateSelectText = computed(() => {
return '请选择迭代提示词:'
})
// 处理输入变化
const handleInput = (event) => {
+1 -1
View File
@@ -1,6 +1,6 @@
<template>
<div
class="fixed inset-0 bg-black bg-opacity-50 z-50 flex items-center justify-center overflow-y-auto"
class="fixed inset-0 bg-black bg-opacity-50 z-[60] flex items-center justify-center overflow-y-auto"
@click="$emit('close')"
>
<div
+5 -1
View File
@@ -8,7 +8,7 @@
>
<div class="flex items-center justify-between">
<div class="flex items-center space-x-2">
<span class="text-white/60">优化功能提示词:</span>
<span class="text-white/60">{{ typeText }}:</span>
<span v-if="modelValue" class="text-purple-300 group-hover:text-purple-200">
{{ modelValue.name }}
</span>
@@ -85,6 +85,10 @@ const emit = defineEmits(['update:modelValue', 'manage'])
const isOpen = ref(false)
const typeText = computed(() => {
return props.type === 'iterate' ? '迭代功能提示词' : '优化功能提示词'
})
const templates = computed(() =>
templateManager.listTemplatesByType(props.type)
)