Files
inspector/client/src/components/ResourcesTab.tsx
2024-10-28 10:42:31 +00:00

89 lines
2.9 KiB
TypeScript

import { Alert, AlertDescription, AlertTitle } from "@/components/ui/alert";
import { Button } from "@/components/ui/button";
import { TabsContent } from "@/components/ui/tabs";
import { ListResourcesResult, Resource } from "@modelcontextprotocol/sdk/types.js";
import { AlertCircle, ChevronRight, FileText, RefreshCw } from "lucide-react";
import ListPane from "./ListPane";
const ResourcesTab = ({
resources,
listResources,
readResource,
selectedResource,
setSelectedResource,
resourceContent,
nextCursor,
error,
}: {
resources: Resource[];
listResources: () => void;
readResource: (uri: string) => void;
selectedResource: Resource | null;
setSelectedResource: (resource: Resource) => void;
resourceContent: string;
nextCursor: ListResourcesResult["nextCursor"];
error: string | null;
}) => (
<TabsContent value="resources" className="grid grid-cols-2 gap-4">
<ListPane
items={resources}
listItems={listResources}
setSelectedItem={(resource) => {
setSelectedResource(resource);
readResource(resource.uri);
}}
renderItem={(resource) => (
<div className="flex items-center w-full">
<FileText className="w-4 h-4 mr-2 flex-shrink-0 text-gray-500" />
<span className="flex-1 truncate" title={resource.uri.toString()}>
{resource.name}
</span>
<ChevronRight className="w-4 h-4 flex-shrink-0 text-gray-400" />
</div>
)}
title="Resources"
buttonText={nextCursor ? "List More Resources" : "List Resources"}
isButtonDisabled={!nextCursor && resources.length > 0}
/>
<div className="bg-white rounded-lg shadow">
<div className="p-4 border-b border-gray-200 flex justify-between items-center">
<h3 className="font-semibold truncate" title={selectedResource?.name}>
{selectedResource ? selectedResource.name : "Select a resource"}
</h3>
{selectedResource && (
<Button
variant="outline"
size="sm"
onClick={() => readResource(selectedResource.uri)}
>
<RefreshCw className="w-4 h-4 mr-2" />
Refresh
</Button>
)}
</div>
<div className="p-4">
{error ? (
<Alert variant="destructive">
<AlertCircle className="h-4 w-4" />
<AlertTitle>Error</AlertTitle>
<AlertDescription>{error}</AlertDescription>
</Alert>
) : selectedResource ? (
<pre className="bg-gray-50 p-4 rounded text-sm overflow-auto max-h-96 whitespace-pre-wrap break-words">
{resourceContent}
</pre>
) : (
<Alert>
<AlertDescription>
Select a resource from the list to view its contents
</AlertDescription>
</Alert>
)}
</div>
</div>
</TabsContent>
);
export default ResourcesTab;