@tscircuit/fake-snippets 0.0.105 → 0.0.107
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/CLAUDE.md +92 -0
- package/api/generated-index.js +3 -4
- package/bun-tests/fake-snippets-api/routes/package_builds/get.test.ts +294 -0
- package/bun-tests/fake-snippets-api/routes/package_builds/list.test.ts +304 -0
- package/dist/bundle.js +698 -335
- package/dist/index.d.ts +147 -4
- package/dist/index.js +195 -7
- package/dist/schema.d.ts +206 -1
- package/dist/schema.js +31 -2
- package/fake-snippets-api/lib/db/db-client.ts +60 -3
- package/fake-snippets-api/lib/db/schema.ts +31 -0
- package/fake-snippets-api/lib/db/seed.ts +139 -2
- package/fake-snippets-api/lib/public-mapping/public-map-package-build.ts +41 -0
- package/fake-snippets-api/routes/api/package_builds/get.ts +70 -0
- package/fake-snippets-api/routes/api/package_builds/list.ts +97 -0
- package/package.json +3 -2
- package/src/App.tsx +21 -5
- package/src/components/PackageBreadcrumb.tsx +111 -0
- package/src/components/ViewPackagePage/components/sidebar-releases-section.tsx +22 -11
- package/src/components/preview/BuildsList.tsx +196 -211
- package/src/components/preview/ConnectedPackagesList.tsx +54 -25
- package/src/components/preview/ConnectedRepoOverview.tsx +63 -35
- package/src/components/preview/{ConnectedRepoDashboard.tsx → PackageReleasesDashboard.tsx} +33 -71
- package/src/components/preview/index.tsx +20 -77
- package/src/hooks/use-package-builds.ts +87 -0
- package/src/hooks/use-package-release-by-id-or-version.ts +36 -0
- package/src/hooks/use-package-release.ts +32 -0
- package/src/lib/utils/isUuid.ts +5 -0
- package/src/pages/preview-build.tsx +3 -3
- package/src/pages/release-builds.tsx +107 -0
- package/src/pages/release-detail.tsx +118 -0
- package/src/pages/releases.tsx +51 -0
- package/src/pages/view-connected-repo.tsx +0 -18
|
@@ -1,16 +1,8 @@
|
|
|
1
1
|
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"
|
|
2
2
|
import { Badge } from "@/components/ui/badge"
|
|
3
3
|
import { Button } from "@/components/ui/button"
|
|
4
|
-
import {
|
|
5
|
-
|
|
6
|
-
GitBranch,
|
|
7
|
-
AlertCircle,
|
|
8
|
-
CheckCircle,
|
|
9
|
-
Loader2,
|
|
10
|
-
MoreHorizontal,
|
|
11
|
-
GitCommit,
|
|
12
|
-
Plus,
|
|
13
|
-
} from "lucide-react"
|
|
4
|
+
import { Skeleton } from "@/components/ui/skeleton"
|
|
5
|
+
import { GitBranch, MoreHorizontal, GitCommit } from "lucide-react"
|
|
14
6
|
import {
|
|
15
7
|
DropdownMenu,
|
|
16
8
|
DropdownMenuContent,
|
|
@@ -25,217 +17,210 @@ import {
|
|
|
25
17
|
TableHeader,
|
|
26
18
|
TableRow,
|
|
27
19
|
} from "@/components/ui/table"
|
|
28
|
-
import { getBuildStatus,
|
|
20
|
+
import { getBuildStatus, StatusIcon } from "."
|
|
29
21
|
import { formatTimeAgo } from "@/lib/utils/formatTimeAgo"
|
|
30
22
|
import { Package } from "fake-snippets-api/lib/db/schema"
|
|
23
|
+
import { usePackageReleasesByPackageId } from "@/hooks/use-package-release"
|
|
24
|
+
import { useQueries } from "react-query"
|
|
25
|
+
import { useAxios } from "@/hooks/use-axios"
|
|
31
26
|
|
|
32
|
-
export const BuildsList = ({
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
pkg: Package
|
|
37
|
-
onSelectBuild?: (build: PackageBuild) => void
|
|
38
|
-
}) => {
|
|
39
|
-
const builds = MOCK_DEPLOYMENTS
|
|
40
|
-
return (
|
|
41
|
-
<div className="space-y-6">
|
|
42
|
-
<div className="flex items-center justify-between">
|
|
43
|
-
<div>
|
|
44
|
-
<h2 className="text-2xl font-bold text-gray-900">Builds</h2>
|
|
45
|
-
<p className="text-gray-600">Manage and monitor your builds</p>
|
|
46
|
-
</div>
|
|
47
|
-
</div>
|
|
48
|
-
|
|
49
|
-
<Card>
|
|
50
|
-
<CardHeader>
|
|
51
|
-
<CardTitle>Recent Deployments</CardTitle>
|
|
52
|
-
</CardHeader>
|
|
53
|
-
<CardContent>
|
|
54
|
-
<div className="overflow-x-auto">
|
|
55
|
-
<Table>
|
|
56
|
-
<TableHeader>
|
|
57
|
-
<TableRow>
|
|
58
|
-
<TableHead>Status</TableHead>
|
|
59
|
-
<TableHead>Build ID</TableHead>
|
|
60
|
-
<TableHead>Branch</TableHead>
|
|
61
|
-
<TableHead>Commit</TableHead>
|
|
62
|
-
<TableHead>Author</TableHead>
|
|
63
|
-
<TableHead>Created</TableHead>
|
|
64
|
-
<TableHead>Actions</TableHead>
|
|
65
|
-
</TableRow>
|
|
66
|
-
</TableHeader>
|
|
67
|
-
<TableBody>
|
|
68
|
-
{builds.map((build) => {
|
|
69
|
-
const { status, label } = getBuildStatus(build)
|
|
70
|
-
|
|
71
|
-
return (
|
|
72
|
-
<TableRow
|
|
73
|
-
key={build.package_build_id}
|
|
74
|
-
className="cursor-pointer hover:bg-gray-50"
|
|
75
|
-
onClick={() => onSelectBuild?.(build)}
|
|
76
|
-
>
|
|
77
|
-
<TableCell>
|
|
78
|
-
<div className="flex items-center gap-2">
|
|
79
|
-
<StatusIcon status={status} />
|
|
80
|
-
<Badge
|
|
81
|
-
variant={
|
|
82
|
-
status === "success"
|
|
83
|
-
? "default"
|
|
84
|
-
: status === "error"
|
|
85
|
-
? "destructive"
|
|
86
|
-
: "secondary"
|
|
87
|
-
}
|
|
88
|
-
className="text-xs"
|
|
89
|
-
>
|
|
90
|
-
{label}
|
|
91
|
-
</Badge>
|
|
92
|
-
</div>
|
|
93
|
-
</TableCell>
|
|
94
|
-
<TableCell>
|
|
95
|
-
<code className="text-sm bg-gray-100 px-2 py-1 rounded">
|
|
96
|
-
{build.package_build_id.slice(-8)}
|
|
97
|
-
</code>
|
|
98
|
-
</TableCell>
|
|
99
|
-
<TableCell>
|
|
100
|
-
<div className="flex items-center gap-2">
|
|
101
|
-
{build.branch_name?.includes("/") ? (
|
|
102
|
-
<GitBranch className="w-3 h-3 text-gray-500" />
|
|
103
|
-
) : (
|
|
104
|
-
<GitCommit className="w-3 h-3 text-gray-500" />
|
|
105
|
-
)}
|
|
106
|
-
<Badge variant="outline" className="text-xs">
|
|
107
|
-
{build.branch_name || "main"}
|
|
108
|
-
</Badge>
|
|
109
|
-
</div>
|
|
110
|
-
</TableCell>
|
|
111
|
-
<TableCell>
|
|
112
|
-
<div className="max-w-xs">
|
|
113
|
-
<p className="text-sm font-medium truncate">
|
|
114
|
-
{build.commit_message || "No commit message"}
|
|
115
|
-
</p>
|
|
116
|
-
</div>
|
|
117
|
-
</TableCell>
|
|
118
|
-
<TableCell>
|
|
119
|
-
<span className="text-sm text-gray-600">
|
|
120
|
-
{build.commit_author || "Unknown"}
|
|
121
|
-
</span>
|
|
122
|
-
</TableCell>
|
|
123
|
-
<TableCell>
|
|
124
|
-
<span className="text-sm text-gray-600">
|
|
125
|
-
{formatTimeAgo(build.created_at)}
|
|
126
|
-
</span>
|
|
127
|
-
</TableCell>
|
|
128
|
-
<TableCell>
|
|
129
|
-
<div className="flex items-center gap-2">
|
|
130
|
-
<DropdownMenu>
|
|
131
|
-
<DropdownMenuTrigger asChild>
|
|
132
|
-
<Button
|
|
133
|
-
variant="ghost"
|
|
134
|
-
size="sm"
|
|
135
|
-
onClick={(e) => e.stopPropagation()}
|
|
136
|
-
>
|
|
137
|
-
<MoreHorizontal className="w-3 h-3" />
|
|
138
|
-
</Button>
|
|
139
|
-
</DropdownMenuTrigger>
|
|
140
|
-
<DropdownMenuContent align="end">
|
|
141
|
-
<DropdownMenuItem
|
|
142
|
-
onClick={() => onSelectBuild?.(build)}
|
|
143
|
-
>
|
|
144
|
-
View Details
|
|
145
|
-
</DropdownMenuItem>
|
|
146
|
-
<DropdownMenuItem
|
|
147
|
-
onClick={() => onSelectBuild?.(build)}
|
|
148
|
-
>
|
|
149
|
-
View Logs
|
|
150
|
-
</DropdownMenuItem>
|
|
151
|
-
</DropdownMenuContent>
|
|
152
|
-
</DropdownMenu>
|
|
153
|
-
</div>
|
|
154
|
-
</TableCell>
|
|
155
|
-
</TableRow>
|
|
156
|
-
)
|
|
157
|
-
})}
|
|
158
|
-
</TableBody>
|
|
159
|
-
</Table>
|
|
160
|
-
</div>
|
|
161
|
-
</CardContent>
|
|
162
|
-
</Card>
|
|
163
|
-
|
|
164
|
-
<div className="grid grid-cols-1 md:grid-cols-4 gap-4">
|
|
165
|
-
<Card>
|
|
166
|
-
<CardContent className="p-6">
|
|
167
|
-
<div className="flex items-center gap-3">
|
|
168
|
-
<div className="p-2 bg-green-100 rounded-lg">
|
|
169
|
-
<CheckCircle className="w-5 h-5 text-green-600" />
|
|
170
|
-
</div>
|
|
171
|
-
<div>
|
|
172
|
-
<p className="text-sm text-gray-600">Successful</p>
|
|
173
|
-
<p className="text-2xl font-bold text-gray-900">
|
|
174
|
-
{
|
|
175
|
-
builds.filter((d) => getBuildStatus(d).status === "success")
|
|
176
|
-
.length
|
|
177
|
-
}
|
|
178
|
-
</p>
|
|
179
|
-
</div>
|
|
180
|
-
</div>
|
|
181
|
-
</CardContent>
|
|
182
|
-
</Card>
|
|
27
|
+
export const BuildsList = ({ pkg }: { pkg: Package }) => {
|
|
28
|
+
const { data: releases, isLoading: isLoadingReleases } =
|
|
29
|
+
usePackageReleasesByPackageId(pkg.package_id)
|
|
30
|
+
const axios = useAxios()
|
|
183
31
|
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
32
|
+
// Get the latest build for each release to show status
|
|
33
|
+
const latestBuildQueries = useQueries(
|
|
34
|
+
(releases || [])
|
|
35
|
+
.filter((release) => release.latest_package_build_id)
|
|
36
|
+
.map((release) => ({
|
|
37
|
+
queryKey: ["packageBuild", release.latest_package_build_id],
|
|
38
|
+
queryFn: async () => {
|
|
39
|
+
if (!release.latest_package_build_id) return null
|
|
40
|
+
const { data } = await axios.get("/package_builds/get", {
|
|
41
|
+
params: { package_build_id: release.latest_package_build_id },
|
|
42
|
+
})
|
|
43
|
+
return data.package_build
|
|
44
|
+
},
|
|
45
|
+
enabled: Boolean(release.latest_package_build_id),
|
|
46
|
+
retry: false,
|
|
47
|
+
refetchOnWindowFocus: false,
|
|
48
|
+
})),
|
|
49
|
+
)
|
|
202
50
|
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
<div className="flex items-center gap-3">
|
|
206
|
-
<div className="p-2 bg-blue-100 rounded-lg">
|
|
207
|
-
<Loader2 className="w-5 h-5 text-blue-600 animate-spin" />
|
|
208
|
-
</div>
|
|
209
|
-
<div>
|
|
210
|
-
<p className="text-sm text-gray-600">Building</p>
|
|
211
|
-
<p className="text-2xl font-bold text-gray-900">
|
|
212
|
-
{
|
|
213
|
-
builds.filter(
|
|
214
|
-
(d) => getBuildStatus(d).status === "building",
|
|
215
|
-
).length
|
|
216
|
-
}
|
|
217
|
-
</p>
|
|
218
|
-
</div>
|
|
219
|
-
</div>
|
|
220
|
-
</CardContent>
|
|
221
|
-
</Card>
|
|
51
|
+
const isLoading =
|
|
52
|
+
isLoadingReleases || latestBuildQueries.some((q) => q.isLoading)
|
|
222
53
|
|
|
54
|
+
// Create a map of release ID to latest build for easy access
|
|
55
|
+
const latestBuildsMap = new Map()
|
|
56
|
+
latestBuildQueries.forEach((query, index) => {
|
|
57
|
+
if (query.data && releases?.[index]) {
|
|
58
|
+
latestBuildsMap.set(releases[index].package_release_id, query.data)
|
|
59
|
+
}
|
|
60
|
+
})
|
|
61
|
+
return (
|
|
62
|
+
<>
|
|
63
|
+
<div className="space-y-6">
|
|
223
64
|
<Card>
|
|
224
|
-
<
|
|
225
|
-
<
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
<
|
|
230
|
-
<
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
65
|
+
<CardHeader>
|
|
66
|
+
<CardTitle>Recent Releases</CardTitle>
|
|
67
|
+
</CardHeader>
|
|
68
|
+
<CardContent>
|
|
69
|
+
<div className="overflow-x-auto [&>div]:no-scrollbar">
|
|
70
|
+
<Table className="no-scrollbar">
|
|
71
|
+
<TableHeader>
|
|
72
|
+
<TableRow>
|
|
73
|
+
<TableHead>Status</TableHead>
|
|
74
|
+
<TableHead>Release ID</TableHead>
|
|
75
|
+
<TableHead>Version</TableHead>
|
|
76
|
+
<TableHead>Branch/PR</TableHead>
|
|
77
|
+
<TableHead>Latest Build</TableHead>
|
|
78
|
+
<TableHead>Created</TableHead>
|
|
79
|
+
<TableHead>Actions</TableHead>
|
|
80
|
+
</TableRow>
|
|
81
|
+
</TableHeader>
|
|
82
|
+
<TableBody>
|
|
83
|
+
{isLoading
|
|
84
|
+
? Array.from({ length: 3 }).map((_, i) => (
|
|
85
|
+
<TableRow key={i}>
|
|
86
|
+
<TableCell>
|
|
87
|
+
<Skeleton className="h-6 w-20" />
|
|
88
|
+
</TableCell>
|
|
89
|
+
<TableCell>
|
|
90
|
+
<Skeleton className="h-6 w-16" />
|
|
91
|
+
</TableCell>
|
|
92
|
+
<TableCell>
|
|
93
|
+
<Skeleton className="h-6 w-12" />
|
|
94
|
+
</TableCell>
|
|
95
|
+
<TableCell>
|
|
96
|
+
<Skeleton className="h-6 w-32" />
|
|
97
|
+
</TableCell>
|
|
98
|
+
<TableCell>
|
|
99
|
+
<Skeleton className="h-6 w-20" />
|
|
100
|
+
</TableCell>
|
|
101
|
+
<TableCell>
|
|
102
|
+
<Skeleton className="h-6 w-16" />
|
|
103
|
+
</TableCell>
|
|
104
|
+
<TableCell>
|
|
105
|
+
<Skeleton className="h-6 w-8" />
|
|
106
|
+
</TableCell>
|
|
107
|
+
</TableRow>
|
|
108
|
+
))
|
|
109
|
+
: releases?.map((release) => {
|
|
110
|
+
const latestBuild = latestBuildsMap.get(
|
|
111
|
+
release.package_release_id,
|
|
112
|
+
)
|
|
113
|
+
const { status, label } = latestBuild
|
|
114
|
+
? getBuildStatus(latestBuild)
|
|
115
|
+
: { status: "unknown", label: "No builds" }
|
|
116
|
+
return (
|
|
117
|
+
<TableRow
|
|
118
|
+
key={release.package_release_id}
|
|
119
|
+
className="cursor-pointer hover:bg-gray-50 no-scrollbar"
|
|
120
|
+
onClick={() => {
|
|
121
|
+
window.location.href = `/${pkg.name}/release/${release.package_release_id}`
|
|
122
|
+
}}
|
|
123
|
+
>
|
|
124
|
+
<TableCell>
|
|
125
|
+
<div className="flex items-center gap-2">
|
|
126
|
+
<StatusIcon status={status} />
|
|
127
|
+
<Badge
|
|
128
|
+
variant={
|
|
129
|
+
status === "success"
|
|
130
|
+
? "default"
|
|
131
|
+
: status === "error"
|
|
132
|
+
? "destructive"
|
|
133
|
+
: "secondary"
|
|
134
|
+
}
|
|
135
|
+
className="text-xs"
|
|
136
|
+
>
|
|
137
|
+
{label}
|
|
138
|
+
</Badge>
|
|
139
|
+
</div>
|
|
140
|
+
</TableCell>
|
|
141
|
+
<TableCell>
|
|
142
|
+
<code className="text-sm bg-gray-100 px-2 py-1 rounded">
|
|
143
|
+
{release.package_release_id.slice(-8)}
|
|
144
|
+
</code>
|
|
145
|
+
</TableCell>
|
|
146
|
+
<TableCell>
|
|
147
|
+
<span className="text-sm font-medium">
|
|
148
|
+
{release.version ||
|
|
149
|
+
"v" + release.package_release_id.slice(-6)}
|
|
150
|
+
</span>
|
|
151
|
+
</TableCell>
|
|
152
|
+
<TableCell>
|
|
153
|
+
<div className="flex items-center gap-2">
|
|
154
|
+
{release.is_pr_preview ? (
|
|
155
|
+
<GitBranch className="w-3 h-3 text-gray-500" />
|
|
156
|
+
) : (
|
|
157
|
+
<GitCommit className="w-3 h-3 text-gray-500" />
|
|
158
|
+
)}
|
|
159
|
+
<Badge variant="outline" className="text-xs">
|
|
160
|
+
{release.is_pr_preview
|
|
161
|
+
? `#${release.github_pr_number}`
|
|
162
|
+
: "main"}
|
|
163
|
+
</Badge>
|
|
164
|
+
</div>
|
|
165
|
+
</TableCell>
|
|
166
|
+
<TableCell>
|
|
167
|
+
<div className="max-w-xs">
|
|
168
|
+
{latestBuild ? (
|
|
169
|
+
<p className="text-sm text-gray-600">
|
|
170
|
+
{formatTimeAgo(latestBuild.created_at)}
|
|
171
|
+
</p>
|
|
172
|
+
) : (
|
|
173
|
+
<p className="text-sm text-gray-400">
|
|
174
|
+
No builds
|
|
175
|
+
</p>
|
|
176
|
+
)}
|
|
177
|
+
</div>
|
|
178
|
+
</TableCell>
|
|
179
|
+
<TableCell>
|
|
180
|
+
<span className="text-sm text-gray-600">
|
|
181
|
+
{formatTimeAgo(release.created_at)}
|
|
182
|
+
</span>
|
|
183
|
+
</TableCell>
|
|
184
|
+
<TableCell>
|
|
185
|
+
<div className="flex items-center gap-2">
|
|
186
|
+
<DropdownMenu>
|
|
187
|
+
<DropdownMenuTrigger asChild>
|
|
188
|
+
<Button
|
|
189
|
+
variant="ghost"
|
|
190
|
+
size="sm"
|
|
191
|
+
onClick={(e) => e.stopPropagation()}
|
|
192
|
+
>
|
|
193
|
+
<MoreHorizontal className="w-3 h-3" />
|
|
194
|
+
</Button>
|
|
195
|
+
</DropdownMenuTrigger>
|
|
196
|
+
<DropdownMenuContent align="end">
|
|
197
|
+
<DropdownMenuItem
|
|
198
|
+
onClick={() => {
|
|
199
|
+
window.location.href = `/${pkg.name}/release/${release.package_release_id}`
|
|
200
|
+
}}
|
|
201
|
+
>
|
|
202
|
+
View Release
|
|
203
|
+
</DropdownMenuItem>
|
|
204
|
+
<DropdownMenuItem
|
|
205
|
+
onClick={() => {
|
|
206
|
+
window.location.href = `/${pkg.name}/release/${release.package_release_id}/builds`
|
|
207
|
+
}}
|
|
208
|
+
>
|
|
209
|
+
View All Builds
|
|
210
|
+
</DropdownMenuItem>
|
|
211
|
+
</DropdownMenuContent>
|
|
212
|
+
</DropdownMenu>
|
|
213
|
+
</div>
|
|
214
|
+
</TableCell>
|
|
215
|
+
</TableRow>
|
|
216
|
+
)
|
|
217
|
+
})}
|
|
218
|
+
</TableBody>
|
|
219
|
+
</Table>
|
|
235
220
|
</div>
|
|
236
221
|
</CardContent>
|
|
237
222
|
</Card>
|
|
238
223
|
</div>
|
|
239
|
-
|
|
224
|
+
</>
|
|
240
225
|
)
|
|
241
226
|
}
|
|
@@ -9,11 +9,12 @@ import { formatTimeAgo } from "@/lib/utils/formatTimeAgo"
|
|
|
9
9
|
import {
|
|
10
10
|
getBuildStatus,
|
|
11
11
|
getLatestBuildForPackage,
|
|
12
|
-
|
|
13
|
-
PackageBuild,
|
|
12
|
+
MOCK_PACKAGE_BUILDS,
|
|
14
13
|
StatusIcon,
|
|
15
14
|
} from "."
|
|
16
|
-
import { Package } from "fake-snippets-api/lib/db/schema"
|
|
15
|
+
import { Package, PackageBuild } from "fake-snippets-api/lib/db/schema"
|
|
16
|
+
import { usePackageBuild } from "@/hooks/use-package-builds"
|
|
17
|
+
import { useLatestPackageRelease } from "@/hooks/use-package-release"
|
|
17
18
|
|
|
18
19
|
export const ConnectedPackageCardSkeleton = () => {
|
|
19
20
|
return (
|
|
@@ -47,6 +48,22 @@ export const ConnectedPackageCardSkeleton = () => {
|
|
|
47
48
|
)
|
|
48
49
|
}
|
|
49
50
|
|
|
51
|
+
// Custom hook to get latest package build info
|
|
52
|
+
const useLatestPackageBuildInfo = (packageId: string) => {
|
|
53
|
+
const { data: latestRelease, isLoading: releaseLoading } =
|
|
54
|
+
useLatestPackageRelease(packageId)
|
|
55
|
+
const { data: latestBuild, isLoading: buildLoading } = usePackageBuild(
|
|
56
|
+
latestRelease?.latest_package_build_id || null,
|
|
57
|
+
)
|
|
58
|
+
|
|
59
|
+
return {
|
|
60
|
+
data: latestBuild,
|
|
61
|
+
isLoading:
|
|
62
|
+
releaseLoading ||
|
|
63
|
+
(latestRelease?.latest_package_build_id && buildLoading),
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
50
67
|
export const ConnectedPackageCard = ({
|
|
51
68
|
pkg,
|
|
52
69
|
className,
|
|
@@ -54,8 +71,18 @@ export const ConnectedPackageCard = ({
|
|
|
54
71
|
pkg: Package
|
|
55
72
|
className?: string
|
|
56
73
|
}) => {
|
|
57
|
-
const
|
|
58
|
-
|
|
74
|
+
const { data: latestBuildInfo, isLoading } = useLatestPackageBuildInfo(
|
|
75
|
+
pkg.package_id,
|
|
76
|
+
)
|
|
77
|
+
|
|
78
|
+
if (isLoading && !latestBuildInfo) {
|
|
79
|
+
return <ConnectedPackageCardSkeleton />
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
const { status, label } = latestBuildInfo
|
|
83
|
+
? getBuildStatus(latestBuildInfo)
|
|
84
|
+
: { status: "pending", label: "Pending" }
|
|
85
|
+
|
|
59
86
|
return (
|
|
60
87
|
<Card
|
|
61
88
|
className={cn(
|
|
@@ -75,7 +102,7 @@ export const ConnectedPackageCard = ({
|
|
|
75
102
|
href="#"
|
|
76
103
|
className="text-lg font-semibold text-gray-900 hover:text-blue-600 transition-colors"
|
|
77
104
|
>
|
|
78
|
-
|
|
105
|
+
{pkg.unscoped_name}
|
|
79
106
|
</a>
|
|
80
107
|
</div>
|
|
81
108
|
|
|
@@ -108,7 +135,7 @@ export const ConnectedPackageCard = ({
|
|
|
108
135
|
</a>
|
|
109
136
|
</div>
|
|
110
137
|
|
|
111
|
-
{latestBuildInfo
|
|
138
|
+
{latestBuildInfo?.commit_message && (
|
|
112
139
|
<div className="mb-6 flex-1">
|
|
113
140
|
<h4
|
|
114
141
|
title={latestBuildInfo.commit_message}
|
|
@@ -129,27 +156,31 @@ export const ConnectedPackageCard = ({
|
|
|
129
156
|
)}
|
|
130
157
|
|
|
131
158
|
<div className="flex gap-2 w-full mt-auto">
|
|
132
|
-
|
|
133
|
-
className="w-full"
|
|
134
|
-
href={`/build/${latestBuildInfo.package_build_id}`}
|
|
135
|
-
>
|
|
136
|
-
<Button
|
|
137
|
-
size="sm"
|
|
138
|
-
className="bg-blue-600 w-full hover:bg-blue-700 text-white px-4 py-2"
|
|
139
|
-
>
|
|
140
|
-
View
|
|
141
|
-
</Button>
|
|
142
|
-
</PrefetchPageLink>
|
|
143
|
-
{latestBuildInfo.preview_url && status === "success" && (
|
|
159
|
+
{latestBuildInfo?.package_build_id && (
|
|
144
160
|
<PrefetchPageLink
|
|
145
161
|
className="w-full"
|
|
146
|
-
href={`/build/${latestBuildInfo.package_build_id}
|
|
162
|
+
href={`/build/${latestBuildInfo.package_build_id}`}
|
|
147
163
|
>
|
|
148
|
-
<Button
|
|
149
|
-
|
|
164
|
+
<Button
|
|
165
|
+
size="sm"
|
|
166
|
+
className="bg-blue-600 w-full hover:bg-blue-700 text-white px-4 py-2"
|
|
167
|
+
>
|
|
168
|
+
View
|
|
150
169
|
</Button>
|
|
151
170
|
</PrefetchPageLink>
|
|
152
171
|
)}
|
|
172
|
+
{latestBuildInfo?.preview_url &&
|
|
173
|
+
latestBuildInfo?.package_build_id &&
|
|
174
|
+
status === "success" && (
|
|
175
|
+
<PrefetchPageLink
|
|
176
|
+
className="w-full"
|
|
177
|
+
href={`/build/${latestBuildInfo.package_build_id}/preview`}
|
|
178
|
+
>
|
|
179
|
+
<Button size="sm" variant="outline" className="px-4 py-2 w-full">
|
|
180
|
+
Preview
|
|
181
|
+
</Button>
|
|
182
|
+
</PrefetchPageLink>
|
|
183
|
+
)}
|
|
153
184
|
</div>
|
|
154
185
|
</Card>
|
|
155
186
|
)
|
|
@@ -158,9 +189,7 @@ export const ConnectedPackageCard = ({
|
|
|
158
189
|
export const ConnectedPackagesList = ({
|
|
159
190
|
packages,
|
|
160
191
|
}: { packages: Package[] }) => {
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
if (pkgs.length === 0) {
|
|
192
|
+
if (packages.length === 0) {
|
|
164
193
|
return (
|
|
165
194
|
<div className="flex flex-col items-center justify-center py-20 text-black">
|
|
166
195
|
<Rocket className="w-12 h-12 mb-4 text-black" />
|