/** * 计划卡片组件 * * 功能说明: * - 显示执行计划的卡片界面 * - 包含计划标题、摘要和步骤列表 * - 提供确认执行、修改计划、取消等操作按钮 */ import { plannerIconSvg } from "../constants/toolIcons"; /** * 获取计划卡片的样式 */ export function getPlanCardStyles(): string { return ` /* 计划卡片样式 */ .segment-plan { margin: 12px 0; } .plan-card { border: 1px solid var(--vscode-input-border); border-radius: 8px; overflow: hidden; background: var(--vscode-editor-background); } .plan-header { display: flex; align-items: center; gap: 10px; padding: 12px 16px; background: var(--vscode-sideBar-background); border-bottom: 1px solid var(--vscode-input-border); } .plan-icon { font-size: 18px; } .plan-title { font-weight: 600; font-size: 14px; } .plan-body { padding: 16px; } .plan-summary { color: var(--vscode-descriptionForeground); margin-bottom: 12px; font-size: 13px; line-height: 1.5; } .plan-steps { font-size: 13px; } .plan-step { padding: 8px 12px; margin-bottom: 6px; background: var(--vscode-list-hoverBackground); border-radius: 4px; line-height: 1.5; } .plan-step:last-child { margin-bottom: 0; } .step-num { color: var(--vscode-textLink-foreground); font-weight: 500; margin-right: 6px; } .plan-actions { display: flex; flex-direction: column; gap: 10px; padding: 14px 16px; border-top: 1px solid var(--vscode-input-border); background: var(--vscode-sideBar-background); } .plan-actions .question-options { display: flex; flex-wrap: wrap; gap: 8px; } .plan-btn { padding: 8px 18px; border-radius: 4px; border: none; cursor: pointer; font-size: 12px; font-weight: 500; } .plan-btn-confirm { background: var(--vscode-button-background); color: var(--vscode-button-foreground); } .plan-btn-confirm:hover { background: var(--vscode-button-hoverBackground); } .plan-btn-modify { background: var(--vscode-input-background); color: var(--vscode-foreground); border: 1px solid var(--vscode-input-border); } .plan-btn-cancel { background: transparent; color: var(--vscode-descriptionForeground); } .plan-actions .custom-input-container { display: flex; gap: 8px; width: 100%; } .plan-actions .custom-input { flex: 1; padding: 8px 12px; background: var(--vscode-input-background); color: var(--vscode-input-foreground); border: 1px solid var(--vscode-input-border); border-radius: 4px; font-size: 13px; } .plan-actions .custom-submit { padding: 8px 18px; background: var(--vscode-button-background); color: var(--vscode-button-foreground); border: none; border-radius: 4px; cursor: pointer; font-size: 12px; font-weight: 500; } .plan-actions .custom-submit:hover { background: var(--vscode-button-hoverBackground); } `; } /** * 获取计划卡片的脚本 */ export function getPlanCardScript(): string { return ` // 渲染计划卡片(在 updateSegmentsRealtime 中使用) function renderPlanCardInSegment(segment, segmentDiv, answeredQuestions) { segmentDiv.className += ' segment-plan'; // 检查是否已回答 const isAnswered = answeredQuestions.has(segment.askId); const selectedAnswer = answeredQuestions.get(segment.askId); if (isAnswered) { segmentDiv.classList.add('answered'); } const stepsHtml = (segment.planSteps || []).map((step, i) => \`
\${i + 1}. \${step}
\` ).join(''); // 选项按钮 const options = ['确认执行', '修改计划', '取消']; const optionsHtml = options.map(opt => { const isSelected = isAnswered && opt === selectedAnswer; return \`\`; }).join(''); segmentDiv.innerHTML = \`
${plannerIconSvg} \${segment.planTitle || '执行计划'}
\${segment.planSummary || ''}
\${stepsHtml}
\${optionsHtml}
\`; // 只在未回答时添加事件监听 if (!isAnswered) { setTimeout(() => { const optionButtons = segmentDiv.querySelectorAll('.question-option'); optionButtons.forEach(btn => { btn.addEventListener('click', function() { const option = this.getAttribute('data-option'); // 发送答案到后端 handleQuestionAnswerInSegment(segment.askId, option, segmentDiv); // 同时发送 planAction 用于模式切换 const actionMap = { '确认执行': 'confirm', '修改计划': 'modify', '取消': 'cancel' }; vscode.postMessage({ command: 'planAction', action: actionMap[option] || option, planTitle: segment.planTitle }); }); }); const submitBtn = segmentDiv.querySelector('.custom-submit'); const customInput = segmentDiv.querySelector('.custom-input'); if (submitBtn && customInput) { submitBtn.addEventListener('click', function() { const customValue = customInput.value.trim(); if (customValue) { handleQuestionAnswerInSegment(segment.askId, customValue, segmentDiv); } }); customInput.addEventListener('keypress', function(e) { if (e.key === 'Enter') { const customValue = customInput.value.trim(); if (customValue) { handleQuestionAnswerInSegment(segment.askId, customValue, segmentDiv); } } }); } }, 0); } } // 渲染计划卡片(在 renderSegments 中使用) function renderPlanCardStatic(segment, segmentDiv) { segmentDiv.className += ' segment-plan'; const stepsHtml = (segment.planSteps || []).map((step, i) => \`
\${i + 1}. \${step}
\` ).join(''); segmentDiv.innerHTML = \`
📋 \${segment.planTitle || '执行计划'}
\${segment.planSummary || ''}
\${stepsHtml}
\`; // 绑定按钮事件 setTimeout(() => { const planCard = segmentDiv.querySelector('.plan-card'); if (planCard) { planCard.querySelectorAll('.plan-btn').forEach(btn => { btn.addEventListener('click', (e) => { const action = e.currentTarget?.dataset?.action; vscode.postMessage({ command: 'planAction', action: action, planTitle: segment.planTitle }); }); }); } }, 0); } `; }