Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 6 additions & 4 deletions src/components/Home/RunSection/RunRow.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ import {
TooltipContent,
TooltipTrigger,
} from "@/components/ui/tooltip";
import { Paragraph } from "@/components/ui/typography";
import useToastNotification from "@/hooks/useToastNotification";
import { useBackend } from "@/providers/BackendProvider";
import { APP_ROUTES } from "@/routes/router";
Expand Down Expand Up @@ -95,14 +94,17 @@ const RunRow = ({ run }: { run: PipelineRunResponse }) => {
return (
<TableRow
onClick={handleRowClick}
className="cursor-pointer text-gray-500 text-xs"
className="cursor-pointer text-gray-500 text-xs h-10"
>
<TableCell>
<InlineStack gap="2" blockAlign="center" wrap="nowrap">
<StatusIcon status={overallStatus} />
<Paragraph className="truncate max-w-100 text-sm" title={name}>
<span
className="truncate max-w-100 text-sm text-foreground"
title={name}
>
{name}
</Paragraph>
</span>
<div
onClick={(e) => e.stopPropagation()}
className="flex items-center text-sm"
Expand Down
6 changes: 4 additions & 2 deletions src/components/layout/RootLayout.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Outlet } from "@tanstack/react-router";
import { Outlet, useLocation } from "@tanstack/react-router";
import { TanStackRouterDevtools } from "@tanstack/router-devtools";
import { ToastContainer } from "react-toastify";

Expand All @@ -11,6 +11,8 @@ import AppMenu from "./AppMenu";

const RootLayout = () => {
useDocumentTitle();
const { pathname } = useLocation();
const isDashboard = pathname.startsWith("/dashboard");

return (
<BackendProvider>
Expand All @@ -24,7 +26,7 @@ const RootLayout = () => {
<Outlet />
</main>

<AppFooter />
{!isDashboard && <AppFooter />}

{import.meta.env.VITE_ENABLE_ROUTER_DEVTOOLS === "true" && (
<TanStackRouterDevtools />
Expand Down
194 changes: 117 additions & 77 deletions src/routes/Dashboard/DashboardLayout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,17 @@ import { Badge } from "@/components/ui/badge";
import { Icon, type IconName } from "@/components/ui/icon";
import { BlockStack, InlineStack } from "@/components/ui/layout";
import { Link as UILink } from "@/components/ui/link";
import { Heading, Text } from "@/components/ui/typography";
import { Text } from "@/components/ui/typography";
import { cn } from "@/lib/utils";
import { DOCUMENTATION_URL } from "@/utils/constants";
import {
ABOUT_URL,
DOCUMENTATION_URL,
GIT_COMMIT,
GIT_REPO_URL,
GIVE_FEEDBACK_URL,
PRIVACY_POLICY_URL,
TOP_NAV_HEIGHT,
} from "@/utils/constants";

interface SidebarItem {
to: string;
Expand All @@ -17,11 +25,11 @@ interface SidebarItem {
}

const SIDEBAR_ITEMS: SidebarItem[] = [
{ to: "/dashboard/runs", label: "Runs", icon: "Play" },
{ to: "/dashboard/pipelines", label: "Pipelines", icon: "GitBranch" },
{ to: "/dashboard/components", label: "Components", icon: "Package" },
{ to: "/dashboard/favorites", label: "Favorites", icon: "Star" },
{ to: "/dashboard/recently-viewed", label: "Recently Viewed", icon: "Clock" },
{ to: "/runs", label: "Runs", icon: "Play" },
{ to: "/pipelines", label: "Pipelines", icon: "GitBranch" },
{ to: "/components", label: "Components", icon: "Package" },
{ to: "/favorites", label: "Favorites", icon: "Star" },
{ to: "/recently-viewed", label: "Recently Viewed", icon: "Clock" },
];

const navItemClass = (isActive: boolean) =>
Expand All @@ -34,81 +42,113 @@ export function DashboardLayout() {
const requiresAuthorization = isAuthorizationRequired();

return (
<div className="w-full px-8 py-6">
<BlockStack gap="6">
<InlineStack gap="2" blockAlign="center">
<Heading level={1}>Dashboard</Heading>
<Badge className="bg-amber-100 text-amber-800 hover:bg-amber-100">
Beta
</Badge>
</InlineStack>
<div
className="flex w-full overflow-hidden"
style={{ height: `calc(100vh - ${TOP_NAV_HEIGHT}px)` }}
>
{/* Sidebar — fixed height, independent scroll */}
<div className="w-56 shrink-0 border-r border-border flex flex-col overflow-y-auto">
{/* Dashboard heading */}
<div className="px-6 pt-6 pb-4 shrink-0">
<InlineStack gap="2" blockAlign="center">
<Text size="lg" weight="semibold">
Dashboard
</Text>
<Badge className="bg-amber-100 text-amber-800 hover:bg-amber-100">
Beta
</Badge>
</InlineStack>
</div>

<InlineStack gap="8" blockAlign="start" className="w-full min-h-100">
<BlockStack
inlineAlign="space-between"
className="w-48 shrink-0 border-r border-border pr-4 self-stretch"
>
{/* Top nav */}
<BlockStack gap="1">
{SIDEBAR_ITEMS.map((item) => (
<Link
key={item.to}
to={item.to}
className="w-full"
activeProps={{ className: "is-active" }}
<BlockStack gap="1" className="px-3">
{SIDEBAR_ITEMS.map((item) => (
<Link
key={item.to}
to={item.to}
className="w-full"
activeProps={{ className: "is-active" }}
>
{({ isActive }) => (
<InlineStack
gap="2"
blockAlign="center"
className={navItemClass(isActive)}
>
{({ isActive }) => (
<InlineStack
gap="2"
blockAlign="center"
className={navItemClass(isActive)}
>
<Icon name={item.icon} size="sm" />
<Text size="sm">{item.label}</Text>
</InlineStack>
)}
</Link>
))}
</BlockStack>

{/* Bottom utilities */}
<BlockStack gap="1" className="border-t border-border pt-3">
<UILink
href={DOCUMENTATION_URL}
external
variant="block"
className={navItemClass(false)}
>
<InlineStack gap="2" blockAlign="center">
<Icon name="CircleQuestionMark" size="sm" />
<Text size="sm">Docs</Text>
<Icon name={item.icon} size="sm" />
<Text size="sm">{item.label}</Text>
</InlineStack>
</UILink>
<Link to="/settings/backend" className="w-full">
{({ isActive }) => (
<InlineStack
gap="2"
blockAlign="center"
className={navItemClass(isActive)}
>
<Icon name="Settings" size="sm" />
<Text size="sm">Settings</Text>
</InlineStack>
)}
</Link>
{requiresAuthorization && (
<div className="px-3 py-2">
<TopBarAuthentication />
</div>
)}
</BlockStack>
</BlockStack>
</Link>
))}
</BlockStack>

{/* Spacer */}
<div className="flex-1 min-h-4" />

{/* Bottom utilities */}
<div className="flex flex-col gap-1 px-3 border-t border-border pt-3 pb-3">
<UILink
href={DOCUMENTATION_URL}
external
variant="block"
className={navItemClass(false)}
>
<InlineStack gap="2" blockAlign="center">
<Icon name="CircleQuestionMark" size="sm" />
<Text size="sm">Docs</Text>
</InlineStack>
</UILink>
<Link to="/settings/backend" className="w-full">
{({ isActive }) => (
<InlineStack
gap="2"
blockAlign="center"
className={navItemClass(isActive)}
>
<Icon name="Settings" size="sm" />
<Text size="sm">Settings</Text>
</InlineStack>
)}
</Link>
{requiresAuthorization && (
<div className="px-3 py-2">
<TopBarAuthentication />
</div>
)}

{/* Footer links */}
<div className="flex flex-col gap-0.5 pt-2 mt-1 border-t border-border">
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

BlockStack

{[
{ label: "About", href: ABOUT_URL },
{ label: "Give feedback", href: GIVE_FEEDBACK_URL },
{ label: "Privacy policy", href: PRIVACY_POLICY_URL },
Comment on lines +122 to +124
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this should be a constant outside of the render function

].map(({ label, href }) => (
<a
key={label}
href={href}
target="_blank"
rel="noopener noreferrer"
className="px-3 py-1 text-xs text-muted-foreground hover:text-foreground rounded-md hover:bg-accent"
>
{label}
</a>
Comment on lines 126 to 134
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

imo these should be buttons rather than styled hyperlinks

))}
<a
href={`${GIT_REPO_URL}/commit/${GIT_COMMIT}`}
target="_blank"
rel="noopener noreferrer"
className="px-3 py-1 text-xs text-muted-foreground hover:text-foreground rounded-md hover:bg-accent font-mono"
>
ver: {GIT_COMMIT.substring(0, 6)}
</a>
</div>
</div>
</div>

<BlockStack className="flex-1 min-w-0">
<Outlet />
</BlockStack>
</InlineStack>
</BlockStack>
{/* Main content — independent scroll */}
<div className="flex-1 min-w-0 overflow-y-auto px-8 pb-6 pt-4">
<Outlet />
</div>
</div>
);
}
Loading