feat: add a preview experience to the resource details panel - #51
feat: add a preview experience to the resource details panel#51marekdano wants to merge 1 commit into
Conversation
Signed-off-by: Marek Dano <mk.dano@gmail.com>
| <img | ||
| src={dataUrl} | ||
| alt="" | ||
| className="max-h-[420px] max-w-full rounded-md border border-border object-contain" | ||
| /> |
There was a problem hiding this comment.
Issue: Images use empty alt text (alt=""), making them decorative. For content images, this may not be appropriate.
Current Code:
// ❌ POTENTIALLY PROBLEMATIC - Empty alt for content images
<img
src={dataUrl}
alt=""
className="max-h-[420px] max-w-full rounded-md border border-border object-contain"
/>Recommendation:
// ✅ BETTER - Descriptive alt text
<img
src={dataUrl}
alt={intl.formatMessage(
{ id: "resources.details.preview.imageAlt" },
{ mimeType, size: sizeLabel }
)}
className="max-h-[420px] max-w-full rounded-md border border-border object-contain"
/>| // Land on `initialTab` (default "Try it") each time the panel opens, | ||
| // regardless of which tab was active when it was last closed — mirrors | ||
| // PromptDetailsPanel. | ||
| useEffect(() => { | ||
| if (open) setActiveTab(initialTab); | ||
| }, [open, initialTab]); |
There was a problem hiding this comment.
Issue: When switching between "Try it" and "Definition" tabs, focus is not managed, potentially disorienting keyboard users.
Risk: Screen reader users may lose context when tabs change.
Recommendation:
// Add focus management to tab change handler
const tabContentRef = useRef<HTMLDivElement>(null);
useEffect(() => {
if (open && tabContentRef.current) {
// Focus the tab content when switching tabs
tabContentRef.current.focus();
}
}, [activeTab, open]);
// In TabsContent:
<TabsContent
value="tryIt"
className="mt-8"
ref={tabContentRef}
tabIndex={-1}
>| * template variables (see `parseUriTemplate.resolveUriTemplate`) before | ||
| * passing it in. | ||
| */ | ||
| export function useResourcePreview(uri: string): ResourcePreviewState { |
There was a problem hiding this comment.
Issue: The preview hook allows rapid-fire requests without client-side throttling.
Risk: Users could accidentally trigger many concurrent requests by rapidly clicking Preview or switching resources.
Recommendation:
Add a debouncer to this function, and memoise the debounced version with useMemo
Closes IBM/mcp-context-forge#5593
Summary
GET /v1/resources/test/{uri}and shows the status, timing, and rendered content (text/JSON/XML/image/PDF/binary). Mirrors the existing Prompts preview pattern; the panel now opens on "Try it" by default, with the previous list-detail table moved to a new "Definition" tab (row actions — Edit/Delete/Activate — live there).resourcesApi.testandapi.getWithMetato support the preview call, including percent-encoding?/#in the resource URI so it survives as a full path segment instead of being parsed as a query string/fragment.$, backticks, and"in the URI can't be interpreted as shell syntax if the snippet is pasted into a terminal.ToolsTableandPromptDefinitionTablenow truncate long names with a native tooltip (titleattr) instead ofline-clamp-1, matchingResourcesTable.Test plan
npx vitest run— 2993 tests passing, including new unit coverage foruseResourcePreview,buildResourceSnippets,parseUriTemplate,ResourceArgsForm/ResourceTryItTab/ResourcePreviewResult, and expandedResourcesTablecoverage (keyboard selection, toggle menu)npx playwright test e2e/resources.spec.ts— 20/20 passing, including new e2e coverage for the Try it preview flow and placeholder gatingnpx tsc --noEmit— clean