diff --git a/src/components/tabs.tsx b/src/components/tabs.tsx new file mode 100644 index 0000000..031e992 --- /dev/null +++ b/src/components/tabs.tsx @@ -0,0 +1,16 @@ +interface Tab { + label: string; + value: string; +} + +export default function Tabs({ tabs, activeTab }: { tabs: Tab[], activeTab: string }) { + return ( + + {tabs.map((tab) => ( + + {tab.label} + + ))} + + ); +} \ No newline at end of file diff --git a/src/constants.ts b/src/constants.ts new file mode 100644 index 0000000..64c88e8 --- /dev/null +++ b/src/constants.ts @@ -0,0 +1,19 @@ +export const VIEWS = [ + "home", + "single-worker", + "single-r2-bucket", + "single-d1-database", + "single-queue", +]; + +export const PANELS = [ + "workers", + "durables", + "buckets", + "domains", + "queues", + "d1", + "kv", +]; + +export const WORKER_TABS = ["events", "deployments"] as const; \ No newline at end of file diff --git a/src/index.tsx b/src/index.tsx index 5dc9205..76a67ba 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -32,6 +32,7 @@ import SingleD1DatabaseView from "./views/d1/single"; import SingleQueueView from "./views/queues/single"; import { CheckForUpdate } from "./components/utils/check-for-update"; import type { Namespace } from "cloudflare/src/resources/kv.js"; +import { PANELS, WORKER_TABS } from "./constants"; const { values, positionals } = parseArgs({ args: Bun.argv, @@ -67,24 +68,6 @@ if (positionals.length == 2) { // user has just called cftop function App() { - const views = [ - "home", - "single-worker", - "single-r2-bucket", - "single-d1-database", - "single-queue", - ]; - - const panels = [ - "workers", - "durables", - "buckets", - "domains", - "queues", - "d1", - "kv", - ]; - const renderer = useRenderer(); const [view, setView] = useState("home"); const [workers, setWorkers] = useState([]); @@ -106,6 +89,8 @@ if (positionals.length == 2) { const [metrics, setMetrics] = useState([]); const [loading, setLoading] = useState(false); + const [activeTab, setActiveTab] = useState<(typeof WORKER_TABS)[number]>("events"); + const { start, end } = CloudflareAPI.getTimeRange(24); const nowTimestamp = Date.now(); const startTimestamp = nowTimestamp - 24 * 60 * 60 * 1000; @@ -217,9 +202,12 @@ if (positionals.length == 2) { } if (key.name === "tab") { - setFocussedSection( - panels[(panels.indexOf(focussedSection) + 1) % panels.length] as string, - ); + if (view === "home") { + setFocussedSection( + PANELS[(PANELS.indexOf(focussedSection) + 1) % PANELS.length] as string, + ); + } else if (view === "single-worker") { + } } if (key.name === "escape" || key.name === "esc") { @@ -298,13 +286,9 @@ if (positionals.length == 2) { const nextIndex = (currentIndex + 1) % d1Databases.length; setFocussedItem(d1Databases[nextIndex]?.uuid || ""); } else if (focussedSection === "queues") { - console.log("down in queues"); const currentIndex = queues.findIndex((q) => q.queue_id === focussedItem); - console.log(`queues current index: ${currentIndex}`); const nextIndex = (currentIndex + 1) % queues.length; - console.log(`queues next index: ${nextIndex}`); setFocussedItem(queues[nextIndex]?.queue_id || ""); - console.log(`queues focussed item: ${focussedItem}`); } else { setFocussedItem(""); } @@ -368,7 +352,10 @@ if (positionals.length == 2) { ); } else if (view === "single-worker") { visibleView = ( - + ); } else if (view === "single-r2-bucket") { visibleView = ; diff --git a/src/views/workers/single.tsx b/src/views/workers/single.tsx index 6342676..7c58790 100644 --- a/src/views/workers/single.tsx +++ b/src/views/workers/single.tsx @@ -5,105 +5,138 @@ import type { WorkerSummary } from "../../types"; import { getConfig } from "../../config"; import { CloudflareAPI } from "../../api"; import { useKeyboard } from "@opentui/react"; +import Tabs from "../../components/tabs"; +import { WORKER_TABS } from "../../constants"; function SingleWorkerView({ - focussedItemLogs, - focussedItem, + focussedItemLogs, + focussedItem, }: { - focussedItemLogs: any[]; - focussedItem: string; + focussedItemLogs: any[]; + focussedItem: string; }) { - const logCount = Array.isArray(focussedItemLogs) - ? focussedItemLogs.length - : 0; - const [metrics, setMetrics] = useState(null); - const [showTimestamp, setShowTimestamp] = useState(true); - const { start, end } = CloudflareAPI.getTimeRange(24); + const logCount = Array.isArray(focussedItemLogs) + ? focussedItemLogs.length + : 0; + const [view, setView] = useState<"events" | "deployments">("events"); + const [metrics, setMetrics] = useState(null); + const [showTimestamp, setShowTimestamp] = useState(true); + const [activeTab, setActiveTab] = useState("events"); + const { start, end } = CloudflareAPI.getTimeRange(24); + const tabs = [ + { + label: 'Events', + value: 'events', + }, + { + label: 'Deployments', + value: 'deployments', + }, + ]; - useKeyboard((key) => { - if (key.name === "t") { - setShowTimestamp((prev) => !prev); - } - }); + useKeyboard((key) => { + if (key.name === "t") { + setShowTimestamp((prev) => !prev); + } - useEffect(() => { - const fetchMetrics = async () => { - const config = await getConfig(); - const api = new CloudflareAPI({ - apiToken: config.apiToken, - accountTag: config.accountId, - }); - const metrics = await api.getSingleWorkerSummary( - focussedItem, - start, - end, - ); - setMetrics(metrics); - }; - fetchMetrics(); - }, [focussedItem]); + if (key.name === 'tab') { + setActiveTab( + WORKER_TABS[ + (WORKER_TABS.indexOf(activeTab) + 1) % WORKER_TABS.length + ] as (typeof WORKER_TABS)[number], + ); + } - return ( - - + if (key.name === "return") { + setActiveTab("events"); + } + }); - + useEffect(() => { + const fetchMetrics = async () => { + const config = await getConfig(); + const api = new CloudflareAPI({ + apiToken: config.apiToken, + accountTag: config.accountId, + }); + const metrics = await api.getSingleWorkerSummary( + focussedItem, + start, + end, + ); + setMetrics(metrics); + }; + fetchMetrics(); + }, [focussedItem]); - - - - - - - {focussedItem} events ({logCount} total) - - - - - {/* @ts-ignore */} - {focussedItemLogs && - Array.isArray(focussedItemLogs) && - focussedItemLogs.length > 0 ? ( - focussedItemLogs.map((log: any, index: number) => { - const logMessage = - log.$metadata?.messageTemplate || JSON.stringify(log); + return ( + + + - return ( - - - {showTimestamp && } - {logMessage} - + + + + + + {focussedItem} events ({logCount} total) + + + + + {/* @ts-ignore */} + {focussedItemLogs && + Array.isArray(focussedItemLogs) && + focussedItemLogs.length > 0 ? ( + focussedItemLogs.map((log: any, index: number) => { + const logMessage = + log.$metadata?.messageTemplate || JSON.stringify(log); + + return ( + + + {showTimestamp && } + {logMessage} + + + ); + }) + ) : ( + No logs yet... + )} + + + )} + {view === "deployments" && ( + + Deployments - ); - }) - ) : ( - No logs yet... - )} + )} + - - - ); + ); } function Keybindings() { - return ( - - t: toggle timestamp - - ); + return ( + + t: toggle timestamp + + ); } export default SingleWorkerView;