Skip to content

Commit f9ae351

Browse files
committed
feat dashboard latout
1 parent 4be9508 commit f9ae351

5 files changed

Lines changed: 152 additions & 17 deletions

File tree

src/hooks/useRecentlyViewed.ts

Lines changed: 15 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -50,18 +50,21 @@ export function useRecentlyViewed() {
5050
() => [],
5151
);
5252

53-
const addRecentlyViewed = useCallback((item: Omit<RecentlyViewedItem, "viewedAt">) => {
54-
const current = readRecentlyViewed();
55-
// Remove any existing entry for the same item, then prepend the fresh one
56-
const deduped = current.filter(
57-
(i) => !(i.type === item.type && i.id === item.id),
58-
);
59-
const updated = [{ ...item, viewedAt: Date.now() }, ...deduped].slice(
60-
0,
61-
MAX_ITEMS,
62-
);
63-
storage.setItem(RECENTLY_VIEWED_KEY, updated);
64-
}, []);
53+
const addRecentlyViewed = useCallback(
54+
(item: Omit<RecentlyViewedItem, "viewedAt">) => {
55+
const current = readRecentlyViewed();
56+
// Remove any existing entry for the same item, then prepend the fresh one
57+
const deduped = current.filter(
58+
(i) => !(i.type === item.type && i.id === item.id),
59+
);
60+
const updated = [{ ...item, viewedAt: Date.now() }, ...deduped].slice(
61+
0,
62+
MAX_ITEMS,
63+
);
64+
storage.setItem(RECENTLY_VIEWED_KEY, updated);
65+
},
66+
[],
67+
);
6568

6669
return { recentlyViewed, addRecentlyViewed };
6770
}
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
import { Link, Outlet } from "@tanstack/react-router";
2+
3+
import { Icon, type IconName } from "@/components/ui/icon";
4+
import { BlockStack, InlineStack } from "@/components/ui/layout";
5+
import { Heading, Text } from "@/components/ui/typography";
6+
import { cn } from "@/lib/utils";
7+
8+
interface SidebarItem {
9+
to: string;
10+
label: string;
11+
icon: IconName;
12+
}
13+
14+
const SIDEBAR_ITEMS: SidebarItem[] = [
15+
{ to: "/dashboard/runs", label: "Runs", icon: "Play" },
16+
{ to: "/dashboard/pipelines", label: "Pipelines", icon: "GitBranch" },
17+
{ to: "/dashboard/components", label: "Components", icon: "Package" },
18+
{ to: "/dashboard/favorites", label: "Favorites", icon: "Star" },
19+
{ to: "/dashboard/recently-viewed", label: "Recently Viewed", icon: "Clock" },
20+
];
21+
22+
export function DashboardLayout() {
23+
return (
24+
<div className="container mx-auto p-6 max-w-6xl">
25+
<BlockStack gap="6">
26+
<InlineStack gap="2" blockAlign="center">
27+
<Heading level={1}>Dashboard</Heading>
28+
<Text
29+
as="span"
30+
size="xs"
31+
weight="semibold"
32+
className="px-2 py-1 rounded-full bg-amber-100 text-amber-800"
33+
>
34+
Beta
35+
</Text>
36+
</InlineStack>
37+
38+
<InlineStack gap="8" blockAlign="start" className="w-full min-h-100">
39+
<BlockStack
40+
gap="1"
41+
className="w-48 shrink-0 border-r border-border pr-4"
42+
>
43+
{SIDEBAR_ITEMS.map((item) => (
44+
<Link
45+
key={item.to}
46+
to={item.to}
47+
className="w-full"
48+
activeProps={{ className: "is-active" }}
49+
>
50+
{({ isActive }) => (
51+
<div
52+
className={cn(
53+
"flex items-center gap-2 w-full px-3 py-2 rounded-md text-sm cursor-pointer hover:bg-accent",
54+
isActive && "bg-accent font-medium",
55+
)}
56+
>
57+
<Icon name={item.icon} size="sm" />
58+
<Text size="sm">{item.label}</Text>
59+
</div>
60+
)}
61+
</Link>
62+
))}
63+
</BlockStack>
64+
65+
<BlockStack className="flex-1 min-w-0">
66+
<Outlet />
67+
</BlockStack>
68+
</InlineStack>
69+
</BlockStack>
70+
</div>
71+
);
72+
}

src/routes/Editor/Editor.tsx

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,11 @@ const Editor = () => {
1818

1919
useEffect(() => {
2020
if (!componentSpec?.name) return;
21-
addRecentlyViewed({ type: "pipeline", id: componentSpec.name, name: componentSpec.name });
21+
addRecentlyViewed({
22+
type: "pipeline",
23+
id: componentSpec.name,
24+
name: componentSpec.name,
25+
});
2226
}, [componentSpec?.name, addRecentlyViewed]);
2327

2428
if (error) {

src/routes/PipelineRun/PipelineRun.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,8 @@ const PipelineRunContent = () => {
8080
});
8181

8282
useEffect(() => {
83-
const id = "id" in params && typeof params.id === "string" ? params.id : null;
83+
const id =
84+
"id" in params && typeof params.id === "string" ? params.id : null;
8485
if (!componentSpec?.name || !id) return;
8586
addRecentlyViewed({ type: "run", id, name: componentSpec.name });
8687
}, [componentSpec?.name, params, addRecentlyViewed]);

src/routes/router.ts

Lines changed: 58 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ import { isFlagEnabled } from "@/components/shared/Settings/useFlags";
1717
import { BASE_URL, IS_GITHUB_PAGES } from "@/utils/constants";
1818

1919
import RootLayout from "../components/layout/RootLayout";
20-
import { Dashboard } from "./Dashboard/Dashboard";
20+
import { DashboardLayout } from "./Dashboard/DashboardLayout";
2121
import Editor from "./Editor";
2222
import Home from "./Home";
2323
import { ImportPage } from "./Import";
@@ -45,6 +45,11 @@ const DASHBOARD_PATH = "/dashboard";
4545
export const APP_ROUTES = {
4646
HOME: "/",
4747
DASHBOARD: DASHBOARD_PATH,
48+
DASHBOARD_RUNS: `${DASHBOARD_PATH}/runs`,
49+
DASHBOARD_PIPELINES: `${DASHBOARD_PATH}/pipelines`,
50+
DASHBOARD_COMPONENTS: `${DASHBOARD_PATH}/components`,
51+
DASHBOARD_FAVORITES: `${DASHBOARD_PATH}/favorites`,
52+
DASHBOARD_RECENTLY_VIEWED: `${DASHBOARD_PATH}/recently-viewed`,
4853
QUICK_START: QUICK_START_PATH,
4954
IMPORT: IMPORT_PATH,
5055
PIPELINE_EDITOR: `${EDITOR_PATH}/$name`,
@@ -83,14 +88,55 @@ const indexRoute = createRoute({
8388
const dashboardRoute = createRoute({
8489
getParentRoute: () => mainLayout,
8590
path: APP_ROUTES.DASHBOARD,
86-
component: Dashboard,
91+
component: DashboardLayout,
8792
beforeLoad: () => {
8893
if (!isFlagEnabled("dashboard")) {
8994
throw redirect({ to: APP_ROUTES.HOME });
9095
}
9196
},
9297
});
9398

99+
const dashboardIndexRoute = createRoute({
100+
getParentRoute: () => dashboardRoute,
101+
path: "/",
102+
beforeLoad: () => {
103+
throw redirect({ to: APP_ROUTES.DASHBOARD_RUNS });
104+
},
105+
});
106+
107+
// Placeholder component — replaced in subsequent PRs
108+
const ComingSoon = () => null;
109+
110+
const dashboardRunsRoute = createRoute({
111+
getParentRoute: () => dashboardRoute,
112+
path: "/runs",
113+
component: ComingSoon,
114+
});
115+
116+
const dashboardPipelinesRoute = createRoute({
117+
getParentRoute: () => dashboardRoute,
118+
path: "/pipelines",
119+
component: ComingSoon,
120+
});
121+
122+
const dashboardComponentsRoute = createRoute({
123+
getParentRoute: () => dashboardRoute,
124+
path: "/components",
125+
component: ComingSoon,
126+
});
127+
128+
const dashboardFavoritesRoute = createRoute({
129+
getParentRoute: () => dashboardRoute,
130+
path: "/favorites",
131+
component: ComingSoon,
132+
});
133+
134+
const dashboardRecentlyViewedRoute = createRoute({
135+
getParentRoute: () => dashboardRoute,
136+
path: "/recently-viewed",
137+
component: ComingSoon,
138+
});
139+
94140
const quickStartRoute = createRoute({
95141
getParentRoute: () => mainLayout,
96142
path: APP_ROUTES.QUICK_START,
@@ -207,9 +253,18 @@ const settingsRouteTree = settingsLayoutRoute.addChildren([
207253
secretsRouteTree,
208254
]);
209255

256+
const dashboardRouteTree = dashboardRoute.addChildren([
257+
dashboardIndexRoute,
258+
dashboardRunsRoute,
259+
dashboardPipelinesRoute,
260+
dashboardComponentsRoute,
261+
dashboardFavoritesRoute,
262+
dashboardRecentlyViewedRoute,
263+
]);
264+
210265
const appRouteTree = mainLayout.addChildren([
211266
indexRoute,
212-
dashboardRoute,
267+
dashboardRouteTree,
213268
quickStartRoute,
214269
settingsRouteTree,
215270
importRoute,

0 commit comments

Comments
 (0)