Add Last Seen column and color-coded status badges in Machines table
- New Last Seen column showing last_seen_at timestamp per machine - Status badges: online=green (success), offline=red (error), waking/pending=amber - Update Machine interface with last_seen_at and created_at fields
This commit is contained in:
@@ -1,5 +1,5 @@
|
|||||||
BINARY=syncserver
|
BINARY=syncserver
|
||||||
VERSION?=1.0.40
|
VERSION?=1.0.41
|
||||||
GO?=go
|
GO?=go
|
||||||
LDFLAGS=-s -w -X main.version=$(VERSION) -X main.commit=$(shell git rev-parse --short HEAD 2>/dev/null || echo unknown)
|
LDFLAGS=-s -w -X main.version=$(VERSION) -X main.commit=$(shell git rev-parse --short HEAD 2>/dev/null || echo unknown)
|
||||||
BUILD_FLAGS=CGO_ENABLED=0
|
BUILD_FLAGS=CGO_ENABLED=0
|
||||||
|
|||||||
+1
-1
@@ -20,7 +20,7 @@ import (
|
|||||||
"github.com/syncserver/internal/syncengine"
|
"github.com/syncserver/internal/syncengine"
|
||||||
)
|
)
|
||||||
|
|
||||||
var version = "1.0.40"
|
var version = "1.0.41"
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
cfgPath := flag.String("config", "", "Path to config.yaml")
|
cfgPath := flag.String("config", "", "Path to config.yaml")
|
||||||
|
|||||||
@@ -53,6 +53,8 @@ export interface Machine {
|
|||||||
fingerprint_confirmed: boolean;
|
fingerprint_confirmed: boolean;
|
||||||
host_key_fingerprint: string | null;
|
host_key_fingerprint: string | null;
|
||||||
status: string;
|
status: string;
|
||||||
|
last_seen_at: string | null;
|
||||||
|
created_at: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface TestConnectionResponse {
|
export interface TestConnectionResponse {
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ export type BadgeVariant = VariantProps<typeof badgeVariants>['variant']
|
|||||||
const STATUS_TO_VARIANT: Record<string, BadgeVariant> = {
|
const STATUS_TO_VARIANT: Record<string, BadgeVariant> = {
|
||||||
running: 'running',
|
running: 'running',
|
||||||
pending: 'pending',
|
pending: 'pending',
|
||||||
waking: 'waking',
|
waking: 'pending',
|
||||||
success: 'success',
|
success: 'success',
|
||||||
error: 'error',
|
error: 'error',
|
||||||
failed: 'error',
|
failed: 'error',
|
||||||
@@ -33,6 +33,8 @@ const STATUS_TO_VARIANT: Record<string, BadgeVariant> = {
|
|||||||
cancelled: 'neutral',
|
cancelled: 'neutral',
|
||||||
info: 'info',
|
info: 'info',
|
||||||
unknown: 'neutral',
|
unknown: 'neutral',
|
||||||
|
online: 'success',
|
||||||
|
offline: 'error',
|
||||||
}
|
}
|
||||||
|
|
||||||
export function statusVariant(status: string): BadgeVariant {
|
export function statusVariant(status: string): BadgeVariant {
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import { Input } from '@/components/ui/Input';
|
|||||||
import { Label } from '@/components/ui/Label';
|
import { Label } from '@/components/ui/Label';
|
||||||
import { Select, SelectValue, SelectTrigger, SelectContent, SelectItem } from '@/components/ui/Select';
|
import { Select, SelectValue, SelectTrigger, SelectContent, SelectItem } from '@/components/ui/Select';
|
||||||
import { Badge } from '@/components/ui/Badge';
|
import { Badge } from '@/components/ui/Badge';
|
||||||
|
import { statusVariant } from '@/lib/status';
|
||||||
import {
|
import {
|
||||||
Modal,
|
Modal,
|
||||||
ModalContent,
|
ModalContent,
|
||||||
@@ -278,6 +279,7 @@ export default function Machines() {
|
|||||||
<TableHead>WoL</TableHead>
|
<TableHead>WoL</TableHead>
|
||||||
<TableHead>WoL Timeout</TableHead>
|
<TableHead>WoL Timeout</TableHead>
|
||||||
<TableHead>Status</TableHead>
|
<TableHead>Status</TableHead>
|
||||||
|
<TableHead>Last Seen</TableHead>
|
||||||
<TableHead className="w-24">Actions</TableHead>
|
<TableHead className="w-24">Actions</TableHead>
|
||||||
</TableRow>
|
</TableRow>
|
||||||
</TableHeader>
|
</TableHeader>
|
||||||
@@ -312,6 +314,11 @@ export default function Machines() {
|
|||||||
<TableCell>
|
<TableCell>
|
||||||
<StatusBadge status={m.status} />
|
<StatusBadge status={m.status} />
|
||||||
</TableCell>
|
</TableCell>
|
||||||
|
<TableCell>
|
||||||
|
<span className="text-xs text-fg-muted">
|
||||||
|
{m.last_seen_at ? new Date(m.last_seen_at).toLocaleString() : <span className="text-fg-subtle">—</span>}
|
||||||
|
</span>
|
||||||
|
</TableCell>
|
||||||
<TableCell>
|
<TableCell>
|
||||||
<div className="flex items-center gap-1">
|
<div className="flex items-center gap-1">
|
||||||
<Button
|
<Button
|
||||||
@@ -696,11 +703,5 @@ export default function Machines() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function StatusBadge({ status }: { status: string }) {
|
function StatusBadge({ status }: { status: string }) {
|
||||||
const variant =
|
return <Badge variant={statusVariant(status)} label={status} />;
|
||||||
status === 'online'
|
|
||||||
? 'success'
|
|
||||||
: status === 'offline'
|
|
||||||
? 'neutral'
|
|
||||||
: 'info';
|
|
||||||
return <Badge variant={variant} label={status} />;
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user