@tscircuit/fake-snippets 0.0.87 → 0.0.89
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 +96 -14
- package/bun-tests/fake-snippets-api/routes/proxy.test.ts +42 -0
- package/bun.lock +187 -206
- package/dist/bundle.js +207 -101
- package/fake-snippets-api/routes/api/package_releases/create.ts +1 -1
- package/fake-snippets-api/routes/api/proxy.ts +128 -0
- package/package.json +57 -50
- package/renovate.json +2 -1
- package/src/App.tsx +22 -3
- package/src/ContextProviders.tsx +2 -0
- package/src/build-watcher.ts +52 -0
- package/src/components/CmdKMenu.tsx +533 -197
- package/src/components/DownloadButtonAndMenu.tsx +104 -26
- package/src/components/FileSidebar.tsx +11 -1
- package/src/components/Header.tsx +5 -1
- package/src/components/Header2.tsx +7 -2
- package/src/components/HeaderLogin.tsx +1 -1
- package/src/components/PackageBuildsPage/LogContent.tsx +25 -22
- package/src/components/PackageBuildsPage/PackageBuildDetailsPage.tsx +6 -6
- package/src/components/PackageBuildsPage/build-preview-content.tsx +5 -5
- package/src/components/PackageBuildsPage/package-build-details-panel.tsx +15 -13
- package/src/components/PackageBuildsPage/package-build-header.tsx +17 -16
- package/src/components/PackageCard.tsx +66 -16
- package/src/components/PrefetchPageLink.tsx +66 -15
- package/src/components/SearchComponent.tsx +2 -2
- package/src/components/SuspenseRunFrame.tsx +14 -2
- package/src/components/ViewPackagePage/components/important-files-view.tsx +97 -22
- package/src/components/ViewPackagePage/components/main-content-header.tsx +27 -3
- package/src/components/ViewPackagePage/components/mobile-sidebar.tsx +2 -2
- package/src/components/ViewPackagePage/components/repo-page-content.tsx +49 -34
- package/src/components/ViewPackagePage/components/sidebar-about-section.tsx +2 -2
- package/src/components/ViewPackagePage/components/sidebar-releases-section.tsx +20 -12
- package/src/components/ViewPackagePage/components/tab-views/files-view.tsx +0 -7
- package/src/components/ViewPackagePage/utils/fuzz-search.ts +121 -0
- package/src/components/ViewPackagePage/utils/is-hidden-file.ts +4 -0
- package/src/components/ViewPackagePage/utils/is-package-file-important.ts +18 -5
- package/src/components/dialogs/confirm-delete-package-dialog.tsx +1 -1
- package/src/components/dialogs/confirm-discard-changes-dialog.tsx +73 -0
- package/src/components/dialogs/edit-package-details-dialog.tsx +2 -2
- package/src/components/dialogs/view-ts-files-dialog.tsx +478 -42
- package/src/components/package-port/CodeAndPreview.tsx +16 -0
- package/src/components/package-port/CodeEditor.tsx +113 -11
- package/src/components/package-port/CodeEditorHeader.tsx +39 -4
- package/src/components/package-port/EditorNav.tsx +41 -15
- package/src/components/package-port/GlobalFindReplace.tsx +681 -0
- package/src/components/package-port/QuickOpen.tsx +241 -0
- package/src/components/ui/dialog.tsx +1 -1
- package/src/components/ui/tree-view.tsx +1 -1
- package/src/global.d.ts +3 -0
- package/src/hooks/use-ai-review.ts +31 -0
- package/src/hooks/use-current-package-release.ts +5 -1
- package/src/hooks/use-download-zip.ts +50 -0
- package/src/hooks/use-hotkey.ts +116 -0
- package/src/hooks/use-package-by-package-id.ts +1 -0
- package/src/hooks/use-package-by-package-name.ts +1 -0
- package/src/hooks/use-package-files.ts +3 -0
- package/src/hooks/use-package-release.ts +5 -1
- package/src/hooks/use-package.ts +1 -0
- package/src/hooks/use-request-ai-review-mutation.ts +14 -6
- package/src/hooks/use-snippet.ts +1 -0
- package/src/hooks/useFileManagement.ts +26 -8
- package/src/hooks/usePackageFilesLoader.ts +3 -1
- package/src/index.css +11 -0
- package/src/lib/decodeUrlHashToFsMap.ts +17 -0
- package/src/lib/download-fns/download-circuit-png.ts +88 -0
- package/src/lib/download-fns/download-png-utils.ts +31 -0
- package/src/lib/encodeFsMapToUrlHash.ts +13 -0
- package/src/lib/populate-query-cache-with-ssr-data.ts +39 -38
- package/src/lib/ts-lib-cache.ts +47 -0
- package/src/lib/types.ts +2 -0
- package/src/main.tsx +7 -0
- package/src/pages/dashboard.tsx +8 -5
- package/src/pages/user-profile.tsx +1 -1
- package/src/pages/view-package.tsx +15 -7
- package/vite.config.ts +100 -1
|
@@ -13,24 +13,31 @@ import { downloadFabricationFiles } from "@/lib/download-fns/download-fabricatio
|
|
|
13
13
|
import { downloadSchematicSvg } from "@/lib/download-fns/download-schematic-svg"
|
|
14
14
|
import { downloadReadableNetlist } from "@/lib/download-fns/download-readable-netlist"
|
|
15
15
|
import { downloadAssemblySvg } from "@/lib/download-fns/download-assembly-svg"
|
|
16
|
-
import { downloadPcbSvg } from "@/lib/download-fns/download-pcb-svg"
|
|
17
16
|
import { usePcbDownloadDialog } from "@/components/dialogs/pcb-download-dialog"
|
|
18
17
|
import { downloadKicadFiles } from "@/lib/download-fns/download-kicad-files"
|
|
19
18
|
import { AnyCircuitElement } from "circuit-json"
|
|
20
19
|
import { ChevronDown, Download, Hammer } from "lucide-react"
|
|
21
20
|
import { downloadGltf } from "@/lib/download-fns/download-gltf"
|
|
21
|
+
import { downloadPngImage } from "@/lib/download-fns/download-png-utils"
|
|
22
|
+
import { ImageFormat } from "@/lib/download-fns/download-circuit-png"
|
|
22
23
|
import { CubeIcon } from "@radix-ui/react-icons"
|
|
23
24
|
|
|
24
25
|
interface DownloadButtonAndMenuProps {
|
|
25
26
|
className?: string
|
|
26
|
-
|
|
27
|
+
unscopedName?: string
|
|
28
|
+
author?: string
|
|
27
29
|
circuitJson?: AnyCircuitElement[] | null
|
|
30
|
+
desiredImageType?: string
|
|
31
|
+
offerMultipleImageFormats?: boolean
|
|
28
32
|
}
|
|
29
33
|
|
|
30
34
|
export function DownloadButtonAndMenu({
|
|
31
35
|
className,
|
|
32
|
-
|
|
36
|
+
unscopedName,
|
|
37
|
+
author,
|
|
38
|
+
desiredImageType = "pcb",
|
|
33
39
|
circuitJson,
|
|
40
|
+
offerMultipleImageFormats = false,
|
|
34
41
|
}: DownloadButtonAndMenuProps) {
|
|
35
42
|
const notImplemented = useNotImplementedToast()
|
|
36
43
|
const { Dialog: PcbDownloadDialog, openDialog: openPcbDownloadDialog } =
|
|
@@ -65,13 +72,13 @@ export function DownloadButtonAndMenu({
|
|
|
65
72
|
<ChevronDown className="w-4 h-4 ml-1" />
|
|
66
73
|
</Button>
|
|
67
74
|
</DropdownMenuTrigger>
|
|
68
|
-
<DropdownMenuContent>
|
|
75
|
+
<DropdownMenuContent className="!z-[101]">
|
|
69
76
|
<DropdownMenuItem
|
|
70
77
|
className="text-xs"
|
|
71
78
|
onSelect={() => {
|
|
72
79
|
downloadCircuitJson(
|
|
73
80
|
circuitJson,
|
|
74
|
-
|
|
81
|
+
unscopedName || "circuit" + ".json",
|
|
75
82
|
)
|
|
76
83
|
}}
|
|
77
84
|
>
|
|
@@ -85,7 +92,7 @@ export function DownloadButtonAndMenu({
|
|
|
85
92
|
className="text-xs"
|
|
86
93
|
onClick={async () => {
|
|
87
94
|
try {
|
|
88
|
-
await downloadGltf(
|
|
95
|
+
await downloadGltf(unscopedName || "circuit")
|
|
89
96
|
} catch (error: any) {
|
|
90
97
|
toast({
|
|
91
98
|
title: "Error Downloading 3D Model",
|
|
@@ -106,7 +113,7 @@ export function DownloadButtonAndMenu({
|
|
|
106
113
|
onClick={async () => {
|
|
107
114
|
await downloadFabricationFiles({
|
|
108
115
|
circuitJson,
|
|
109
|
-
snippetUnscopedName:
|
|
116
|
+
snippetUnscopedName: unscopedName || "snippet",
|
|
110
117
|
}).catch((error) => {
|
|
111
118
|
console.error(error)
|
|
112
119
|
console.log(error, error.stack)
|
|
@@ -137,10 +144,7 @@ export function DownloadButtonAndMenu({
|
|
|
137
144
|
<DropdownMenuItem
|
|
138
145
|
className="text-xs"
|
|
139
146
|
onSelect={() => {
|
|
140
|
-
downloadKicadFiles(
|
|
141
|
-
circuitJson,
|
|
142
|
-
snippetUnscopedName || "kicad_project",
|
|
143
|
-
)
|
|
147
|
+
downloadKicadFiles(circuitJson, unscopedName || "kicad_project")
|
|
144
148
|
}}
|
|
145
149
|
>
|
|
146
150
|
<Download className="mr-1 h-3 w-3" />
|
|
@@ -153,10 +157,7 @@ export function DownloadButtonAndMenu({
|
|
|
153
157
|
<DropdownMenuItem
|
|
154
158
|
className="text-xs"
|
|
155
159
|
onSelect={() => {
|
|
156
|
-
downloadSchematicSvg(
|
|
157
|
-
circuitJson,
|
|
158
|
-
snippetUnscopedName || "circuit",
|
|
159
|
-
)
|
|
160
|
+
downloadSchematicSvg(circuitJson, unscopedName || "circuit")
|
|
160
161
|
}}
|
|
161
162
|
>
|
|
162
163
|
<Download className="mr-1 h-3 w-3" />
|
|
@@ -168,7 +169,7 @@ export function DownloadButtonAndMenu({
|
|
|
168
169
|
<DropdownMenuItem
|
|
169
170
|
className="text-xs"
|
|
170
171
|
onSelect={() => {
|
|
171
|
-
downloadAssemblySvg(circuitJson,
|
|
172
|
+
downloadAssemblySvg(circuitJson, unscopedName || "circuit")
|
|
172
173
|
}}
|
|
173
174
|
>
|
|
174
175
|
<Download className="mr-1 h-3 w-3" />
|
|
@@ -192,7 +193,7 @@ export function DownloadButtonAndMenu({
|
|
|
192
193
|
<DropdownMenuItem
|
|
193
194
|
className="text-xs"
|
|
194
195
|
onSelect={() => {
|
|
195
|
-
downloadDsnFile(circuitJson,
|
|
196
|
+
downloadDsnFile(circuitJson, unscopedName || "circuit")
|
|
196
197
|
}}
|
|
197
198
|
>
|
|
198
199
|
<Download className="mr-1 h-3 w-3" />
|
|
@@ -204,10 +205,7 @@ export function DownloadButtonAndMenu({
|
|
|
204
205
|
<DropdownMenuItem
|
|
205
206
|
className="text-xs"
|
|
206
207
|
onClick={() => {
|
|
207
|
-
downloadReadableNetlist(
|
|
208
|
-
circuitJson,
|
|
209
|
-
snippetUnscopedName || "circuit",
|
|
210
|
-
)
|
|
208
|
+
downloadReadableNetlist(circuitJson, unscopedName || "circuit")
|
|
211
209
|
}}
|
|
212
210
|
>
|
|
213
211
|
<Download className="mr-1 h-3 w-3" />
|
|
@@ -219,10 +217,7 @@ export function DownloadButtonAndMenu({
|
|
|
219
217
|
<DropdownMenuItem
|
|
220
218
|
className="text-xs"
|
|
221
219
|
onSelect={() => {
|
|
222
|
-
downloadSimpleRouteJson(
|
|
223
|
-
circuitJson,
|
|
224
|
-
snippetUnscopedName || "circuit",
|
|
225
|
-
)
|
|
220
|
+
downloadSimpleRouteJson(circuitJson, unscopedName || "circuit")
|
|
226
221
|
}}
|
|
227
222
|
>
|
|
228
223
|
<Download className="mr-1 h-3 w-3" />
|
|
@@ -231,11 +226,94 @@ export function DownloadButtonAndMenu({
|
|
|
231
226
|
json
|
|
232
227
|
</span>
|
|
233
228
|
</DropdownMenuItem>
|
|
229
|
+
|
|
230
|
+
{!offerMultipleImageFormats && (
|
|
231
|
+
<DropdownMenuItem
|
|
232
|
+
className="text-xs"
|
|
233
|
+
onClick={() => {
|
|
234
|
+
const desiredImageFormat = [
|
|
235
|
+
"pcb",
|
|
236
|
+
"schematic",
|
|
237
|
+
"assembly",
|
|
238
|
+
"3d",
|
|
239
|
+
].includes(desiredImageType)
|
|
240
|
+
? desiredImageType
|
|
241
|
+
: "pcb"
|
|
242
|
+
downloadPngImage({
|
|
243
|
+
circuitJson,
|
|
244
|
+
unscopedName,
|
|
245
|
+
author,
|
|
246
|
+
format: desiredImageFormat as ImageFormat,
|
|
247
|
+
})
|
|
248
|
+
}}
|
|
249
|
+
>
|
|
250
|
+
<Download className="mr-1 h-3 w-3" />
|
|
251
|
+
<span className="flex-grow mr-6">Image PNG</span>
|
|
252
|
+
<span className="text-[0.6rem] opacity-80 bg-teal-600 text-white font-mono rounded-md px-1 text-center py-0.5 mr-1">
|
|
253
|
+
png
|
|
254
|
+
</span>
|
|
255
|
+
</DropdownMenuItem>
|
|
256
|
+
)}
|
|
257
|
+
{offerMultipleImageFormats && (
|
|
258
|
+
<>
|
|
259
|
+
<DropdownMenuItem
|
|
260
|
+
className="text-xs"
|
|
261
|
+
onClick={() =>
|
|
262
|
+
downloadPngImage({
|
|
263
|
+
circuitJson,
|
|
264
|
+
unscopedName,
|
|
265
|
+
author,
|
|
266
|
+
format: "schematic",
|
|
267
|
+
})
|
|
268
|
+
}
|
|
269
|
+
>
|
|
270
|
+
<Download className="mr-1 h-3 w-3" />
|
|
271
|
+
<span className="flex-grow mr-6">Schematic PNG</span>
|
|
272
|
+
<span className="text-[0.6rem] opacity-80 bg-teal-600 text-white font-mono rounded-md px-1 text-center py-0.5 mr-1">
|
|
273
|
+
png
|
|
274
|
+
</span>
|
|
275
|
+
</DropdownMenuItem>
|
|
276
|
+
<DropdownMenuItem
|
|
277
|
+
className="text-xs"
|
|
278
|
+
onClick={() =>
|
|
279
|
+
downloadPngImage({
|
|
280
|
+
circuitJson,
|
|
281
|
+
unscopedName,
|
|
282
|
+
author,
|
|
283
|
+
format: "pcb",
|
|
284
|
+
})
|
|
285
|
+
}
|
|
286
|
+
>
|
|
287
|
+
<Download className="mr-1 h-3 w-3" />
|
|
288
|
+
<span className="flex-grow mr-6">PCB PNG</span>
|
|
289
|
+
<span className="text-[0.6rem] opacity-80 bg-teal-600 text-white font-mono rounded-md px-1 text-center py-0.5 mr-1">
|
|
290
|
+
png
|
|
291
|
+
</span>
|
|
292
|
+
</DropdownMenuItem>
|
|
293
|
+
<DropdownMenuItem
|
|
294
|
+
className="text-xs"
|
|
295
|
+
onClick={() =>
|
|
296
|
+
downloadPngImage({
|
|
297
|
+
circuitJson,
|
|
298
|
+
unscopedName,
|
|
299
|
+
author,
|
|
300
|
+
format: "assembly",
|
|
301
|
+
})
|
|
302
|
+
}
|
|
303
|
+
>
|
|
304
|
+
<Download className="mr-1 h-3 w-3" />
|
|
305
|
+
<span className="flex-grow mr-6">Assembly PNG</span>
|
|
306
|
+
<span className="text-[0.6rem] opacity-80 bg-teal-600 text-white font-mono rounded-md px-1 text-center py-0.5 mr-1">
|
|
307
|
+
png
|
|
308
|
+
</span>
|
|
309
|
+
</DropdownMenuItem>
|
|
310
|
+
</>
|
|
311
|
+
)}
|
|
234
312
|
</DropdownMenuContent>
|
|
235
313
|
</DropdownMenu>
|
|
236
314
|
<PcbDownloadDialog
|
|
237
315
|
circuitJson={circuitJson}
|
|
238
|
-
fileName={
|
|
316
|
+
fileName={unscopedName || "circuit"}
|
|
239
317
|
/>
|
|
240
318
|
</div>
|
|
241
319
|
)
|
|
@@ -167,6 +167,16 @@ const FileSidebar: React.FC<FileSidebarProps> = ({
|
|
|
167
167
|
}
|
|
168
168
|
}
|
|
169
169
|
|
|
170
|
+
const handleCreateFileBlur = () => {
|
|
171
|
+
if (newFileName.trim() === "") {
|
|
172
|
+
setIsCreatingFile(false)
|
|
173
|
+
setNewFileName("")
|
|
174
|
+
setErrorMessage("")
|
|
175
|
+
return
|
|
176
|
+
}
|
|
177
|
+
handleCreateFileInline()
|
|
178
|
+
}
|
|
179
|
+
|
|
170
180
|
const toggleSidebar = () => {
|
|
171
181
|
setSidebarOpen(!sidebarOpen)
|
|
172
182
|
setErrorMessage("")
|
|
@@ -204,7 +214,7 @@ const FileSidebar: React.FC<FileSidebarProps> = ({
|
|
|
204
214
|
value={newFileName}
|
|
205
215
|
spellCheck={false}
|
|
206
216
|
onChange={(e) => setNewFileName(e.target.value)}
|
|
207
|
-
onBlur={
|
|
217
|
+
onBlur={handleCreateFileBlur}
|
|
208
218
|
onKeyDown={(e) => {
|
|
209
219
|
if (e.key === "Enter") {
|
|
210
220
|
handleCreateFileInline()
|
|
@@ -168,10 +168,14 @@ export default function Header() {
|
|
|
168
168
|
Docs
|
|
169
169
|
</HeaderButton>
|
|
170
170
|
</li>
|
|
171
|
+
<li>
|
|
172
|
+
<HeaderButton className="w-full justify-start" href="/search">
|
|
173
|
+
Search
|
|
174
|
+
</HeaderButton>
|
|
175
|
+
</li>
|
|
171
176
|
</ul>
|
|
172
177
|
</nav>
|
|
173
178
|
<div className="flex flex-col gap-4">
|
|
174
|
-
<SearchComponent />
|
|
175
179
|
<HeaderDropdown />
|
|
176
180
|
<HeaderLogin />
|
|
177
181
|
</div>
|
|
@@ -8,6 +8,7 @@ import HeaderDropdown from "./HeaderDropdown"
|
|
|
8
8
|
import { useState } from "react"
|
|
9
9
|
import { useGlobalStore } from "@/hooks/use-global-store"
|
|
10
10
|
import { Analytics } from "./Analytics"
|
|
11
|
+
import CmdKMenu from "./CmdKMenu"
|
|
11
12
|
|
|
12
13
|
const SearchButtonComponent = () => {
|
|
13
14
|
const [isExpanded, setIsExpanded] = useState(false)
|
|
@@ -57,10 +58,13 @@ export const Header2 = () => {
|
|
|
57
58
|
<>
|
|
58
59
|
<header className="sticky top-0 z-50 w-full border-b bg-background/95 backdrop-blur supports-[backdrop-filter]:bg-background/60">
|
|
59
60
|
<div className="container mx-auto flex h-16 items-center justify-between px-2 md:px-6">
|
|
60
|
-
<
|
|
61
|
+
<PrefetchPageLink
|
|
62
|
+
href="/"
|
|
63
|
+
className="flex select-none items-center gap-2"
|
|
64
|
+
>
|
|
61
65
|
<CircuitBoard className="h-6 w-6" />
|
|
62
66
|
<span className="text-lg font-bold">tscircuit</span>
|
|
63
|
-
</
|
|
67
|
+
</PrefetchPageLink>
|
|
64
68
|
<nav className="flex md:hidden">
|
|
65
69
|
{isLoggedIn && (
|
|
66
70
|
<Link
|
|
@@ -120,6 +124,7 @@ export const Header2 = () => {
|
|
|
120
124
|
</div>
|
|
121
125
|
</div>
|
|
122
126
|
</header>
|
|
127
|
+
<CmdKMenu />
|
|
123
128
|
<Analytics />
|
|
124
129
|
</>
|
|
125
130
|
)
|
|
@@ -43,7 +43,7 @@ export const HeaderLogin = () => {
|
|
|
43
43
|
</AvatarFallback>
|
|
44
44
|
</Avatar>
|
|
45
45
|
</DropdownMenuTrigger>
|
|
46
|
-
<DropdownMenuContent>
|
|
46
|
+
<DropdownMenuContent className="ml-1 md:ml-0 md:mr-1">
|
|
47
47
|
<DropdownMenuItem asChild className="text-gray-500 text-xs" disabled>
|
|
48
48
|
<div>
|
|
49
49
|
AI Usage $
|
|
@@ -16,35 +16,38 @@ export const LogContent = ({
|
|
|
16
16
|
error,
|
|
17
17
|
}: {
|
|
18
18
|
logs: Array<{
|
|
19
|
-
type
|
|
20
|
-
|
|
21
|
-
timestamp
|
|
19
|
+
type?: "info" | "success" | "error"
|
|
20
|
+
msg?: string
|
|
21
|
+
timestamp?: string
|
|
22
22
|
}>
|
|
23
23
|
error?: ErrorObject | string | null
|
|
24
24
|
}) => {
|
|
25
25
|
return (
|
|
26
26
|
<div className="font-mono text-xs space-y-1 min-w-0">
|
|
27
|
-
{logs.map(
|
|
28
|
-
(log
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
27
|
+
{logs.map((log, i) => {
|
|
28
|
+
if (!log.msg) return null
|
|
29
|
+
|
|
30
|
+
return (
|
|
31
|
+
<div
|
|
32
|
+
key={i}
|
|
33
|
+
className={`break-words whitespace-pre-wrap ${
|
|
34
|
+
log.type === "error"
|
|
35
|
+
? "text-red-600"
|
|
36
|
+
: log.type === "success"
|
|
37
|
+
? "text-green-600"
|
|
38
|
+
: "text-gray-600"
|
|
39
|
+
}`}
|
|
40
|
+
>
|
|
41
|
+
{log.timestamp && (
|
|
41
42
|
<span className="text-gray-500 whitespace-nowrap">
|
|
42
43
|
{new Date(log.timestamp).toLocaleTimeString()}
|
|
43
|
-
</span>
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
44
|
+
</span>
|
|
45
|
+
)}
|
|
46
|
+
{log.timestamp && " "}
|
|
47
|
+
<span className="break-all">{log.msg}</span>
|
|
48
|
+
</div>
|
|
49
|
+
)
|
|
50
|
+
})}
|
|
48
51
|
{error && (
|
|
49
52
|
<div className="text-red-600 break-words whitespace-pre-wrap">
|
|
50
53
|
{getErrorText(error)}
|
|
@@ -53,12 +53,12 @@ export const PackageBuildDetailsPage = () => {
|
|
|
53
53
|
<div className="min-h-screen bg-gray-50 text-gray-900">
|
|
54
54
|
<PackageBuildHeader />
|
|
55
55
|
|
|
56
|
-
<div className="px-6 py-6 container mx-auto">
|
|
56
|
+
<div className="px-4 sm:px-6 py-4 sm:py-6 container mx-auto max-w-7xl">
|
|
57
57
|
{/* Main Content */}
|
|
58
|
-
<div className="grid grid-cols-1 lg:grid-cols-3 gap-6 mb-8 items-start">
|
|
58
|
+
<div className="grid grid-cols-1 lg:grid-cols-3 gap-4 sm:gap-6 mb-6 sm:mb-8 items-start">
|
|
59
59
|
{/* Preview Section */}
|
|
60
60
|
<div className="lg:col-span-2">
|
|
61
|
-
<div className="bg-white border border-gray-200 rounded-lg p-4 flex items-center justify-center max-h-[420px]">
|
|
61
|
+
<div className="bg-white border border-gray-200 rounded-lg p-4 flex items-center justify-center min-h-[280px] sm:min-h-[340px] lg:max-h-[420px]">
|
|
62
62
|
<BuildPreviewContent />
|
|
63
63
|
</div>
|
|
64
64
|
</div>
|
|
@@ -68,7 +68,7 @@ export const PackageBuildDetailsPage = () => {
|
|
|
68
68
|
</div>
|
|
69
69
|
|
|
70
70
|
{/* Collapsible Sections */}
|
|
71
|
-
<div className="space-y-4 mb-8">
|
|
71
|
+
<div className="space-y-4 mb-6 sm:mb-8">
|
|
72
72
|
<CollapsibleSection
|
|
73
73
|
title="Transpilation Logs"
|
|
74
74
|
duration={computeDuration(
|
|
@@ -82,7 +82,7 @@ export const PackageBuildDetailsPage = () => {
|
|
|
82
82
|
<LogContent
|
|
83
83
|
logs={
|
|
84
84
|
transpilation_logs ?? [
|
|
85
|
-
{
|
|
85
|
+
{ msg: "No transpilation logs available" },
|
|
86
86
|
]
|
|
87
87
|
}
|
|
88
88
|
error={transpilation_error}
|
|
@@ -102,7 +102,7 @@ export const PackageBuildDetailsPage = () => {
|
|
|
102
102
|
<LogContent
|
|
103
103
|
logs={
|
|
104
104
|
circuit_json_build_logs ?? [
|
|
105
|
-
{
|
|
105
|
+
{ msg: "No Circuit JSON logs available" },
|
|
106
106
|
]
|
|
107
107
|
}
|
|
108
108
|
error={circuit_json_build_error!}
|
|
@@ -7,19 +7,19 @@ export function BuildPreviewContent() {
|
|
|
7
7
|
|
|
8
8
|
if (!packageRelease) {
|
|
9
9
|
return (
|
|
10
|
-
<div className="flex items-center justify-center">
|
|
11
|
-
<div className="w-48 h-48 bg-gray-200 rounded animate-pulse-slow"></div>
|
|
10
|
+
<div className="flex items-center justify-center w-full h-full">
|
|
11
|
+
<div className="w-32 h-32 sm:w-48 sm:h-48 bg-gray-200 rounded animate-pulse-slow"></div>
|
|
12
12
|
</div>
|
|
13
13
|
)
|
|
14
14
|
}
|
|
15
15
|
|
|
16
16
|
return (
|
|
17
|
-
<div className="flex items-center justify-center">
|
|
18
|
-
<div className="rounded overflow-hidden">
|
|
17
|
+
<div className="flex items-center justify-center w-full h-full">
|
|
18
|
+
<div className="rounded overflow-hidden w-full max-w-full">
|
|
19
19
|
<img
|
|
20
20
|
src={`https://api.tscircuit.com/packages/images/${packageInfo?.name}/pcb.png`}
|
|
21
21
|
alt="Package build preview"
|
|
22
|
-
className="object-contain rounded max-h-[360px]"
|
|
22
|
+
className="object-contain rounded w-full h-auto max-h-[240px] sm:max-h-[300px] lg:max-h-[360px]"
|
|
23
23
|
/>
|
|
24
24
|
</div>
|
|
25
25
|
</div>
|
|
@@ -76,16 +76,16 @@ export function PackageBuildDetailsPanel() {
|
|
|
76
76
|
: null
|
|
77
77
|
|
|
78
78
|
return (
|
|
79
|
-
<div className="space-y-6 bg-white p-4 border border-gray-200 rounded-lg">
|
|
79
|
+
<div className="space-y-4 sm:space-y-6 bg-white p-3 sm:p-4 border border-gray-200 rounded-lg">
|
|
80
80
|
{/* Created */}
|
|
81
81
|
<div>
|
|
82
82
|
<h3 className="text-sm font-medium text-gray-600 mb-2">Created</h3>
|
|
83
|
-
<div className="flex items-center gap-2">
|
|
84
|
-
<div className="w-6 h-6 bg-orange-500 rounded-full flex items-center justify-center text-xs font-bold">
|
|
83
|
+
<div className="flex items-center gap-2 min-w-0">
|
|
84
|
+
<div className="w-6 h-6 bg-orange-500 rounded-full flex items-center justify-center text-xs font-bold flex-shrink-0">
|
|
85
85
|
I
|
|
86
86
|
</div>
|
|
87
|
-
<span className="text-sm">{author}</span>
|
|
88
|
-
<span className="text-sm text-gray-500">
|
|
87
|
+
<span className="text-sm truncate">{author}</span>
|
|
88
|
+
<span className="text-sm text-gray-500 flex-shrink-0">
|
|
89
89
|
{timeAgo(created_at, "")}
|
|
90
90
|
</span>
|
|
91
91
|
</div>
|
|
@@ -96,7 +96,7 @@ export function PackageBuildDetailsPanel() {
|
|
|
96
96
|
<h3 className="text-sm font-medium text-gray-600 mb-2">Status</h3>
|
|
97
97
|
<div className="flex items-center gap-2">
|
|
98
98
|
<div
|
|
99
|
-
className={`w-2 h-2 ${getColorFromDisplayStatus(display_status)} rounded-full`}
|
|
99
|
+
className={`w-2 h-2 ${getColorFromDisplayStatus(display_status)} rounded-full flex-shrink-0`}
|
|
100
100
|
></div>
|
|
101
101
|
<span className="text-sm">{capitalCase(display_status)}</span>
|
|
102
102
|
{/* <Badge
|
|
@@ -110,12 +110,14 @@ export function PackageBuildDetailsPanel() {
|
|
|
110
110
|
|
|
111
111
|
<div>
|
|
112
112
|
<h3 className="text-sm font-medium text-gray-600 mb-2">Build Time</h3>
|
|
113
|
-
<div className="flex items-center gap-2">
|
|
114
|
-
<Clock className="w-4 h-4 text-gray-500" />
|
|
113
|
+
<div className="flex items-center gap-2 min-w-0">
|
|
114
|
+
<Clock className="w-4 h-4 text-gray-500 flex-shrink-0" />
|
|
115
115
|
{elapsedMs !== null && (
|
|
116
|
-
<span className="text-sm">
|
|
116
|
+
<span className="text-sm flex-shrink-0">
|
|
117
|
+
{Math.floor(elapsedMs / 1000)}s
|
|
118
|
+
</span>
|
|
117
119
|
)}
|
|
118
|
-
<span className="text-sm text-gray-500">
|
|
120
|
+
<span className="text-sm text-gray-500 truncate">
|
|
119
121
|
{buildStartedAt
|
|
120
122
|
? `Started ${timeAgo(buildStartedAt)}`
|
|
121
123
|
: "waiting..."}
|
|
@@ -126,9 +128,9 @@ export function PackageBuildDetailsPanel() {
|
|
|
126
128
|
{/* Version */}
|
|
127
129
|
<div>
|
|
128
130
|
<h3 className="text-sm font-medium text-gray-600 mb-2">Version</h3>
|
|
129
|
-
<div className="flex items-center gap-2">
|
|
130
|
-
<Globe className="w-4 h-4 text-gray-500" />
|
|
131
|
-
<span className="text-sm">{packageRelease.version}</span>
|
|
131
|
+
<div className="flex items-center gap-2 min-w-0">
|
|
132
|
+
<Globe className="w-4 h-4 text-gray-500 flex-shrink-0" />
|
|
133
|
+
<span className="text-sm break-all">{packageRelease.version}</span>
|
|
132
134
|
{/* <Badge variant="default" className="bg-blue-600 text-white text-xs">
|
|
133
135
|
Current
|
|
134
136
|
</Badge> */}
|
|
@@ -14,18 +14,20 @@ export function PackageBuildHeader() {
|
|
|
14
14
|
useRebuildPackageReleaseMutation()
|
|
15
15
|
|
|
16
16
|
return (
|
|
17
|
-
<div className="border-b border-gray-200 bg-white px-6 py-4">
|
|
18
|
-
<div className="flex items-center justify-between container mx-auto">
|
|
19
|
-
<
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
17
|
+
<div className="border-b border-gray-200 bg-white px-4 sm:px-6 py-4">
|
|
18
|
+
<div className="flex flex-col sm:flex-row sm:items-center sm:justify-between gap-3 sm:gap-4 container mx-auto max-w-7xl">
|
|
19
|
+
<div className="min-w-0 flex-1">
|
|
20
|
+
<h1 className="text-xl sm:text-2xl font-semibold flex flex-col sm:flex-row sm:items-center gap-1 sm:gap-2">
|
|
21
|
+
<span className="whitespace-nowrap">Package Build</span>
|
|
22
|
+
<a
|
|
23
|
+
className="bg-gray-100 px-2 py-1 rounded font-mono text-blue-600 text-sm sm:text-base truncate w-fit"
|
|
24
|
+
href={`/${author}/${packageName}`}
|
|
25
|
+
>
|
|
26
|
+
{author}/{packageName}
|
|
27
|
+
</a>
|
|
28
|
+
</h1>
|
|
29
|
+
</div>
|
|
30
|
+
<div className="flex items-center gap-2 sm:gap-3 flex-shrink-0">
|
|
29
31
|
<Button
|
|
30
32
|
variant="outline"
|
|
31
33
|
size="sm"
|
|
@@ -38,7 +40,8 @@ export function PackageBuildHeader() {
|
|
|
38
40
|
rel="noopener noreferrer"
|
|
39
41
|
>
|
|
40
42
|
<Github className="w-3 h-3 sm:w-4 sm:h-4 mr-1 sm:mr-2" />
|
|
41
|
-
Report Issue
|
|
43
|
+
<span className="hidden xs:inline">Report Issue</span>
|
|
44
|
+
<span className="xs:hidden">Report</span>
|
|
42
45
|
</a>
|
|
43
46
|
</Button>
|
|
44
47
|
<Button
|
|
@@ -66,9 +69,7 @@ export function PackageBuildHeader() {
|
|
|
66
69
|
>
|
|
67
70
|
<RotateCcw className="w-3 h-3 sm:w-4 sm:h-4" />
|
|
68
71
|
</Button>
|
|
69
|
-
<DownloadButtonAndMenu
|
|
70
|
-
snippetUnscopedName={`${author}/${packageName}`}
|
|
71
|
-
/>
|
|
72
|
+
<DownloadButtonAndMenu unscopedName={packageName} author={author} />
|
|
72
73
|
</div>
|
|
73
74
|
</div>
|
|
74
75
|
</div>
|