@wopr-network/platform-ui-core 1.6.0 → 1.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json
CHANGED
|
@@ -4,6 +4,7 @@ import { ArrowDownToLine, Loader2, MoreHorizontal, Pencil } from "lucide-react";
|
|
|
4
4
|
import Link from "next/link";
|
|
5
5
|
import { useMemo, useState } from "react";
|
|
6
6
|
import { toast } from "sonner";
|
|
7
|
+
import { UpdateAvailableBadge } from "@/components/instances/update-available-badge";
|
|
7
8
|
import { StatusBadge } from "@/components/status-badge";
|
|
8
9
|
import {
|
|
9
10
|
AlertDialog,
|
|
@@ -285,7 +286,14 @@ export function InstanceListClient() {
|
|
|
285
286
|
</Link>
|
|
286
287
|
</TableCell>
|
|
287
288
|
<TableCell>
|
|
288
|
-
<
|
|
289
|
+
<div className="flex items-center gap-2">
|
|
290
|
+
<StatusBadge status={inst.status} />
|
|
291
|
+
<InstanceUpdateBadge
|
|
292
|
+
instanceId={inst.id}
|
|
293
|
+
instanceName={inst.name}
|
|
294
|
+
onUpdated={refetch}
|
|
295
|
+
/>
|
|
296
|
+
</div>
|
|
289
297
|
</TableCell>
|
|
290
298
|
<TableCell className="text-muted-foreground">{inst.provider}</TableCell>
|
|
291
299
|
<TableCell className="text-muted-foreground">
|
|
@@ -538,3 +546,32 @@ export function InstanceRowActions({
|
|
|
538
546
|
</>
|
|
539
547
|
);
|
|
540
548
|
}
|
|
549
|
+
|
|
550
|
+
/* --- Instance Update Badge — inline "Update" pill next to status --- */
|
|
551
|
+
|
|
552
|
+
function InstanceUpdateBadge({
|
|
553
|
+
instanceId,
|
|
554
|
+
instanceName,
|
|
555
|
+
onUpdated,
|
|
556
|
+
}: {
|
|
557
|
+
instanceId: string;
|
|
558
|
+
instanceName: string;
|
|
559
|
+
onUpdated?: () => void;
|
|
560
|
+
}) {
|
|
561
|
+
const { updateAvailable } = useImageStatus(instanceId);
|
|
562
|
+
const { data: changelog } = trpc.fleet.getChangelog.useQuery(
|
|
563
|
+
{ instanceId },
|
|
564
|
+
{ enabled: updateAvailable },
|
|
565
|
+
);
|
|
566
|
+
|
|
567
|
+
if (!updateAvailable) return null;
|
|
568
|
+
|
|
569
|
+
return (
|
|
570
|
+
<UpdateAvailableBadge
|
|
571
|
+
instanceId={instanceId}
|
|
572
|
+
instanceName={instanceName}
|
|
573
|
+
changelog={changelog ?? null}
|
|
574
|
+
onUpdated={onUpdated}
|
|
575
|
+
/>
|
|
576
|
+
);
|
|
577
|
+
}
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import { ArrowUpCircle, Loader2 } from "lucide-react";
|
|
4
|
+
import { useState } from "react";
|
|
5
|
+
import { toast } from "sonner";
|
|
6
|
+
import {
|
|
7
|
+
AlertDialog,
|
|
8
|
+
AlertDialogAction,
|
|
9
|
+
AlertDialogCancel,
|
|
10
|
+
AlertDialogContent,
|
|
11
|
+
AlertDialogDescription,
|
|
12
|
+
AlertDialogFooter,
|
|
13
|
+
AlertDialogHeader,
|
|
14
|
+
AlertDialogTitle,
|
|
15
|
+
AlertDialogTrigger,
|
|
16
|
+
} from "@/components/ui/alert-dialog";
|
|
17
|
+
import { Badge } from "@/components/ui/badge";
|
|
18
|
+
import { pullImageUpdate } from "@/lib/api";
|
|
19
|
+
import { toUserMessage } from "@/lib/errors";
|
|
20
|
+
|
|
21
|
+
interface ChangelogSection {
|
|
22
|
+
title: string;
|
|
23
|
+
items: string[];
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
interface Changelog {
|
|
27
|
+
version: string;
|
|
28
|
+
date: string;
|
|
29
|
+
sections: ChangelogSection[];
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
interface UpdateAvailableBadgeProps {
|
|
33
|
+
instanceId: string;
|
|
34
|
+
instanceName: string;
|
|
35
|
+
changelog?: Changelog | null;
|
|
36
|
+
onUpdated?: () => void;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export function UpdateAvailableBadge({
|
|
40
|
+
instanceId,
|
|
41
|
+
instanceName,
|
|
42
|
+
changelog,
|
|
43
|
+
onUpdated,
|
|
44
|
+
}: UpdateAvailableBadgeProps) {
|
|
45
|
+
const [pulling, setPulling] = useState(false);
|
|
46
|
+
|
|
47
|
+
async function handleUpdate() {
|
|
48
|
+
setPulling(true);
|
|
49
|
+
try {
|
|
50
|
+
await pullImageUpdate(instanceId);
|
|
51
|
+
toast.success(`${instanceName} is updating...`);
|
|
52
|
+
onUpdated?.();
|
|
53
|
+
} catch (err) {
|
|
54
|
+
toast.error(toUserMessage(err));
|
|
55
|
+
} finally {
|
|
56
|
+
setPulling(false);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
return (
|
|
61
|
+
<AlertDialog>
|
|
62
|
+
<AlertDialogTrigger asChild>
|
|
63
|
+
<Badge
|
|
64
|
+
variant="outline"
|
|
65
|
+
className="cursor-pointer gap-1 border-amber-500/30 bg-amber-500/10 text-amber-500 hover:bg-amber-500/20 transition-colors"
|
|
66
|
+
>
|
|
67
|
+
<ArrowUpCircle className="h-3 w-3" />
|
|
68
|
+
Update
|
|
69
|
+
</Badge>
|
|
70
|
+
</AlertDialogTrigger>
|
|
71
|
+
<AlertDialogContent>
|
|
72
|
+
<AlertDialogHeader>
|
|
73
|
+
<AlertDialogTitle>Update Available for {instanceName}</AlertDialogTitle>
|
|
74
|
+
<AlertDialogDescription>
|
|
75
|
+
A new version is ready. This will pull the latest image and restart the instance.
|
|
76
|
+
</AlertDialogDescription>
|
|
77
|
+
</AlertDialogHeader>
|
|
78
|
+
|
|
79
|
+
{changelog && changelog.sections.length > 0 && (
|
|
80
|
+
<div className="max-h-64 overflow-y-auto rounded-md border border-border bg-muted/30 p-4 text-sm">
|
|
81
|
+
<p className="mb-2 font-medium text-foreground">What's new ({changelog.date})</p>
|
|
82
|
+
{changelog.sections.map((section) => (
|
|
83
|
+
<div key={section.title} className="mb-3 last:mb-0">
|
|
84
|
+
<p className="mb-1 text-xs font-semibold uppercase tracking-wider text-muted-foreground">
|
|
85
|
+
{section.title}
|
|
86
|
+
</p>
|
|
87
|
+
<ul className="list-inside list-disc space-y-0.5 text-muted-foreground">
|
|
88
|
+
{section.items.map((item) => (
|
|
89
|
+
<li key={item}>{item}</li>
|
|
90
|
+
))}
|
|
91
|
+
</ul>
|
|
92
|
+
</div>
|
|
93
|
+
))}
|
|
94
|
+
</div>
|
|
95
|
+
)}
|
|
96
|
+
|
|
97
|
+
<AlertDialogFooter>
|
|
98
|
+
<AlertDialogCancel>Later</AlertDialogCancel>
|
|
99
|
+
<AlertDialogAction
|
|
100
|
+
onClick={handleUpdate}
|
|
101
|
+
disabled={pulling}
|
|
102
|
+
className="bg-amber-600 hover:bg-amber-700"
|
|
103
|
+
>
|
|
104
|
+
{pulling ? (
|
|
105
|
+
<>
|
|
106
|
+
<Loader2 className="mr-2 h-4 w-4 animate-spin" />
|
|
107
|
+
Updating...
|
|
108
|
+
</>
|
|
109
|
+
) : (
|
|
110
|
+
"Update Now"
|
|
111
|
+
)}
|
|
112
|
+
</AlertDialogAction>
|
|
113
|
+
</AlertDialogFooter>
|
|
114
|
+
</AlertDialogContent>
|
|
115
|
+
</AlertDialog>
|
|
116
|
+
);
|
|
117
|
+
}
|
package/src/lib/trpc-types.ts
CHANGED
|
@@ -133,6 +133,7 @@ type AppRouterRecord = {
|
|
|
133
133
|
getInstanceLogs: AnyTRPCQueryProcedure;
|
|
134
134
|
getInstanceMetrics: AnyTRPCQueryProcedure;
|
|
135
135
|
listTemplates: AnyTRPCQueryProcedure;
|
|
136
|
+
getChangelog: AnyTRPCQueryProcedure;
|
|
136
137
|
};
|
|
137
138
|
settings: {
|
|
138
139
|
notificationPreferences: AnyTRPCQueryProcedure;
|