@tscircuit/fake-snippets 0.0.106 → 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 +2 -3
- package/dist/bundle.js +339 -413
- package/dist/index.d.ts +5 -0
- package/dist/index.js +24 -5
- package/dist/schema.d.ts +8 -0
- package/dist/schema.js +3 -1
- package/fake-snippets-api/lib/db/db-client.ts +9 -0
- package/fake-snippets-api/lib/db/schema.ts +3 -0
- package/fake-snippets-api/lib/db/seed.ts +17 -3
- package/fake-snippets-api/routes/api/package_builds/list.ts +0 -1
- package/package.json +3 -2
- package/src/App.tsx +19 -4
- package/src/components/PackageBreadcrumb.tsx +111 -0
- package/src/components/ViewPackagePage/components/sidebar-releases-section.tsx +17 -7
- package/src/components/preview/BuildsList.tsx +74 -168
- package/src/components/preview/ConnectedPackagesList.tsx +22 -5
- package/src/components/preview/ConnectedRepoOverview.tsx +12 -2
- package/src/components/preview/{ConnectedRepoDashboard.tsx → PackageReleasesDashboard.tsx} +30 -74
- package/src/components/preview/index.tsx +7 -4
- package/src/hooks/use-package-builds.ts +0 -48
- 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/fake-snippets-api/routes/api/package_builds/latest.ts +0 -109
- package/src/pages/view-connected-repo.tsx +0 -49
|
@@ -2,15 +2,7 @@ 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
4
|
import { Skeleton } from "@/components/ui/skeleton"
|
|
5
|
-
import {
|
|
6
|
-
Clock,
|
|
7
|
-
GitBranch,
|
|
8
|
-
AlertCircle,
|
|
9
|
-
CheckCircle,
|
|
10
|
-
Loader2,
|
|
11
|
-
MoreHorizontal,
|
|
12
|
-
GitCommit,
|
|
13
|
-
} from "lucide-react"
|
|
5
|
+
import { GitBranch, MoreHorizontal, GitCommit } from "lucide-react"
|
|
14
6
|
import {
|
|
15
7
|
DropdownMenu,
|
|
16
8
|
DropdownMenuContent,
|
|
@@ -27,64 +19,51 @@ import {
|
|
|
27
19
|
} from "@/components/ui/table"
|
|
28
20
|
import { getBuildStatus, StatusIcon } from "."
|
|
29
21
|
import { formatTimeAgo } from "@/lib/utils/formatTimeAgo"
|
|
30
|
-
import { Package
|
|
31
|
-
import {
|
|
32
|
-
import { usePackageReleaseById } from "@/hooks/use-package-release"
|
|
22
|
+
import { Package } from "fake-snippets-api/lib/db/schema"
|
|
23
|
+
import { usePackageReleasesByPackageId } from "@/hooks/use-package-release"
|
|
33
24
|
import { useQueries } from "react-query"
|
|
34
25
|
import { useAxios } from "@/hooks/use-axios"
|
|
35
26
|
|
|
36
|
-
export const BuildsList = ({
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
}: {
|
|
40
|
-
pkg: Package
|
|
41
|
-
onSelectBuild?: (build: PackageBuild) => void
|
|
42
|
-
}) => {
|
|
43
|
-
const { data: builds, isLoading } = usePackageBuilds({
|
|
44
|
-
package_id: pkg.package_id,
|
|
45
|
-
})
|
|
27
|
+
export const BuildsList = ({ pkg }: { pkg: Package }) => {
|
|
28
|
+
const { data: releases, isLoading: isLoadingReleases } =
|
|
29
|
+
usePackageReleasesByPackageId(pkg.package_id)
|
|
46
30
|
const axios = useAxios()
|
|
47
31
|
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
refetchOnWindowFocus: false,
|
|
66
|
-
})),
|
|
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
|
+
})),
|
|
67
49
|
)
|
|
68
50
|
|
|
69
|
-
const
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
51
|
+
const isLoading =
|
|
52
|
+
isLoadingReleases || latestBuildQueries.some((q) => q.isLoading)
|
|
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)
|
|
73
59
|
}
|
|
74
60
|
})
|
|
75
61
|
return (
|
|
76
62
|
<>
|
|
77
63
|
<div className="space-y-6">
|
|
78
|
-
<div className="flex items-center justify-between">
|
|
79
|
-
<div>
|
|
80
|
-
<h2 className="text-2xl font-bold text-gray-900">Builds</h2>
|
|
81
|
-
<p className="text-gray-600">Manage and monitor your builds</p>
|
|
82
|
-
</div>
|
|
83
|
-
</div>
|
|
84
|
-
|
|
85
64
|
<Card>
|
|
86
65
|
<CardHeader>
|
|
87
|
-
<CardTitle>Recent
|
|
66
|
+
<CardTitle>Recent Releases</CardTitle>
|
|
88
67
|
</CardHeader>
|
|
89
68
|
<CardContent>
|
|
90
69
|
<div className="overflow-x-auto [&>div]:no-scrollbar">
|
|
@@ -92,10 +71,10 @@ export const BuildsList = ({
|
|
|
92
71
|
<TableHeader>
|
|
93
72
|
<TableRow>
|
|
94
73
|
<TableHead>Status</TableHead>
|
|
95
|
-
<TableHead>
|
|
74
|
+
<TableHead>Release ID</TableHead>
|
|
75
|
+
<TableHead>Version</TableHead>
|
|
96
76
|
<TableHead>Branch/PR</TableHead>
|
|
97
|
-
<TableHead>
|
|
98
|
-
<TableHead>Author</TableHead>
|
|
77
|
+
<TableHead>Latest Build</TableHead>
|
|
99
78
|
<TableHead>Created</TableHead>
|
|
100
79
|
<TableHead>Actions</TableHead>
|
|
101
80
|
</TableRow>
|
|
@@ -127,16 +106,20 @@ export const BuildsList = ({
|
|
|
127
106
|
</TableCell>
|
|
128
107
|
</TableRow>
|
|
129
108
|
))
|
|
130
|
-
:
|
|
131
|
-
const
|
|
132
|
-
|
|
133
|
-
build.package_release_id,
|
|
109
|
+
: releases?.map((release) => {
|
|
110
|
+
const latestBuild = latestBuildsMap.get(
|
|
111
|
+
release.package_release_id,
|
|
134
112
|
)
|
|
113
|
+
const { status, label } = latestBuild
|
|
114
|
+
? getBuildStatus(latestBuild)
|
|
115
|
+
: { status: "unknown", label: "No builds" }
|
|
135
116
|
return (
|
|
136
117
|
<TableRow
|
|
137
|
-
key={
|
|
118
|
+
key={release.package_release_id}
|
|
138
119
|
className="cursor-pointer hover:bg-gray-50 no-scrollbar"
|
|
139
|
-
onClick={() =>
|
|
120
|
+
onClick={() => {
|
|
121
|
+
window.location.href = `/${pkg.name}/release/${release.package_release_id}`
|
|
122
|
+
}}
|
|
140
123
|
>
|
|
141
124
|
<TableCell>
|
|
142
125
|
<div className="flex items-center gap-2">
|
|
@@ -157,38 +140,45 @@ export const BuildsList = ({
|
|
|
157
140
|
</TableCell>
|
|
158
141
|
<TableCell>
|
|
159
142
|
<code className="text-sm bg-gray-100 px-2 py-1 rounded">
|
|
160
|
-
{
|
|
143
|
+
{release.package_release_id.slice(-8)}
|
|
161
144
|
</code>
|
|
162
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>
|
|
163
152
|
<TableCell>
|
|
164
153
|
<div className="flex items-center gap-2">
|
|
165
|
-
{
|
|
154
|
+
{release.is_pr_preview ? (
|
|
166
155
|
<GitBranch className="w-3 h-3 text-gray-500" />
|
|
167
156
|
) : (
|
|
168
157
|
<GitCommit className="w-3 h-3 text-gray-500" />
|
|
169
158
|
)}
|
|
170
159
|
<Badge variant="outline" className="text-xs">
|
|
171
|
-
{
|
|
172
|
-
? `#${
|
|
173
|
-
:
|
|
160
|
+
{release.is_pr_preview
|
|
161
|
+
? `#${release.github_pr_number}`
|
|
162
|
+
: "main"}
|
|
174
163
|
</Badge>
|
|
175
164
|
</div>
|
|
176
165
|
</TableCell>
|
|
177
166
|
<TableCell>
|
|
178
167
|
<div className="max-w-xs">
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
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
|
+
)}
|
|
182
177
|
</div>
|
|
183
178
|
</TableCell>
|
|
184
179
|
<TableCell>
|
|
185
180
|
<span className="text-sm text-gray-600">
|
|
186
|
-
{
|
|
187
|
-
</span>
|
|
188
|
-
</TableCell>
|
|
189
|
-
<TableCell>
|
|
190
|
-
<span className="text-sm text-gray-600">
|
|
191
|
-
{formatTimeAgo(build.created_at)}
|
|
181
|
+
{formatTimeAgo(release.created_at)}
|
|
192
182
|
</span>
|
|
193
183
|
</TableCell>
|
|
194
184
|
<TableCell>
|
|
@@ -205,14 +195,18 @@ export const BuildsList = ({
|
|
|
205
195
|
</DropdownMenuTrigger>
|
|
206
196
|
<DropdownMenuContent align="end">
|
|
207
197
|
<DropdownMenuItem
|
|
208
|
-
onClick={() =>
|
|
198
|
+
onClick={() => {
|
|
199
|
+
window.location.href = `/${pkg.name}/release/${release.package_release_id}`
|
|
200
|
+
}}
|
|
209
201
|
>
|
|
210
|
-
View
|
|
202
|
+
View Release
|
|
211
203
|
</DropdownMenuItem>
|
|
212
204
|
<DropdownMenuItem
|
|
213
|
-
onClick={() =>
|
|
205
|
+
onClick={() => {
|
|
206
|
+
window.location.href = `/${pkg.name}/release/${release.package_release_id}/builds`
|
|
207
|
+
}}
|
|
214
208
|
>
|
|
215
|
-
View
|
|
209
|
+
View All Builds
|
|
216
210
|
</DropdownMenuItem>
|
|
217
211
|
</DropdownMenuContent>
|
|
218
212
|
</DropdownMenu>
|
|
@@ -226,94 +220,6 @@ export const BuildsList = ({
|
|
|
226
220
|
</div>
|
|
227
221
|
</CardContent>
|
|
228
222
|
</Card>
|
|
229
|
-
|
|
230
|
-
<div className="grid grid-cols-1 md:grid-cols-4 gap-4">
|
|
231
|
-
<Card>
|
|
232
|
-
<CardContent className="p-6">
|
|
233
|
-
<div className="flex items-center gap-3">
|
|
234
|
-
<div className="p-2 bg-green-100 rounded-lg">
|
|
235
|
-
<CheckCircle className="w-5 h-5 text-green-600" />
|
|
236
|
-
</div>
|
|
237
|
-
<div>
|
|
238
|
-
<p className="text-sm text-gray-600">Successful</p>
|
|
239
|
-
{isLoading ? (
|
|
240
|
-
<Skeleton className="h-8 w-8" />
|
|
241
|
-
) : (
|
|
242
|
-
<p className="text-2xl font-bold text-gray-900">
|
|
243
|
-
{builds?.filter(
|
|
244
|
-
(d) => getBuildStatus(d).status === "success",
|
|
245
|
-
).length || 0}
|
|
246
|
-
</p>
|
|
247
|
-
)}
|
|
248
|
-
</div>
|
|
249
|
-
</div>
|
|
250
|
-
</CardContent>
|
|
251
|
-
</Card>
|
|
252
|
-
|
|
253
|
-
<Card>
|
|
254
|
-
<CardContent className="p-6">
|
|
255
|
-
<div className="flex items-center gap-3">
|
|
256
|
-
<div className="p-2 bg-red-100 rounded-lg">
|
|
257
|
-
<AlertCircle className="w-5 h-5 text-red-600" />
|
|
258
|
-
</div>
|
|
259
|
-
<div>
|
|
260
|
-
<p className="text-sm text-gray-600">Failed</p>
|
|
261
|
-
{isLoading ? (
|
|
262
|
-
<Skeleton className="h-8 w-8" />
|
|
263
|
-
) : (
|
|
264
|
-
<p className="text-2xl font-bold text-gray-900">
|
|
265
|
-
{builds?.filter(
|
|
266
|
-
(d) => getBuildStatus(d).status === "error",
|
|
267
|
-
).length || 0}
|
|
268
|
-
</p>
|
|
269
|
-
)}
|
|
270
|
-
</div>
|
|
271
|
-
</div>
|
|
272
|
-
</CardContent>
|
|
273
|
-
</Card>
|
|
274
|
-
|
|
275
|
-
<Card>
|
|
276
|
-
<CardContent className="p-6">
|
|
277
|
-
<div className="flex items-center gap-3">
|
|
278
|
-
<div className="p-2 bg-blue-100 rounded-lg">
|
|
279
|
-
<Loader2 className="w-5 h-5 text-blue-600 animate-spin" />
|
|
280
|
-
</div>
|
|
281
|
-
<div>
|
|
282
|
-
<p className="text-sm text-gray-600">Building</p>
|
|
283
|
-
{isLoading ? (
|
|
284
|
-
<Skeleton className="h-8 w-8" />
|
|
285
|
-
) : (
|
|
286
|
-
<p className="text-2xl font-bold text-gray-900">
|
|
287
|
-
{builds?.filter(
|
|
288
|
-
(d) => getBuildStatus(d).status === "building",
|
|
289
|
-
).length || 0}
|
|
290
|
-
</p>
|
|
291
|
-
)}
|
|
292
|
-
</div>
|
|
293
|
-
</div>
|
|
294
|
-
</CardContent>
|
|
295
|
-
</Card>
|
|
296
|
-
|
|
297
|
-
<Card>
|
|
298
|
-
<CardContent className="p-6">
|
|
299
|
-
<div className="flex items-center gap-3">
|
|
300
|
-
<div className="p-2 bg-gray-100 rounded-lg">
|
|
301
|
-
<Clock className="w-5 h-5 text-gray-600" />
|
|
302
|
-
</div>
|
|
303
|
-
<div>
|
|
304
|
-
<p className="text-sm text-gray-600">Total</p>
|
|
305
|
-
{isLoading ? (
|
|
306
|
-
<Skeleton className="h-8 w-8" />
|
|
307
|
-
) : (
|
|
308
|
-
<p className="text-2xl font-bold text-gray-900">
|
|
309
|
-
{builds?.length || 0}
|
|
310
|
-
</p>
|
|
311
|
-
)}
|
|
312
|
-
</div>
|
|
313
|
-
</div>
|
|
314
|
-
</CardContent>
|
|
315
|
-
</Card>
|
|
316
|
-
</div>
|
|
317
223
|
</div>
|
|
318
224
|
</>
|
|
319
225
|
)
|
|
@@ -9,11 +9,12 @@ import { formatTimeAgo } from "@/lib/utils/formatTimeAgo"
|
|
|
9
9
|
import {
|
|
10
10
|
getBuildStatus,
|
|
11
11
|
getLatestBuildForPackage,
|
|
12
|
-
|
|
12
|
+
MOCK_PACKAGE_BUILDS,
|
|
13
13
|
StatusIcon,
|
|
14
14
|
} from "."
|
|
15
15
|
import { Package, PackageBuild } from "fake-snippets-api/lib/db/schema"
|
|
16
|
-
import {
|
|
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,9 +71,9 @@ export const ConnectedPackageCard = ({
|
|
|
54
71
|
pkg: Package
|
|
55
72
|
className?: string
|
|
56
73
|
}) => {
|
|
57
|
-
const { data: latestBuildInfo, isLoading } =
|
|
58
|
-
|
|
59
|
-
|
|
74
|
+
const { data: latestBuildInfo, isLoading } = useLatestPackageBuildInfo(
|
|
75
|
+
pkg.package_id,
|
|
76
|
+
)
|
|
60
77
|
|
|
61
78
|
if (isLoading && !latestBuildInfo) {
|
|
62
79
|
return <ConnectedPackageCardSkeleton />
|
|
@@ -111,7 +111,7 @@ export const ConnectedRepoOverview = ({
|
|
|
111
111
|
onClick={() => window.open(build.preview_url!, "_blank")}
|
|
112
112
|
>
|
|
113
113
|
<ExternalLink className="w-3 h-3" />
|
|
114
|
-
Preview
|
|
114
|
+
Preview
|
|
115
115
|
</Button>
|
|
116
116
|
)}
|
|
117
117
|
</div>
|
|
@@ -216,7 +216,17 @@ export const ConnectedRepoOverview = ({
|
|
|
216
216
|
</div>
|
|
217
217
|
|
|
218
218
|
<div className="space-y-3">
|
|
219
|
-
<
|
|
219
|
+
<div className="flex items-center justify-between">
|
|
220
|
+
<h2 className="text-lg font-semibold text-gray-900">
|
|
221
|
+
Latest Build Logs
|
|
222
|
+
</h2>
|
|
223
|
+
<a
|
|
224
|
+
href={`/${pkg.name.split("/")[0]}/${pkg.name.split("/")[1]}/release/${packageRelease.package_release_id}/builds`}
|
|
225
|
+
className="text-sm text-blue-600 hover:text-blue-800 transition-colors"
|
|
226
|
+
>
|
|
227
|
+
(previous builds)
|
|
228
|
+
</a>
|
|
229
|
+
</div>
|
|
220
230
|
|
|
221
231
|
<Collapsible
|
|
222
232
|
open={openSections.transpilation}
|
|
@@ -1,57 +1,44 @@
|
|
|
1
|
-
import { useState } from "react"
|
|
2
1
|
import { Button } from "@/components/ui/button"
|
|
3
2
|
import { Badge } from "@/components/ui/badge"
|
|
4
|
-
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs"
|
|
5
3
|
import {
|
|
6
4
|
DropdownMenu,
|
|
7
5
|
DropdownMenuContent,
|
|
8
6
|
DropdownMenuItem,
|
|
9
7
|
DropdownMenuTrigger,
|
|
10
8
|
} from "@/components/ui/dropdown-menu"
|
|
11
|
-
import {
|
|
12
|
-
|
|
13
|
-
List,
|
|
14
|
-
Github,
|
|
15
|
-
MoreHorizontal,
|
|
16
|
-
Zap,
|
|
17
|
-
Clock,
|
|
18
|
-
GitBranch,
|
|
19
|
-
Eye,
|
|
20
|
-
} from "lucide-react"
|
|
9
|
+
import { MoreHorizontal, Clock, GitBranch, Eye } from "lucide-react"
|
|
10
|
+
import { GitHubLogoIcon } from "@radix-ui/react-icons"
|
|
21
11
|
import { useLocation } from "wouter"
|
|
22
|
-
import { ConnectedRepoOverview } from "./ConnectedRepoOverview"
|
|
23
12
|
import { BuildsList } from "./BuildsList"
|
|
24
13
|
import Header from "../Header"
|
|
25
14
|
import { formatTimeAgo } from "@/lib/utils/formatTimeAgo"
|
|
26
15
|
import { getBuildStatus } from "."
|
|
27
16
|
import { PrefetchPageLink } from "../PrefetchPageLink"
|
|
28
|
-
import {
|
|
29
|
-
|
|
30
|
-
PackageBuild,
|
|
31
|
-
PackageRelease,
|
|
32
|
-
} from "fake-snippets-api/lib/db/schema"
|
|
17
|
+
import { PackageBreadcrumb } from "../PackageBreadcrumb"
|
|
18
|
+
import { Package, PackageBuild } from "fake-snippets-api/lib/db/schema"
|
|
33
19
|
|
|
34
|
-
export const
|
|
20
|
+
export const PackageReleasesDashboard = ({
|
|
35
21
|
latestBuild,
|
|
36
22
|
pkg,
|
|
37
|
-
packageRelease,
|
|
38
23
|
}: {
|
|
39
|
-
latestBuild: PackageBuild
|
|
24
|
+
latestBuild: PackageBuild | null
|
|
40
25
|
pkg: Package
|
|
41
|
-
packageRelease: PackageRelease
|
|
42
26
|
}) => {
|
|
43
|
-
const [activeTab, setActiveTab] = useState("overview")
|
|
44
27
|
const [, setLocation] = useLocation()
|
|
45
|
-
const handleSelectBuild = (build: PackageBuild) => {
|
|
46
|
-
setLocation(`/build/${build.package_build_id}`)
|
|
47
|
-
setActiveTab("overview")
|
|
48
|
-
}
|
|
49
28
|
const { status, label } = getBuildStatus(latestBuild)
|
|
50
29
|
|
|
51
30
|
return (
|
|
52
31
|
<>
|
|
53
32
|
<Header />
|
|
54
33
|
<div className="min-h-screen bg-white">
|
|
34
|
+
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 pt-4">
|
|
35
|
+
<PackageBreadcrumb
|
|
36
|
+
author={pkg.name.split("/")[0]}
|
|
37
|
+
packageName={pkg.name}
|
|
38
|
+
unscopedName={pkg.unscoped_name}
|
|
39
|
+
currentPage="releases"
|
|
40
|
+
/>
|
|
41
|
+
</div>
|
|
55
42
|
{/* Project Header */}
|
|
56
43
|
<div className="bg-gray-50 border-b md:py-10">
|
|
57
44
|
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-6">
|
|
@@ -70,7 +57,7 @@ export const ConnectedRepoDashboard = ({
|
|
|
70
57
|
href={"/" + pkg.name}
|
|
71
58
|
className="text-2xl font-bold text-gray-900 truncate"
|
|
72
59
|
>
|
|
73
|
-
{pkg.
|
|
60
|
+
{pkg.name}
|
|
74
61
|
</PrefetchPageLink>
|
|
75
62
|
<Badge
|
|
76
63
|
variant={
|
|
@@ -101,22 +88,26 @@ export const ConnectedRepoDashboard = ({
|
|
|
101
88
|
className="flex cursor-pointer items-center gap-1"
|
|
102
89
|
onClick={() =>
|
|
103
90
|
window?.open(
|
|
104
|
-
`https://github.com/${pkg.github_repo_full_name}/tree/${latestBuild
|
|
91
|
+
`https://github.com/${pkg.github_repo_full_name}/tree/${latestBuild?.branch_name || "main"}`,
|
|
105
92
|
"_blank",
|
|
106
93
|
)
|
|
107
94
|
}
|
|
108
95
|
>
|
|
109
96
|
<GitBranch className="w-4 h-4 flex-shrink-0" />
|
|
110
97
|
<span className="truncate">
|
|
111
|
-
{latestBuild
|
|
98
|
+
{latestBuild?.branch_name || "main"}
|
|
112
99
|
</span>
|
|
113
100
|
</div>
|
|
114
101
|
<div className="flex items-center gap-1">
|
|
115
102
|
<Clock className="w-4 h-4 flex-shrink-0" />
|
|
116
103
|
<span>
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
104
|
+
{latestBuild?.created_at ? (
|
|
105
|
+
<time dateTime={latestBuild.created_at}>
|
|
106
|
+
Last built {formatTimeAgo(latestBuild.created_at)}
|
|
107
|
+
</time>
|
|
108
|
+
) : (
|
|
109
|
+
"No builds yet"
|
|
110
|
+
)}
|
|
120
111
|
</span>
|
|
121
112
|
</div>
|
|
122
113
|
</div>
|
|
@@ -135,18 +126,18 @@ export const ConnectedRepoDashboard = ({
|
|
|
135
126
|
)
|
|
136
127
|
}
|
|
137
128
|
>
|
|
138
|
-
<
|
|
129
|
+
<GitHubLogoIcon className="w-4 h-4" />
|
|
139
130
|
<span className="hidden sm:inline">Repository</span>
|
|
140
131
|
<span className="sm:hidden">Repository</span>
|
|
141
132
|
</Button>
|
|
142
|
-
{latestBuild
|
|
133
|
+
{latestBuild?.preview_url && (
|
|
143
134
|
<Button
|
|
144
135
|
variant="outline"
|
|
145
136
|
size="sm"
|
|
146
137
|
className="flex items-center gap-2 justify-center min-w-[120px] h-9"
|
|
147
138
|
onClick={() =>
|
|
148
139
|
window.open(
|
|
149
|
-
`/build/${latestBuild
|
|
140
|
+
`/build/${latestBuild?.package_build_id}/preview`,
|
|
150
141
|
"_blank",
|
|
151
142
|
)
|
|
152
143
|
}
|
|
@@ -156,14 +147,6 @@ export const ConnectedRepoDashboard = ({
|
|
|
156
147
|
<span className="sm:hidden">Preview</span>
|
|
157
148
|
</Button>
|
|
158
149
|
)}
|
|
159
|
-
<Button
|
|
160
|
-
size="sm"
|
|
161
|
-
className="flex items-center gap-2 justify-center min-w-[120px] h-9 bg-black text-white"
|
|
162
|
-
>
|
|
163
|
-
<Zap className="w-4 h-4" />
|
|
164
|
-
<span className="hidden sm:inline">Rebuild</span>
|
|
165
|
-
<span className="sm:hidden">Rebuild</span>
|
|
166
|
-
</Button>
|
|
167
150
|
<DropdownMenu>
|
|
168
151
|
<DropdownMenuTrigger asChild>
|
|
169
152
|
<Button
|
|
@@ -212,36 +195,9 @@ export const ConnectedRepoDashboard = ({
|
|
|
212
195
|
|
|
213
196
|
{/* Main Content */}
|
|
214
197
|
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-8">
|
|
215
|
-
<
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
className="space-y-6"
|
|
219
|
-
>
|
|
220
|
-
<TabsList className="grid w-full grid-cols-2 lg:w-auto lg:grid-cols-2">
|
|
221
|
-
<TabsTrigger value="overview" className="flex items-center gap-2">
|
|
222
|
-
<Activity className="w-4 h-4" />
|
|
223
|
-
Overview
|
|
224
|
-
</TabsTrigger>
|
|
225
|
-
<TabsTrigger value="builds" className="flex items-center gap-2">
|
|
226
|
-
<List className="w-4 h-4" />
|
|
227
|
-
Builds
|
|
228
|
-
</TabsTrigger>
|
|
229
|
-
</TabsList>
|
|
230
|
-
|
|
231
|
-
<TabsContent value="overview" className="space-y-6">
|
|
232
|
-
{latestBuild && (
|
|
233
|
-
<ConnectedRepoOverview
|
|
234
|
-
build={latestBuild}
|
|
235
|
-
pkg={pkg}
|
|
236
|
-
packageRelease={packageRelease}
|
|
237
|
-
/>
|
|
238
|
-
)}
|
|
239
|
-
</TabsContent>
|
|
240
|
-
|
|
241
|
-
<TabsContent value="builds" className="space-y-6">
|
|
242
|
-
<BuildsList pkg={pkg} onSelectBuild={handleSelectBuild} />
|
|
243
|
-
</TabsContent>
|
|
244
|
-
</Tabs>
|
|
198
|
+
<div className="space-y-6">
|
|
199
|
+
<BuildsList pkg={pkg} />
|
|
200
|
+
</div>
|
|
245
201
|
</div>
|
|
246
202
|
</div>
|
|
247
203
|
</>
|
|
@@ -1,13 +1,16 @@
|
|
|
1
1
|
export { ConnectedRepoOverview } from "./ConnectedRepoOverview"
|
|
2
2
|
export { BuildsList } from "./BuildsList"
|
|
3
|
-
export {
|
|
3
|
+
export { PackageReleasesDashboard } from "./PackageReleasesDashboard"
|
|
4
4
|
import {
|
|
5
5
|
Package,
|
|
6
6
|
PackageBuild,
|
|
7
7
|
PackageRelease,
|
|
8
8
|
} from "fake-snippets-api/lib/db/schema"
|
|
9
9
|
import { Clock, CheckCircle, AlertCircle, Loader2 } from "lucide-react"
|
|
10
|
-
export const getBuildStatus = (build: PackageBuild) => {
|
|
10
|
+
export const getBuildStatus = (build: PackageBuild | null) => {
|
|
11
|
+
if (!build) {
|
|
12
|
+
return { status: "pending", label: "No builds" }
|
|
13
|
+
}
|
|
11
14
|
if (
|
|
12
15
|
build?.build_error ||
|
|
13
16
|
build?.transpilation_error ||
|
|
@@ -28,7 +31,7 @@ export const getBuildStatus = (build: PackageBuild) => {
|
|
|
28
31
|
return { status: "queued", label: "Queued" }
|
|
29
32
|
}
|
|
30
33
|
|
|
31
|
-
export const
|
|
34
|
+
export const MOCK_PACKAGE_BUILDS: PackageBuild[] = [
|
|
32
35
|
{
|
|
33
36
|
package_build_id: "pb_1a2b3c4d",
|
|
34
37
|
package_release_id: "pr_5e6f7g8h",
|
|
@@ -184,5 +187,5 @@ export const StatusIcon = ({ status }: { status: string }) => {
|
|
|
184
187
|
}
|
|
185
188
|
|
|
186
189
|
export const getLatestBuildForPackage = (pkg: Package): PackageBuild => {
|
|
187
|
-
return
|
|
190
|
+
return MOCK_PACKAGE_BUILDS[0]
|
|
188
191
|
}
|