From 6f32561e20ea2619d4c6ad2cadb841f4c5144608 Mon Sep 17 00:00:00 2001 From: Sam Newby Date: Sat, 15 Nov 2025 02:25:36 +0000 Subject: [PATCH 1/3] chore: init deployments, tabs, and tidy --- src/components/tabs.tsx | 16 +++++++++++++++ src/constants.ts | 19 ++++++++++++++++++ src/index.tsx | 39 ++++++++++++------------------------ src/views/workers/single.tsx | 14 ++++++++++++- 4 files changed, 61 insertions(+), 27 deletions(-) create mode 100644 src/components/tabs.tsx create mode 100644 src/constants.ts 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..51c4012 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('events'); + const { start, end } = CloudflareAPI.getTimeRange(24); const nowTimestamp = Date.now(); const startTimestamp = nowTimestamp - 24 * 60 * 60 * 1000; @@ -217,9 +202,15 @@ 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') { + setActiveTab( + WORKER_TABS[(WORKER_TABS.indexOf(activeTab) + 1) % WORKER_TABS.length] as typeof WORKER_TABS[number], + ); + } } if (key.name === "escape" || key.name === "esc") { @@ -298,13 +289,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 +355,7 @@ 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 65b65c7..9bbc3f1 100644 --- a/src/views/workers/single.tsx +++ b/src/views/workers/single.tsx @@ -3,11 +3,22 @@ import { useEffect, useState } from "react"; import type { WorkerSummary } from "../../types"; import { getConfig } from "../../config"; import { CloudflareAPI } from "../../api"; +import Tabs from "../../components/tabs"; -function SingleWorkerView({ focussedItemLogs, focussedItem }: { focussedItemLogs: any[], focussedItem: string }) { +function SingleWorkerView({ focussedItemLogs, focussedItem, activeTab }: { focussedItemLogs: any[], focussedItem: string, activeTab: string }) { const logCount = Array.isArray(focussedItemLogs) ? focussedItemLogs.length : 0; const [metrics, setMetrics] = useState(null); const { start, end } = CloudflareAPI.getTimeRange(24); + const tabs = [ + { + label: 'Events', + value: 'events', + }, + { + label: 'Deployments', + value: 'deployments', + }, + ]; useEffect(() => { const fetchMetrics = async () => { @@ -25,6 +36,7 @@ function SingleWorkerView({ focussedItemLogs, focussedItem }: { focussedItemLogs return ( + Date: Sun, 16 Nov 2025 23:08:00 +0000 Subject: [PATCH 2/3] chore: fix --- src/views/workers/single.tsx | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/src/views/workers/single.tsx b/src/views/workers/single.tsx index 2df2db6..b322716 100644 --- a/src/views/workers/single.tsx +++ b/src/views/workers/single.tsx @@ -5,13 +5,16 @@ import type { WorkerSummary } from "../../types"; import { getConfig } from "../../config"; import { CloudflareAPI } from "../../api"; import { useKeyboard } from "@opentui/react"; +import Tabs from "../../components/tabs"; function SingleWorkerView({ focussedItemLogs, focussedItem, + activeTab, }: { focussedItemLogs: any[]; focussedItem: string; + activeTab: string; }) { const logCount = Array.isArray(focussedItemLogs) ? focussedItemLogs.length @@ -19,6 +22,16 @@ function SingleWorkerView({ const [metrics, setMetrics] = useState(null); const [showTimestamp, setShowTimestamp] = useState(true); const { start, end } = CloudflareAPI.getTimeRange(24); + const tabs = [ + { + label: 'Events', + value: 'events', + }, + { + label: 'Deployments', + value: 'deployments', + }, + ]; useKeyboard((key) => { if (key.name === "t") { @@ -46,8 +59,7 @@ function SingleWorkerView({ return ( - - + + ); } From a6f8fa38a23b95ec5618fbc420d9296e1687030b Mon Sep 17 00:00:00 2001 From: Sam Newby Date: Sun, 23 Nov 2025 23:39:14 +0000 Subject: [PATCH 3/3] chore: tidying --- src/index.tsx | 14 ++--- src/views/workers/single.tsx | 108 +++++++++++++++++++++-------------- 2 files changed, 71 insertions(+), 51 deletions(-) diff --git a/src/index.tsx b/src/index.tsx index 51c4012..76a67ba 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -89,7 +89,7 @@ if (positionals.length == 2) { const [metrics, setMetrics] = useState([]); const [loading, setLoading] = useState(false); - const [activeTab, setActiveTab] = useState('events'); + const [activeTab, setActiveTab] = useState<(typeof WORKER_TABS)[number]>("events"); const { start, end } = CloudflareAPI.getTimeRange(24); const nowTimestamp = Date.now(); @@ -202,14 +202,11 @@ if (positionals.length == 2) { } if (key.name === "tab") { - if (view === 'home') { + if (view === "home") { setFocussedSection( PANELS[(PANELS.indexOf(focussedSection) + 1) % PANELS.length] as string, ); - } else if (view === 'single-worker') { - setActiveTab( - WORKER_TABS[(WORKER_TABS.indexOf(activeTab) + 1) % WORKER_TABS.length] as typeof WORKER_TABS[number], - ); + } else if (view === "single-worker") { } } @@ -355,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 b322716..7c58790 100644 --- a/src/views/workers/single.tsx +++ b/src/views/workers/single.tsx @@ -6,21 +6,22 @@ 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, - activeTab, }: { focussedItemLogs: any[]; focussedItem: string; - activeTab: string; }) { 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 = [ { @@ -37,6 +38,18 @@ function SingleWorkerView({ if (key.name === "t") { setShowTimestamp((prev) => !prev); } + + if (key.name === 'tab') { + setActiveTab( + WORKER_TABS[ + (WORKER_TABS.indexOf(activeTab) + 1) % WORKER_TABS.length + ] as (typeof WORKER_TABS)[number], + ); + } + + if (key.name === "return") { + setActiveTab("events"); + } }); useEffect(() => { @@ -61,51 +74,58 @@ function SingleWorkerView({ - - - - - - - {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); + {view === "events" && ( + + + + + + + {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} + return ( + + + {showTimestamp && } + {logMessage} + - - ); - }) - ) : ( - No logs yet... - )} + ); + }) + ) : ( + No logs yet... + )} + + + )} + {view === "deployments" && ( + + Deployments - + )} );