- Rewrite template.rs to scan all remote branches via git commands (git fetch/branch -r/ls-tree/git show/git archive) - Add manual template picker dropdown in CreateForm UI - Remove sentence-transformers/embed.py from Dockerfile (separate container) - Clean up Gitea API approach, use local git repo instead - Add chat panel and sidebar layout improvements
183 lines
3.8 KiB
Vue
183 lines
3.8 KiB
Vue
<script setup lang="ts">
|
|
import { ref, onMounted } from 'vue'
|
|
import { api } from '../api'
|
|
import examples from '../examples.json'
|
|
|
|
const emit = defineEmits<{
|
|
submit: [requirement: string, templateId?: string]
|
|
cancel: []
|
|
}>()
|
|
|
|
const requirement = ref('')
|
|
const inputEl = ref<HTMLTextAreaElement>()
|
|
const templates = ref<{ id: string; name: string; description: string }[]>([])
|
|
const selectedTemplate = ref('')
|
|
|
|
onMounted(async () => {
|
|
inputEl.value?.focus()
|
|
try {
|
|
templates.value = await api.listTemplates()
|
|
} catch {
|
|
// ignore — templates dropdown just won't show
|
|
}
|
|
})
|
|
|
|
function onSubmit() {
|
|
const text = requirement.value.trim()
|
|
if (text) emit('submit', text, selectedTemplate.value || undefined)
|
|
}
|
|
</script>
|
|
|
|
<template>
|
|
<div class="create-form">
|
|
<h2>输入你的需求</h2>
|
|
<div class="create-examples">
|
|
<span
|
|
v-for="ex in examples"
|
|
:key="ex.label"
|
|
class="example-tag"
|
|
@click="requirement = Array.isArray(ex.text) ? ex.text.join('\n') : ex.text"
|
|
>{{ ex.label }}</span>
|
|
</div>
|
|
<textarea
|
|
ref="inputEl"
|
|
v-model="requirement"
|
|
class="create-textarea"
|
|
placeholder="描述你想让 AI 做什么..."
|
|
rows="4"
|
|
@keydown.ctrl.enter="onSubmit"
|
|
@keydown.meta.enter="onSubmit"
|
|
/>
|
|
<div v-if="templates.length" class="template-select">
|
|
<label>模板</label>
|
|
<select v-model="selectedTemplate">
|
|
<option value="">自动选择</option>
|
|
<option v-for="t in templates" :key="t.id" :value="t.id">{{ t.name }}</option>
|
|
</select>
|
|
</div>
|
|
<div class="create-hint">Ctrl+Enter 提交</div>
|
|
<div class="create-actions">
|
|
<button class="btn-cancel" @click="emit('cancel')">取消</button>
|
|
<button class="btn-confirm" @click="onSubmit" :disabled="!requirement.trim()">开始</button>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
|
|
<style scoped>
|
|
.create-form {
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 12px;
|
|
width: 480px;
|
|
}
|
|
|
|
.create-form h2 {
|
|
font-size: 18px;
|
|
font-weight: 600;
|
|
color: var(--text-primary);
|
|
}
|
|
|
|
.create-examples {
|
|
display: flex;
|
|
flex-wrap: wrap;
|
|
gap: 8px;
|
|
}
|
|
|
|
.example-tag {
|
|
padding: 4px 10px;
|
|
font-size: 12px;
|
|
background: var(--bg-tertiary);
|
|
color: var(--text-secondary);
|
|
border: 1px solid var(--border);
|
|
border-radius: 12px;
|
|
cursor: pointer;
|
|
transition: all 0.15s;
|
|
}
|
|
|
|
.example-tag:hover {
|
|
color: var(--accent);
|
|
border-color: var(--accent);
|
|
background: rgba(79, 195, 247, 0.08);
|
|
}
|
|
|
|
.create-textarea {
|
|
padding: 10px 12px;
|
|
background: var(--bg-secondary);
|
|
border: 1px solid var(--border);
|
|
border-radius: 6px;
|
|
color: var(--text-primary);
|
|
font-size: 14px;
|
|
font-family: inherit;
|
|
outline: none;
|
|
resize: vertical;
|
|
min-height: 80px;
|
|
}
|
|
|
|
.create-textarea:focus {
|
|
border-color: var(--accent);
|
|
}
|
|
|
|
.template-select {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 8px;
|
|
}
|
|
|
|
.template-select label {
|
|
font-size: 13px;
|
|
color: var(--text-secondary);
|
|
white-space: nowrap;
|
|
}
|
|
|
|
.template-select select {
|
|
flex: 1;
|
|
padding: 6px 8px;
|
|
background: var(--bg-secondary);
|
|
border: 1px solid var(--border);
|
|
border-radius: 6px;
|
|
color: var(--text-primary);
|
|
font-size: 13px;
|
|
font-family: inherit;
|
|
outline: none;
|
|
}
|
|
|
|
.template-select select:focus {
|
|
border-color: var(--accent);
|
|
}
|
|
|
|
.create-hint {
|
|
font-size: 12px;
|
|
color: var(--text-secondary);
|
|
text-align: right;
|
|
}
|
|
|
|
.create-actions {
|
|
display: flex;
|
|
gap: 8px;
|
|
justify-content: flex-end;
|
|
}
|
|
|
|
.btn-cancel {
|
|
padding: 8px 16px;
|
|
background: var(--bg-tertiary);
|
|
color: var(--text-secondary);
|
|
border: 1px solid var(--border);
|
|
border-radius: 6px;
|
|
font-size: 13px;
|
|
}
|
|
|
|
.btn-confirm {
|
|
padding: 8px 16px;
|
|
background: var(--accent);
|
|
color: var(--bg-primary);
|
|
border: none;
|
|
border-radius: 6px;
|
|
font-size: 13px;
|
|
font-weight: 500;
|
|
}
|
|
|
|
.btn-confirm:disabled {
|
|
opacity: 0.4;
|
|
}
|
|
</style>
|