mirror of
https://github.com/fabro-sh/fabro.git
synced 2026-10-10 03:30:59 +00:00
Convert workflow detail tabs to nested routes
Definition at /workflows/:name, Diagram at /workflows/:name/diagram, Runs at /workflows/:name/runs. Detail page is now a layout with Outlet. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
4dac57685c
commit
093eecdb6e
5 changed files with 41 additions and 30 deletions
|
|
@ -10,7 +10,11 @@ export default [
|
|||
layout("layouts/app-shell.tsx", [
|
||||
route("start", "routes/start.tsx"),
|
||||
route("workflows", "routes/workflows.tsx"),
|
||||
route("workflows/:name", "routes/workflow-detail.tsx"),
|
||||
route("workflows/:name", "routes/workflow-detail.tsx", [
|
||||
index("routes/workflow-definition.tsx"),
|
||||
route("diagram", "routes/workflow-diagram.tsx"),
|
||||
route("runs", "routes/workflow-runs.tsx"),
|
||||
]),
|
||||
route("runs", "routes/pipelines.tsx"),
|
||||
route("insights", "routes/insights.tsx"),
|
||||
route("settings", "routes/settings.tsx"),
|
||||
|
|
|
|||
3
apps/arc-web/app/routes/workflow-definition.tsx
Normal file
3
apps/arc-web/app/routes/workflow-definition.tsx
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
export default function WorkflowDefinition() {
|
||||
return <p className="text-sm text-navy-600">Workflow definition will appear here.</p>;
|
||||
}
|
||||
|
|
@ -1,8 +1,7 @@
|
|||
import { useState } from "react";
|
||||
import { useParams } from "react-router";
|
||||
import { Link, Outlet, useLocation, useParams } from "react-router";
|
||||
import type { Route } from "./+types/workflow-detail";
|
||||
|
||||
const workflowData: Record<string, { title: string; description: string; filename: string }> = {
|
||||
export const workflowData: Record<string, { title: string; description: string; filename: string }> = {
|
||||
fix_build: {
|
||||
title: "Fix Build",
|
||||
filename: "fix_build.dot",
|
||||
|
|
@ -25,8 +24,11 @@ const workflowData: Record<string, { title: string; description: string; filenam
|
|||
},
|
||||
};
|
||||
|
||||
const tabs = ["Definition", "Diagram", "Runs"] as const;
|
||||
type Tab = (typeof tabs)[number];
|
||||
const tabs = [
|
||||
{ name: "Definition", path: "" },
|
||||
{ name: "Diagram", path: "/diagram" },
|
||||
{ name: "Runs", path: "/runs" },
|
||||
];
|
||||
|
||||
export function meta({ params }: Route.MetaArgs) {
|
||||
const workflow = workflowData[params.name ?? ""];
|
||||
|
|
@ -36,8 +38,9 @@ export function meta({ params }: Route.MetaArgs) {
|
|||
|
||||
export default function WorkflowDetail() {
|
||||
const { name } = useParams();
|
||||
const { pathname } = useLocation();
|
||||
const workflow = workflowData[name ?? ""];
|
||||
const [activeTab, setActiveTab] = useState<Tab>("Definition");
|
||||
const basePath = `/workflows/${name}`;
|
||||
|
||||
if (workflow == null) {
|
||||
return <p className="text-sm text-ice-300">Workflow not found.</p>;
|
||||
|
|
@ -55,33 +58,28 @@ export default function WorkflowDetail() {
|
|||
|
||||
<div className="border-b border-white/[0.06]">
|
||||
<nav className="-mb-px flex gap-6">
|
||||
{tabs.map((tab) => (
|
||||
<button
|
||||
key={tab}
|
||||
type="button"
|
||||
onClick={() => setActiveTab(tab)}
|
||||
className={`border-b-2 pb-3 text-sm font-medium transition-colors ${
|
||||
activeTab === tab
|
||||
? "border-teal-500 text-white"
|
||||
: "border-transparent text-navy-600 hover:border-white/10 hover:text-ice-300"
|
||||
}`}
|
||||
>
|
||||
{tab}
|
||||
</button>
|
||||
))}
|
||||
{tabs.map((tab) => {
|
||||
const tabPath = `${basePath}${tab.path}`;
|
||||
const isActive = pathname === tabPath;
|
||||
return (
|
||||
<Link
|
||||
key={tab.name}
|
||||
to={tabPath}
|
||||
className={`border-b-2 pb-3 text-sm font-medium transition-colors ${
|
||||
isActive
|
||||
? "border-teal-500 text-white"
|
||||
: "border-transparent text-navy-600 hover:border-white/10 hover:text-ice-300"
|
||||
}`}
|
||||
>
|
||||
{tab.name}
|
||||
</Link>
|
||||
);
|
||||
})}
|
||||
</nav>
|
||||
</div>
|
||||
|
||||
<div className="mt-6">
|
||||
{activeTab === "Definition" && (
|
||||
<p className="text-sm text-navy-600">Workflow definition will appear here.</p>
|
||||
)}
|
||||
{activeTab === "Diagram" && (
|
||||
<p className="text-sm text-navy-600">Workflow diagram will appear here.</p>
|
||||
)}
|
||||
{activeTab === "Runs" && (
|
||||
<p className="text-sm text-navy-600">Recent runs will appear here.</p>
|
||||
)}
|
||||
<Outlet />
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
|
|
|||
3
apps/arc-web/app/routes/workflow-diagram.tsx
Normal file
3
apps/arc-web/app/routes/workflow-diagram.tsx
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
export default function WorkflowDiagram() {
|
||||
return <p className="text-sm text-navy-600">Workflow diagram will appear here.</p>;
|
||||
}
|
||||
3
apps/arc-web/app/routes/workflow-runs.tsx
Normal file
3
apps/arc-web/app/routes/workflow-runs.tsx
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
export default function WorkflowRuns() {
|
||||
return <p className="text-sm text-navy-600">Recent runs will appear here.</p>;
|
||||
}
|
||||
Loading…
Add table
Reference in a new issue