diff --git a/site/bun.lockb b/site/bun.lockb
index 3763ac4..c35f27c 100755
Binary files a/site/bun.lockb and b/site/bun.lockb differ
diff --git a/site/package.json b/site/package.json
index 2290537..36c6572 100644
--- a/site/package.json
+++ b/site/package.json
@@ -10,6 +10,7 @@
},
"dependencies": {
"@nanostores/preact": "^0.5.1",
+ "@radix-ui/react-alert-dialog": "^1.1.1",
"@radix-ui/react-dialog": "^1.1.1",
"@radix-ui/react-dropdown-menu": "^2.1.1",
"@radix-ui/react-label": "^2.1.0",
diff --git a/site/src/components/command-dialog.tsx b/site/src/components/command-dialog.tsx
index 2881ec3..90d0cbf 100644
--- a/site/src/components/command-dialog.tsx
+++ b/site/src/components/command-dialog.tsx
@@ -1,6 +1,6 @@
'use client'
-import { Database, Home, Server } from 'lucide-react'
+import { Database, Github, Home, Server } from 'lucide-react'
import {
CommandDialog,
@@ -14,9 +14,12 @@ import {
} from '@/components/ui/command'
import { useEffect, useState } from 'preact/hooks'
import { navigate } from 'wouter-preact/use-browser-location'
+import { useStore } from '@nanostores/preact'
+import { $servers } from '@/lib/stores'
export function CommandPalette() {
const [open, setOpen] = useState(false)
+ const servers = useStore($servers)
useEffect(() => {
const down = (e: KeyboardEvent) => {
@@ -45,6 +48,7 @@ export function CommandPalette() {
>
Enter your email to sign in to your account @@ -33,19 +37,12 @@ export default function LoginPage() { }} >
diff --git a/site/src/components/routes/home.tsx b/site/src/components/routes/home.tsx index 9c18991..fb78072 100644 --- a/site/src/components/routes/home.tsx +++ b/site/src/components/routes/home.tsx @@ -1,47 +1,56 @@ -import { useEffect, useState } from 'preact/hooks' -import { pb } from '@/lib/stores' -import { SystemRecord } from '@/types' +import { useEffect } from 'preact/hooks' +import { $servers, pb } from '@/lib/stores' import { DataTable } from '../server-table/data-table' import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '../ui/card' +import { useStore } from '@nanostores/preact' +import { SystemRecord } from '@/types' export function Home() { - const [systems, setSystems] = useState([] as SystemRecord[]) + const servers = useStore($servers) + // const [systems, setSystems] = useState([] as SystemRecord[]) useEffect(() => { document.title = 'Home' }, []) useEffect(() => { - pb.collection('systems') - .getFullList({ - sort: 'name', - }) - .then((items) => { - setSystems(items) - }) + console.log('servers', servers) + }, [servers]) - // pb.collection ('systems').subscribe('*', (e) => { - // setSystems((curSystems) => { - // const i = curSystems.findIndex((s) => s.id === e.record.id) - // if (i > -1) { - // const newSystems = [...curSystems] - // newSystems[i] = e.record - // return newSystems - // } else { - // return [...curSystems, e.record] - // } - // }) - // }) - // return () => pb.collection('systems').unsubscribe('*') + useEffect(() => { + pb.collection ('systems').subscribe('*', (e) => { + const curServers = $servers.get() + const newServers = [] + console.log('e', e) + if (e.action === 'delete') { + for (const server of curServers) { + if (server.id !== e.record.id) { + newServers.push(server) + } + } + } else { + let found = 0 + for (const server of curServers) { + if (server.id === e.record.id) { + found = newServers.push(e.record) + } else { + newServers.push(server) + } + } + if (!found) { + newServers.push(e.record) + } + } + $servers.set(newServers) + }) + return () => pb.collection('systems').unsubscribe('*') }, []) - // if (!systems.length) return <>Loading...> - return ( <> - {/* - All Systems +All Servers Press{' '} @@ -51,10 +60,9 @@ export function Home() { - + {JSON.stringify(systems, null, 2)}*/} > ) } diff --git a/site/src/components/routes/server.tsx b/site/src/components/routes/server.tsx index 72e62f0..f4e4ed5 100644 --- a/site/src/components/routes/server.tsx +++ b/site/src/components/routes/server.tsx @@ -6,7 +6,7 @@ import { Card, CardHeader, CardTitle, CardDescription, CardContent } from '../ui export function ServerDetail() { const [_, params] = useRoute('/server/:name') - const [node, setNode] = useState({} as SystemRecord) + const [server, setServer] = useState({} as SystemRecord) useEffect(() => { document.title = params!.name @@ -16,7 +16,7 @@ export function ServerDetail() { pb.collection('systems') .getFirstListItem(`name="${params!.name}"`) .then((record) => { - setNode(record) + setServer(record) }) }) @@ -24,11 +24,11 @@ export function ServerDetail() { <> > diff --git a/site/src/components/server-table/data-table.tsx b/site/src/components/server-table/data-table.tsx index 101160b..b5ac83f 100644 --- a/site/src/components/server-table/data-table.tsx +++ b/site/src/components/server-table/data-table.tsx @@ -32,10 +32,23 @@ import { DropdownMenuTrigger, } from '@/components/ui/dropdown-menu' +import { + AlertDialog, + AlertDialogAction, + AlertDialogCancel, + AlertDialogContent, + AlertDialogDescription, + AlertDialogFooter, + AlertDialogHeader, + AlertDialogTitle, +} from '@/components/ui/alert-dialog' + import { SystemRecord } from '@/types' -import { MoreHorizontal, ArrowUpDown, Copy, RefreshCcw } from 'lucide-react' -import { Link } from 'wouter-preact' -import { useState } from 'preact/hooks' +import { MoreHorizontal, ArrowUpDown, Copy, RefreshCcw, Eye } from 'lucide-react' +import { useMemo, useState } from 'preact/hooks' +import { navigate } from 'wouter-preact/use-browser-location' +import { $servers, pb } from '@/lib/stores' +import { useStore } from '@nanostores/preact' function CellFormatter(info: CellContext - {node.name} +{server.name} 5.342.34.234 - {JSON.stringify(node, null, 2)}+{JSON.stringify(server, null, 2)}) { const val = info.getValue() as number @@ -73,76 +86,91 @@ function sortableHeader(column: Column , name: string) { ) } -export function DataTable({ data }: { data: SystemRecord[] }) { - const columns: ColumnDef [] = [ - { - // size: 70, - accessorKey: 'name', - cell: (info) => ( - - {info.getValue() as string}{' '} - - {/* */} - - ), - header: ({ column }) => sortableHeader(column, 'Node'), - }, - { - accessorKey: 'stats.cpu', - cell: CellFormatter, - header: ({ column }) => sortableHeader(column, 'CPU'), - }, - { - accessorKey: 'stats.memPct', - cell: CellFormatter, - header: ({ column }) => sortableHeader(column, 'Memory'), - }, - { - accessorKey: 'stats.diskPct', - cell: CellFormatter, - header: ({ column }) => sortableHeader(column, 'Disk'), - }, - { - id: 'actions', - size: 32, - maxSize: 32, - cell: ({ row }) => { - const system = row.original +export function DataTable() { + const data = useStore($servers) + const [liveUpdates, setLiveUpdates] = useState(true) + const [deleteServer, setDeleteServer] = useState({} as SystemRecord) - return ( - -- ) + const columns: ColumnDef- -- - -- -Actions -- - View details - - -navigator.clipboard.writeText(system.id)}> - Copy IP address - -- Delete node -[] = useMemo( + () => [ + { + // size: 70, + accessorKey: 'name', + cell: (info) => ( + + {info.getValue() as string}{' '} + + {/* */} + + ), + header: ({ column }) => sortableHeader(column, 'Server'), }, - }, - ] + { + accessorKey: 'stats.cpu', + cell: CellFormatter, + header: ({ column }) => sortableHeader(column, 'CPU'), + }, + { + accessorKey: 'stats.memPct', + cell: CellFormatter, + header: ({ column }) => sortableHeader(column, 'Memory'), + }, + { + accessorKey: 'stats.diskPct', + cell: CellFormatter, + header: ({ column }) => sortableHeader(column, 'Disk'), + }, + { + id: 'actions', + size: 32, + maxSize: 32, + cell: ({ row }) => { + const system = row.original + + return ( + ++ ) + }, + }, + ], + [] + ) const [sorting, setSorting] = useState+ ++ + ++ +Actions +{ + navigate(`/server/${system.name}`) + }} + > + View details + +navigator.clipboard.writeText(system.id)}> + Copy IP address + ++ { + setDeleteServer(system) + }} + > + Delete server + +([]) @@ -172,16 +200,32 @@ export function DataTable({ data }: { data: SystemRecord[] }) { onChange={(event: Event) => table.getColumn('name')?.setFilterValue(event.target.value)} className="max-w-sm" /> - + + {liveUpdates || ( + + )} + +
{deleteServer.name}
from the database.
+