Skip to content
Open
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
166 changes: 103 additions & 63 deletions src/routes/Dashboard/DashboardLayout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,17 @@ import { isAuthorizationRequired } from "@/components/shared/Authentication/help
import { TopBarAuthentication } from "@/components/shared/Authentication/TopBarAuthentication";
import { Icon, type IconName } from "@/components/ui/icon";
import { BlockStack, InlineStack } from "@/components/ui/layout";
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 @@ -32,76 +40,108 @@ 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>
<Text
as="span"
size="xs"
weight="semibold"
className="px-2 py-1 rounded-full bg-amber-100 text-amber-800"
>
Beta
</Text>
</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>
<Text
as="span"
size="xs"
weight="semibold"
className="px-2 py-0.5 rounded-full bg-amber-100 text-amber-800"
>
Beta
</Text>
</InlineStack>
</div>

<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 }) => (
<div className={navItemClass(isActive)}>
<Icon name={item.icon} size="sm" />
<Text size="sm">{item.label}</Text>
</div>
)}
</Link>
))}
</BlockStack>

<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"
{/* 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">
<a
href={DOCUMENTATION_URL}
target="_blank"
rel="noopener noreferrer"
className={navItemClass(false)}
>
{/* Top nav */}
<BlockStack gap="1">
{SIDEBAR_ITEMS.map((item) => (
<Link
key={item.to}
to={item.to}
className="w-full"
activeProps={{ className: "is-active" }}
>
{({ isActive }) => (
<div className={navItemClass(isActive)}>
<Icon name={item.icon} size="sm" />
<Text size="sm">{item.label}</Text>
</div>
)}
</Link>
))}
</BlockStack>
<Icon name="BookOpen" size="sm" />
<Text size="sm">Docs</Text>
</a>
<Link to="/settings/backend" className="w-full">
{({ isActive }) => (
<div className={navItemClass(isActive)}>
<Icon name="Settings" size="sm" />
<Text size="sm">Settings</Text>
</div>
)}
</Link>
{requiresAuthorization && (
<div className="px-3 py-2">
<TopBarAuthentication />
</div>
)}

{/* Bottom utilities */}
<BlockStack gap="1" className="border-t border-border pt-3">
{/* Footer links */}
<div className="flex flex-col gap-0.5 pt-2 mt-1 border-t border-border">
{[
{ label: "About", href: ABOUT_URL },
{ label: "Give feedback", href: GIVE_FEEDBACK_URL },
{ label: "Privacy policy", href: PRIVACY_POLICY_URL },
].map(({ label, href }) => (
<a
href={DOCUMENTATION_URL}
key={label}
href={href}
target="_blank"
rel="noopener noreferrer"
className={navItemClass(false)}
className="px-3 py-1 text-xs text-muted-foreground hover:text-foreground rounded-md hover:bg-accent"
>
<Icon name="BookOpen" size="sm" />
<Text size="sm">Docs</Text>
{label}
</a>
<Link to="/settings/backend" className="w-full">
{({ isActive }) => (
<div className={navItemClass(isActive)}>
<Icon name="Settings" size="sm" />
<Text size="sm">Settings</Text>
</div>
)}
</Link>
{requiresAuthorization && (
<div className="px-3 py-2">
<TopBarAuthentication />
</div>
)}
</BlockStack>
</BlockStack>
))}
<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