Skip to content

Commit e19c5df

Browse files
prettier
1 parent a5d5897 commit e19c5df

File tree

8 files changed

+191
-142
lines changed

8 files changed

+191
-142
lines changed

mcpjam-inspector/client/src/components/learn-more/LearnMoreExpandedPanel.tsx

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,14 +12,20 @@ interface LearnMoreExpandedPanelProps {
1212
const PANEL_WIDTH = 900;
1313
const EASING: [number, number, number, number] = [0.16, 1, 0.3, 1]; // ease-out-expo
1414

15-
function VideoThumbnail({ entry }: { entry: { title: string; videoUrl: string; videoThumbnail?: string } }) {
15+
function VideoThumbnail({
16+
entry,
17+
}: {
18+
entry: { title: string; videoUrl: string; videoThumbnail?: string };
19+
}) {
1620
const [playing, setPlaying] = useState(false);
1721
const videoRef = useRef<HTMLVideoElement>(null);
1822

1923
const isMP4 = entry.videoUrl?.endsWith(".mp4");
2024
const isYouTube = entry.videoUrl?.includes("youtube.com/embed/");
21-
const youtubeId = isYouTube ? entry.videoUrl.split("/embed/")[1]?.split("?")[0] : null;
22-
const hasVideo = !!(entry.videoUrl);
25+
const youtubeId = isYouTube
26+
? entry.videoUrl.split("/embed/")[1]?.split("?")[0]
27+
: null;
28+
const hasVideo = !!entry.videoUrl;
2329

2430
if (!hasVideo) {
2531
return (

mcpjam-inspector/client/src/components/learn-more/LearnMoreHoverCard.tsx

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -74,10 +74,19 @@ export function LearnMoreHoverCard({
7474
};
7575

7676
const hasPreview = !!entry.previewVideoUrl;
77-
const hasThumbnail = hasPreview || entry.videoUrl?.endsWith(".mp4") || entry.videoUrl?.includes("youtube.com/embed/") || entry.videoThumbnail;
77+
const hasThumbnail =
78+
hasPreview ||
79+
entry.videoUrl?.endsWith(".mp4") ||
80+
entry.videoUrl?.includes("youtube.com/embed/") ||
81+
entry.videoThumbnail;
7882

7983
return (
80-
<HoverCard openDelay={400} closeDelay={200} open={open} onOpenChange={setOpen}>
84+
<HoverCard
85+
openDelay={400}
86+
closeDelay={200}
87+
open={open}
88+
onOpenChange={setOpen}
89+
>
8190
<HoverCardTrigger asChild>{children}</HoverCardTrigger>
8291
<HoverCardContent side="right" sideOffset={8} className="w-72">
8392
<div ref={wrapperRef}>
@@ -134,9 +143,7 @@ export function LearnMoreHoverCard({
134143
</div>
135144

136145
<div className="flex items-end justify-between gap-2">
137-
<p className="text-sm text-muted-foreground">
138-
{entry.description}
139-
</p>
146+
<p className="text-sm text-muted-foreground">{entry.description}</p>
140147
<button
141148
type="button"
142149
onClick={handleExpand}

mcpjam-inspector/client/src/components/learn-more/__tests__/LearnMoreExpandedPanel.test.tsx

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,14 @@ vi.mock("framer-motion", async () => {
1414
transition?: unknown;
1515
}
1616
>(function MotionDiv(
17-
{ children, initial: _initial, animate: _animate, exit: _exit, transition: _transition, ...props },
17+
{
18+
children,
19+
initial: _initial,
20+
animate: _animate,
21+
exit: _exit,
22+
transition: _transition,
23+
...props
24+
},
1825
ref,
1926
) {
2027
return (

mcpjam-inspector/client/src/components/mcp-sidebar.tsx

Lines changed: 76 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -460,76 +460,84 @@ export function MCPSidebar({
460460

461461
return (
462462
<>
463-
<Sidebar collapsible="icon" {...props}>
464-
<SidebarHeader>
465-
<button
466-
onClick={() => handleNavClick("#servers")}
467-
className="flex items-center justify-center px-4 py-4 w-full cursor-pointer hover:opacity-80 transition-opacity"
468-
>
469-
<img
470-
src={
471-
themeMode === "dark" ? "/mcp_jam_dark.png" : "/mcp_jam_light.png"
463+
<Sidebar collapsible="icon" {...props}>
464+
<SidebarHeader>
465+
<button
466+
onClick={() => handleNavClick("#servers")}
467+
className="flex items-center justify-center px-4 py-4 w-full cursor-pointer hover:opacity-80 transition-opacity"
468+
>
469+
<img
470+
src={
471+
themeMode === "dark"
472+
? "/mcp_jam_dark.png"
473+
: "/mcp_jam_light.png"
474+
}
475+
alt="MCP Jam"
476+
className="h-4 w-auto"
477+
/>
478+
</button>
479+
{updateReady && (
480+
<div className="px-2 pb-2">
481+
<Button
482+
size="sm"
483+
onClick={restartAndInstall}
484+
className="w-full bg-primary hover:bg-primary/90 text-primary-foreground h-7 text-xs font-medium rounded-md"
485+
>
486+
Update & Restart
487+
</Button>
488+
</div>
489+
)}
490+
<SidebarWorkspaceSelector
491+
activeWorkspaceId={activeWorkspaceId}
492+
workspaces={workspaces}
493+
onSwitchWorkspace={onSwitchWorkspace}
494+
onCreateWorkspace={onCreateWorkspace}
495+
onDeleteWorkspace={onDeleteWorkspace}
496+
isLoading={isLoadingWorkspaces}
497+
onNavigateToSettings={() => handleNavClick("#workspace-settings")}
498+
onLearnMoreExpand={
499+
learnMoreEnabled ? learnMore.openExpandedModal : undefined
472500
}
473-
alt="MCP Jam"
474-
className="h-4 w-auto"
475501
/>
476-
</button>
477-
{updateReady && (
478-
<div className="px-2 pb-2">
479-
<Button
480-
size="sm"
481-
onClick={restartAndInstall}
482-
className="w-full bg-primary hover:bg-primary/90 text-primary-foreground h-7 text-xs font-medium rounded-md"
483-
>
484-
Update & Restart
485-
</Button>
486-
</div>
487-
)}
488-
<SidebarWorkspaceSelector
489-
activeWorkspaceId={activeWorkspaceId}
490-
workspaces={workspaces}
491-
onSwitchWorkspace={onSwitchWorkspace}
492-
onCreateWorkspace={onCreateWorkspace}
493-
onDeleteWorkspace={onDeleteWorkspace}
494-
isLoading={isLoadingWorkspaces}
495-
onNavigateToSettings={() => handleNavClick("#workspace-settings")}
496-
onLearnMoreExpand={learnMoreEnabled ? learnMore.openExpandedModal : undefined}
502+
</SidebarHeader>
503+
<SidebarContent>
504+
{visibleNavigationSections.map((section, sectionIndex) => (
505+
<React.Fragment key={section.id}>
506+
<NavMain
507+
items={section.items.map((item) => ({
508+
...item,
509+
isActive: item.url === `#${activeTab}`,
510+
}))}
511+
onItemClick={handleNavClick}
512+
appBuilderBubble={
513+
section.id === "mcp-apps" ? appBuilderBubble : null
514+
}
515+
learnMore={
516+
learnMoreEnabled
517+
? {
518+
onExpand: learnMore.openExpandedModal,
519+
}
520+
: null
521+
}
522+
/>
523+
{/* Add subtle divider between sections (except after the last section) */}
524+
{sectionIndex < visibleNavigationSections.length - 1 && (
525+
<div className="mx-4 my-2 border-t border-border/50" />
526+
)}
527+
</React.Fragment>
528+
))}
529+
</SidebarContent>
530+
<SidebarFooter>
531+
<SidebarUser activeOrganizationId={activeOrganizationId} />
532+
</SidebarFooter>
533+
</Sidebar>
534+
{learnMoreEnabled && (
535+
<LearnMoreExpandedPanel
536+
tabId={learnMore.expandedTabId}
537+
sourceRect={learnMore.sourceRect}
538+
onClose={learnMore.closeExpandedModal}
497539
/>
498-
</SidebarHeader>
499-
<SidebarContent>
500-
{visibleNavigationSections.map((section, sectionIndex) => (
501-
<React.Fragment key={section.id}>
502-
<NavMain
503-
items={section.items.map((item) => ({
504-
...item,
505-
isActive: item.url === `#${activeTab}`,
506-
}))}
507-
onItemClick={handleNavClick}
508-
appBuilderBubble={
509-
section.id === "mcp-apps" ? appBuilderBubble : null
510-
}
511-
learnMore={learnMoreEnabled ? {
512-
onExpand: learnMore.openExpandedModal,
513-
} : null}
514-
/>
515-
{/* Add subtle divider between sections (except after the last section) */}
516-
{sectionIndex < visibleNavigationSections.length - 1 && (
517-
<div className="mx-4 my-2 border-t border-border/50" />
518-
)}
519-
</React.Fragment>
520-
))}
521-
</SidebarContent>
522-
<SidebarFooter>
523-
<SidebarUser activeOrganizationId={activeOrganizationId} />
524-
</SidebarFooter>
525-
</Sidebar>
526-
{learnMoreEnabled && (
527-
<LearnMoreExpandedPanel
528-
tabId={learnMore.expandedTabId}
529-
sourceRect={learnMore.sourceRect}
530-
onClose={learnMore.closeExpandedModal}
531-
/>
532-
)}
533-
</>
540+
)}
541+
</>
534542
);
535543
}

mcpjam-inspector/client/src/components/sidebar/__tests__/sidebar-workspace-selector.test.tsx

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -65,9 +65,13 @@ vi.mock("@/components/ui/tooltip", () => ({
6565
}));
6666

6767
vi.mock("@/components/learn-more/LearnMoreHoverCard", () => ({
68-
LearnMoreHoverCard: ({ tabId, children }: { tabId: string; children: ReactNode }) => (
69-
<div data-testid={`learn-more-${tabId}`}>{children}</div>
70-
),
68+
LearnMoreHoverCard: ({
69+
tabId,
70+
children,
71+
}: {
72+
tabId: string;
73+
children: ReactNode;
74+
}) => <div data-testid={`learn-more-${tabId}`}>{children}</div>,
7175
}));
7276

7377
describe("SidebarWorkspaceSelector", () => {

mcpjam-inspector/client/src/components/sidebar/sidebar-workspace-selector.tsx

Lines changed: 52 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -131,13 +131,64 @@ export function SidebarWorkspaceSelector({
131131
size="lg"
132132
className="data-[state=open]:bg-sidebar-accent data-[state=open]:text-sidebar-accent-foreground"
133133
>
134+
<WorkspaceIconBadge
135+
icon={activeWorkspace?.icon}
136+
fallback={initial}
137+
size={8}
138+
/>
139+
<div className="grid flex-1 text-left text-sm leading-tight group-data-[collapsible=icon]:hidden">
140+
<span className="truncate font-semibold">
141+
{workspaceName}
142+
</span>
143+
{displayMembers.length > 0 && (
144+
<div className="flex -space-x-1.5 mt-0.5">
145+
{displayMembers.map((member) => {
146+
const name = member.user?.name || member.email;
147+
const initials = getInitials(name);
148+
return (
149+
<Avatar
150+
key={member._id}
151+
className="size-5 border border-sidebar-background"
152+
>
153+
<AvatarImage
154+
src={member.user?.imageUrl || undefined}
155+
alt={name}
156+
/>
157+
<AvatarFallback className="text-[8px] bg-muted">
158+
{initials}
159+
</AvatarFallback>
160+
</Avatar>
161+
);
162+
})}
163+
{activeMembers.length > 3 && (
164+
<div className="size-5 rounded-full border border-sidebar-background bg-muted flex items-center justify-center">
165+
<span className="text-[8px] text-muted-foreground font-medium">
166+
+{activeMembers.length - 3}
167+
</span>
168+
</div>
169+
)}
170+
</div>
171+
)}
172+
</div>
173+
<ChevronsUpDown className="ml-auto size-4 group-data-[collapsible=icon]:hidden" />
174+
</SidebarMenuButton>
175+
</DropdownMenuTrigger>
176+
</LearnMoreHoverCard>
177+
) : (
178+
<DropdownMenuTrigger asChild>
179+
<SidebarMenuButton
180+
size="lg"
181+
className="data-[state=open]:bg-sidebar-accent data-[state=open]:text-sidebar-accent-foreground"
182+
>
134183
<WorkspaceIconBadge
135184
icon={activeWorkspace?.icon}
136185
fallback={initial}
137186
size={8}
138187
/>
139188
<div className="grid flex-1 text-left text-sm leading-tight group-data-[collapsible=icon]:hidden">
140-
<span className="truncate font-semibold">{workspaceName}</span>
189+
<span className="truncate font-semibold">
190+
{workspaceName}
191+
</span>
141192
{displayMembers.length > 0 && (
142193
<div className="flex -space-x-1.5 mt-0.5">
143194
{displayMembers.map((member) => {
@@ -169,53 +220,6 @@ export function SidebarWorkspaceSelector({
169220
)}
170221
</div>
171222
<ChevronsUpDown className="ml-auto size-4 group-data-[collapsible=icon]:hidden" />
172-
</SidebarMenuButton>
173-
</DropdownMenuTrigger>
174-
</LearnMoreHoverCard>
175-
) : (
176-
<DropdownMenuTrigger asChild>
177-
<SidebarMenuButton
178-
size="lg"
179-
className="data-[state=open]:bg-sidebar-accent data-[state=open]:text-sidebar-accent-foreground"
180-
>
181-
<WorkspaceIconBadge
182-
icon={activeWorkspace?.icon}
183-
fallback={initial}
184-
size={8}
185-
/>
186-
<div className="grid flex-1 text-left text-sm leading-tight group-data-[collapsible=icon]:hidden">
187-
<span className="truncate font-semibold">{workspaceName}</span>
188-
{displayMembers.length > 0 && (
189-
<div className="flex -space-x-1.5 mt-0.5">
190-
{displayMembers.map((member) => {
191-
const name = member.user?.name || member.email;
192-
const initials = getInitials(name);
193-
return (
194-
<Avatar
195-
key={member._id}
196-
className="size-5 border border-sidebar-background"
197-
>
198-
<AvatarImage
199-
src={member.user?.imageUrl || undefined}
200-
alt={name}
201-
/>
202-
<AvatarFallback className="text-[8px] bg-muted">
203-
{initials}
204-
</AvatarFallback>
205-
</Avatar>
206-
);
207-
})}
208-
{activeMembers.length > 3 && (
209-
<div className="size-5 rounded-full border border-sidebar-background bg-muted flex items-center justify-center">
210-
<span className="text-[8px] text-muted-foreground font-medium">
211-
+{activeMembers.length - 3}
212-
</span>
213-
</div>
214-
)}
215-
</div>
216-
)}
217-
</div>
218-
<ChevronsUpDown className="ml-auto size-4 group-data-[collapsible=icon]:hidden" />
219223
</SidebarMenuButton>
220224
</DropdownMenuTrigger>
221225
)}

mcpjam-inspector/client/src/hooks/use-learn-more.ts

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,13 @@ export function useLearnMore() {
99
return tabId in learnMoreContent;
1010
}, []);
1111

12-
const openExpandedModal = useCallback((tabId: string, rect?: DOMRect | null): void => {
13-
sourceRectRef.current = rect ?? null;
14-
setExpandedTabId(tabId);
15-
}, []);
12+
const openExpandedModal = useCallback(
13+
(tabId: string, rect?: DOMRect | null): void => {
14+
sourceRectRef.current = rect ?? null;
15+
setExpandedTabId(tabId);
16+
},
17+
[],
18+
);
1619

1720
const closeExpandedModal = useCallback((): void => {
1821
setExpandedTabId(null);

0 commit comments

Comments
 (0)