mirror of
https://github.com/coleam00/Archon.git
synced 2025-12-24 02:39:17 -05:00
fix: Resolve button nesting error and improve metadata display
- Fix button nesting error by using div with onClick instead of nested buttons - Move metadata panel outside the clickable item area - Add close button for metadata panel - Ensure metadata displays within the UI (not opening in new tab) - Fix type comparison for showMetadata state - Improve layout with better spacing and scrollable metadata 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -73,6 +73,7 @@ export const InspectorSidebar: React.FC<InspectorSidebarProps> = ({
|
||||
return extractDomain(url) === selectedDomain;
|
||||
});
|
||||
}, [items, selectedDomain, viewMode]);
|
||||
|
||||
const getItemTitle = (item: DocumentChunk | CodeExample) => {
|
||||
const idSuffix = String(item.id).slice(-6);
|
||||
if (viewMode === "documents") {
|
||||
@@ -164,101 +165,109 @@ export const InspectorSidebar: React.FC<InspectorSidebarProps> = ({
|
||||
) : (
|
||||
<div className="p-2">
|
||||
{filteredItems.map((item) => (
|
||||
<motion.button
|
||||
type="button"
|
||||
key={item.id}
|
||||
whileHover={{ x: 2 }}
|
||||
whileTap={{ scale: 0.98 }}
|
||||
onClick={() => onItemSelect(item)}
|
||||
className={cn(
|
||||
"w-full text-left p-3 rounded-lg mb-1 transition-all",
|
||||
"hover:bg-white/5 focus:outline-none focus:ring-2 focus:ring-cyan-500/50",
|
||||
selectedItemId === item.id
|
||||
? "bg-cyan-500/10 border border-cyan-500/30 ring-1 ring-cyan-500/20"
|
||||
: "border border-transparent",
|
||||
)}
|
||||
role="option"
|
||||
aria-selected={selectedItemId === item.id}
|
||||
aria-label={`${getItemTitle(item)}. ${getItemDescription(item)}`}
|
||||
>
|
||||
<div className="flex items-start gap-3">
|
||||
{/* Icon - Fixed size */}
|
||||
<div className="mt-0.5 flex-shrink-0" aria-hidden="true">
|
||||
{viewMode === "documents" ? (
|
||||
<FileText className="w-4 h-4 text-cyan-400" />
|
||||
) : (
|
||||
<Code className="w-4 h-4 text-green-400" />
|
||||
)}
|
||||
</div>
|
||||
|
||||
{/* Content - Can shrink with proper overflow */}
|
||||
<div className="flex-1 min-w-0">
|
||||
<div className="flex items-center gap-2 mb-1 min-w-0">
|
||||
<span className="text-sm font-medium text-white/90 truncate flex-1" title={getItemTitle(item)}>
|
||||
{getItemTitle(item)}
|
||||
</span>
|
||||
{viewMode === "code" && (item as CodeExample).language && (
|
||||
<span className="px-1.5 py-0.5 bg-green-500/10 text-green-400 text-xs rounded flex-shrink-0">
|
||||
{(item as CodeExample).language}
|
||||
</span>
|
||||
<div key={item.id} className="mb-1">
|
||||
<motion.div
|
||||
whileHover={{ x: 2 }}
|
||||
whileTap={{ scale: 0.98 }}
|
||||
onClick={() => onItemSelect(item)}
|
||||
className={cn(
|
||||
"w-full text-left p-3 rounded-lg transition-all cursor-pointer",
|
||||
"hover:bg-white/5 focus:outline-none focus:ring-2 focus:ring-cyan-500/50",
|
||||
selectedItemId === item.id
|
||||
? "bg-cyan-500/10 border border-cyan-500/30 ring-1 ring-cyan-500/20"
|
||||
: "border border-transparent",
|
||||
)}
|
||||
role="option"
|
||||
aria-selected={selectedItemId === item.id}
|
||||
aria-label={`${getItemTitle(item)}. ${getItemDescription(item)}`}
|
||||
>
|
||||
<div className="flex items-start gap-3">
|
||||
{/* Icon - Fixed size */}
|
||||
<div className="mt-0.5 flex-shrink-0" aria-hidden="true">
|
||||
{viewMode === "documents" ? (
|
||||
<FileText className="w-4 h-4 text-cyan-400" />
|
||||
) : (
|
||||
<Code className="w-4 h-4 text-green-400" />
|
||||
)}
|
||||
</div>
|
||||
<p className="text-xs text-gray-500 line-clamp-2" title={getItemDescription(item)}>
|
||||
{getItemDescription(item)}
|
||||
</p>
|
||||
|
||||
{/* Action buttons for documents */}
|
||||
{viewMode === "documents" && (
|
||||
<div className="flex items-center gap-1 mt-1">
|
||||
{(item as DocumentChunk).url && (
|
||||
<a
|
||||
href={(item as DocumentChunk).url}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
onClick={(e) => e.stopPropagation()}
|
||||
className="text-[10px] px-1.5 py-0.5 rounded bg-white/5 text-gray-500 hover:text-cyan-400 hover:bg-cyan-500/10 transition-colors flex items-center gap-1"
|
||||
title="View source"
|
||||
>
|
||||
<ExternalLink className="w-3 h-3" />
|
||||
View Source
|
||||
</a>
|
||||
{/* Content - Can shrink with proper overflow */}
|
||||
<div className="flex-1 min-w-0">
|
||||
<div className="flex items-center gap-2 mb-1 min-w-0">
|
||||
<span className="text-sm font-medium text-white/90 truncate flex-1" title={getItemTitle(item)}>
|
||||
{getItemTitle(item)}
|
||||
</span>
|
||||
{viewMode === "code" && (item as CodeExample).language && (
|
||||
<span className="px-1.5 py-0.5 bg-green-500/10 text-green-400 text-xs rounded flex-shrink-0">
|
||||
{(item as CodeExample).language}
|
||||
</span>
|
||||
)}
|
||||
{(item as DocumentChunk).metadata && (
|
||||
<button
|
||||
type="button"
|
||||
</div>
|
||||
<p className="text-xs text-gray-500 line-clamp-2" title={getItemDescription(item)}>
|
||||
{getItemDescription(item)}
|
||||
</p>
|
||||
|
||||
{/* Action buttons for documents */}
|
||||
{viewMode === "documents" && (
|
||||
<div className="flex items-center gap-1 mt-1">
|
||||
{(item as DocumentChunk).url && (
|
||||
<a
|
||||
href={(item as DocumentChunk).url}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
onClick={(e) => e.stopPropagation()}
|
||||
className="text-[10px] px-1.5 py-0.5 rounded bg-white/5 text-gray-500 hover:text-cyan-400 hover:bg-cyan-500/10 transition-colors flex items-center gap-1"
|
||||
title="View source"
|
||||
>
|
||||
<ExternalLink className="w-3 h-3" />
|
||||
Source
|
||||
</a>
|
||||
)}
|
||||
<div
|
||||
onClick={(e) => {
|
||||
e.stopPropagation();
|
||||
setShowMetadata(showMetadata === item.id ? null : String(item.id));
|
||||
setShowMetadata(showMetadata === String(item.id) ? null : String(item.id));
|
||||
}}
|
||||
className="text-[10px] px-1.5 py-0.5 rounded bg-white/5 text-gray-500 hover:text-cyan-400 hover:bg-cyan-500/10 transition-colors flex items-center gap-1"
|
||||
title="View metadata"
|
||||
className="inline-flex items-center gap-1 text-[10px] px-1.5 py-0.5 rounded bg-white/5 text-gray-500 hover:text-cyan-400 hover:bg-cyan-500/10 transition-colors cursor-pointer"
|
||||
title="Toggle metadata"
|
||||
>
|
||||
<Info className="w-3 h-3" />
|
||||
Metadata
|
||||
</button>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
{showMetadata === String(item.id) ? "Hide" : "Show"} Meta
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* Metadata panel */}
|
||||
{showMetadata === item.id && (item as DocumentChunk).metadata && (
|
||||
<div className="mt-2 p-2 bg-black/30 rounded text-[10px] text-gray-400 font-mono">
|
||||
<pre className="whitespace-pre-wrap overflow-x-auto">
|
||||
{JSON.stringify((item as DocumentChunk).metadata, null, 2)}
|
||||
</pre>
|
||||
</div>
|
||||
)}
|
||||
{item.metadata?.relevance_score != null && (
|
||||
<div className="flex items-center gap-1 mt-1">
|
||||
<Hash className="w-3 h-3 text-gray-600" aria-hidden="true" />
|
||||
<span className="text-xs text-gray-600">
|
||||
{(item.metadata.relevance_score * 100).toFixed(0)}%
|
||||
</span>
|
||||
</div>
|
||||
)}
|
||||
{item.metadata?.relevance_score != null && (
|
||||
<div className="flex items-center gap-1 mt-1">
|
||||
<Hash className="w-3 h-3 text-gray-600" aria-hidden="true" />
|
||||
<span className="text-xs text-gray-600">
|
||||
{(item.metadata.relevance_score * 100).toFixed(0)}%
|
||||
</span>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</motion.button>
|
||||
</motion.div>
|
||||
|
||||
{/* Metadata panel - Outside clickable area */}
|
||||
{showMetadata === String(item.id) && viewMode === "documents" && (item as DocumentChunk).metadata && (
|
||||
<div className="mt-1 ml-7 mr-3 p-2 bg-black/40 border border-white/10 rounded text-[10px] text-gray-400 font-mono">
|
||||
<div className="flex justify-between items-center mb-1">
|
||||
<span className="text-cyan-400">Metadata:</span>
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => setShowMetadata(null)}
|
||||
className="text-gray-500 hover:text-white text-sm"
|
||||
>
|
||||
×
|
||||
</button>
|
||||
</div>
|
||||
<pre className="whitespace-pre-wrap overflow-x-auto max-h-48 overflow-y-auto">
|
||||
{JSON.stringify((item as DocumentChunk).metadata, null, 2)}
|
||||
</pre>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
))}
|
||||
|
||||
{/* Load More Button */}
|
||||
@@ -280,7 +289,7 @@ export const InspectorSidebar: React.FC<InspectorSidebarProps> = ({
|
||||
) : (
|
||||
<>
|
||||
<span>Load More {viewMode}</span>
|
||||
<span className="sr-only">. Press to load additional items.</span>
|
||||
<span className="sr-only"> Press to load additional items.</span>
|
||||
</>
|
||||
)}
|
||||
</Button>
|
||||
@@ -291,4 +300,4 @@ export const InspectorSidebar: React.FC<InspectorSidebarProps> = ({
|
||||
</div>
|
||||
</aside>
|
||||
);
|
||||
};
|
||||
};
|
||||
Reference in New Issue
Block a user