mirror of
https://github.com/fabro-sh/fabro.git
synced 2026-09-07 08:27:12 +00:00
Add a "Run Logs" entry to the run detail sidebar that fetches the
worker tracing log via GET /api/v1/runs/{id}/logs and renders it with
auto-refresh while the run is live. Refreshes the embedded SPA bundle.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
112 lines
3.5 KiB
TypeScript
112 lines
3.5 KiB
TypeScript
import { createElement } from "react";
|
|
import { type RouteObject, useParams } from "react-router";
|
|
|
|
import Root, { ErrorBoundary as RootErrorBoundary } from "./root";
|
|
import * as RedirectHome from "./routes/redirect-home";
|
|
import * as Setup from "./routes/setup";
|
|
import * as AuthLogin from "./routes/auth-login";
|
|
import * as Start from "./routes/start";
|
|
import * as Workflows from "./routes/workflows";
|
|
import * as WorkflowDetail from "./routes/workflow-detail";
|
|
import * as WorkflowDefinition from "./routes/workflow-definition";
|
|
import * as WorkflowDiagram from "./routes/workflow-diagram";
|
|
import * as WorkflowRuns from "./routes/workflow-runs";
|
|
import * as Runs from "./routes/runs";
|
|
import * as RunDetail from "./routes/run-detail";
|
|
import * as RunOverview from "./routes/run-overview";
|
|
import * as RunStages from "./routes/run-stages";
|
|
import * as RunSettings from "./routes/run-settings";
|
|
import * as RunGraph from "./routes/run-graph";
|
|
import * as RunLogs from "./routes/run-logs";
|
|
import * as RunFiles from "./routes/run-files";
|
|
import * as RunBilling from "./routes/run-billing";
|
|
import * as Insights from "./routes/insights";
|
|
import * as InsightsEditor from "./routes/insights-editor";
|
|
import * as InsightsNew from "./routes/insights-new";
|
|
import * as Settings from "./routes/settings";
|
|
import AppShellModule from "./layouts/app-shell";
|
|
|
|
type RouteModule = {
|
|
default: React.ComponentType<any>;
|
|
handle?: RouteObject["handle"];
|
|
ErrorBoundary?: React.ComponentType<any>;
|
|
};
|
|
|
|
function withRouteModule(module: RouteModule) {
|
|
return function WrappedRouteComponent() {
|
|
const params = useParams();
|
|
return createElement(module.default, { params });
|
|
};
|
|
}
|
|
|
|
function route(
|
|
path: string,
|
|
module: RouteModule,
|
|
extra: Omit<RouteObject, "path" | "Component" | "index"> = {},
|
|
): RouteObject {
|
|
return {
|
|
path,
|
|
handle: module.handle,
|
|
Component: withRouteModule(module),
|
|
ErrorBoundary: module.ErrorBoundary,
|
|
...extra,
|
|
};
|
|
}
|
|
|
|
function indexRoute(module: RouteModule): RouteObject {
|
|
return {
|
|
index: true,
|
|
handle: module.handle,
|
|
Component: withRouteModule(module),
|
|
ErrorBoundary: module.ErrorBoundary,
|
|
};
|
|
}
|
|
|
|
export const routes: RouteObject[] = [
|
|
{
|
|
path: "/",
|
|
Component: Root,
|
|
ErrorBoundary: RootErrorBoundary,
|
|
children: [
|
|
indexRoute(RedirectHome),
|
|
route("setup", Setup),
|
|
route("login", AuthLogin),
|
|
{
|
|
Component: withRouteModule({
|
|
default: AppShellModule,
|
|
}),
|
|
children: [
|
|
route("start", Start),
|
|
route("workflows", Workflows),
|
|
route("workflows/:name", WorkflowDetail, {
|
|
children: [
|
|
indexRoute(WorkflowDefinition),
|
|
route("diagram", WorkflowDiagram),
|
|
route("runs", WorkflowRuns),
|
|
],
|
|
}),
|
|
route("runs", Runs),
|
|
route("runs/:id", RunDetail, {
|
|
children: [
|
|
indexRoute(RunOverview),
|
|
route("stages", RunStages),
|
|
route("stages/:stageId", RunStages),
|
|
route("settings", RunSettings),
|
|
route("graph", RunGraph),
|
|
route("logs", RunLogs),
|
|
route("files", RunFiles),
|
|
route("billing", RunBilling),
|
|
],
|
|
}),
|
|
route("insights", Insights, {
|
|
children: [
|
|
indexRoute(InsightsEditor),
|
|
route("new", InsightsNew),
|
|
],
|
|
}),
|
|
route("settings", Settings),
|
|
],
|
|
},
|
|
],
|
|
},
|
|
];
|