Dashboard: Deployments nav group, tool detail page, deployment links, static-aware detail

- Nav: Services/Scheduled/Tools nested under a 'Deployments' group (expandable;
  flattened to icons when the sidebar is collapsed). Programs stays top-level.
- Overview: Tools tile (Wrench, count of tool programs).
- New /tools/:name tool detail page (useDeployment): Install/Uninstall lifecycle,
  a link up to its program, and an editable ToolFields (description + env).
- ServiceDetail is static-aware: a caddy deployment shows served-by-gateway +
  URL + root, no start/stop, and edits via a new StaticFields (root + public + env)
  so a launcher is never injected into a caddy deployment.
- Program detail's Deployment section is now a clean list of links — every
  deployment (tool→/tools, service/static→/services, job→/jobs) links to its
  detail page; lifecycle controls moved onto those pages.

clean pnpm build + tsc.
This commit is contained in:
2026-07-01 12:57:25 -07:00
parent 01505328ad
commit 86d4552fdc
9 changed files with 453 additions and 136 deletions

View File

@@ -3,14 +3,22 @@ import { useNavigate } from "react-router-dom"
import { useQueryClient } from "@tanstack/react-query"
import { Check, RefreshCw } from "lucide-react"
import { apiClient } from "@/services/api/client"
import type { AnyDetail, ProgramDetail, ServiceDetail, JobDetail } from "@/types"
import type {
AnyDetail,
DeploymentDetail,
ProgramDetail,
ServiceDetail,
JobDetail,
} from "@/types"
import { ProgramFields } from "./ProgramFields"
import { ServiceFields } from "./ServiceFields"
import { JobFields } from "./JobFields"
import { ToolFields } from "./ToolFields"
import { StaticFields } from "./StaticFields"
interface ConfigPanelProps {
deployment: AnyDetail
configSection: "services" | "jobs" | "programs"
deployment: AnyDetail | DeploymentDetail
configSection: "services" | "jobs" | "programs" | "tools" | "static"
onRefetch: () => void
}
@@ -139,6 +147,18 @@ export function ConfigPanel({ deployment, configSection, onRefetch }: ConfigPane
onSave={handleSave}
onDelete={handleDelete}
/>
) : configSection === "tools" ? (
<ToolFields
tool={deployment as DeploymentDetail}
onSave={handleSave}
onDelete={handleDelete}
/>
) : configSection === "static" ? (
<StaticFields
static_={deployment as DeploymentDetail}
onSave={handleSave}
onDelete={handleDelete}
/>
) : (
<JobFields
job={deployment as JobDetail}