feat: Refactor tool management and update documentation for clarity
This commit is contained in:
@@ -3,7 +3,7 @@ import { Link } from "react-router-dom"
|
||||
import { ArrowDown, ArrowUp, ArrowUpDown, Download, Play, RefreshCw, Square, Trash2 } from "lucide-react"
|
||||
import type { ComponentSummary, HealthStatus } from "@/types"
|
||||
import { useServiceAction, useToolAction } from "@/services/api/hooks"
|
||||
import { runnerLabel, toolTypeLabel } from "@/lib/labels"
|
||||
import { runnerLabel } from "@/lib/labels"
|
||||
import { HealthBadge } from "./HealthBadge"
|
||||
import { RoleBadge } from "./RoleBadge"
|
||||
|
||||
@@ -12,7 +12,7 @@ interface ComponentTableProps {
|
||||
statuses: HealthStatus[]
|
||||
}
|
||||
|
||||
type SortKey = "id" | "role" | "runner" | "tool_type" | "category" | "schedule" | "port" | "status"
|
||||
type SortKey = "id" | "role" | "runner" | "schedule" | "port" | "status"
|
||||
type SortDir = "asc" | "desc"
|
||||
|
||||
function statusRank(s: HealthStatus | undefined, installed: boolean | null): number {
|
||||
@@ -76,10 +76,6 @@ export function ComponentTable({ components, statuses }: ComponentTableProps) {
|
||||
return dir * (a.roles[0] ?? "").localeCompare(b.roles[0] ?? "")
|
||||
case "runner":
|
||||
return dir * (a.runner ?? "").localeCompare(b.runner ?? "")
|
||||
case "tool_type":
|
||||
return dir * (a.tool_type ?? "").localeCompare(b.tool_type ?? "")
|
||||
case "category":
|
||||
return dir * (a.category ?? "").localeCompare(b.category ?? "")
|
||||
case "schedule":
|
||||
return dir * (a.schedule ?? "").localeCompare(b.schedule ?? "")
|
||||
case "port":
|
||||
@@ -137,8 +133,6 @@ export function ComponentTable({ components, statuses }: ComponentTableProps) {
|
||||
<SortHeader label="Name" sortKey="id" current={sortKey} dir={sortDir} onSort={toggleSort} />
|
||||
<SortHeader label="Roles" sortKey="role" current={sortKey} dir={sortDir} onSort={toggleSort} />
|
||||
<SortHeader label="Runner" sortKey="runner" current={sortKey} dir={sortDir} onSort={toggleSort} />
|
||||
<SortHeader label="Package" sortKey="tool_type" current={sortKey} dir={sortDir} onSort={toggleSort} />
|
||||
<SortHeader label="Category" sortKey="category" current={sortKey} dir={sortDir} onSort={toggleSort} />
|
||||
<SortHeader label="Schedule" sortKey="schedule" current={sortKey} dir={sortDir} onSort={toggleSort} />
|
||||
<SortHeader label="Port" sortKey="port" current={sortKey} dir={sortDir} onSort={toggleSort} />
|
||||
<SortHeader label="Status" sortKey="status" current={sortKey} dir={sortDir} onSort={toggleSort} />
|
||||
@@ -155,7 +149,7 @@ export function ComponentTable({ components, statuses }: ComponentTableProps) {
|
||||
))}
|
||||
{sorted.length === 0 && (
|
||||
<tr>
|
||||
<td colSpan={9} className="px-3 py-6 text-center text-[var(--muted)]">
|
||||
<td colSpan={7} className="px-3 py-6 text-center text-[var(--muted)]">
|
||||
No components match.
|
||||
</td>
|
||||
</tr>
|
||||
@@ -228,6 +222,7 @@ function ComponentRow({
|
||||
<Link
|
||||
to={`/${component.id}`}
|
||||
className="font-medium hover:text-[var(--primary)] transition-colors"
|
||||
title={component.systemd?.unit_path ?? undefined}
|
||||
>
|
||||
{component.id}
|
||||
</Link>
|
||||
@@ -247,12 +242,6 @@ function ComponentRow({
|
||||
<td className="px-3 py-2.5 text-[var(--muted)]">
|
||||
{component.runner ? runnerLabel(component.runner) : "—"}
|
||||
</td>
|
||||
<td className="px-3 py-2.5 text-[var(--muted)]">
|
||||
{component.tool_type ? toolTypeLabel(component.tool_type) : "—"}
|
||||
</td>
|
||||
<td className="px-3 py-2.5 text-[var(--muted)]">
|
||||
{component.category ?? "—"}
|
||||
</td>
|
||||
<td className="px-3 py-2.5 font-mono text-[var(--muted)]">
|
||||
{component.schedule ?? "—"}
|
||||
</td>
|
||||
|
||||
@@ -7,11 +7,6 @@ export const RUNNER_LABELS: Record<string, string> = {
|
||||
remote: "Remote",
|
||||
}
|
||||
|
||||
export const TOOL_TYPE_LABELS: Record<string, string> = {
|
||||
python_standalone: "Python package",
|
||||
script: "Shell script",
|
||||
}
|
||||
|
||||
export const ROLE_DESCRIPTIONS: Record<string, string> = {
|
||||
service: "Exposes HTTP endpoints",
|
||||
tool: "CLI utility installed to PATH",
|
||||
@@ -25,7 +20,3 @@ export const ROLE_DESCRIPTIONS: Record<string, string> = {
|
||||
export function runnerLabel(runner: string): string {
|
||||
return RUNNER_LABELS[runner] ?? runner
|
||||
}
|
||||
|
||||
export function toolTypeLabel(toolType: string): string {
|
||||
return TOOL_TYPE_LABELS[toolType] ?? toolType
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@ import { ArrowLeft, Check, Play, RefreshCw, Square } from "lucide-react"
|
||||
import { useQueryClient } from "@tanstack/react-query"
|
||||
import { apiClient } from "@/services/api/client"
|
||||
import { useComponent, useStatus, useServiceAction, useEventStream, useToolDetail } from "@/services/api/hooks"
|
||||
import { runnerLabel, toolTypeLabel } from "@/lib/labels"
|
||||
import { runnerLabel } from "@/lib/labels"
|
||||
import { ComponentFields } from "@/components/ComponentFields"
|
||||
import { HealthBadge } from "@/components/HealthBadge"
|
||||
import { LogViewer } from "@/components/LogViewer"
|
||||
@@ -142,12 +142,6 @@ export function ComponentDetailPage() {
|
||||
How this tool is packaged and what it depends on.
|
||||
</p>
|
||||
<div className="grid grid-cols-2 gap-x-6 gap-y-2 text-sm mb-4">
|
||||
{toolDetail.category && (
|
||||
<>
|
||||
<span className="text-[var(--muted)]">Category</span>
|
||||
<span>{toolDetail.category}</span>
|
||||
</>
|
||||
)}
|
||||
{toolDetail.source && (
|
||||
<>
|
||||
<span className="text-[var(--muted)]">Source</span>
|
||||
@@ -160,12 +154,6 @@ export function ComponentDetailPage() {
|
||||
<span>{toolDetail.version}</span>
|
||||
</>
|
||||
)}
|
||||
{toolDetail.tool_type && (
|
||||
<>
|
||||
<span className="text-[var(--muted)]">Type</span>
|
||||
<span>{toolTypeLabel(toolDetail.tool_type)}</span>
|
||||
</>
|
||||
)}
|
||||
{toolDetail.runner && (
|
||||
<>
|
||||
<span className="text-[var(--muted)]">Runner</span>
|
||||
@@ -199,6 +187,26 @@ export function ComponentDetailPage() {
|
||||
</div>
|
||||
)}
|
||||
|
||||
{component.systemd && (
|
||||
<div className="bg-[var(--card)] border border-[var(--border)] rounded-lg p-5 mb-6">
|
||||
<h2 className="text-sm font-semibold text-[var(--muted)] uppercase tracking-wider mb-1">
|
||||
Systemd
|
||||
</h2>
|
||||
<div className="grid grid-cols-2 gap-x-6 gap-y-2 text-sm mt-3">
|
||||
<span className="text-[var(--muted)]">Unit</span>
|
||||
<span className="font-mono">{component.systemd.unit_name}</span>
|
||||
<span className="text-[var(--muted)]">Path</span>
|
||||
<span className="font-mono">{component.systemd.unit_path}</span>
|
||||
{component.systemd.timer && (
|
||||
<>
|
||||
<span className="text-[var(--muted)]">Timer</span>
|
||||
<span>Active</span>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
<div className="bg-[var(--card)] border border-[var(--border)] rounded-lg p-5 mb-6">
|
||||
<h2 className="text-sm font-semibold text-[var(--muted)] uppercase tracking-wider mb-4">
|
||||
Configuration
|
||||
|
||||
@@ -1,3 +1,9 @@
|
||||
export interface SystemdInfo {
|
||||
unit_name: string
|
||||
unit_path: string
|
||||
timer: boolean
|
||||
}
|
||||
|
||||
export interface ComponentSummary {
|
||||
id: string
|
||||
description: string | null
|
||||
@@ -7,9 +13,8 @@ export interface ComponentSummary {
|
||||
health_path: string | null
|
||||
proxy_path: string | null
|
||||
managed: boolean
|
||||
category: string | null
|
||||
systemd: SystemdInfo | null
|
||||
version: string | null
|
||||
tool_type: string | null
|
||||
source: string | null
|
||||
system_dependencies: string[]
|
||||
schedule: string | null
|
||||
@@ -57,9 +62,7 @@ export interface SSEServiceActionEvent {
|
||||
export interface ToolSummary {
|
||||
id: string
|
||||
description: string | null
|
||||
category: string | null
|
||||
source: string | null
|
||||
tool_type: string | null
|
||||
version: string | null
|
||||
runner: string | null
|
||||
system_dependencies: string[]
|
||||
|
||||
Reference in New Issue
Block a user