feat(ui): 计划批准弹窗支持最小化关闭,状态栏可恢复处理
- PlanApprovalDialog windowbar 新增关闭(X)按钮,点击后弹窗收起不打扰 - InputComposer 底部状态栏新增「有待批准的计划」按钮(对齐等待回答问题交互),点击恢复弹窗 - floatingStatusVisible 可见性判断纳入计划批准最小化状态,修复弹窗收起后浮栏不渲染的问题 - 批准解决后自动复位最小化状态,避免按钮残留
This commit is contained in:
parent
89bcca744d
commit
4c3d8cedc7
@ -302,6 +302,8 @@
|
||||
:project-git-summary="projectGitSummary"
|
||||
:user-question-minimized="userQuestionMinimized"
|
||||
:pending-user-question-count="pendingUserQuestions.length"
|
||||
:plan-approval-minimized="planApprovalMinimized"
|
||||
:pending-plan-approval-count="pendingPlanApprovals.length"
|
||||
:goal-mode-armed="goalModeArmed"
|
||||
:goal-running="goalRunning"
|
||||
:goal-progress="goalProgress"
|
||||
@ -319,6 +321,7 @@
|
||||
:active-sub-agent-count="activeSubAgentCount"
|
||||
:avatar-status="showStatusAvatar && messages.length > 0 ? avatarStatus : null"
|
||||
@restore-user-question="restoreUserQuestionDialog"
|
||||
@restore-plan-approval="restorePlanApprovalDialog"
|
||||
@stop-all-sub-agents="handleStopAllSubAgents"
|
||||
@update:input-message="inputSetMessage"
|
||||
@input-change="handleInputChange"
|
||||
@ -544,10 +547,11 @@
|
||||
@dismiss="dismissUserQuestions"
|
||||
/>
|
||||
<PlanApprovalDialog
|
||||
:visible="pendingPlanApprovals.length > 0"
|
||||
:visible="pendingPlanApprovals.length > 0 && !planApprovalMinimized"
|
||||
:approvals="pendingPlanApprovals"
|
||||
:submitting-ids="answeringPlanApprovalIds"
|
||||
@submit="submitPlanApproval"
|
||||
@minimize="minimizePlanApprovalDialog"
|
||||
/>
|
||||
<transition name="overlay-fade">
|
||||
<VersioningDialog
|
||||
|
||||
@ -446,6 +446,10 @@ export const toolMethods = {
|
||||
this.pendingPlanApprovals = this.pendingPlanApprovals.filter(
|
||||
(item: any) => item && String(item.approval_id || '') !== id
|
||||
);
|
||||
// 弹窗被关闭(最小化)期间批准已解决:无待批事项时复位,避免状态栏按钮残留
|
||||
if (!this.pendingPlanApprovals.length) {
|
||||
this.planApprovalMinimized = false;
|
||||
}
|
||||
// 批准后后端已切换运行模式/恢复权限与执行环境,刷新显示(多标签页同步场景)
|
||||
if (String(data?.decision || '') === 'approved') {
|
||||
this.fetchWorkMode();
|
||||
|
||||
@ -95,6 +95,18 @@ export const dialogMethods = {
|
||||
// ignore
|
||||
}
|
||||
},
|
||||
minimizePlanApprovalDialog() {
|
||||
if (!Array.isArray(this.pendingPlanApprovals) || !this.pendingPlanApprovals.length) {
|
||||
return;
|
||||
}
|
||||
this.planApprovalMinimized = true;
|
||||
},
|
||||
restorePlanApprovalDialog() {
|
||||
if (!Array.isArray(this.pendingPlanApprovals) || !this.pendingPlanApprovals.length) {
|
||||
return;
|
||||
}
|
||||
this.planApprovalMinimized = false;
|
||||
},
|
||||
async submitPlanApproval(payload) {
|
||||
const approvalId = String(payload?.approval_id || '').trim();
|
||||
if (!approvalId) {
|
||||
|
||||
@ -292,6 +292,7 @@ export function dataState() {
|
||||
pendingUserQuestions: [],
|
||||
pendingPlanApprovals: [],
|
||||
answeringPlanApprovalIds: [],
|
||||
planApprovalMinimized: false,
|
||||
userQuestionDialogVisible: false,
|
||||
userQuestionMinimized: false,
|
||||
userQuestionActiveIndex: 0,
|
||||
|
||||
@ -179,6 +179,14 @@
|
||||
>
|
||||
{{ $t('input.waitingForQuestion') }}
|
||||
</button>
|
||||
<button
|
||||
v-if="planApprovalMinimized && (pendingPlanApprovalCount || 0) > 0"
|
||||
type="button"
|
||||
class="floating-project-status__notice floating-project-status__notice--button"
|
||||
@click.stop="$emit('restore-plan-approval')"
|
||||
>
|
||||
{{ $t('input.planApprovalPending') }}
|
||||
</button>
|
||||
<button
|
||||
v-if="(activeSubAgentCount || 0) > 0"
|
||||
type="button"
|
||||
@ -698,6 +706,7 @@ const emit = defineEmits([
|
||||
'delete-runtime-message',
|
||||
'composer-height-change',
|
||||
'restore-user-question',
|
||||
'restore-plan-approval',
|
||||
'toggle-goal-mode',
|
||||
'open-goal-dialog',
|
||||
'workflow-activated',
|
||||
@ -776,6 +785,8 @@ const props = defineProps<{
|
||||
} | null;
|
||||
userQuestionMinimized?: boolean;
|
||||
pendingUserQuestionCount?: number;
|
||||
planApprovalMinimized?: boolean;
|
||||
pendingPlanApprovalCount?: number;
|
||||
goalModeArmed?: boolean;
|
||||
goalRunning?: boolean;
|
||||
goalProgress?: Record<string, any> | null;
|
||||
@ -1066,6 +1077,7 @@ const floatingStatusVisible = computed(() => {
|
||||
!!props.goalRunning ||
|
||||
!!props.goalModeArmed ||
|
||||
(Number(props.pendingUserQuestionCount || 0) > 0) ||
|
||||
(!!props.planApprovalMinimized && Number(props.pendingPlanApprovalCount || 0) > 0) ||
|
||||
(Number(props.activeSubAgentCount || 0) > 0);
|
||||
return visible;
|
||||
});
|
||||
|
||||
@ -4,6 +4,17 @@
|
||||
<section class="plan-approval-card" role="dialog" aria-modal="true" :aria-label="$t('overlay.planApprovalAriaLabel')">
|
||||
<header class="plan-approval-windowbar">
|
||||
<div class="plan-approval-window-title">{{ $t('overlay.planApprovalTitle') }}</div>
|
||||
<button
|
||||
type="button"
|
||||
class="plan-approval-close"
|
||||
:title="$t('overlay.planApprovalMinimize')"
|
||||
:aria-label="$t('overlay.planApprovalMinimize')"
|
||||
@click="emit('minimize')"
|
||||
>
|
||||
<svg viewBox="0 0 20 20" width="14" height="14" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
|
||||
<path d="M5 5l10 10M15 5L5 15" />
|
||||
</svg>
|
||||
</button>
|
||||
</header>
|
||||
|
||||
<header class="plan-approval-header">
|
||||
@ -75,6 +86,7 @@ const props = defineProps<{
|
||||
|
||||
const emit = defineEmits<{
|
||||
(event: 'submit', payload: { approval_id: string; approved: boolean; comment: string }): void;
|
||||
(event: 'minimize'): void;
|
||||
}>();
|
||||
|
||||
// 计划批准一次只处理一份(plan 模式下模型阻塞等待,天然串行);
|
||||
@ -139,6 +151,7 @@ function reject() {
|
||||
}
|
||||
|
||||
.plan-approval-windowbar {
|
||||
position: relative;
|
||||
height: 40px;
|
||||
flex: 0 0 40px;
|
||||
display: flex;
|
||||
@ -147,6 +160,29 @@ function reject() {
|
||||
border-bottom: 1px solid var(--border-default);
|
||||
}
|
||||
|
||||
.plan-approval-close {
|
||||
position: absolute;
|
||||
right: 10px;
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
width: 26px;
|
||||
height: 26px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 0;
|
||||
border: none;
|
||||
border-radius: 7px;
|
||||
background: transparent;
|
||||
color: var(--text-secondary);
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.plan-approval-close:hover {
|
||||
background: var(--hover-bg);
|
||||
color: var(--text-primary);
|
||||
}
|
||||
|
||||
.plan-approval-window-title {
|
||||
font-size: 13px;
|
||||
font-weight: 600;
|
||||
|
||||
@ -9,6 +9,7 @@ export default {
|
||||
goalModeRunning: 'Goal mode running',
|
||||
goalModeReady: 'Goal mode ready',
|
||||
waitingForQuestion: 'Waiting for your answer',
|
||||
planApprovalPending: 'Plan awaiting approval',
|
||||
subAgentsRunning: '{n} sub-agents running',
|
||||
terminalsRunning: '{n} terminals',
|
||||
quickMenuAriaLabel: 'Quick menu',
|
||||
|
||||
@ -88,6 +88,7 @@ export default {
|
||||
// ── PlanApprovalDialog ──
|
||||
planApprovalAriaLabel: 'Plan awaiting approval',
|
||||
planApprovalTitle: 'Plan awaiting approval',
|
||||
planApprovalMinimize: 'Close the dialog; restore it later from the status bar',
|
||||
planTruncatedNote: '(Content too long; preview truncated. See the file for the full content)',
|
||||
planCommentPlaceholder:
|
||||
'Feedback (optional): added as extra requirements when approving, or describe what to adjust when rejecting...',
|
||||
|
||||
@ -9,6 +9,7 @@ export default {
|
||||
goalModeRunning: '目标模式运行中',
|
||||
goalModeReady: '目标模式就绪',
|
||||
waitingForQuestion: '等待回答问题',
|
||||
planApprovalPending: '有待批准的计划',
|
||||
subAgentsRunning: '{n} 个子智能体运行中',
|
||||
terminalsRunning: '{n} 个终端',
|
||||
quickMenuAriaLabel: '快捷菜单',
|
||||
|
||||
@ -87,6 +87,7 @@ export default {
|
||||
// ── PlanApprovalDialog:计划待批准 ──
|
||||
planApprovalAriaLabel: '计划待批准',
|
||||
planApprovalTitle: '计划待批准',
|
||||
planApprovalMinimize: '关闭弹窗,稍后从状态栏恢复',
|
||||
planTruncatedNote: '(内容过长,已截断预览,完整内容见文件)',
|
||||
planCommentPlaceholder: '意见(可选):批准时作为补充要求,拒绝时说明需要调整的方向…',
|
||||
planRejectTitle: '拒绝这份计划,AI 将根据你的意见修订后重新提交',
|
||||
|
||||
Loading…
Reference in New Issue
Block a user