feat(resources): render annotations on ResourceListItem (#1249)
* feat(resources): render annotations on ResourceListItem (#1238) Half-finished Phase 5 spec target: ResourceListItem already used title ?? name but ignored resource.annotations entirely. Now renders audience and priority via the existing AnnotationBadge element, matching how ResourcePreviewPanel surfaces the same fields. Layout: a wrapping Group keeps the title + badges on a single line when the row is wide, and lets badges drop below when narrow. When neither annotation is present, the row renders the bare Text (no Group, no leaked spacing). Adds stories for audience-only, priority-only, both, and a ResourceTemplate with annotations. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * Address PR #1249 review feedback - Inline the audience/priority narrowing checks instead of routing through aliased booleans, matching ResourcePreviewPanel's pattern and avoiding reliance on TS aliased-condition narrowing for the inner badges. - Use a distinct resource name (settings.json) for WithAudience so the Storybook canvas reads more clearly across the four annotation stories. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
9f452807f6
commit
f1d6fbd704
2 changed files with 79 additions and 2 deletions
|
|
@ -53,3 +53,48 @@ export const Template: Story = {
|
|||
selected: false,
|
||||
},
|
||||
};
|
||||
|
||||
export const WithAudience: Story = {
|
||||
args: {
|
||||
resource: {
|
||||
name: "settings.json",
|
||||
uri: "file:///settings.json",
|
||||
annotations: { audience: ["user"] },
|
||||
},
|
||||
selected: false,
|
||||
},
|
||||
};
|
||||
|
||||
export const WithPriority: Story = {
|
||||
args: {
|
||||
resource: {
|
||||
name: "schema.sql",
|
||||
uri: "file:///schema.sql",
|
||||
annotations: { priority: 0.8 },
|
||||
},
|
||||
selected: false,
|
||||
},
|
||||
};
|
||||
|
||||
export const WithAudienceAndPriority: Story = {
|
||||
args: {
|
||||
resource: {
|
||||
name: "config.json",
|
||||
title: "Configuration File",
|
||||
uri: "file:///config.json",
|
||||
annotations: { audience: ["user", "assistant"], priority: 0.5 },
|
||||
},
|
||||
selected: false,
|
||||
},
|
||||
};
|
||||
|
||||
export const TemplateWithAnnotations: Story = {
|
||||
args: {
|
||||
resource: {
|
||||
name: "User Profile",
|
||||
uriTemplate: "file:///users/{userId}/profile",
|
||||
annotations: { audience: ["assistant"], priority: 0.2 },
|
||||
},
|
||||
selected: false,
|
||||
},
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,8 +1,9 @@
|
|||
import { Text, UnstyledButton } from "@mantine/core";
|
||||
import { Group, Text, UnstyledButton } from "@mantine/core";
|
||||
import type {
|
||||
Resource,
|
||||
ResourceTemplate,
|
||||
} from "@modelcontextprotocol/sdk/types.js";
|
||||
import { AnnotationBadge } from "../../elements/AnnotationBadge/AnnotationBadge";
|
||||
|
||||
export interface ResourceListItemProps {
|
||||
resource: Resource | ResourceTemplate;
|
||||
|
|
@ -10,11 +11,28 @@ export interface ResourceListItemProps {
|
|||
onClick: () => void;
|
||||
}
|
||||
|
||||
const RowGroup = Group.withProps({
|
||||
gap: "xs",
|
||||
wrap: "wrap",
|
||||
justify: "space-between",
|
||||
});
|
||||
|
||||
const BadgeGroup = Group.withProps({
|
||||
gap: "xs",
|
||||
wrap: "wrap",
|
||||
});
|
||||
|
||||
export function ResourceListItem({
|
||||
resource,
|
||||
selected,
|
||||
onClick,
|
||||
}: ResourceListItemProps) {
|
||||
const audience = resource.annotations?.audience;
|
||||
const priority = resource.annotations?.priority;
|
||||
const showBadges =
|
||||
(audience !== undefined && audience.length > 0) || priority !== undefined;
|
||||
const label = <Text fw={500}>{resource.title ?? resource.name}</Text>;
|
||||
|
||||
return (
|
||||
<UnstyledButton
|
||||
w="100%"
|
||||
|
|
@ -23,7 +41,21 @@ export function ResourceListItem({
|
|||
bg={selected ? "var(--mantine-primary-color-light)" : undefined}
|
||||
onClick={onClick}
|
||||
>
|
||||
<Text fw={500}>{resource.title ?? resource.name}</Text>
|
||||
{showBadges ? (
|
||||
<RowGroup>
|
||||
{label}
|
||||
<BadgeGroup>
|
||||
{audience !== undefined && audience.length > 0 && (
|
||||
<AnnotationBadge facet="audience" value={audience} />
|
||||
)}
|
||||
{priority !== undefined && (
|
||||
<AnnotationBadge facet="priority" value={priority} />
|
||||
)}
|
||||
</BadgeGroup>
|
||||
</RowGroup>
|
||||
) : (
|
||||
label
|
||||
)}
|
||||
</UnstyledButton>
|
||||
);
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue