Skip to main content
Glama

docs-mcp-server

VersionDetailsRow.tsx7.16 kB
import type { VersionSummary } from "../../store/types"; import VersionBadge from "./VersionBadge"; import LoadingSpinner from "./LoadingSpinner"; // Import spinner /** * Props for the VersionDetailsRow component. */ interface VersionDetailsRowProps { version: VersionSummary; libraryName: string; showDelete?: boolean; // Optional prop to control delete button visibility } /** * Renders details for a single library version in a row format. * Includes version, stats, and an optional delete button. * @param props - Component props including version, libraryName, and showDelete flag. */ const VersionDetailsRow = ({ version, libraryName, showDelete = true, // Default to true }: VersionDetailsRowProps) => { // Format the indexed date nicely, handle null case const indexedDate = version.indexedAt ? new Date(version.indexedAt).toLocaleDateString() : "N/A"; // Display 'Unversioned' if version string is empty const versionLabel = version.ref.version || "Unversioned"; // Use empty string for unversioned in param and rowId const versionParam = version.ref.version || ""; // Sanitize both libraryName and versionParam for valid CSS selector const sanitizedLibraryName = libraryName.replace(/[^a-zA-Z0-9-_]/g, "-"); const sanitizedVersionParam = versionParam.replace(/[^a-zA-Z0-9-_]/g, "-"); const rowId = `row-${sanitizedLibraryName}-${sanitizedVersionParam}`; // Define state-specific button classes for Alpine toggling const defaultStateClasses = "text-red-700 border border-red-700 hover:bg-red-700 hover:text-white focus:ring-4 focus:outline-none focus:ring-red-300 dark:border-red-500 dark:text-red-500 dark:hover:text-white dark:focus:ring-red-800 dark:hover:bg-red-500"; const confirmingStateClasses = "bg-red-600 text-white border-red-600 focus:ring-4 focus:outline-none focus:ring-red-300 dark:bg-red-700 dark:border-red-700 dark:focus:ring-red-800"; return ( // Use flexbox for layout, add border between rows <div id={rowId} class="flex justify-between items-center py-1 border-b border-gray-200 dark:border-gray-600 last:border-b-0" > {/* Version Label */} <span class="text-sm text-gray-900 dark:text-white w-1/4 truncate" title={versionLabel} > {version.ref.version ? ( <VersionBadge version={version.ref.version} /> ) : ( <span>Unversioned</span> )} </span> {/* Stats Group */} <div class="flex space-x-2 text-sm text-gray-600 dark:text-gray-400 w-3/4 justify-end items-center"> <span title="Number of unique pages indexed"> Pages:{" "} <span class="font-semibold" safe> {version.counts.uniqueUrls.toLocaleString()} </span> </span> <span title="Number of indexed snippets"> Snippets:{" "} <span class="font-semibold" safe> {version.counts.documents.toLocaleString()} </span> </span> <span title="Date last indexed"> Last Update:{" "} <span class="font-semibold" safe> {indexedDate} </span> </span> </div> {/** * Conditionally renders a delete button for the version row. * The button has three states: * 1. Default: Displays a trash icon. * 2. Confirming: Displays a confirmation text with an accessible label. * 3. Deleting: Displays a spinner icon indicating the deletion process. * The button uses AlpineJS for state management and htmx for server interaction. */} {showDelete && ( <button type="button" class="ml-2 font-medium rounded-lg text-sm p-1 text-center inline-flex items-center transition-colors duration-150 ease-in-out" title="Remove this version" x-data="{}" x-bind:class={`$store.confirmingAction.type === 'version-delete' && $store.confirmingAction.id === '${libraryName}:${versionParam}' ? '${confirmingStateClasses}' : '${defaultStateClasses}'`} x-bind:disabled={`$store.confirmingAction.type === 'version-delete' && $store.confirmingAction.id === '${libraryName}:${versionParam}' && $store.confirmingAction.isDeleting`} x-on:click={` if ($store.confirmingAction.type === 'version-delete' && $store.confirmingAction.id === '${libraryName}:${versionParam}') { $store.confirmingAction.isDeleting = true; $el.dispatchEvent(new CustomEvent('confirmed-delete', { bubbles: true })); } else { if ($store.confirmingAction.timeoutId) { clearTimeout($store.confirmingAction.timeoutId); $store.confirmingAction.timeoutId = null; } $store.confirmingAction.type = 'version-delete'; $store.confirmingAction.id = '${libraryName}:${versionParam}'; $store.confirmingAction.isDeleting = false; $store.confirmingAction.timeoutId = setTimeout(() => { $store.confirmingAction.type = null; $store.confirmingAction.id = null; $store.confirmingAction.isDeleting = false; $store.confirmingAction.timeoutId = null; }, 3000); } `} hx-delete={`/web/libraries/${encodeURIComponent(libraryName)}/versions/${encodeURIComponent(versionParam)}`} hx-target={`#${rowId}`} hx-swap="outerHTML" hx-trigger="confirmed-delete" > {/* Default State: Trash Icon */} <span x-show={`!($store.confirmingAction.type === 'version-delete' && $store.confirmingAction.id === '${libraryName}:${versionParam}' && $store.confirmingAction.isDeleting)`} > <svg class="w-4 h-4" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 18 20" > <path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M1 5h16M7 8v8m4-8v8M7 1h4a1 1 0 0 1 1 1v3H6V2a1 1 0 0 1-1-1ZM3 5h12v13a1 1 0 0 1-1 1H4a1 1 0 0 1-1-1V5Z" /> </svg> <span class="sr-only">Remove version</span> </span> {/* Confirming State: Text */} <span x-show={`$store.confirmingAction.type === 'version-delete' && $store.confirmingAction.id === '${libraryName}:${versionParam}' && !$store.confirmingAction.isDeleting`} class="mx-1" > Confirm?<span class="sr-only">Confirm delete</span> </span> {/* Deleting State: Spinner Icon */} <span x-show={`$store.confirmingAction.type === 'version-delete' && $store.confirmingAction.id === '${libraryName}:${versionParam}' && $store.confirmingAction.isDeleting`} > <LoadingSpinner /> <span class="sr-only">Loading...</span> </span> </button> )} </div> ); }; export default VersionDetailsRow;

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/arabold/docs-mcp-server'

If you have feedback or need assistance with the MCP directory API, please join our Discord server