优化: aichat 工具体验补强(切生成会话占位气泡治丢首响应/read_symbol符号级提示/失败引导/审批失败toast) + 修复 WorkflowDagDisplay 崩页与 aiChat i18n 缺key
This commit is contained in:
@@ -129,6 +129,11 @@
|
||||
{{ $t('aiChat.popupOpenPanel') }}
|
||||
</button>
|
||||
|
||||
<!-- P1-e-d:审批失败 toast(窗口内自包含 useToast;独立 WebviewWindow 无根 toast,自管渲染) -->
|
||||
<Transition name="ai-toast">
|
||||
<div v-if="toast.visible" class="ai-toast" :class="'ai-toast-' + toast.type">{{ toast.msg }}</div>
|
||||
</Transition>
|
||||
|
||||
<!-- M5:path 类 deny 二次确认(拒绝不可逆,与 ToolCard 同款;独立窗口本地 ConfirmDialog,
|
||||
不复用主窗口 useConfirm reactive——跨 WebviewWindow JS 上下文隔离) -->
|
||||
<ConfirmDialog
|
||||
@@ -149,6 +154,7 @@ import { toolDisplayName } from '@/composables/ai/useToolCardHeader'
|
||||
import { dispatchApprovalIPC } from '@/composables/ai/useToolApproval'
|
||||
import { ApprovalPopupEvents } from '@/composables/ai/useApprovalPopup'
|
||||
import ConfirmDialog from '@/components/ConfirmDialog.vue'
|
||||
import { useToast } from '@/composables/useToast'
|
||||
import type { AiToolCallInfo } from '@/api/types'
|
||||
|
||||
const { t } = useI18n()
|
||||
@@ -157,6 +163,9 @@ const { t } = useI18n()
|
||||
const approvals = ref<AiToolCallInfo[]>([])
|
||||
/** 操作中 id(防抖 + 按钮加载态) */
|
||||
const processingId = ref<string>('')
|
||||
// P1-e-d: 审批失败 toast——独立 WebviewWindow 无共享组件树,窗口内自包含 useToast
|
||||
// (不走跨窗口 emit 中转,失败反馈一定显示在用户当前关注的浮窗内)
|
||||
const { toast, showToast } = useToast()
|
||||
/** 拖动态(样式反馈) */
|
||||
const isDragging = ref(false)
|
||||
|
||||
@@ -436,6 +445,8 @@ async function runApproval(tc: AiToolCallInfo, approved: boolean, decision?: 'on
|
||||
await maybeAutoClose()
|
||||
} catch (e) {
|
||||
console.error('[ApprovalPopup] 审批失败:', e)
|
||||
// P1-e-d:IPC 未送达给用户可见反馈(独立窗口自包含 toast;文案复用 ai.approvalNotDelivered)
|
||||
showToast(t('ai.approvalNotDelivered', { error: e instanceof Error ? e.message : String(e) }), 'error')
|
||||
} finally {
|
||||
processingId.value = ''
|
||||
}
|
||||
@@ -802,4 +813,28 @@ function onDragEnd() { isDragging.value = false }
|
||||
@keyframes df-spin {
|
||||
to { transform: rotate(360deg); }
|
||||
}
|
||||
|
||||
/* P1-e-d:审批失败 toast(自包含 useToast;独立窗口无根 toast 自管渲染。fixed 相对本窗口视口,
|
||||
top 让出 header,不遮挡审批按钮区。样式对齐 AiChat .ai-toast 同款,scoped 防冲突) */
|
||||
.ai-toast {
|
||||
position: fixed;
|
||||
top: 44px;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
padding: 6px 12px;
|
||||
border-radius: var(--df-radius);
|
||||
font-size: 11px;
|
||||
font-weight: 600;
|
||||
z-index: 100;
|
||||
box-shadow: 0 4px 16px rgba(0, 0, 0, 0.35);
|
||||
max-width: 80%;
|
||||
overflow-wrap: anywhere;
|
||||
text-align: center;
|
||||
}
|
||||
.ai-toast-error { background: var(--df-danger-bg); color: var(--df-danger); border: 0.5px solid var(--df-danger); }
|
||||
.ai-toast-warning { background: var(--df-warning-bg); color: var(--df-warning); border: 0.5px solid var(--df-warning); }
|
||||
.ai-toast-info { background: var(--df-accent-bg); color: var(--df-accent); border: 0.5px solid var(--df-accent); }
|
||||
.ai-toast-success { background: var(--df-success-bg); color: var(--df-success); border: 0.5px solid var(--df-success); }
|
||||
.ai-toast-enter-active, .ai-toast-leave-active { transition: opacity 0.2s, transform 0.2s; }
|
||||
.ai-toast-enter-from, .ai-toast-leave-to { opacity: 0; transform: translate(-50%, -8px); }
|
||||
</style>
|
||||
|
||||
Reference in New Issue
Block a user