@tscircuit/fake-snippets 0.0.109 → 0.0.111
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/.github/workflows/bun-formatcheck.yml +2 -2
- package/.github/workflows/bun-pver-release.yml +3 -3
- package/.github/workflows/bun-test.yml +1 -1
- package/.github/workflows/bun-typecheck.yml +2 -2
- package/.github/workflows/update-snapshots.yml +1 -1
- package/README.md +4 -0
- package/api/generated-index.js +37 -3
- package/biome.json +2 -1
- package/bun-tests/fake-snippets-api/fixtures/get-test-server.ts +32 -3
- package/bun-tests/fake-snippets-api/fixtures/preload.ts +18 -0
- package/bun-tests/fake-snippets-api/routes/orgs/add_member.test.ts +26 -0
- package/bun-tests/fake-snippets-api/routes/orgs/create.test.ts +37 -0
- package/bun-tests/fake-snippets-api/routes/orgs/get.test.ts +52 -0
- package/bun-tests/fake-snippets-api/routes/orgs/list.test.ts +17 -0
- package/bun-tests/fake-snippets-api/routes/orgs/list_members.test.ts +23 -0
- package/bun-tests/fake-snippets-api/routes/orgs/remove_member.test.ts +81 -0
- package/bun-tests/fake-snippets-api/routes/orgs/update.test.ts +151 -0
- package/bun-tests/fake-snippets-api/routes/package_builds/get.test.ts +1 -1
- package/bun-tests/fake-snippets-api/routes/package_files/create.test.ts +15 -13
- package/bun-tests/fake-snippets-api/routes/package_files/create_or_update.test.ts +26 -24
- package/bun-tests/fake-snippets-api/routes/package_files/delete.test.ts +9 -9
- package/bun-tests/fake-snippets-api/routes/package_files/download.test.ts +4 -4
- package/bun-tests/fake-snippets-api/routes/package_files/get.test.ts +38 -28
- package/bun-tests/fake-snippets-api/routes/package_files/list.test.ts +23 -15
- package/bun-tests/fake-snippets-api/routes/package_releases/create.test.ts +33 -0
- package/bun-tests/fake-snippets-api/routes/package_releases/get.test.ts +4 -4
- package/bun-tests/fake-snippets-api/routes/package_releases/get_image_generation_fields.test.ts +38 -0
- package/bun-tests/fake-snippets-api/routes/packages/create.test.ts +19 -0
- package/bun-tests/fake-snippets-api/routes/packages/fork.test.ts +3 -4
- package/bun-tests/fake-snippets-api/routes/packages/get.test.ts +30 -0
- package/bun-tests/fake-snippets-api/routes/packages/images.test.ts +4 -2
- package/bun-tests/fake-snippets-api/routes/packages/list-1.test.ts +34 -0
- package/bun.lock +361 -453
- package/bunfig.toml +2 -1
- package/dist/bundle.js +1313 -639
- package/dist/index.d.ts +313 -6
- package/dist/index.js +328 -24
- package/dist/schema.d.ts +290 -1
- package/dist/schema.js +54 -1
- package/fake-snippets-api/lib/db/autoload-dev-packages.ts +31 -20
- package/fake-snippets-api/lib/db/db-client.ts +219 -4
- package/fake-snippets-api/lib/db/schema.ts +63 -1
- package/fake-snippets-api/lib/db/seed.ts +100 -0
- package/fake-snippets-api/lib/middleware/with-session-auth.ts +60 -8
- package/fake-snippets-api/lib/package_file/get-package-file-id-from-file-descriptor.ts +2 -2
- package/fake-snippets-api/lib/public-mapping/public-map-org.ts +33 -0
- package/fake-snippets-api/lib/public-mapping/public-map-package-build.ts +10 -0
- package/fake-snippets-api/lib/public-mapping/public-map-package-release.ts +17 -0
- package/fake-snippets-api/routes/api/orgs/add_member.ts +52 -0
- package/fake-snippets-api/routes/api/orgs/create.ts +48 -0
- package/fake-snippets-api/routes/api/orgs/get.ts +39 -0
- package/fake-snippets-api/routes/api/orgs/list.ts +31 -0
- package/fake-snippets-api/routes/api/orgs/list_members.ts +60 -0
- package/fake-snippets-api/routes/api/orgs/remove_member.ts +46 -0
- package/fake-snippets-api/routes/api/orgs/update.ts +118 -0
- package/fake-snippets-api/routes/api/package_files/get.ts +3 -6
- package/fake-snippets-api/routes/api/package_files/list.ts +7 -4
- package/fake-snippets-api/routes/api/packages/create.ts +57 -10
- package/fake-snippets-api/routes/api/packages/get.ts +23 -0
- package/fake-snippets-api/routes/api/packages/images/[owner_github_username]/[unscoped_name]/[view_format].ts +13 -11
- package/fake-snippets-api/routes/api/packages/list.ts +29 -2
- package/fake-snippets-api/routes/api/packages/update_ai_description.ts +37 -0
- package/package.json +25 -19
- package/renovate.json +1 -1
- package/scripts/generate-sitemap.ts +1 -1
- package/src/App.tsx +27 -8
- package/src/ContextProviders.tsx +25 -2
- package/src/components/CircuitJsonImportDialog.tsx +1 -1
- package/src/components/CmdKMenu.tsx +281 -247
- package/src/components/DownloadButtonAndMenu.tsx +17 -5
- package/src/components/FileSidebar.tsx +11 -17
- package/src/components/Footer.tsx +8 -9
- package/src/components/Header.tsx +19 -32
- package/src/components/Header2.tsx +16 -32
- package/src/components/HeaderDropdown.tsx +13 -8
- package/src/components/HeaderLogin.tsx +43 -15
- package/src/components/NotFound.tsx +5 -5
- package/src/components/PackageBreadcrumb.tsx +6 -12
- package/src/components/PackageSearchResults.tsx +1 -1
- package/src/components/PrefetchPageLink.tsx +7 -1
- package/src/components/ProfileRouter.tsx +32 -0
- package/src/components/SearchComponent.tsx +12 -8
- package/src/components/SentryNotFoundReporter.tsx +44 -0
- package/src/components/UserCard.tsx +80 -0
- package/src/components/ViewPackagePage/components/build-status.tsx +1 -1
- package/src/components/ViewPackagePage/components/important-files-view.tsx +105 -34
- package/src/components/ViewPackagePage/components/main-content-header.tsx +10 -6
- package/src/components/ViewPackagePage/components/main-content-view-selector.tsx +1 -1
- package/src/components/ViewPackagePage/components/mobile-sidebar.tsx +54 -19
- package/src/components/ViewPackagePage/components/package-header.tsx +25 -33
- package/src/components/ViewPackagePage/components/preview-image-squares.tsx +11 -18
- package/src/components/ViewPackagePage/components/repo-page-content.tsx +12 -5
- package/src/components/ViewPackagePage/components/sidebar-about-section.tsx +16 -10
- package/src/components/ViewPackagePage/components/sidebar-releases-section.tsx +11 -11
- package/src/components/ViewPackagePage/components/tab-views/pcb-view.tsx +1 -2
- package/src/components/ViewPackagePage/components/tab-views/schematic-view.tsx +2 -1
- package/src/components/dialogs/GitHubRepositorySelector.tsx +56 -49
- package/src/components/dialogs/edit-package-details-dialog.tsx +5 -6
- package/src/components/dialogs/import-component-dialog.tsx +16 -9
- package/src/components/dialogs/import-package-dialog.tsx +3 -2
- package/src/components/dialogs/new-package-save-prompt-dialog.tsx +190 -0
- package/src/components/organization/OrganizationCard.tsx +206 -0
- package/src/components/organization/OrganizationCardSkeleton.tsx +55 -0
- package/src/components/organization/OrganizationHeader.tsx +154 -0
- package/src/components/organization/OrganizationMembers.tsx +146 -0
- package/src/components/package-port/CodeAndPreview.tsx +15 -12
- package/src/components/package-port/CodeEditor.tsx +4 -30
- package/src/components/package-port/CodeEditorHeader.tsx +123 -61
- package/src/components/package-port/EditorNav.tsx +32 -49
- package/src/components/preview/ConnectedPackagesList.tsx +8 -8
- package/src/components/preview/ConnectedRepoOverview.tsx +102 -2
- package/src/components/preview/PackageReleasesDashboard.tsx +23 -11
- package/src/components/ui/tree-view.tsx +6 -3
- package/src/hooks/use-add-org-member-mutation.ts +51 -0
- package/src/hooks/use-create-org-mutation.ts +38 -0
- package/src/hooks/use-create-package-mutation.ts +3 -0
- package/src/hooks/use-current-package-release.ts +4 -3
- package/src/hooks/use-download-zip.ts +2 -2
- package/src/hooks/use-global-store.ts +6 -4
- package/src/hooks/use-hydration.ts +30 -0
- package/src/hooks/use-jlcpcb-component-import.tsx +164 -0
- package/src/hooks/use-list-org-members.ts +27 -0
- package/src/hooks/use-list-user-orgs.ts +25 -0
- package/src/hooks/use-org-by-github-handle.ts +26 -0
- package/src/hooks/use-org.ts +24 -0
- package/src/hooks/use-organization.ts +42 -0
- package/src/hooks/use-package-as-snippet.ts +4 -2
- package/src/hooks/use-package-builds.ts +6 -2
- package/src/hooks/use-package-files.ts +5 -3
- package/src/hooks/use-package-release-by-id-or-version.ts +29 -20
- package/src/hooks/use-package-release-images.ts +105 -0
- package/src/hooks/use-package-release.ts +2 -2
- package/src/hooks/use-package-stars.ts +80 -4
- package/src/hooks/use-preview-images.ts +6 -3
- package/src/hooks/use-remove-org-member-mutation.ts +32 -0
- package/src/hooks/use-update-ai-description-mutation.ts +42 -0
- package/src/hooks/use-update-org-mutation.ts +41 -0
- package/src/hooks/use-warn-user-on-page-change.ts +71 -4
- package/src/hooks/useFileManagement.ts +51 -22
- package/src/hooks/useOptimizedPackageFilesLoader.ts +11 -24
- package/src/hooks/usePackageFilesLoader.ts +2 -2
- package/src/hooks/useUpdatePackageFilesMutation.ts +13 -1
- package/src/lib/download-fns/download-gltf-from-circuit-json.ts +1 -1
- package/src/lib/download-fns/download-kicad-files.ts +22 -11
- package/src/lib/download-fns/download-step.ts +12 -0
- package/src/lib/normalize-svg-for-tile.ts +50 -0
- package/src/lib/posthog.ts +11 -9
- package/src/lib/react-query-api-failure-tracking.ts +148 -0
- package/src/lib/sentry.ts +14 -0
- package/src/lib/templates/blank-circuit-board-template.ts +0 -4
- package/src/lib/ts-lib-cache.ts +122 -7
- package/src/lib/utils/checkIfManualEditsImported.ts +4 -4
- package/src/lib/utils/findTargetFile.ts +45 -10
- package/src/lib/utils/isComponentExported.ts +2 -1
- package/src/main.tsx +2 -1
- package/src/pages/create-organization.tsx +169 -0
- package/src/pages/dashboard.tsx +38 -6
- package/src/pages/datasheet.tsx +1 -1
- package/src/pages/datasheets.tsx +3 -3
- package/src/pages/editor.tsx +4 -6
- package/src/pages/landing.tsx +6 -6
- package/src/pages/latest.tsx +3 -0
- package/src/pages/organization-profile.tsx +199 -0
- package/src/pages/organization-settings.tsx +569 -0
- package/src/pages/package-editor.tsx +21 -21
- package/src/pages/preview-release.tsx +75 -145
- package/src/pages/quickstart.tsx +159 -123
- package/src/pages/release-detail.tsx +119 -31
- package/src/pages/search.tsx +197 -57
- package/src/pages/settings-redirect.tsx +44 -0
- package/src/pages/trending.tsx +29 -20
- package/src/pages/user-profile.tsx +58 -7
- package/src/pages/user-settings.tsx +161 -0
- package/src/pages/view-package.tsx +30 -16
- package/vite.config.ts +9 -0
- package/fake-snippets-api/routes/api/autocomplete/create_autocomplete.ts +0 -133
- package/src/components/JLCPCBImportDialog.tsx +0 -280
- package/src/components/PackageBuildsPage/LogContent.tsx +0 -72
- package/src/components/PackageBuildsPage/PackageBuildDetailsPage.tsx +0 -113
- package/src/components/PackageBuildsPage/build-preview-content.tsx +0 -56
- package/src/components/PackageBuildsPage/collapsible-section.tsx +0 -63
- package/src/components/PackageBuildsPage/package-build-details-panel.tsx +0 -166
- package/src/components/PackageBuildsPage/package-build-header.tsx +0 -79
- package/src/components/PageSearchComponent.tsx +0 -148
- package/src/pages/package-builds.tsx +0 -33
|
@@ -1,72 +0,0 @@
|
|
|
1
|
-
type ErrorObject =
|
|
2
|
-
| {
|
|
3
|
-
message: string
|
|
4
|
-
}
|
|
5
|
-
| string
|
|
6
|
-
|
|
7
|
-
const getErrorText = (error: ErrorObject | string) => {
|
|
8
|
-
if (typeof error === "string") {
|
|
9
|
-
return error
|
|
10
|
-
}
|
|
11
|
-
return error.message
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
export const LogContent = ({
|
|
15
|
-
logs,
|
|
16
|
-
error,
|
|
17
|
-
}: {
|
|
18
|
-
logs: Array<{
|
|
19
|
-
type?: "info" | "success" | "error"
|
|
20
|
-
msg?: string
|
|
21
|
-
message?: string
|
|
22
|
-
timestamp?: string | number
|
|
23
|
-
[key: string]: unknown
|
|
24
|
-
}>
|
|
25
|
-
error?: ErrorObject | string | null
|
|
26
|
-
}) => {
|
|
27
|
-
return (
|
|
28
|
-
<div className="font-mono text-xs space-y-1 min-w-0">
|
|
29
|
-
{logs.map((log, i) => {
|
|
30
|
-
const { type, msg, message, timestamp, ...rest } = log
|
|
31
|
-
const text = msg ?? message
|
|
32
|
-
if (!text) return null
|
|
33
|
-
|
|
34
|
-
return (
|
|
35
|
-
<div
|
|
36
|
-
key={i}
|
|
37
|
-
className={`break-words whitespace-pre-wrap ${
|
|
38
|
-
type === "error"
|
|
39
|
-
? "text-red-600"
|
|
40
|
-
: type === "success"
|
|
41
|
-
? "text-green-600"
|
|
42
|
-
: "text-gray-600"
|
|
43
|
-
}`}
|
|
44
|
-
>
|
|
45
|
-
{timestamp !== undefined && (
|
|
46
|
-
<span className="text-gray-500 whitespace-nowrap">
|
|
47
|
-
{new Date(Number(timestamp)).toLocaleTimeString()}
|
|
48
|
-
</span>
|
|
49
|
-
)}
|
|
50
|
-
{timestamp !== undefined && " "}
|
|
51
|
-
<span className="break-all">{text}</span>
|
|
52
|
-
{Object.keys(rest).filter((k) => k !== "package_release_id")
|
|
53
|
-
.length > 0 && (
|
|
54
|
-
<span className="text-gray-500">
|
|
55
|
-
{" "}
|
|
56
|
-
{Object.entries(rest)
|
|
57
|
-
.filter(([key]) => key !== "package_release_id")
|
|
58
|
-
.map(([key, value]) => `${key}: ${String(value)}`)
|
|
59
|
-
.join(" ")}
|
|
60
|
-
</span>
|
|
61
|
-
)}
|
|
62
|
-
</div>
|
|
63
|
-
)
|
|
64
|
-
})}
|
|
65
|
-
{error && (
|
|
66
|
-
<div className="text-red-600 break-words whitespace-pre-wrap">
|
|
67
|
-
{getErrorText(error)}
|
|
68
|
-
</div>
|
|
69
|
-
)}
|
|
70
|
-
</div>
|
|
71
|
-
)
|
|
72
|
-
}
|
|
@@ -1,113 +0,0 @@
|
|
|
1
|
-
import { useCurrentPackageRelease } from "@/hooks/use-current-package-release"
|
|
2
|
-
import { PackageRelease } from "fake-snippets-api/lib/db/schema"
|
|
3
|
-
import { useState } from "react"
|
|
4
|
-
import { LogContent } from "./LogContent"
|
|
5
|
-
import { BuildPreviewContent } from "./build-preview-content"
|
|
6
|
-
import { CollapsibleSection } from "./collapsible-section"
|
|
7
|
-
import { PackageBuildDetailsPanel } from "./package-build-details-panel"
|
|
8
|
-
import { PackageBuildHeader } from "./package-build-header"
|
|
9
|
-
|
|
10
|
-
function computeDuration(
|
|
11
|
-
startedAt: string | null | undefined,
|
|
12
|
-
completedAt: string | null | undefined,
|
|
13
|
-
) {
|
|
14
|
-
if (!startedAt || !completedAt) return ""
|
|
15
|
-
return `${Math.floor((new Date(completedAt).getTime() - new Date(startedAt).getTime()) / 1000)}s`
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
export const PackageBuildDetailsPage = () => {
|
|
19
|
-
const { packageRelease } = useCurrentPackageRelease({
|
|
20
|
-
include_logs: true,
|
|
21
|
-
refetchInterval: 2000,
|
|
22
|
-
})
|
|
23
|
-
const [openSections, setOpenSections] = useState<Record<string, boolean>>({})
|
|
24
|
-
|
|
25
|
-
const {
|
|
26
|
-
circuit_json_build_logs,
|
|
27
|
-
circuit_json_build_completed_at,
|
|
28
|
-
circuit_json_build_in_progress,
|
|
29
|
-
circuit_json_build_is_stale,
|
|
30
|
-
circuit_json_build_started_at,
|
|
31
|
-
circuit_json_build_error,
|
|
32
|
-
circuit_json_build_error_last_updated_at,
|
|
33
|
-
transpilation_completed_at,
|
|
34
|
-
transpilation_in_progress,
|
|
35
|
-
transpilation_is_stale,
|
|
36
|
-
transpilation_logs,
|
|
37
|
-
transpilation_started_at,
|
|
38
|
-
circuit_json_build_display_status,
|
|
39
|
-
transpilation_display_status,
|
|
40
|
-
transpilation_error,
|
|
41
|
-
} = packageRelease ?? ({} as Partial<PackageRelease>)
|
|
42
|
-
|
|
43
|
-
const toggleSection = (section: string) => {
|
|
44
|
-
setOpenSections((prev) => ({
|
|
45
|
-
...prev,
|
|
46
|
-
[section]: !prev[section],
|
|
47
|
-
}))
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
return (
|
|
51
|
-
<div className="min-h-screen bg-gray-50 text-gray-900">
|
|
52
|
-
<PackageBuildHeader />
|
|
53
|
-
|
|
54
|
-
<div className="px-4 sm:px-6 py-4 sm:py-6 container mx-auto max-w-7xl">
|
|
55
|
-
{/* Main Content */}
|
|
56
|
-
<div className="grid grid-cols-1 lg:grid-cols-3 gap-4 sm:gap-6 mb-6 sm:mb-8 items-start">
|
|
57
|
-
{/* Preview Section */}
|
|
58
|
-
<div className="lg:col-span-2">
|
|
59
|
-
<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]">
|
|
60
|
-
<BuildPreviewContent />
|
|
61
|
-
</div>
|
|
62
|
-
</div>
|
|
63
|
-
|
|
64
|
-
{/* Details Panel */}
|
|
65
|
-
<PackageBuildDetailsPanel />
|
|
66
|
-
</div>
|
|
67
|
-
|
|
68
|
-
{/* Collapsible Sections */}
|
|
69
|
-
<div className="space-y-4 mb-6 sm:mb-8">
|
|
70
|
-
<CollapsibleSection
|
|
71
|
-
title="Transpilation Logs"
|
|
72
|
-
duration={computeDuration(
|
|
73
|
-
transpilation_started_at,
|
|
74
|
-
transpilation_completed_at,
|
|
75
|
-
)}
|
|
76
|
-
displayStatus={transpilation_display_status}
|
|
77
|
-
isOpen={openSections.summary}
|
|
78
|
-
onToggle={() => toggleSection("summary")}
|
|
79
|
-
>
|
|
80
|
-
<LogContent
|
|
81
|
-
logs={
|
|
82
|
-
transpilation_logs ?? [
|
|
83
|
-
{ msg: "No transpilation logs available" },
|
|
84
|
-
]
|
|
85
|
-
}
|
|
86
|
-
error={transpilation_error}
|
|
87
|
-
/>
|
|
88
|
-
</CollapsibleSection>
|
|
89
|
-
|
|
90
|
-
<CollapsibleSection
|
|
91
|
-
title="Circuit JSON Build Logs"
|
|
92
|
-
duration={computeDuration(
|
|
93
|
-
circuit_json_build_started_at,
|
|
94
|
-
circuit_json_build_completed_at,
|
|
95
|
-
)}
|
|
96
|
-
displayStatus={circuit_json_build_display_status}
|
|
97
|
-
isOpen={openSections.logs}
|
|
98
|
-
onToggle={() => toggleSection("logs")}
|
|
99
|
-
>
|
|
100
|
-
<LogContent
|
|
101
|
-
logs={
|
|
102
|
-
circuit_json_build_logs ?? [
|
|
103
|
-
{ msg: "No Circuit JSON logs available" },
|
|
104
|
-
]
|
|
105
|
-
}
|
|
106
|
-
error={circuit_json_build_error!}
|
|
107
|
-
/>
|
|
108
|
-
</CollapsibleSection>
|
|
109
|
-
</div>
|
|
110
|
-
</div>
|
|
111
|
-
</div>
|
|
112
|
-
)
|
|
113
|
-
}
|
|
@@ -1,56 +0,0 @@
|
|
|
1
|
-
import { useCurrentPackageInfo } from "@/hooks/use-current-package-info"
|
|
2
|
-
import { useCurrentPackageRelease } from "@/hooks/use-current-package-release"
|
|
3
|
-
import { useState } from "react"
|
|
4
|
-
import { CircuitBoard } from "lucide-react"
|
|
5
|
-
|
|
6
|
-
export function BuildPreviewContent() {
|
|
7
|
-
const { packageRelease } = useCurrentPackageRelease({ refetchInterval: 2000 })
|
|
8
|
-
const { packageInfo } = useCurrentPackageInfo()
|
|
9
|
-
const [imageError, setImageError] = useState(false)
|
|
10
|
-
const [imageLoading, setImageLoading] = useState(true)
|
|
11
|
-
|
|
12
|
-
if (!packageRelease) {
|
|
13
|
-
return (
|
|
14
|
-
<div className="flex items-center justify-center w-full h-full">
|
|
15
|
-
<div className="w-32 h-32 sm:w-48 sm:h-48 bg-gray-200 rounded animate-pulse-slow"></div>
|
|
16
|
-
</div>
|
|
17
|
-
)
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
return (
|
|
21
|
-
<div className="flex items-center justify-center w-full h-full">
|
|
22
|
-
<div className="rounded overflow-hidden w-full max-w-full">
|
|
23
|
-
{imageError ? (
|
|
24
|
-
<div className="flex flex-col items-center justify-center bg-gray-50 border border-gray-300 rounded-lg p-8 sm:p-12 lg:p-16 min-h-[240px] sm:min-h-[300px] lg:min-h-[360px]">
|
|
25
|
-
<CircuitBoard className="w-12 h-12 sm:w-16 sm:h-16 lg:w-20 lg:h-20 text-gray-400 mb-4" />
|
|
26
|
-
<h3 className="text-lg sm:text-xl font-medium text-gray-600 mb-2">
|
|
27
|
-
Preview Not Available
|
|
28
|
-
</h3>
|
|
29
|
-
<p className="text-sm sm:text-base text-gray-500 text-center max-w-sm">
|
|
30
|
-
The build preview image could not be loaded. This may be because
|
|
31
|
-
the build is still processing or the image is not available.
|
|
32
|
-
</p>
|
|
33
|
-
</div>
|
|
34
|
-
) : (
|
|
35
|
-
<>
|
|
36
|
-
{imageLoading && (
|
|
37
|
-
<div className="flex items-center justify-center bg-gray-100 rounded-lg min-h-[240px] sm:min-h-[300px] lg:min-h-[360px]">
|
|
38
|
-
<div className="w-16 h-16 sm:w-20 sm:h-20 bg-gray-200 rounded animate-pulse"></div>
|
|
39
|
-
</div>
|
|
40
|
-
)}
|
|
41
|
-
<img
|
|
42
|
-
src={`https://api.tscircuit.com/packages/images/${packageInfo?.name}/pcb.png`}
|
|
43
|
-
alt="Package build preview"
|
|
44
|
-
className={`object-contain rounded w-full h-auto max-h-[240px] sm:max-h-[300px] lg:max-h-[360px] ${imageLoading ? "hidden" : "block"}`}
|
|
45
|
-
onLoad={() => setImageLoading(false)}
|
|
46
|
-
onError={() => {
|
|
47
|
-
setImageError(true)
|
|
48
|
-
setImageLoading(false)
|
|
49
|
-
}}
|
|
50
|
-
/>
|
|
51
|
-
</>
|
|
52
|
-
)}
|
|
53
|
-
</div>
|
|
54
|
-
</div>
|
|
55
|
-
)
|
|
56
|
-
}
|
|
@@ -1,63 +0,0 @@
|
|
|
1
|
-
import type React from "react"
|
|
2
|
-
import { ChevronRight } from "lucide-react"
|
|
3
|
-
import {
|
|
4
|
-
Collapsible,
|
|
5
|
-
CollapsibleContent,
|
|
6
|
-
CollapsibleTrigger,
|
|
7
|
-
} from "@/components/ui/collapsible"
|
|
8
|
-
import { getColorForDisplayStatus } from "./getColorForDisplayStatus"
|
|
9
|
-
import { PackageRelease } from "fake-snippets-api/lib/db/schema"
|
|
10
|
-
import { ErrorObjectOrString } from "./ErrorObject"
|
|
11
|
-
import { capitalCase } from "./capitalCase"
|
|
12
|
-
|
|
13
|
-
interface CollapsibleSectionProps {
|
|
14
|
-
title: string
|
|
15
|
-
duration?: string
|
|
16
|
-
error?: ErrorObjectOrString | null
|
|
17
|
-
displayStatus?: PackageRelease["display_status"]
|
|
18
|
-
isOpen: boolean
|
|
19
|
-
onToggle: () => void
|
|
20
|
-
children?: React.ReactNode
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
export function CollapsibleSection({
|
|
24
|
-
title,
|
|
25
|
-
duration,
|
|
26
|
-
displayStatus,
|
|
27
|
-
isOpen,
|
|
28
|
-
onToggle,
|
|
29
|
-
children,
|
|
30
|
-
}: CollapsibleSectionProps) {
|
|
31
|
-
return (
|
|
32
|
-
<Collapsible open={isOpen} onOpenChange={onToggle}>
|
|
33
|
-
<CollapsibleTrigger asChild>
|
|
34
|
-
<div className="flex flex-col sm:flex-row sm:items-center sm:justify-between gap-2 p-4 bg-white border border-gray-200 rounded-lg cursor-pointer hover:bg-gray-100">
|
|
35
|
-
<div className="flex items-center gap-2 min-w-0">
|
|
36
|
-
<ChevronRight
|
|
37
|
-
className={`w-4 h-4 flex-shrink-0 transition-transform ${isOpen ? "rotate-90" : ""}`}
|
|
38
|
-
/>
|
|
39
|
-
<span className="font-medium truncate">{title}</span>
|
|
40
|
-
</div>
|
|
41
|
-
<div className="flex items-center gap-2 flex-shrink-0 ml-6 sm:ml-0">
|
|
42
|
-
{duration && (
|
|
43
|
-
<span className="text-sm text-gray-600 whitespace-nowrap">
|
|
44
|
-
{duration}
|
|
45
|
-
</span>
|
|
46
|
-
)}
|
|
47
|
-
<div
|
|
48
|
-
className={`w-2 h-2 rounded-lg flex-shrink-0 ${getColorForDisplayStatus(displayStatus)}`}
|
|
49
|
-
/>
|
|
50
|
-
<div className="text-gray-600 text-xs font-medium whitespace-nowrap">
|
|
51
|
-
{capitalCase(displayStatus) || "???"}
|
|
52
|
-
</div>
|
|
53
|
-
</div>
|
|
54
|
-
</div>
|
|
55
|
-
</CollapsibleTrigger>
|
|
56
|
-
<CollapsibleContent>
|
|
57
|
-
<div className="bg-white border-x border-b border-gray-200 rounded-b-lg overflow-hidden">
|
|
58
|
-
<div className="p-4 overflow-x-auto max-w-full">{children}</div>
|
|
59
|
-
</div>
|
|
60
|
-
</CollapsibleContent>
|
|
61
|
-
</Collapsible>
|
|
62
|
-
)
|
|
63
|
-
}
|
|
@@ -1,166 +0,0 @@
|
|
|
1
|
-
import { useCurrentPackageRelease } from "@/hooks/use-current-package-release"
|
|
2
|
-
import { useNow } from "@/hooks/use-now"
|
|
3
|
-
import { timeAgo } from "@/lib/utils/timeAgo"
|
|
4
|
-
import { PackageRelease } from "fake-snippets-api/lib/db/schema"
|
|
5
|
-
import { Clock, GitBranch, GitCommit, Globe } from "lucide-react"
|
|
6
|
-
import { useParams } from "wouter"
|
|
7
|
-
|
|
8
|
-
const capitalCase = (str: string) => {
|
|
9
|
-
return str.charAt(0).toUpperCase() + str.slice(1)
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
function getColorFromDisplayStatus(
|
|
13
|
-
display_status: PackageRelease["display_status"],
|
|
14
|
-
) {
|
|
15
|
-
switch (display_status) {
|
|
16
|
-
case "pending":
|
|
17
|
-
return "bg-yellow-500"
|
|
18
|
-
case "building":
|
|
19
|
-
return "bg-blue-500"
|
|
20
|
-
case "complete":
|
|
21
|
-
return "bg-green-500"
|
|
22
|
-
case "error":
|
|
23
|
-
return "bg-red-500"
|
|
24
|
-
}
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
export function PackageBuildDetailsPanel() {
|
|
28
|
-
const { packageRelease } = useCurrentPackageRelease({ refetchInterval: 2000 })
|
|
29
|
-
const { author } = useParams() // TODO use packageRelease.author_account_id when it's added by backed
|
|
30
|
-
const now = useNow(1000)
|
|
31
|
-
|
|
32
|
-
if (!packageRelease) {
|
|
33
|
-
// TODO show skeleton instead
|
|
34
|
-
return null
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
const {
|
|
38
|
-
circuit_json_build_display_status,
|
|
39
|
-
circuit_json_build_in_progress,
|
|
40
|
-
circuit_json_build_is_stale,
|
|
41
|
-
circuit_json_build_logs,
|
|
42
|
-
transpilation_display_status,
|
|
43
|
-
transpilation_in_progress,
|
|
44
|
-
transpilation_logs,
|
|
45
|
-
circuit_json_build_completed_at,
|
|
46
|
-
transpilation_is_stale,
|
|
47
|
-
display_status,
|
|
48
|
-
created_at,
|
|
49
|
-
has_transpiled,
|
|
50
|
-
circuit_json_build_started_at,
|
|
51
|
-
circuit_json_build_error,
|
|
52
|
-
circuit_json_build_error_last_updated_at,
|
|
53
|
-
total_build_duration_ms,
|
|
54
|
-
transpilation_completed_at,
|
|
55
|
-
transpilation_error,
|
|
56
|
-
transpilation_started_at,
|
|
57
|
-
commit_sha,
|
|
58
|
-
} = packageRelease
|
|
59
|
-
|
|
60
|
-
const buildStartedAt = (() => {
|
|
61
|
-
if (transpilation_started_at && circuit_json_build_started_at) {
|
|
62
|
-
return new Date(transpilation_started_at) <
|
|
63
|
-
new Date(circuit_json_build_started_at)
|
|
64
|
-
? transpilation_started_at
|
|
65
|
-
: circuit_json_build_started_at
|
|
66
|
-
}
|
|
67
|
-
return transpilation_started_at || circuit_json_build_started_at || null
|
|
68
|
-
})()
|
|
69
|
-
|
|
70
|
-
const buildCompletedAt =
|
|
71
|
-
circuit_json_build_completed_at || transpilation_completed_at || null
|
|
72
|
-
|
|
73
|
-
const elapsedMs = buildStartedAt
|
|
74
|
-
? (buildCompletedAt ? new Date(buildCompletedAt).getTime() : now) -
|
|
75
|
-
new Date(buildStartedAt).getTime()
|
|
76
|
-
: null
|
|
77
|
-
|
|
78
|
-
return (
|
|
79
|
-
<div className="space-y-4 sm:space-y-6 bg-white p-3 sm:p-4 border border-gray-200 rounded-lg">
|
|
80
|
-
{/* Created */}
|
|
81
|
-
<div>
|
|
82
|
-
<h3 className="text-sm font-medium text-gray-600 mb-2">Created</h3>
|
|
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
|
-
I
|
|
86
|
-
</div>
|
|
87
|
-
<span className="text-sm truncate">{author}</span>
|
|
88
|
-
<span className="text-sm text-gray-500 flex-shrink-0">
|
|
89
|
-
{timeAgo(created_at, "")}
|
|
90
|
-
</span>
|
|
91
|
-
</div>
|
|
92
|
-
</div>
|
|
93
|
-
|
|
94
|
-
{/* Status */}
|
|
95
|
-
<div>
|
|
96
|
-
<h3 className="text-sm font-medium text-gray-600 mb-2">Status</h3>
|
|
97
|
-
<div className="flex items-center gap-2">
|
|
98
|
-
<div
|
|
99
|
-
className={`w-2 h-2 ${getColorFromDisplayStatus(display_status)} rounded-full flex-shrink-0`}
|
|
100
|
-
></div>
|
|
101
|
-
<span className="text-sm">{capitalCase(display_status)}</span>
|
|
102
|
-
{/* <Badge
|
|
103
|
-
variant="secondary"
|
|
104
|
-
className="bg-gray-200 text-gray-700 text-xs"
|
|
105
|
-
>
|
|
106
|
-
Latest
|
|
107
|
-
</Badge> */}
|
|
108
|
-
</div>
|
|
109
|
-
</div>
|
|
110
|
-
|
|
111
|
-
<div>
|
|
112
|
-
<h3 className="text-sm font-medium text-gray-600 mb-2">Build Time</h3>
|
|
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
|
-
{elapsedMs !== null && (
|
|
116
|
-
<span className="text-sm flex-shrink-0">
|
|
117
|
-
{Math.floor(elapsedMs / 1000)}s
|
|
118
|
-
</span>
|
|
119
|
-
)}
|
|
120
|
-
<span className="text-sm text-gray-500 truncate">
|
|
121
|
-
{buildStartedAt
|
|
122
|
-
? `Started ${timeAgo(buildStartedAt)}`
|
|
123
|
-
: "waiting..."}
|
|
124
|
-
</span>
|
|
125
|
-
</div>
|
|
126
|
-
</div>
|
|
127
|
-
|
|
128
|
-
{/* Version */}
|
|
129
|
-
<div>
|
|
130
|
-
<h3 className="text-sm font-medium text-gray-600 mb-2">Version</h3>
|
|
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>
|
|
134
|
-
{/* <Badge variant="default" className="bg-blue-600 text-white text-xs">
|
|
135
|
-
Current
|
|
136
|
-
</Badge> */}
|
|
137
|
-
</div>
|
|
138
|
-
</div>
|
|
139
|
-
|
|
140
|
-
{/* Outputs */}
|
|
141
|
-
<div>
|
|
142
|
-
<h3 className="text-sm font-medium text-gray-600 mb-2">Outputs</h3>
|
|
143
|
-
<div>
|
|
144
|
-
<span className="text-sm text-gray-400">None</span>
|
|
145
|
-
</div>
|
|
146
|
-
</div>
|
|
147
|
-
|
|
148
|
-
{/* Source */}
|
|
149
|
-
{/* <div>
|
|
150
|
-
<h3 className="text-sm font-medium text-gray-600 mb-2">Source</h3>
|
|
151
|
-
<div className="space-y-2">
|
|
152
|
-
<div className="flex items-center gap-2">
|
|
153
|
-
<GitBranch className="w-4 h-4 text-gray-500" />
|
|
154
|
-
<span className="text-sm">main</span>
|
|
155
|
-
</div>
|
|
156
|
-
<div className="flex items-center gap-2">
|
|
157
|
-
<GitCommit className="w-4 h-4 text-gray-500" />
|
|
158
|
-
<span className="text-sm text-gray-500">
|
|
159
|
-
edfdc67 support empty file creation (#356)
|
|
160
|
-
</span>
|
|
161
|
-
</div>
|
|
162
|
-
</div>
|
|
163
|
-
</div> */}
|
|
164
|
-
</div>
|
|
165
|
-
)
|
|
166
|
-
}
|
|
@@ -1,79 +0,0 @@
|
|
|
1
|
-
import { Button } from "@/components/ui/button"
|
|
2
|
-
import { useCurrentPackageRelease } from "@/hooks/use-current-package-release"
|
|
3
|
-
import { useRebuildPackageReleaseMutation } from "@/hooks/use-rebuild-package-release-mutation"
|
|
4
|
-
import { Github, RefreshCw } from "lucide-react"
|
|
5
|
-
import { useParams } from "wouter"
|
|
6
|
-
import { DownloadButtonAndMenu } from "../DownloadButtonAndMenu"
|
|
7
|
-
import { useGlobalStore } from "@/hooks/use-global-store"
|
|
8
|
-
import { useCurrentPackageCircuitJson } from "../ViewPackagePage/hooks/use-current-package-circuit-json"
|
|
9
|
-
|
|
10
|
-
export function PackageBuildHeader() {
|
|
11
|
-
const { author, packageName } = useParams()
|
|
12
|
-
const session = useGlobalStore((s) => s.session)
|
|
13
|
-
const { packageRelease } = useCurrentPackageRelease({
|
|
14
|
-
include_logs: true,
|
|
15
|
-
})
|
|
16
|
-
const { mutate: rebuildPackage, isLoading } =
|
|
17
|
-
useRebuildPackageReleaseMutation()
|
|
18
|
-
|
|
19
|
-
const { circuitJson } = useCurrentPackageCircuitJson()
|
|
20
|
-
|
|
21
|
-
return (
|
|
22
|
-
<div className="border-b border-gray-200 bg-white px-4 sm:px-6 py-4">
|
|
23
|
-
<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">
|
|
24
|
-
<div className="min-w-0 flex-1">
|
|
25
|
-
<h1 className="text-xl sm:text-2xl font-semibold flex flex-col sm:flex-row sm:items-center gap-1 sm:gap-2">
|
|
26
|
-
<span className="whitespace-nowrap">Package Build</span>
|
|
27
|
-
<a
|
|
28
|
-
className="bg-gray-100 px-2 py-1 rounded font-mono text-blue-600 text-sm sm:text-base truncate w-fit"
|
|
29
|
-
href={`/${author}/${packageName}`}
|
|
30
|
-
>
|
|
31
|
-
{author}/{packageName}
|
|
32
|
-
</a>
|
|
33
|
-
</h1>
|
|
34
|
-
</div>
|
|
35
|
-
<div className="flex items-center gap-2 sm:gap-3 flex-shrink-0">
|
|
36
|
-
<Button
|
|
37
|
-
variant="outline"
|
|
38
|
-
size="sm"
|
|
39
|
-
className="border-gray-300 bg-white hover:bg-gray-50 text-xs sm:text-sm"
|
|
40
|
-
asChild
|
|
41
|
-
>
|
|
42
|
-
<a
|
|
43
|
-
href="https://github.com/tscircuit/tscircuit.com/issues/new"
|
|
44
|
-
target="_blank"
|
|
45
|
-
rel="noopener noreferrer"
|
|
46
|
-
>
|
|
47
|
-
<Github className="w-3 h-3 sm:w-4 sm:h-4 mr-1 sm:mr-2" />
|
|
48
|
-
<span className="hidden xs:inline">Report Issue</span>
|
|
49
|
-
<span className="xs:hidden">Report</span>
|
|
50
|
-
</a>
|
|
51
|
-
</Button>
|
|
52
|
-
{session?.github_username == author && (
|
|
53
|
-
<Button
|
|
54
|
-
variant="outline"
|
|
55
|
-
size="sm"
|
|
56
|
-
className="border-gray-300 bg-white hover:bg-gray-50 text-xs sm:text-sm"
|
|
57
|
-
disabled={isLoading || !packageRelease}
|
|
58
|
-
onClick={() =>
|
|
59
|
-
packageRelease &&
|
|
60
|
-
rebuildPackage({
|
|
61
|
-
package_release_id: packageRelease.package_release_id,
|
|
62
|
-
})
|
|
63
|
-
}
|
|
64
|
-
>
|
|
65
|
-
<RefreshCw className="w-3 h-3 sm:w-4 sm:h-4 mr-1 sm:mr-2" />
|
|
66
|
-
{isLoading ? "Rebuilding..." : "Rebuild"}
|
|
67
|
-
</Button>
|
|
68
|
-
)}
|
|
69
|
-
<DownloadButtonAndMenu
|
|
70
|
-
offerMultipleImageFormats
|
|
71
|
-
circuitJson={circuitJson}
|
|
72
|
-
unscopedName={packageName}
|
|
73
|
-
author={author}
|
|
74
|
-
/>
|
|
75
|
-
</div>
|
|
76
|
-
</div>
|
|
77
|
-
</div>
|
|
78
|
-
)
|
|
79
|
-
}
|