@tscircuit/fake-snippets 0.0.68 → 0.0.70
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/bun-tests/fake-snippets-api/routes/packages/update.test.ts +104 -0
- package/bun.lock +15 -25
- package/dist/bundle.js +25 -5
- package/dist/index.d.ts +5 -0
- package/dist/index.js +2 -1
- package/dist/schema.d.ts +8 -0
- package/dist/schema.js +2 -1
- package/fake-snippets-api/lib/db/schema.ts +4 -0
- package/fake-snippets-api/routes/api/packages/create.ts +1 -0
- package/fake-snippets-api/routes/api/packages/get.ts +12 -0
- package/fake-snippets-api/routes/api/packages/update.ts +11 -2
- package/package.json +3 -3
- package/src/components/CircuitJsonImportDialog.tsx +113 -52
- package/src/components/DownloadButtonAndMenu.tsx +1 -1
- package/src/components/HeaderLogin.tsx +1 -1
- package/src/components/ViewPackagePage/components/important-files-view.tsx +1 -1
- package/src/components/ViewPackagePage/components/mobile-sidebar.tsx +1 -0
- package/src/components/ViewPackagePage/components/package-header.tsx +21 -11
- package/src/components/ViewPackagePage/components/repo-page-content.tsx +24 -7
- package/src/components/ViewPackagePage/components/sidebar-about-section.tsx +1 -0
- package/src/components/dialogs/edit-package-details-dialog.tsx +33 -2
- package/src/components/package-port/CodeAndPreview.tsx +1 -1
- package/src/components/package-port/CodeEditorHeader.tsx +12 -4
- package/src/components/package-port/EditorNav.tsx +33 -8
- package/src/hooks/use-create-package-mutation.ts +0 -2
- package/src/hooks/use-package-details-form.ts +15 -1
- package/src/index.css +13 -0
- package/src/pages/package-editor.tsx +2 -1
- package/src/pages/quickstart.tsx +1 -1
- package/src/pages/view-package.tsx +13 -11
|
@@ -35,6 +35,7 @@ interface EditPackageDetailsDialogProps {
|
|
|
35
35
|
currentDescription: string
|
|
36
36
|
currentWebsite: string
|
|
37
37
|
currentLicense?: string | null
|
|
38
|
+
currentDefaultView?: string
|
|
38
39
|
isPrivate?: boolean
|
|
39
40
|
packageName: string
|
|
40
41
|
packageReleaseId: string | null
|
|
@@ -43,6 +44,7 @@ interface EditPackageDetailsDialogProps {
|
|
|
43
44
|
newDescription: string,
|
|
44
45
|
newWebsite: string,
|
|
45
46
|
newLicense: string | null,
|
|
47
|
+
newDefaultView: string,
|
|
46
48
|
) => void
|
|
47
49
|
}
|
|
48
50
|
|
|
@@ -53,6 +55,7 @@ export const EditPackageDetailsDialog = ({
|
|
|
53
55
|
currentDescription,
|
|
54
56
|
currentWebsite,
|
|
55
57
|
currentLicense,
|
|
58
|
+
currentDefaultView = "files",
|
|
56
59
|
isPrivate = false,
|
|
57
60
|
packageName,
|
|
58
61
|
packageReleaseId,
|
|
@@ -68,12 +71,14 @@ export const EditPackageDetailsDialog = ({
|
|
|
68
71
|
setFormData,
|
|
69
72
|
websiteError,
|
|
70
73
|
hasLicenseChanged,
|
|
74
|
+
hasDefaultViewChanged,
|
|
71
75
|
hasChanges,
|
|
72
76
|
isFormValid,
|
|
73
77
|
} = usePackageDetailsForm({
|
|
74
78
|
initialDescription: currentDescription,
|
|
75
79
|
initialWebsite: currentWebsite,
|
|
76
80
|
initialLicense: currentLicense || null,
|
|
81
|
+
initialDefaultView: currentDefaultView,
|
|
77
82
|
isDialogOpen: open,
|
|
78
83
|
initialVisibility: isPrivate ? "private" : "public",
|
|
79
84
|
})
|
|
@@ -108,6 +113,7 @@ export const EditPackageDetailsDialog = ({
|
|
|
108
113
|
description: formData.description,
|
|
109
114
|
website: formData.website,
|
|
110
115
|
is_private: formData.visibility == "private",
|
|
116
|
+
default_view: formData.defaultView,
|
|
111
117
|
})
|
|
112
118
|
const privacyUpdateResponse = await axios.post("/snippets/update", {
|
|
113
119
|
snippet_id: packageId,
|
|
@@ -149,6 +155,7 @@ export const EditPackageDetailsDialog = ({
|
|
|
149
155
|
website: formData.website,
|
|
150
156
|
license: formData.license,
|
|
151
157
|
visibility: formData.visibility,
|
|
158
|
+
defaultView: formData.defaultView,
|
|
152
159
|
}
|
|
153
160
|
},
|
|
154
161
|
onMutate: async () => {
|
|
@@ -160,11 +167,12 @@ export const EditPackageDetailsDialog = ({
|
|
|
160
167
|
website: formData.website,
|
|
161
168
|
license: formData.license,
|
|
162
169
|
is_private: formData.visibility == "private",
|
|
170
|
+
default_view: formData.defaultView,
|
|
163
171
|
}))
|
|
164
172
|
return { previous }
|
|
165
173
|
},
|
|
166
174
|
onSuccess: (data) => {
|
|
167
|
-
onUpdate?.(data.description, data.website, data.license)
|
|
175
|
+
onUpdate?.(data.description, data.website, data.license, data.defaultView)
|
|
168
176
|
onOpenChange(false)
|
|
169
177
|
qc.invalidateQueries([
|
|
170
178
|
"packageFile",
|
|
@@ -218,7 +226,7 @@ export const EditPackageDetailsDialog = ({
|
|
|
218
226
|
</DialogContent>
|
|
219
227
|
</Dialog>
|
|
220
228
|
<Dialog open={open !== showConfirmDelete} onOpenChange={onOpenChange}>
|
|
221
|
-
<DialogContent className="sm:max-w-[500px] lg:h-[
|
|
229
|
+
<DialogContent className="sm:max-w-[500px] lg:h-[85vh] sm:h-[90vh] overflow-y-auto no-scrollbar w-[95vw] h-[80vh] p-6 gap-6 rounded-2xl shadow-lg">
|
|
222
230
|
<div className="flex flex-col gap-10">
|
|
223
231
|
<DialogHeader>
|
|
224
232
|
<DialogTitle>Edit Package Details</DialogTitle>
|
|
@@ -310,6 +318,29 @@ export const EditPackageDetailsDialog = ({
|
|
|
310
318
|
</SelectContent>
|
|
311
319
|
</Select>
|
|
312
320
|
</div>
|
|
321
|
+
<div className="space-y-1">
|
|
322
|
+
<Label htmlFor="defaultView">Default View</Label>
|
|
323
|
+
<Select
|
|
324
|
+
value={formData.defaultView}
|
|
325
|
+
onValueChange={(value) =>
|
|
326
|
+
setFormData((prev) => ({
|
|
327
|
+
...prev,
|
|
328
|
+
defaultView: value,
|
|
329
|
+
}))
|
|
330
|
+
}
|
|
331
|
+
disabled={updatePackageDetailsMutation.isLoading}
|
|
332
|
+
>
|
|
333
|
+
<SelectTrigger className="w-full">
|
|
334
|
+
<SelectValue placeholder="Select default view" />
|
|
335
|
+
</SelectTrigger>
|
|
336
|
+
<SelectContent className="!z-[999]">
|
|
337
|
+
<SelectItem value="files">Files</SelectItem>
|
|
338
|
+
<SelectItem value="3d">3D</SelectItem>
|
|
339
|
+
<SelectItem value="pcb">PCB</SelectItem>
|
|
340
|
+
<SelectItem value="schematic">Schematic</SelectItem>
|
|
341
|
+
</SelectContent>
|
|
342
|
+
</Select>
|
|
343
|
+
</div>
|
|
313
344
|
</div>
|
|
314
345
|
|
|
315
346
|
<details
|
|
@@ -136,16 +136,24 @@ export const CodeEditorHeader: React.FC<CodeEditorHeaderProps> = ({
|
|
|
136
136
|
<>
|
|
137
137
|
<div className="flex items-center gap-2 px-2 border-b border-gray-200">
|
|
138
138
|
<button
|
|
139
|
-
className={`text-gray-400 scale-90 transition-opacity duration-
|
|
140
|
-
sidebarOpen
|
|
139
|
+
className={`text-gray-400 scale-90 p-0 transition-[width,opacity] duration-300 ease-in-out overflow-hidden ${
|
|
140
|
+
sidebarOpen
|
|
141
|
+
? "w-0 pointer-events-none opacity-0"
|
|
142
|
+
: "w-6 opacity-100"
|
|
141
143
|
}`}
|
|
142
144
|
onClick={() => setSidebarOpen(true)}
|
|
143
145
|
>
|
|
144
|
-
<
|
|
146
|
+
<div className="w-6 h-6 flex items-center justify-center">
|
|
147
|
+
<PanelRightClose />
|
|
148
|
+
</div>
|
|
145
149
|
</button>
|
|
146
150
|
<div>
|
|
147
151
|
<Select value={currentFile} onValueChange={handleFileChange}>
|
|
148
|
-
<SelectTrigger
|
|
152
|
+
<SelectTrigger
|
|
153
|
+
className={`h-7 px-3 bg-white select-none transition-[margin] duration-300 ease-in-out ${
|
|
154
|
+
sidebarOpen ? "-ml-2" : "-ml-1"
|
|
155
|
+
}`}
|
|
156
|
+
>
|
|
149
157
|
<SelectValue placeholder="Select file" />
|
|
150
158
|
</SelectTrigger>
|
|
151
159
|
<SelectContent>
|
|
@@ -324,7 +324,7 @@ export default function EditorNav({
|
|
|
324
324
|
<DownloadButtonAndMenu
|
|
325
325
|
snippetUnscopedName={pkg?.unscoped_name}
|
|
326
326
|
circuitJson={circuitJson}
|
|
327
|
-
className="
|
|
327
|
+
className="flex"
|
|
328
328
|
/>
|
|
329
329
|
<Button
|
|
330
330
|
variant="ghost"
|
|
@@ -464,17 +464,42 @@ export default function EditorNav({
|
|
|
464
464
|
</div>
|
|
465
465
|
</DropdownMenuTrigger>
|
|
466
466
|
<DropdownMenuContent>
|
|
467
|
-
<DropdownMenuItem
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
467
|
+
<DropdownMenuItem
|
|
468
|
+
className="text-xs"
|
|
469
|
+
onClick={() => {
|
|
470
|
+
if (window) {
|
|
471
|
+
navigator.clipboard.writeText(
|
|
472
|
+
new URL(window.location.href).origin + "/" + pkg?.name,
|
|
473
|
+
)
|
|
474
|
+
toast({
|
|
475
|
+
title: "URL copied!",
|
|
476
|
+
description: "The URL has been copied to your clipboard.",
|
|
477
|
+
})
|
|
478
|
+
}
|
|
479
|
+
}}
|
|
480
|
+
>
|
|
472
481
|
<Share className="mr-1 h-3 w-3" />
|
|
473
482
|
Copy URL
|
|
474
483
|
</DropdownMenuItem>
|
|
475
|
-
<DropdownMenuItem
|
|
484
|
+
<DropdownMenuItem
|
|
485
|
+
className="text-xs"
|
|
486
|
+
onClick={() => {
|
|
487
|
+
if (
|
|
488
|
+
pkg &&
|
|
489
|
+
session?.github_username === pkg.owner_github_username
|
|
490
|
+
) {
|
|
491
|
+
updatePackageVisibilityToPrivate(!isPrivate)
|
|
492
|
+
}
|
|
493
|
+
}}
|
|
494
|
+
>
|
|
476
495
|
<Eye className="mr-1 h-3 w-3" />
|
|
477
|
-
|
|
496
|
+
{session?.github_username === pkg?.owner_github_username
|
|
497
|
+
? isPrivate
|
|
498
|
+
? "Make Public"
|
|
499
|
+
: "Make Private"
|
|
500
|
+
: isPrivate
|
|
501
|
+
? "Private Package"
|
|
502
|
+
: "Public Package"}
|
|
478
503
|
</DropdownMenuItem>
|
|
479
504
|
</DropdownMenuContent>
|
|
480
505
|
</DropdownMenu>
|
|
@@ -7,8 +7,6 @@ import { useUrlParams } from "./use-url-params"
|
|
|
7
7
|
export const useCreatePackageMutation = ({
|
|
8
8
|
onSuccess,
|
|
9
9
|
}: { onSuccess?: (pkg: Package) => void } = {}) => {
|
|
10
|
-
const urlParams = useUrlParams()
|
|
11
|
-
const templateName = urlParams.template
|
|
12
10
|
const axios = useAxios()
|
|
13
11
|
const session = useGlobalStore((s) => s.session)
|
|
14
12
|
|
|
@@ -15,6 +15,7 @@ interface PackageDetailsForm {
|
|
|
15
15
|
website: string
|
|
16
16
|
license: string | null
|
|
17
17
|
visibility: string
|
|
18
|
+
defaultView: string
|
|
18
19
|
}
|
|
19
20
|
|
|
20
21
|
interface UsePackageDetailsFormProps {
|
|
@@ -22,6 +23,7 @@ interface UsePackageDetailsFormProps {
|
|
|
22
23
|
initialWebsite: string
|
|
23
24
|
initialLicense: string | null
|
|
24
25
|
initialVisibility: string
|
|
26
|
+
initialDefaultView: string
|
|
25
27
|
isDialogOpen: boolean
|
|
26
28
|
}
|
|
27
29
|
|
|
@@ -30,6 +32,7 @@ export const usePackageDetailsForm = ({
|
|
|
30
32
|
initialWebsite,
|
|
31
33
|
initialLicense,
|
|
32
34
|
initialVisibility,
|
|
35
|
+
initialDefaultView,
|
|
33
36
|
isDialogOpen,
|
|
34
37
|
}: UsePackageDetailsFormProps) => {
|
|
35
38
|
const [formData, setFormData] = useState<PackageDetailsForm>({
|
|
@@ -37,6 +40,7 @@ export const usePackageDetailsForm = ({
|
|
|
37
40
|
website: initialWebsite,
|
|
38
41
|
license: initialLicense || null,
|
|
39
42
|
visibility: initialVisibility,
|
|
43
|
+
defaultView: initialDefaultView,
|
|
40
44
|
})
|
|
41
45
|
const [websiteError, setWebsiteError] = useState<string | null>(null)
|
|
42
46
|
|
|
@@ -47,6 +51,7 @@ export const usePackageDetailsForm = ({
|
|
|
47
51
|
website: initialWebsite,
|
|
48
52
|
license: initialLicense || null,
|
|
49
53
|
visibility: initialVisibility,
|
|
54
|
+
defaultView: initialDefaultView,
|
|
50
55
|
})
|
|
51
56
|
setWebsiteError(null)
|
|
52
57
|
}
|
|
@@ -56,6 +61,7 @@ export const usePackageDetailsForm = ({
|
|
|
56
61
|
initialWebsite,
|
|
57
62
|
initialLicense,
|
|
58
63
|
initialVisibility,
|
|
64
|
+
initialDefaultView,
|
|
59
65
|
])
|
|
60
66
|
|
|
61
67
|
useEffect(() => {
|
|
@@ -76,18 +82,25 @@ export const usePackageDetailsForm = ({
|
|
|
76
82
|
[formData.visibility, initialVisibility],
|
|
77
83
|
)
|
|
78
84
|
|
|
85
|
+
const hasDefaultViewChanged = useMemo(
|
|
86
|
+
() => formData.defaultView !== initialDefaultView,
|
|
87
|
+
[formData.defaultView, initialDefaultView],
|
|
88
|
+
)
|
|
89
|
+
|
|
79
90
|
const hasChanges = useMemo(
|
|
80
91
|
() =>
|
|
81
92
|
formData.description !== initialDescription ||
|
|
82
93
|
formData.website !== initialWebsite ||
|
|
83
94
|
formData.license !== initialLicense ||
|
|
84
|
-
formData.visibility !== initialVisibility
|
|
95
|
+
formData.visibility !== initialVisibility ||
|
|
96
|
+
formData.defaultView !== initialDefaultView,
|
|
85
97
|
[
|
|
86
98
|
formData,
|
|
87
99
|
initialDescription,
|
|
88
100
|
initialWebsite,
|
|
89
101
|
initialLicense,
|
|
90
102
|
initialVisibility,
|
|
103
|
+
initialDefaultView,
|
|
91
104
|
],
|
|
92
105
|
)
|
|
93
106
|
|
|
@@ -99,6 +112,7 @@ export const usePackageDetailsForm = ({
|
|
|
99
112
|
websiteError,
|
|
100
113
|
hasLicenseChanged,
|
|
101
114
|
hasVisibilityChanged,
|
|
115
|
+
hasDefaultViewChanged,
|
|
102
116
|
hasChanges,
|
|
103
117
|
isFormValid,
|
|
104
118
|
}
|
package/src/index.css
CHANGED
|
@@ -7,6 +7,19 @@
|
|
|
7
7
|
}
|
|
8
8
|
}
|
|
9
9
|
|
|
10
|
+
/* add the code bellow */
|
|
11
|
+
@layer utilities {
|
|
12
|
+
/* Hide scrollbar for Chrome, Safari and Opera */
|
|
13
|
+
.no-scrollbar::-webkit-scrollbar {
|
|
14
|
+
display: none;
|
|
15
|
+
}
|
|
16
|
+
/* Hide scrollbar for IE, Edge and Firefox */
|
|
17
|
+
.no-scrollbar {
|
|
18
|
+
-ms-overflow-style: none; /* IE and Edge */
|
|
19
|
+
scrollbar-width: none; /* Firefox */
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
|
|
10
23
|
.shiki {
|
|
11
24
|
font-family: "Fira Code", monospace;
|
|
12
25
|
font-size: 14px;
|
|
@@ -10,13 +10,14 @@ import { useGetFsMapHashForPackage } from "@/hooks/use-get-fsmap-hash-for-packag
|
|
|
10
10
|
|
|
11
11
|
export const EditorPage = () => {
|
|
12
12
|
const { packageId } = useCurrentPackageId()
|
|
13
|
-
const { data: pkg,
|
|
13
|
+
const { data: pkg, error } = usePackage(packageId)
|
|
14
14
|
const fsMapHash = useGetFsMapHashForPackage(
|
|
15
15
|
pkg?.latest_package_release_id ?? "",
|
|
16
16
|
)
|
|
17
17
|
const uuid4RegExp = new RegExp(
|
|
18
18
|
/^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-4[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}$/,
|
|
19
19
|
)
|
|
20
|
+
|
|
20
21
|
return (
|
|
21
22
|
<div className="overflow-x-hidden">
|
|
22
23
|
<Helmet>
|
package/src/pages/quickstart.tsx
CHANGED
|
@@ -166,7 +166,7 @@ export const QuickstartPage = () => {
|
|
|
166
166
|
<CardHeader className="p-4 pb-0">
|
|
167
167
|
<CardTitle className="text-lg flex items-center justify-between">
|
|
168
168
|
Circuit Json
|
|
169
|
-
<TypeBadge type="
|
|
169
|
+
<TypeBadge type="package" className="ml-2" />
|
|
170
170
|
</CardTitle>
|
|
171
171
|
</CardHeader>
|
|
172
172
|
<CardContent className="p-4 mt-auto">
|
|
@@ -1,18 +1,22 @@
|
|
|
1
1
|
import RepoPageContent from "@/components/ViewPackagePage/components/repo-page-content"
|
|
2
|
-
import { useCurrentPackageInfo } from "@/hooks/use-current-package-info"
|
|
3
2
|
import { usePackageFiles } from "@/hooks/use-package-files"
|
|
4
3
|
import { usePackageRelease } from "@/hooks/use-package-release"
|
|
5
4
|
import { useLocation, useParams } from "wouter"
|
|
6
5
|
import { Helmet } from "react-helmet-async"
|
|
7
6
|
import { useEffect, useState } from "react"
|
|
8
7
|
import NotFoundPage from "./404"
|
|
8
|
+
import { useCurrentPackageId } from "@/hooks/use-current-package-id"
|
|
9
|
+
import { usePackage } from "@/hooks/use-package"
|
|
9
10
|
|
|
10
11
|
export const ViewPackagePage = () => {
|
|
11
|
-
const {
|
|
12
|
+
const {
|
|
13
|
+
packageId,
|
|
14
|
+
error: packageIdError,
|
|
15
|
+
isLoading: isLoadingPackageId,
|
|
16
|
+
} = useCurrentPackageId()
|
|
17
|
+
const { data: packageInfo } = usePackage(packageId)
|
|
12
18
|
const { author, packageName } = useParams()
|
|
13
19
|
const [, setLocation] = useLocation()
|
|
14
|
-
const [isNotFound, setIsNotFound] = useState(false)
|
|
15
|
-
|
|
16
20
|
const {
|
|
17
21
|
data: packageRelease,
|
|
18
22
|
error: packageReleaseError,
|
|
@@ -25,14 +29,12 @@ export const ViewPackagePage = () => {
|
|
|
25
29
|
const { data: packageFiles } = usePackageFiles(
|
|
26
30
|
packageRelease?.package_release_id,
|
|
27
31
|
)
|
|
28
|
-
useEffect(() => {
|
|
29
|
-
if (isLoadingPackageRelease) return
|
|
30
|
-
if (packageReleaseError?.status == 404) {
|
|
31
|
-
setIsNotFound(true)
|
|
32
|
-
}
|
|
33
|
-
}, [isLoadingPackageRelease, packageReleaseError])
|
|
34
32
|
|
|
35
|
-
if (
|
|
33
|
+
if (!isLoadingPackageId && packageIdError) {
|
|
34
|
+
return <NotFoundPage heading="Package Not Found" />
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
if (!isLoadingPackageRelease && packageReleaseError?.status == 404) {
|
|
36
38
|
return <NotFoundPage heading="Package Not Found" />
|
|
37
39
|
}
|
|
38
40
|
|