@tscircuit/fake-snippets 0.0.101 → 0.0.102
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/api/generated-index.js +23 -1
- package/bun.lock +2 -2
- package/dist/bundle.js +530 -367
- package/dist/index.d.ts +29 -2
- package/dist/index.js +18 -1
- package/dist/schema.d.ts +94 -1
- package/dist/schema.js +17 -1
- package/fake-snippets-api/lib/db/db-client.ts +6 -1
- package/fake-snippets-api/lib/db/schema.ts +15 -0
- package/fake-snippets-api/lib/public-mapping/public-map-package.ts +2 -0
- package/fake-snippets-api/routes/api/github/installations/create_new_installation_redirect.ts +75 -0
- package/fake-snippets-api/routes/api/github/repos/list_available.ts +91 -0
- package/fake-snippets-api/routes/api/packages/update.ts +4 -0
- package/package.json +2 -2
- package/src/App.tsx +10 -1
- package/src/components/CreateReleaseDialog.tsx +124 -0
- package/src/components/FileSidebar.tsx +128 -23
- package/src/components/PackageBuildsPage/package-build-header.tsx +9 -1
- package/src/components/PageSearchComponent.tsx +2 -2
- package/src/components/SearchComponent.tsx +2 -2
- package/src/components/SuspenseRunFrame.tsx +2 -2
- package/src/components/TrendingPackagesCarousel.tsx +2 -2
- package/src/components/ViewPackagePage/components/mobile-sidebar.tsx +1 -0
- package/src/components/ViewPackagePage/components/sidebar-about-section.tsx +1 -0
- package/src/components/dialogs/GitHubRepositorySelector.tsx +123 -0
- package/src/components/dialogs/create-use-dialog.tsx +8 -2
- package/src/components/dialogs/edit-package-details-dialog.tsx +22 -3
- package/src/components/dialogs/view-ts-files-dialog.tsx +178 -33
- package/src/components/package-port/CodeAndPreview.tsx +4 -1
- package/src/components/package-port/CodeEditor.tsx +42 -35
- package/src/components/package-port/CodeEditorHeader.tsx +6 -4
- package/src/components/package-port/EditorNav.tsx +94 -37
- package/src/components/preview/BuildsList.tsx +238 -0
- package/src/components/preview/ConnectedRepoDashboard.tsx +258 -0
- package/src/components/preview/ConnectedRepoOverview.tsx +454 -0
- package/src/components/preview/ConnectedRepoSettings.tsx +343 -0
- package/src/components/preview/ConnectedReposCards.tsx +191 -0
- package/src/components/preview/index.tsx +207 -0
- package/src/components/ui/tree-view.tsx +23 -6
- package/src/hooks/use-axios.ts +2 -2
- package/src/hooks/use-create-release-dialog.ts +160 -0
- package/src/hooks/use-package-details-form.ts +7 -0
- package/src/hooks/use-packages-base-api-url.ts +1 -1
- package/src/hooks/use-sign-in.ts +2 -2
- package/src/hooks/useFileManagement.ts +22 -2
- package/src/index.css +4 -0
- package/src/lib/utils/formatTimeAgo.ts +10 -0
- package/src/lib/utils/isValidFileName.ts +15 -3
- package/src/pages/dashboard.tsx +2 -2
- package/src/pages/dev-login.tsx +2 -2
- package/src/pages/latest.tsx +2 -2
- package/src/pages/preview-build.tsx +380 -0
- package/src/pages/search.tsx +2 -2
- package/src/pages/trending.tsx +2 -2
- package/src/pages/user-profile.tsx +32 -24
- package/src/pages/view-connected-repo.tsx +24 -0
|
@@ -0,0 +1,454 @@
|
|
|
1
|
+
import { useState } from "react"
|
|
2
|
+
import { Badge } from "@/components/ui/badge"
|
|
3
|
+
import { Button } from "@/components/ui/button"
|
|
4
|
+
import {
|
|
5
|
+
Clock,
|
|
6
|
+
GitBranch,
|
|
7
|
+
CheckCircle,
|
|
8
|
+
AlertCircle,
|
|
9
|
+
Loader2,
|
|
10
|
+
ExternalLink,
|
|
11
|
+
ChevronRight,
|
|
12
|
+
User,
|
|
13
|
+
Hash,
|
|
14
|
+
} from "lucide-react"
|
|
15
|
+
import {
|
|
16
|
+
Collapsible,
|
|
17
|
+
CollapsibleContent,
|
|
18
|
+
CollapsibleTrigger,
|
|
19
|
+
} from "@/components/ui/collapsible"
|
|
20
|
+
import { getBuildStatus, PackageBuild, StatusIcon } from "."
|
|
21
|
+
import { formatTimeAgo } from "@/lib/utils/formatTimeAgo"
|
|
22
|
+
|
|
23
|
+
interface ConnectedRepoOverviewProps {
|
|
24
|
+
build: PackageBuild
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export const ConnectedRepoOverview = ({
|
|
28
|
+
build,
|
|
29
|
+
}: ConnectedRepoOverviewProps) => {
|
|
30
|
+
const { status, label } = getBuildStatus(build)
|
|
31
|
+
const [openSections, setOpenSections] = useState({
|
|
32
|
+
transpilation: false,
|
|
33
|
+
circuitJson: false,
|
|
34
|
+
finalBuild: false,
|
|
35
|
+
})
|
|
36
|
+
|
|
37
|
+
const copyToClipboard = (text: string) => {
|
|
38
|
+
navigator.clipboard.writeText(text)
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
const buildDuration =
|
|
42
|
+
build.build_started_at && build.build_completed_at
|
|
43
|
+
? Math.floor(
|
|
44
|
+
(new Date(build.build_completed_at).getTime() -
|
|
45
|
+
new Date(build.build_started_at).getTime()) /
|
|
46
|
+
1000,
|
|
47
|
+
)
|
|
48
|
+
: null
|
|
49
|
+
|
|
50
|
+
const toggleSection = (section: keyof typeof openSections) => {
|
|
51
|
+
setOpenSections((prev) => ({ ...prev, [section]: !prev[section] }))
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
const getStepStatus = (
|
|
55
|
+
error: string | null,
|
|
56
|
+
completed: string | null,
|
|
57
|
+
inProgress: boolean,
|
|
58
|
+
) => {
|
|
59
|
+
if (error) return "error"
|
|
60
|
+
if (completed) return "success"
|
|
61
|
+
if (inProgress) return "building"
|
|
62
|
+
return "queued"
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
const getStepDuration = (
|
|
66
|
+
started: string | null,
|
|
67
|
+
completed: string | null,
|
|
68
|
+
) => {
|
|
69
|
+
if (started && completed) {
|
|
70
|
+
const duration = Math.floor(
|
|
71
|
+
(new Date(completed).getTime() - new Date(started).getTime()) / 1000,
|
|
72
|
+
)
|
|
73
|
+
return `${duration}s`
|
|
74
|
+
}
|
|
75
|
+
return null
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
return (
|
|
79
|
+
<div className="max-w-6xl mx-auto px-4 sm:px-6 lg:px-8 py-6 space-y-6 focus:outline-none">
|
|
80
|
+
<div className="bg-white border border-gray-200 rounded-lg">
|
|
81
|
+
<div className="px-6 py-6 border-b border-gray-200">
|
|
82
|
+
<div className="flex flex-col sm:flex-row sm:items-center sm:justify-between gap-4">
|
|
83
|
+
<div className="flex items-center gap-4">
|
|
84
|
+
<StatusIcon status={status} />
|
|
85
|
+
<div className="flex-1">
|
|
86
|
+
<div className="flex flex-col sm:flex-row sm:items-center sm:gap-3">
|
|
87
|
+
<h1 className="text-xl sm:text-2xl font-semibold text-gray-900">
|
|
88
|
+
Deployment {label}
|
|
89
|
+
</h1>
|
|
90
|
+
</div>
|
|
91
|
+
<p className="text-sm text-gray-600 mt-1">
|
|
92
|
+
Created {formatTimeAgo(build.created_at)}
|
|
93
|
+
</p>
|
|
94
|
+
</div>
|
|
95
|
+
</div>
|
|
96
|
+
<div className="flex items-center gap-3 flex-shrink-0">
|
|
97
|
+
{build.preview_url && (
|
|
98
|
+
<Button
|
|
99
|
+
size="sm"
|
|
100
|
+
className="flex items-center gap-2 min-w-[80px] h-9"
|
|
101
|
+
onClick={() => window.open(build.preview_url!, "_blank")}
|
|
102
|
+
>
|
|
103
|
+
<ExternalLink className="w-3 h-3" />
|
|
104
|
+
Preview Deployment
|
|
105
|
+
</Button>
|
|
106
|
+
)}
|
|
107
|
+
</div>
|
|
108
|
+
</div>
|
|
109
|
+
</div>
|
|
110
|
+
|
|
111
|
+
<div className="px-6 py-4">
|
|
112
|
+
<div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-6">
|
|
113
|
+
<div className="flex items-center gap-3 group">
|
|
114
|
+
<Hash className="w-4 h-4 text-gray-500 group-hover:text-blue-500 transition-colors" />
|
|
115
|
+
<div>
|
|
116
|
+
<p className="text-xs text-gray-500 uppercase tracking-wide">
|
|
117
|
+
Build ID
|
|
118
|
+
</p>
|
|
119
|
+
<div className="flex items-center gap-2">
|
|
120
|
+
<button
|
|
121
|
+
onClick={() => copyToClipboard(build.package_build_id)}
|
|
122
|
+
className="group-hover:text-blue-500 rounded transition-colors"
|
|
123
|
+
>
|
|
124
|
+
{build.package_build_id}
|
|
125
|
+
</button>
|
|
126
|
+
</div>
|
|
127
|
+
</div>
|
|
128
|
+
</div>
|
|
129
|
+
|
|
130
|
+
<div className="flex items-center gap-3 group">
|
|
131
|
+
<GitBranch className="w-4 h-4 text-gray-500 group-hover:text-blue-500 transition-colors" />
|
|
132
|
+
<div>
|
|
133
|
+
<p className="text-xs text-gray-500 uppercase tracking-wide">
|
|
134
|
+
Branch
|
|
135
|
+
</p>
|
|
136
|
+
<a
|
|
137
|
+
href={`https://github.com/tscircuit/tscircuit/tree/${build.branch_name || "main"}`}
|
|
138
|
+
target="_blank"
|
|
139
|
+
rel="noopener noreferrer"
|
|
140
|
+
className="inline-block"
|
|
141
|
+
>
|
|
142
|
+
<Badge
|
|
143
|
+
variant="outline"
|
|
144
|
+
className="text-xs mt-1 hover:bg-gray-100 cursor-pointer transition-colors"
|
|
145
|
+
>
|
|
146
|
+
{build.branch_name || "main"}
|
|
147
|
+
</Badge>
|
|
148
|
+
</a>
|
|
149
|
+
</div>
|
|
150
|
+
</div>
|
|
151
|
+
|
|
152
|
+
<div className="flex items-center gap-3 group">
|
|
153
|
+
<User className="w-4 h-4 text-gray-500 group-hover:text-blue-500 transition-colors" />
|
|
154
|
+
<div>
|
|
155
|
+
<p className="text-xs text-gray-500 uppercase tracking-wide">
|
|
156
|
+
Author
|
|
157
|
+
</p>
|
|
158
|
+
<a
|
|
159
|
+
href={`https://github.com/${build.commit_author}`}
|
|
160
|
+
target="_blank"
|
|
161
|
+
rel="noopener noreferrer"
|
|
162
|
+
className="text-sm font-medium hover:text-blue-500 transition-colors"
|
|
163
|
+
>
|
|
164
|
+
{build.commit_author || "Unknown"}
|
|
165
|
+
</a>
|
|
166
|
+
</div>
|
|
167
|
+
</div>
|
|
168
|
+
|
|
169
|
+
{buildDuration && (
|
|
170
|
+
<div className="flex items-center gap-3 group">
|
|
171
|
+
<Clock className="w-4 h-4 text-gray-500 group-hover:text-blue-500 transition-colors" />
|
|
172
|
+
<div>
|
|
173
|
+
<p className="text-xs text-gray-500 uppercase tracking-wide">
|
|
174
|
+
Duration
|
|
175
|
+
</p>
|
|
176
|
+
<p
|
|
177
|
+
className="text-sm font-medium hover:text-blue-500 transition-colors cursor-help"
|
|
178
|
+
title={`Build started at ${build.build_started_at}`}
|
|
179
|
+
>
|
|
180
|
+
{buildDuration}s
|
|
181
|
+
</p>
|
|
182
|
+
</div>
|
|
183
|
+
</div>
|
|
184
|
+
)}
|
|
185
|
+
</div>
|
|
186
|
+
|
|
187
|
+
{build.commit_message && (
|
|
188
|
+
<div className="mt-6 p-4 bg-gray-50 rounded-lg hover:bg-gray-100 transition-colors group">
|
|
189
|
+
<p className="text-xs text-gray-500 uppercase tracking-wide mb-2">
|
|
190
|
+
Commit Message
|
|
191
|
+
</p>
|
|
192
|
+
<p className="text-sm text-gray-900 group-hover:text-gray-700 transition-colors">
|
|
193
|
+
{build.commit_message}
|
|
194
|
+
</p>
|
|
195
|
+
</div>
|
|
196
|
+
)}
|
|
197
|
+
</div>
|
|
198
|
+
</div>
|
|
199
|
+
|
|
200
|
+
<div className="space-y-3">
|
|
201
|
+
<h2 className="text-lg font-semibold text-gray-900">Build Steps</h2>
|
|
202
|
+
|
|
203
|
+
<Collapsible
|
|
204
|
+
open={openSections.transpilation}
|
|
205
|
+
onOpenChange={() => toggleSection("transpilation")}
|
|
206
|
+
>
|
|
207
|
+
<CollapsibleTrigger asChild>
|
|
208
|
+
<div className="flex items-center justify-between p-4 bg-white border border-gray-200 rounded-lg cursor-pointer hover:bg-gray-50">
|
|
209
|
+
<div className="flex items-center gap-3">
|
|
210
|
+
<ChevronRight
|
|
211
|
+
className={`w-4 h-4 transition-transform ${openSections.transpilation ? "rotate-90" : ""}`}
|
|
212
|
+
/>
|
|
213
|
+
{build.transpilation_error ? (
|
|
214
|
+
<AlertCircle className="w-5 h-5 text-red-500" />
|
|
215
|
+
) : build.transpilation_completed_at ? (
|
|
216
|
+
<CheckCircle className="w-5 h-5 text-green-500" />
|
|
217
|
+
) : build.transpilation_in_progress ? (
|
|
218
|
+
<Loader2 className="w-5 h-5 text-blue-500 animate-spin" />
|
|
219
|
+
) : (
|
|
220
|
+
<Clock className="w-5 h-5 text-gray-400" />
|
|
221
|
+
)}
|
|
222
|
+
<span className="font-medium">Transpilation</span>
|
|
223
|
+
</div>
|
|
224
|
+
<div className="flex items-center gap-2">
|
|
225
|
+
{getStepDuration(
|
|
226
|
+
build.transpilation_started_at,
|
|
227
|
+
build.transpilation_completed_at,
|
|
228
|
+
) && (
|
|
229
|
+
<span className="text-sm text-gray-600">
|
|
230
|
+
{getStepDuration(
|
|
231
|
+
build.transpilation_started_at,
|
|
232
|
+
build.transpilation_completed_at,
|
|
233
|
+
)}
|
|
234
|
+
</span>
|
|
235
|
+
)}
|
|
236
|
+
<Badge
|
|
237
|
+
variant={
|
|
238
|
+
getStepStatus(
|
|
239
|
+
build.transpilation_error,
|
|
240
|
+
build.transpilation_completed_at,
|
|
241
|
+
build.transpilation_in_progress,
|
|
242
|
+
) === "success"
|
|
243
|
+
? "default"
|
|
244
|
+
: getStepStatus(
|
|
245
|
+
build.transpilation_error,
|
|
246
|
+
build.transpilation_completed_at,
|
|
247
|
+
build.transpilation_in_progress,
|
|
248
|
+
) === "error"
|
|
249
|
+
? "destructive"
|
|
250
|
+
: "secondary"
|
|
251
|
+
}
|
|
252
|
+
className="text-xs"
|
|
253
|
+
>
|
|
254
|
+
{build.transpilation_error
|
|
255
|
+
? "Failed"
|
|
256
|
+
: build.transpilation_completed_at
|
|
257
|
+
? "Completed"
|
|
258
|
+
: build.transpilation_in_progress
|
|
259
|
+
? "Running"
|
|
260
|
+
: "Queued"}
|
|
261
|
+
</Badge>
|
|
262
|
+
</div>
|
|
263
|
+
</div>
|
|
264
|
+
</CollapsibleTrigger>
|
|
265
|
+
<CollapsibleContent>
|
|
266
|
+
<div className="bg-white border-x border-b border-gray-200 rounded-b-lg p-4">
|
|
267
|
+
<div className="font-mono text-xs space-y-1">
|
|
268
|
+
{build.transpilation_error ? (
|
|
269
|
+
<div className="text-red-600 whitespace-pre-wrap">
|
|
270
|
+
{build.transpilation_error}
|
|
271
|
+
</div>
|
|
272
|
+
) : build.transpilation_logs &&
|
|
273
|
+
build.transpilation_logs.length > 0 ? (
|
|
274
|
+
build.transpilation_logs.map((log: any, i: number) => (
|
|
275
|
+
<div key={i} className="text-gray-600 whitespace-pre-wrap">
|
|
276
|
+
{log.msg || log.message || JSON.stringify(log)}
|
|
277
|
+
</div>
|
|
278
|
+
))
|
|
279
|
+
) : (
|
|
280
|
+
<div className="text-gray-500">No logs available</div>
|
|
281
|
+
)}
|
|
282
|
+
</div>
|
|
283
|
+
</div>
|
|
284
|
+
</CollapsibleContent>
|
|
285
|
+
</Collapsible>
|
|
286
|
+
|
|
287
|
+
<Collapsible
|
|
288
|
+
open={openSections.circuitJson}
|
|
289
|
+
onOpenChange={() => toggleSection("circuitJson")}
|
|
290
|
+
>
|
|
291
|
+
<CollapsibleTrigger asChild>
|
|
292
|
+
<div className="flex items-center justify-between p-4 bg-white border border-gray-200 rounded-lg cursor-pointer hover:bg-gray-50">
|
|
293
|
+
<div className="flex items-center gap-3">
|
|
294
|
+
<ChevronRight
|
|
295
|
+
className={`w-4 h-4 transition-transform ${openSections.circuitJson ? "rotate-90" : ""}`}
|
|
296
|
+
/>
|
|
297
|
+
{build.circuit_json_build_error ? (
|
|
298
|
+
<AlertCircle className="w-5 h-5 text-red-500" />
|
|
299
|
+
) : build.circuit_json_build_completed_at ? (
|
|
300
|
+
<CheckCircle className="w-5 h-5 text-green-500" />
|
|
301
|
+
) : build.circuit_json_build_in_progress ? (
|
|
302
|
+
<Loader2 className="w-5 h-5 text-blue-500 animate-spin" />
|
|
303
|
+
) : (
|
|
304
|
+
<Clock className="w-5 h-5 text-gray-400" />
|
|
305
|
+
)}
|
|
306
|
+
<span className="font-medium">Circuit JSON Build</span>
|
|
307
|
+
</div>
|
|
308
|
+
<div className="flex items-center gap-2">
|
|
309
|
+
{getStepDuration(
|
|
310
|
+
build.circuit_json_build_started_at,
|
|
311
|
+
build.circuit_json_build_completed_at,
|
|
312
|
+
) && (
|
|
313
|
+
<span className="text-sm text-gray-600">
|
|
314
|
+
{getStepDuration(
|
|
315
|
+
build.circuit_json_build_started_at,
|
|
316
|
+
build.circuit_json_build_completed_at,
|
|
317
|
+
)}
|
|
318
|
+
</span>
|
|
319
|
+
)}
|
|
320
|
+
<Badge
|
|
321
|
+
variant={
|
|
322
|
+
getStepStatus(
|
|
323
|
+
build.circuit_json_build_error,
|
|
324
|
+
build.circuit_json_build_completed_at,
|
|
325
|
+
build.circuit_json_build_in_progress,
|
|
326
|
+
) === "success"
|
|
327
|
+
? "default"
|
|
328
|
+
: getStepStatus(
|
|
329
|
+
build.circuit_json_build_error,
|
|
330
|
+
build.circuit_json_build_completed_at,
|
|
331
|
+
build.circuit_json_build_in_progress,
|
|
332
|
+
) === "error"
|
|
333
|
+
? "destructive"
|
|
334
|
+
: "secondary"
|
|
335
|
+
}
|
|
336
|
+
className="text-xs"
|
|
337
|
+
>
|
|
338
|
+
{build.circuit_json_build_error
|
|
339
|
+
? "Failed"
|
|
340
|
+
: build.circuit_json_build_completed_at
|
|
341
|
+
? "Completed"
|
|
342
|
+
: build.circuit_json_build_in_progress
|
|
343
|
+
? "Running"
|
|
344
|
+
: "Queued"}
|
|
345
|
+
</Badge>
|
|
346
|
+
</div>
|
|
347
|
+
</div>
|
|
348
|
+
</CollapsibleTrigger>
|
|
349
|
+
<CollapsibleContent>
|
|
350
|
+
<div className="bg-white border-x border-b border-gray-200 rounded-b-lg p-4">
|
|
351
|
+
<div className="font-mono text-xs space-y-1">
|
|
352
|
+
{build.circuit_json_build_error ? (
|
|
353
|
+
<div className="text-red-600 whitespace-pre-wrap">
|
|
354
|
+
{build.circuit_json_build_error}
|
|
355
|
+
</div>
|
|
356
|
+
) : build.circuit_json_build_logs &&
|
|
357
|
+
build.circuit_json_build_logs.length > 0 ? (
|
|
358
|
+
build.circuit_json_build_logs.map((log: any, i: number) => (
|
|
359
|
+
<div key={i} className="text-gray-600 whitespace-pre-wrap">
|
|
360
|
+
{log.msg || log.message || JSON.stringify(log)}
|
|
361
|
+
</div>
|
|
362
|
+
))
|
|
363
|
+
) : (
|
|
364
|
+
<div className="text-gray-500">No logs available</div>
|
|
365
|
+
)}
|
|
366
|
+
</div>
|
|
367
|
+
</div>
|
|
368
|
+
</CollapsibleContent>
|
|
369
|
+
</Collapsible>
|
|
370
|
+
|
|
371
|
+
<Collapsible
|
|
372
|
+
open={openSections.finalBuild}
|
|
373
|
+
onOpenChange={() => toggleSection("finalBuild")}
|
|
374
|
+
>
|
|
375
|
+
<CollapsibleTrigger asChild>
|
|
376
|
+
<div className="flex items-center justify-between p-4 bg-white border border-gray-200 rounded-lg cursor-pointer hover:bg-gray-50">
|
|
377
|
+
<div className="flex items-center gap-3">
|
|
378
|
+
<ChevronRight
|
|
379
|
+
className={`w-4 h-4 transition-transform ${openSections.finalBuild ? "rotate-90" : ""}`}
|
|
380
|
+
/>
|
|
381
|
+
{build.build_error ? (
|
|
382
|
+
<AlertCircle className="w-5 h-5 text-red-500" />
|
|
383
|
+
) : build.build_completed_at ? (
|
|
384
|
+
<CheckCircle className="w-5 h-5 text-green-500" />
|
|
385
|
+
) : build.build_in_progress ? (
|
|
386
|
+
<Loader2 className="w-5 h-5 text-blue-500 animate-spin" />
|
|
387
|
+
) : (
|
|
388
|
+
<Clock className="w-5 h-5 text-gray-400" />
|
|
389
|
+
)}
|
|
390
|
+
<span className="font-medium">Final Build</span>
|
|
391
|
+
</div>
|
|
392
|
+
<div className="flex items-center gap-2">
|
|
393
|
+
{getStepDuration(
|
|
394
|
+
build.build_started_at,
|
|
395
|
+
build.build_completed_at,
|
|
396
|
+
) && (
|
|
397
|
+
<span className="text-sm text-gray-600">
|
|
398
|
+
{getStepDuration(
|
|
399
|
+
build.build_started_at,
|
|
400
|
+
build.build_completed_at,
|
|
401
|
+
)}
|
|
402
|
+
</span>
|
|
403
|
+
)}
|
|
404
|
+
<Badge
|
|
405
|
+
variant={
|
|
406
|
+
getStepStatus(
|
|
407
|
+
build.build_error,
|
|
408
|
+
build.build_completed_at,
|
|
409
|
+
build.build_in_progress,
|
|
410
|
+
) === "success"
|
|
411
|
+
? "default"
|
|
412
|
+
: getStepStatus(
|
|
413
|
+
build.build_error,
|
|
414
|
+
build.build_completed_at,
|
|
415
|
+
build.build_in_progress,
|
|
416
|
+
) === "error"
|
|
417
|
+
? "destructive"
|
|
418
|
+
: "secondary"
|
|
419
|
+
}
|
|
420
|
+
className="text-xs"
|
|
421
|
+
>
|
|
422
|
+
{build.build_error
|
|
423
|
+
? "Failed"
|
|
424
|
+
: build.build_completed_at
|
|
425
|
+
? "Completed"
|
|
426
|
+
: build.build_in_progress
|
|
427
|
+
? "Running"
|
|
428
|
+
: "Queued"}
|
|
429
|
+
</Badge>
|
|
430
|
+
</div>
|
|
431
|
+
</div>
|
|
432
|
+
</CollapsibleTrigger>
|
|
433
|
+
<CollapsibleContent>
|
|
434
|
+
<div className="bg-white border-x border-b border-gray-200 rounded-b-lg p-4">
|
|
435
|
+
<div className="font-mono text-xs space-y-1">
|
|
436
|
+
{build.build_error ? (
|
|
437
|
+
<div className="text-red-600 whitespace-pre-wrap">
|
|
438
|
+
{build.build_error}
|
|
439
|
+
</div>
|
|
440
|
+
) : build.build_logs ? (
|
|
441
|
+
<div className="text-gray-600 whitespace-pre-wrap">
|
|
442
|
+
{build.build_logs}
|
|
443
|
+
</div>
|
|
444
|
+
) : (
|
|
445
|
+
<div className="text-gray-500">No logs available</div>
|
|
446
|
+
)}
|
|
447
|
+
</div>
|
|
448
|
+
</div>
|
|
449
|
+
</CollapsibleContent>
|
|
450
|
+
</Collapsible>
|
|
451
|
+
</div>
|
|
452
|
+
</div>
|
|
453
|
+
)
|
|
454
|
+
}
|