Fix modal header positioning and step content display

- Header now flush with top of modal (full draggable area)
- Content area properly padded below header
- Fix step rendering: use step.prompt not step.content
- Show provider, output_var, and step name in step display
- Add support for tool steps
- Add max-height with scroll for long prompts/code

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
rob 2026-01-16 15:13:27 -04:00
parent 9035a17f21
commit 957a65397a
1 changed files with 45 additions and 35 deletions

View File

@ -141,8 +141,8 @@
<!-- Tool Detail Modal -->
<div id="detail-modal" class="fixed inset-0 bg-gray-900 bg-opacity-60 hidden overflow-y-auto h-full w-full z-50">
<div id="detail-modal-content" class="relative top-10 mx-auto p-6 border-2 border-gray-300 max-w-4xl shadow-2xl rounded-lg bg-white mb-10">
<div id="detail-modal-header" class="flex items-center justify-between mb-4 cursor-move select-none bg-gray-50 -mx-6 -mt-6 px-6 py-4 rounded-t-lg border-b border-gray-200">
<div id="detail-modal-content" class="relative top-10 mx-auto border-2 border-gray-300 max-w-4xl shadow-2xl rounded-lg bg-white mb-10">
<div id="detail-modal-header" class="flex items-center justify-between cursor-move select-none bg-gray-50 px-6 py-4 rounded-t-lg border-b border-gray-200">
<h3 id="detail-title" class="text-lg font-medium text-gray-900">Tool Details</h3>
<button onclick="closeDetailModal()" class="text-gray-400 hover:text-gray-600">
<svg class="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24">
@ -150,36 +150,38 @@
</svg>
</button>
</div>
<div id="detail-loading" class="py-8 text-center text-gray-500">Loading...</div>
<div id="detail-content" class="hidden">
<!-- Description -->
<div class="mb-6">
<h4 class="text-sm font-medium text-gray-700 mb-2">Description</h4>
<p id="detail-description" class="text-sm text-gray-600"></p>
</div>
<div class="p-6">
<div id="detail-loading" class="py-8 text-center text-gray-500">Loading...</div>
<div id="detail-content" class="hidden">
<!-- Description -->
<div class="mb-6">
<h4 class="text-sm font-medium text-gray-700 mb-2">Description</h4>
<p id="detail-description" class="text-sm text-gray-600"></p>
</div>
<!-- Arguments -->
<div id="detail-args-section" class="mb-6">
<h4 class="text-sm font-medium text-gray-700 mb-2">Arguments</h4>
<div id="detail-args" class="bg-gray-50 rounded-md p-3 text-sm font-mono overflow-x-auto"></div>
</div>
<!-- Arguments -->
<div id="detail-args-section" class="mb-6">
<h4 class="text-sm font-medium text-gray-700 mb-2">Arguments</h4>
<div id="detail-args" class="bg-gray-50 rounded-md p-3 text-sm font-mono overflow-x-auto"></div>
</div>
<!-- Steps -->
<div id="detail-steps-section" class="mb-6">
<h4 class="text-sm font-medium text-gray-700 mb-2">Steps</h4>
<div id="detail-steps" class="space-y-3"></div>
</div>
<!-- Steps -->
<div id="detail-steps-section" class="mb-6">
<h4 class="text-sm font-medium text-gray-700 mb-2">Steps</h4>
<div id="detail-steps" class="space-y-3"></div>
</div>
<!-- README -->
<div id="detail-readme-section" class="mb-6">
<h4 class="text-sm font-medium text-gray-700 mb-2">README</h4>
<div id="detail-readme" class="bg-gray-50 rounded-md p-4 text-sm prose prose-sm max-w-none overflow-auto max-h-64"></div>
<!-- README -->
<div id="detail-readme-section" class="mb-6">
<h4 class="text-sm font-medium text-gray-700 mb-2">README</h4>
<div id="detail-readme" class="bg-gray-50 rounded-md p-4 text-sm prose prose-sm max-w-none overflow-auto max-h-64"></div>
</div>
</div>
<div class="mt-6 flex justify-end space-x-3 border-t pt-4">
<button onclick="closeDetailModal()" class="px-4 py-2 text-sm font-medium text-gray-700 hover:text-gray-500">Close</button>
<button id="detail-approve-btn" class="px-4 py-2 bg-green-600 text-white text-sm font-medium rounded-md hover:bg-green-700">Approve</button>
<button id="detail-reject-btn" class="px-4 py-2 bg-red-600 text-white text-sm font-medium rounded-md hover:bg-red-700">Reject</button>
</div>
</div>
<div class="mt-6 flex justify-end space-x-3 border-t pt-4">
<button onclick="closeDetailModal()" class="px-4 py-2 text-sm font-medium text-gray-700 hover:text-gray-500">Close</button>
<button id="detail-approve-btn" class="px-4 py-2 bg-green-600 text-white text-sm font-medium rounded-md hover:bg-green-700">Approve</button>
<button id="detail-reject-btn" class="px-4 py-2 bg-red-600 text-white text-sm font-medium rounded-md hover:bg-red-700">Reject</button>
</div>
</div>
</div>
@ -253,17 +255,25 @@ async function viewTool(toolId) {
stepsSection.classList.remove('hidden');
stepsDiv.innerHTML = tool.config.steps.map((step, idx) => {
let content = '';
const stepName = step.name ? ` - ${step.name}` : '';
if (step.type === 'prompt') {
content = `<div class="text-xs text-gray-500 mb-1">Prompt Step</div>
<pre class="bg-white p-2 rounded border text-xs overflow-x-auto whitespace-pre-wrap">${escapeHtml(step.content || '')}</pre>`;
const provider = step.provider ? `<span class="text-indigo-600">[${step.provider}]</span> ` : '';
const outputVar = step.output_var ? ` → <span class="text-green-600">${step.output_var}</span>` : '';
content = `<div class="text-xs text-gray-500 mb-2">${provider}Prompt Step${outputVar}</div>
<pre class="bg-white p-3 rounded border text-xs overflow-x-auto whitespace-pre-wrap max-h-48 overflow-y-auto">${escapeHtml(step.prompt || step.prompt_file || 'No prompt content')}</pre>`;
} else if (step.type === 'code') {
content = `<div class="text-xs text-gray-500 mb-1">Code Step${step.output_var ? ` → ${step.output_var}` : ''}</div>
<pre class="bg-gray-900 text-green-400 p-2 rounded text-xs overflow-x-auto"><code>${escapeHtml(step.code || '')}</code></pre>`;
const outputVar = step.output_var ? ` → <span class="text-green-600">${step.output_var}</span>` : '';
content = `<div class="text-xs text-gray-500 mb-2">Code Step${outputVar}</div>
<pre class="bg-gray-900 text-green-400 p-3 rounded text-xs overflow-x-auto max-h-64 overflow-y-auto"><code>${escapeHtml(step.code || step.code_file || 'No code content')}</code></pre>`;
} else if (step.type === 'tool') {
const toolArgs = step.arguments ? Object.entries(step.arguments).map(([k, v]) => `${k}="${v}"`).join(' ') : '';
content = `<div class="text-xs text-gray-500 mb-2">Tool Step: <span class="text-indigo-600">${step.tool || 'unknown'}</span></div>
<pre class="bg-gray-100 p-3 rounded text-xs">${toolArgs || 'No arguments'}</pre>`;
} else {
content = `<div class="text-xs text-gray-500">${step.type} step</div>`;
content = `<div class="text-xs text-gray-500">${step.type || 'Unknown'} step</div>`;
}
return `<div class="bg-gray-50 p-3 rounded-md">
<div class="text-xs font-medium text-gray-700 mb-2">Step ${idx + 1}</div>
return `<div class="bg-gray-50 p-3 rounded-md border border-gray-200">
<div class="text-sm font-medium text-gray-700 mb-2">Step ${idx + 1}${stepName}</div>
${content}
</div>`;
}).join('');