feat: add approve/reject buttons for wait_for_approval

- CommentSection shows explicit approve/reject buttons when waiting
- Reject aborts the workflow, approve continues with optional feedback
- Backend parses approved:/rejected: prefixes from comment content
This commit is contained in:
Fam Zheng
2026-03-07 16:41:15 +00:00
parent 938ba83f37
commit 47546a9d15
2 changed files with 91 additions and 11 deletions

View File

@@ -15,12 +15,8 @@ const emit = defineEmits<{
const input = ref('')
const textareaRef = ref<HTMLTextAreaElement | null>(null)
function submit() {
if (props.disabled) return
function buildText(): string {
const text = input.value.trim()
if (!text && !props.quotes.length) return
// Build final text: quotes as block references, then user text
let final = ''
for (const q of props.quotes) {
final += `> ${q}\n`
@@ -29,8 +25,27 @@ function submit() {
final += '\n'
}
final += text
return final.trim()
}
emit('submit', final.trim())
function submit() {
if (props.disabled) return
const text = input.value.trim()
if (!text && !props.quotes.length) return
emit('submit', buildText())
input.value = ''
}
function approve() {
const feedback = buildText()
emit('submit', feedback ? `approved: ${feedback}` : 'approved:')
input.value = ''
}
function reject() {
const feedback = buildText()
emit('submit', feedback ? `rejected: ${feedback}` : 'rejected: 用户终止')
input.value = ''
}
@@ -53,7 +68,7 @@ defineExpose({ focusInput })
<template>
<div class="comment-section" :class="{ 'waiting-approval': waitingApproval }">
<div v-if="waitingApproval" class="approval-banner">
Agent 正在等待你的确认请在下方输入反馈后发送
Agent 正在等待你的确认
</div>
<div v-if="quotes.length" class="quotes-bar">
<div v-for="(q, i) in quotes" :key="i" class="quote-chip">
@@ -65,11 +80,15 @@ defineExpose({ focusInput })
<textarea
ref="textareaRef"
v-model="input"
:placeholder="quotes.length ? '添加你的评论...' : '输入反馈或调整指令... (Ctrl+Enter 发送)'"
:placeholder="waitingApproval ? '可选:附加反馈或修改意见...' : (quotes.length ? '添加你的评论...' : '输入反馈或调整指令... (Ctrl+Enter 发送)')"
rows="3"
@keydown="onKeydown"
/>
<button class="btn-send" :disabled="disabled || (!input.trim() && !quotes.length)" @click="submit">发送</button>
<div v-if="waitingApproval" class="approval-buttons">
<button class="btn-approve" @click="approve">继续执行</button>
<button class="btn-reject" @click="reject">终止</button>
</div>
<button v-else class="btn-send" :disabled="disabled || (!input.trim() && !quotes.length)" @click="submit">发送</button>
</div>
</div>
</template>
@@ -178,4 +197,40 @@ defineExpose({ focusInput })
.btn-send:hover {
background: var(--accent-hover);
}
.approval-buttons {
display: flex;
flex-direction: column;
gap: 6px;
}
.btn-approve {
background: #4caf50;
color: #fff;
font-weight: 600;
padding: 8px 20px;
border: none;
border-radius: 6px;
cursor: pointer;
white-space: nowrap;
}
.btn-approve:hover {
background: #43a047;
}
.btn-reject {
background: transparent;
color: var(--error, #ef5350);
font-weight: 500;
padding: 6px 20px;
border: 1px solid var(--error, #ef5350);
border-radius: 6px;
cursor: pointer;
white-space: nowrap;
}
.btn-reject:hover {
background: rgba(239, 83, 80, 0.1);
}
</style>