refactor: Update component structure to use behavior and stack attributes, enhancing clarity and functionality across services, tools, and frontends
This commit is contained in:
@@ -8,7 +8,8 @@ import { runnerLabel } from "@/lib/labels"
|
||||
import { ComponentFields } from "@/components/ComponentFields"
|
||||
import { HealthBadge } from "@/components/HealthBadge"
|
||||
import { LogViewer } from "@/components/LogViewer"
|
||||
import { RoleBadge } from "@/components/RoleBadge"
|
||||
import { BehaviorBadge } from "@/components/BehaviorBadge"
|
||||
import { StackBadge } from "@/components/StackBadge"
|
||||
|
||||
export function ComponentDetailPage() {
|
||||
useEventStream()
|
||||
@@ -20,7 +21,7 @@ export function ComponentDetailPage() {
|
||||
const { mutate, isPending } = useServiceAction()
|
||||
const health = statusResp?.statuses.find((s) => s.id === name)
|
||||
const isDown = health?.status === "down"
|
||||
const isTool = component?.category === "tool"
|
||||
const isTool = component?.behavior === "tool"
|
||||
const { data: toolDetail } = useToolDetail(isTool ? (name ?? "") : "")
|
||||
const isGateway = name === "castle-gateway"
|
||||
const { data: caddyfile } = useCaddyfile(isGateway)
|
||||
@@ -28,8 +29,8 @@ export function ComponentDetailPage() {
|
||||
const { data: unitData } = useSystemdUnit(name ?? "", showUnit && !!component?.systemd)
|
||||
const [message, setMessage] = useState<{ type: "ok" | "error"; text: string } | null>(null)
|
||||
|
||||
const configSection = component?.category === "service" ? "services"
|
||||
: component?.category === "job" ? "jobs"
|
||||
const configSection = component?.behavior === "daemon" ? "services"
|
||||
: component?.schedule ? "jobs"
|
||||
: "components"
|
||||
|
||||
const handleSave = async (compName: string, config: Record<string, unknown>) => {
|
||||
@@ -121,7 +122,8 @@ export function ComponentDetailPage() {
|
||||
</div>
|
||||
|
||||
<div className="flex items-center gap-3 mb-6">
|
||||
<RoleBadge role={component.category} />
|
||||
<BehaviorBadge behavior={component.behavior} />
|
||||
<StackBadge stack={component.stack} />
|
||||
{component.source && (
|
||||
<span className="text-sm text-[var(--muted)] font-mono">{component.source}</span>
|
||||
)}
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
import { useMemo } from "react"
|
||||
import { Link } from "react-router-dom"
|
||||
import { useComponents, useStatus, useGateway, useNodes, useMeshStatus, useEventStream } from "@/services/api/hooks"
|
||||
import { GatewayPanel } from "@/components/GatewayPanel"
|
||||
import { MeshPanel } from "@/components/MeshPanel"
|
||||
import { NodeBar } from "@/components/NodeBar"
|
||||
import { ServiceSection } from "@/components/ServiceSection"
|
||||
import { JobSection } from "@/components/JobSection"
|
||||
import { ToolSection } from "@/components/ToolSection"
|
||||
import { ScheduledSection } from "@/components/ScheduledSection"
|
||||
import { ComponentTable } from "@/components/ComponentTable"
|
||||
import { SectionHeader } from "@/components/SectionHeader"
|
||||
|
||||
|
||||
export function Dashboard() {
|
||||
useEventStream()
|
||||
const { data: components, isLoading } = useComponents()
|
||||
@@ -17,16 +17,10 @@ export function Dashboard() {
|
||||
const { data: nodes } = useNodes()
|
||||
const { data: mesh } = useMeshStatus()
|
||||
|
||||
const { services, jobs, tools, frontends, other } = useMemo(() => {
|
||||
const s = { services: [] as typeof components, jobs: [] as typeof components, tools: [] as typeof components, frontends: [] as typeof components, other: [] as typeof components }
|
||||
for (const c of components ?? []) {
|
||||
if (c.category === "service") s.services!.push(c)
|
||||
else if (c.category === "job") s.jobs!.push(c)
|
||||
else if (c.category === "tool") s.tools!.push(c)
|
||||
else if (c.category === "frontend") s.frontends!.push(c)
|
||||
else s.other!.push(c)
|
||||
}
|
||||
return { services: s.services!, jobs: s.jobs!, tools: s.tools!, frontends: s.frontends!, other: s.other! }
|
||||
const { services, scheduled } = useMemo(() => {
|
||||
const svc = (components ?? []).filter((c) => c.managed && !c.schedule)
|
||||
const sch = (components ?? []).filter((c) => c.managed && c.schedule)
|
||||
return { services: svc, scheduled: sch }
|
||||
}, [components])
|
||||
|
||||
const statuses = statusResp?.statuses ?? []
|
||||
@@ -59,62 +53,13 @@ export function Dashboard() {
|
||||
{services.length > 0 && (
|
||||
<ServiceSection services={services} statuses={statuses} />
|
||||
)}
|
||||
{jobs.length > 0 && (
|
||||
<JobSection jobs={jobs} />
|
||||
{scheduled.length > 0 && (
|
||||
<ScheduledSection jobs={scheduled} statuses={statuses} />
|
||||
)}
|
||||
{tools.length > 0 && (
|
||||
<ToolSection tools={tools} />
|
||||
)}
|
||||
{frontends.length > 0 && (
|
||||
{(components ?? []).length > 0 && (
|
||||
<section>
|
||||
<SectionHeader category="frontend" />
|
||||
<div className="border border-[var(--border)] rounded-lg overflow-hidden">
|
||||
<table className="w-full text-sm">
|
||||
<tbody>
|
||||
{frontends.map((fe) => (
|
||||
<tr key={fe.id} className="border-b border-[var(--border)] last:border-b-0 hover:bg-[var(--card)]/50 transition-colors">
|
||||
<td className="px-3 py-2.5">
|
||||
<Link
|
||||
to={`/component/${fe.id}`}
|
||||
className="font-medium hover:text-[var(--primary)] transition-colors"
|
||||
>
|
||||
{fe.id}
|
||||
</Link>
|
||||
</td>
|
||||
<td className="px-3 py-2.5 text-[var(--muted)]">
|
||||
{fe.description ?? "—"}
|
||||
</td>
|
||||
</tr>
|
||||
))}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</section>
|
||||
)}
|
||||
{other.length > 0 && (
|
||||
<section>
|
||||
<SectionHeader category="component" />
|
||||
<div className="border border-[var(--border)] rounded-lg overflow-hidden">
|
||||
<table className="w-full text-sm">
|
||||
<tbody>
|
||||
{other.map((c) => (
|
||||
<tr key={c.id} className="border-b border-[var(--border)] last:border-b-0 hover:bg-[var(--card)]/50 transition-colors">
|
||||
<td className="px-3 py-2.5">
|
||||
<Link
|
||||
to={`/component/${c.id}`}
|
||||
className="font-medium hover:text-[var(--primary)] transition-colors"
|
||||
>
|
||||
{c.id}
|
||||
</Link>
|
||||
</td>
|
||||
<td className="px-3 py-2.5 text-[var(--muted)]">
|
||||
{c.description ?? "—"}
|
||||
</td>
|
||||
</tr>
|
||||
))}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<SectionHeader section="component" />
|
||||
<ComponentTable components={components ?? []} statuses={statuses} />
|
||||
</section>
|
||||
)}
|
||||
</div>
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
import { useParams, Link } from "react-router-dom"
|
||||
import { ArrowLeft, Server } from "lucide-react"
|
||||
import { useNode } from "@/services/api/hooks"
|
||||
import { RoleBadge } from "@/components/RoleBadge"
|
||||
import { BehaviorBadge } from "@/components/BehaviorBadge"
|
||||
import { StackBadge } from "@/components/StackBadge"
|
||||
import { cn } from "@/lib/utils"
|
||||
|
||||
export function NodeDetailPage() {
|
||||
@@ -62,7 +63,8 @@ export function NodeDetailPage() {
|
||||
<thead>
|
||||
<tr className="bg-[var(--card)] border-b border-[var(--border)] text-left">
|
||||
<th className="px-3 py-2 font-medium text-[var(--muted)]">Component</th>
|
||||
<th className="px-3 py-2 font-medium text-[var(--muted)]">Category</th>
|
||||
<th className="px-3 py-2 font-medium text-[var(--muted)]">Behavior</th>
|
||||
<th className="px-3 py-2 font-medium text-[var(--muted)]">Stack</th>
|
||||
<th className="px-3 py-2 font-medium text-[var(--muted)]">Runner</th>
|
||||
<th className="px-3 py-2 font-medium text-[var(--muted)]">Port</th>
|
||||
</tr>
|
||||
@@ -85,7 +87,10 @@ export function NodeDetailPage() {
|
||||
)}
|
||||
</td>
|
||||
<td className="px-3 py-2.5">
|
||||
<RoleBadge role={comp.category} />
|
||||
<BehaviorBadge behavior={comp.behavior} />
|
||||
</td>
|
||||
<td className="px-3 py-2.5">
|
||||
<StackBadge stack={comp.stack} />
|
||||
</td>
|
||||
<td className="px-3 py-2.5 text-[var(--muted)]">
|
||||
{comp.runner ?? "—"}
|
||||
|
||||
Reference in New Issue
Block a user