Skip to content

Commit a6a3e25

Browse files
Claudehotlong
andauthored
Fix sidebar metadata navigation by replacing prop-based handlers with TanStack Router
Agent-Logs-Url: https://github.com/objectstack-ai/framework/sessions/964addb7-666d-4157-bcfb-55dc9ac11d14 Co-authored-by: hotlong <50353452+hotlong@users.noreply.github.com>
1 parent 115612c commit a6a3e25

File tree

7 files changed

+33
-23
lines changed

7 files changed

+33
-23
lines changed

apps/studio/src/components/app-sidebar.tsx

Lines changed: 21 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ import {
3636
type LucideIcon,
3737
} from "lucide-react"
3838
import { useState, useEffect, useCallback, useMemo } from "react"
39+
import { useNavigate, useParams, useLocation } from '@tanstack/react-router';
3940
import { useClient, useMetadataSubscriptionCallback } from '@objectstack/client-react';
4041
import type { InstalledPackage } from '@objectstack/spec/kernel';
4142

@@ -163,23 +164,24 @@ const PKG_TYPE_ICONS: Record<string, LucideIcon> = {
163164
};
164165

165166
interface AppSidebarProps extends React.ComponentProps<typeof Sidebar> {
166-
selectedObject: string | null;
167-
onSelectObject: (name: string) => void;
168-
selectedMeta?: { type: string; name: string } | null;
169-
onSelectMeta?: (type: string, name: string) => void;
170167
packages: InstalledPackage[];
171168
selectedPackage: InstalledPackage | null;
172169
onSelectPackage: (pkg: InstalledPackage) => void;
173-
onSelectView?: (view: 'overview' | 'packages' | 'api-console') => void;
174-
selectedView?: 'overview' | 'packages' | 'object' | 'metadata' | 'api-console';
175170
}
176171

177172
export function AppSidebar({
178-
selectedObject, onSelectObject, selectedMeta, onSelectMeta,
179-
packages, selectedPackage, onSelectPackage, onSelectView, selectedView,
173+
packages, selectedPackage, onSelectPackage,
180174
...props
181175
}: AppSidebarProps) {
182176
const client = useClient();
177+
const navigate = useNavigate();
178+
const params = useParams({ strict: false });
179+
const location = useLocation();
180+
181+
// Extract current selection from URL params
182+
const selectedObject = params.name && params.package && !params.type ? params.name : null;
183+
const selectedMeta = params.type && params.name ? { type: params.type, name: params.name } : null;
184+
183185
const [loading, setLoading] = useState(false);
184186
const [searchQuery, setSearchQuery] = useState("");
185187
const [metaTypes, setMetaTypes] = useState<string[]>([]);
@@ -362,8 +364,8 @@ export function AppSidebar({
362364
<SidebarMenu>
363365
<SidebarMenuItem>
364366
<SidebarMenuButton
365-
isActive={selectedView === 'overview' && !selectedObject}
366-
onClick={() => { onSelectObject(''); onSelectView?.('overview'); }}
367+
isActive={!!params.package && !params.name && !params.type}
368+
onClick={() => navigate({ to: `/${selectedPackage?.manifest?.id || 'default'}` })}
367369
>
368370
<LayoutDashboard className="h-4 w-4" />
369371
<span>Overview</span>
@@ -456,9 +458,11 @@ export function AppSidebar({
456458
const isActive = isObjectType
457459
? selectedObject === itemName
458460
: selectedMeta?.type === type && selectedMeta?.name === itemName;
461+
462+
const packagePath = selectedPackage?.manifest?.id || 'default';
459463
const handleClick = isObjectType
460-
? () => onSelectObject(itemName)
461-
: () => onSelectMeta?.(type, itemName);
464+
? () => navigate({ to: `/${packagePath}/objects/${itemName}` })
465+
: () => navigate({ to: `/${packagePath}/metadata/${type}/${itemName}` });
462466

463467
return (
464468
<SidebarMenuSubItem key={itemName}>
@@ -540,7 +544,7 @@ export function AppSidebar({
540544
<SidebarMenuSubItem key={itemName}>
541545
<SidebarMenuSubButton
542546
isActive={selectedObject === itemName}
543-
onClick={() => onSelectObject(itemName)}
547+
onClick={() => navigate({ to: `/${selectedPackage?.manifest?.id || 'default'}/objects/${itemName}` })}
544548
>
545549
<span className="truncate">
546550
{isSystemObject(item) && (
@@ -562,8 +566,8 @@ export function AppSidebar({
562566
<SidebarMenuItem>
563567
<SidebarMenuButton
564568
tooltip="API Console"
565-
isActive={selectedView === 'api-console'}
566-
onClick={() => onSelectView?.('api-console')}
569+
isActive={location.pathname === '/api-console'}
570+
onClick={() => navigate({ to: '/api-console' })}
567571
>
568572
<Globe className="h-4 w-4" />
569573
<span>API Console</span>
@@ -572,8 +576,8 @@ export function AppSidebar({
572576
<SidebarMenuItem>
573577
<SidebarMenuButton
574578
tooltip="Packages"
575-
isActive={selectedView === 'packages'}
576-
onClick={() => onSelectView?.('packages')}
579+
isActive={location.pathname === '/packages'}
580+
onClick={() => navigate({ to: '/packages' })}
577581
>
578582
<Package className="h-4 w-4" />
579583
<span>Packages</span>

apps/studio/src/routes/$package.metadata.$type.$name.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,14 @@ import { usePackages } from '../hooks/usePackages';
88

99
function MetadataViewComponent() {
1010
const { type, name } = Route.useParams();
11-
const { packages, selectedPackage } = usePackages();
11+
const { packages, selectedPackage, setSelectedPackage } = usePackages();
1212

1313
return (
1414
<>
1515
<AppSidebar
1616
packages={packages}
1717
selectedPackage={selectedPackage}
18+
onSelectPackage={setSelectedPackage}
1819
/>
1920
<main className="flex min-w-0 flex-1 flex-col h-svh overflow-hidden bg-background">
2021
<SiteHeader

apps/studio/src/routes/$package.objects.$name.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,14 @@ import { usePackages } from '../hooks/usePackages';
88

99
function ObjectViewComponent() {
1010
const { name } = Route.useParams();
11-
const { packages, selectedPackage } = usePackages();
11+
const { packages, selectedPackage, setSelectedPackage } = usePackages();
1212

1313
return (
1414
<>
1515
<AppSidebar
1616
packages={packages}
1717
selectedPackage={selectedPackage}
18+
onSelectPackage={setSelectedPackage}
1819
/>
1920
<main className="flex min-w-0 flex-1 flex-col h-svh overflow-hidden bg-background">
2021
<SiteHeader

apps/studio/src/routes/$package.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import { usePackages } from '../hooks/usePackages';
77
import { useEffect } from 'react';
88

99
function PackageLayoutComponent() {
10-
const { packageId } = Route.useParams();
10+
const { package: packageId } = Route.useParams();
1111
const { packages, selectedPackage, setSelectedPackage } = usePackages();
1212

1313
// Update selected package when route param changes
@@ -23,6 +23,7 @@ function PackageLayoutComponent() {
2323
<AppSidebar
2424
packages={packages}
2525
selectedPackage={selectedPackage}
26+
onSelectPackage={setSelectedPackage}
2627
/>
2728
<main className="flex min-w-0 flex-1 flex-col h-svh overflow-hidden bg-background">
2829
<SiteHeader

apps/studio/src/routes/api-console.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,14 @@ import { ApiConsolePage } from '../components/ApiConsolePage';
77
import { usePackages } from '../hooks/usePackages';
88

99
function ApiConsoleComponent() {
10-
const { packages, selectedPackage } = usePackages();
10+
const { packages, selectedPackage, setSelectedPackage } = usePackages();
1111

1212
return (
1313
<>
1414
<AppSidebar
1515
packages={packages}
1616
selectedPackage={selectedPackage}
17+
onSelectPackage={setSelectedPackage}
1718
/>
1819
<main className="flex min-w-0 flex-1 flex-col h-svh overflow-hidden bg-background">
1920
<SiteHeader

apps/studio/src/routes/index.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,14 @@ import { DeveloperOverview } from '../components/DeveloperOverview';
77
import { usePackages } from '../hooks/usePackages';
88

99
function IndexComponent() {
10-
const { packages, selectedPackage } = usePackages();
10+
const { packages, selectedPackage, setSelectedPackage } = usePackages();
1111

1212
return (
1313
<>
1414
<AppSidebar
1515
packages={packages}
1616
selectedPackage={selectedPackage}
17+
onSelectPackage={setSelectedPackage}
1718
/>
1819
<main className="flex min-w-0 flex-1 flex-col h-svh overflow-hidden bg-background">
1920
<SiteHeader

apps/studio/src/routes/packages.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,14 @@ import { PackageManager } from '../components/PackageManager';
77
import { usePackages } from '../hooks/usePackages';
88

99
function PackagesViewComponent() {
10-
const { packages, selectedPackage } = usePackages();
10+
const { packages, selectedPackage, setSelectedPackage } = usePackages();
1111

1212
return (
1313
<>
1414
<AppSidebar
1515
packages={packages}
1616
selectedPackage={selectedPackage}
17+
onSelectPackage={setSelectedPackage}
1718
/>
1819
<main className="flex min-w-0 flex-1 flex-col h-svh overflow-hidden bg-background">
1920
<SiteHeader

0 commit comments

Comments
 (0)