@tscircuit/fake-snippets 0.0.107 → 0.0.108
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 +82 -22
- package/biome.json +7 -1
- package/bun-tests/fake-snippets-api/routes/package_builds/get.test.ts +0 -15
- package/bun-tests/fake-snippets-api/routes/package_builds/list.test.ts +0 -12
- package/dist/bundle.js +23 -23
- package/dist/index.d.ts +21 -15
- package/dist/index.js +17 -17
- package/dist/schema.d.ts +24 -24
- package/dist/schema.js +5 -5
- package/fake-snippets-api/lib/db/db-client.ts +10 -1
- package/fake-snippets-api/lib/db/schema.ts +3 -3
- package/fake-snippets-api/lib/db/seed.ts +6 -9
- package/fake-snippets-api/lib/public-mapping/public-map-package-build.ts +0 -3
- package/fake-snippets-api/lib/public-mapping/public-map-package-release.ts +3 -0
- package/package.json +1 -1
- package/src/App.tsx +12 -9
- package/src/components/FileSidebar.tsx +14 -159
- package/src/components/PackageBreadcrumb.tsx +1 -1
- package/src/components/ViewPackagePage/components/mobile-sidebar.tsx +1 -1
- package/src/components/ViewPackagePage/components/sidebar-about-section.tsx +18 -2
- package/src/components/ViewPackagePage/components/sidebar-releases-section.tsx +1 -1
- package/src/components/preview/BuildsList.tsx +20 -9
- package/src/components/preview/ConnectedPackagesList.tsx +73 -60
- package/src/components/preview/ConnectedRepoOverview.tsx +160 -154
- package/src/components/preview/PackageReleasesDashboard.tsx +11 -5
- package/src/components/preview/index.tsx +16 -153
- package/src/index.css +24 -0
- package/src/lib/utils/transformFilesToTreeData.tsx +195 -0
- package/src/pages/404.tsx +3 -5
- package/src/pages/preview-release.tsx +269 -0
- package/src/pages/release-builds.tsx +0 -8
- package/src/pages/release-detail.tsx +17 -15
- package/src/pages/releases.tsx +5 -1
- package/src/hooks/use-snippets-base-api-url.ts +0 -3
- package/src/pages/preview-build.tsx +0 -380
|
@@ -12,6 +12,7 @@ import {
|
|
|
12
12
|
import { TreeView, TreeDataItem } from "@/components/ui/tree-view"
|
|
13
13
|
import { isHiddenFile } from "./ViewPackagePage/utils/is-hidden-file"
|
|
14
14
|
import { Input } from "@/components/ui/input"
|
|
15
|
+
import { transformFilesToTreeData } from "@/lib/utils/transformFilesToTreeData"
|
|
15
16
|
import {
|
|
16
17
|
DropdownMenu,
|
|
17
18
|
DropdownMenuContent,
|
|
@@ -75,165 +76,19 @@ const FileSidebar: React.FC<FileSidebarProps> = ({
|
|
|
75
76
|
setSelectedFolderForCreation(folderPath)
|
|
76
77
|
}
|
|
77
78
|
|
|
78
|
-
const
|
|
79
|
-
files
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
let currentNode: Record<string, TreeNode> = root
|
|
92
|
-
|
|
93
|
-
pathSegments.forEach((segment, segmentIndex) => {
|
|
94
|
-
const isLeafNode = segmentIndex === pathSegments.length - 1
|
|
95
|
-
const ancestorPath = pathSegments.slice(0, segmentIndex).join("/")
|
|
96
|
-
const relativePath = ancestorPath
|
|
97
|
-
? `${ancestorPath}/${segment}`
|
|
98
|
-
: segment
|
|
99
|
-
const absolutePath = hasLeadingSlash ? `/${relativePath}` : relativePath
|
|
100
|
-
const itemId = absolutePath
|
|
101
|
-
|
|
102
|
-
if (
|
|
103
|
-
!currentNode[segment] &&
|
|
104
|
-
(!isHiddenFile(relativePath) ||
|
|
105
|
-
isHiddenFile(
|
|
106
|
-
currentFile?.startsWith("/")
|
|
107
|
-
? currentFile.slice(1)
|
|
108
|
-
: currentFile || "",
|
|
109
|
-
))
|
|
110
|
-
) {
|
|
111
|
-
currentNode[segment] = {
|
|
112
|
-
id: itemId,
|
|
113
|
-
name: segment,
|
|
114
|
-
isRenaming: renamingFile === itemId,
|
|
115
|
-
onRename: (newFilename: string) => {
|
|
116
|
-
const oldPath = itemId
|
|
117
|
-
const pathParts = oldPath.split("/").filter((part) => part !== "")
|
|
118
|
-
let newPath: string
|
|
119
|
-
|
|
120
|
-
if (pathParts.length > 1) {
|
|
121
|
-
const folderPath = pathParts.slice(0, -1).join("/")
|
|
122
|
-
newPath = folderPath + "/" + newFilename
|
|
123
|
-
} else {
|
|
124
|
-
newPath = newFilename
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
if (oldPath.startsWith("/") && !newPath.startsWith("/")) {
|
|
128
|
-
newPath = "/" + newPath
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
const { fileRenamed } = handleRenameFile({
|
|
132
|
-
oldFilename: itemId,
|
|
133
|
-
newFilename: newPath,
|
|
134
|
-
onError: (error) => {
|
|
135
|
-
toast({
|
|
136
|
-
title: `Error renaming file`,
|
|
137
|
-
description: error.message,
|
|
138
|
-
variant: "destructive",
|
|
139
|
-
})
|
|
140
|
-
},
|
|
141
|
-
})
|
|
142
|
-
if (fileRenamed) {
|
|
143
|
-
setRenamingFile(null)
|
|
144
|
-
}
|
|
145
|
-
},
|
|
146
|
-
onCancelRename: () => {
|
|
147
|
-
setRenamingFile(null)
|
|
148
|
-
},
|
|
149
|
-
icon: isLeafNode ? File : Folder,
|
|
150
|
-
onClick: isLeafNode
|
|
151
|
-
? () => {
|
|
152
|
-
onFileSelect(absolutePath)
|
|
153
|
-
setSelectedFolderForCreation(null)
|
|
154
|
-
}
|
|
155
|
-
: () => onFolderSelect(absolutePath),
|
|
156
|
-
draggable: false,
|
|
157
|
-
droppable: !isLeafNode,
|
|
158
|
-
children: isLeafNode ? undefined : {},
|
|
159
|
-
actions: canModifyFiles ? (
|
|
160
|
-
<>
|
|
161
|
-
<DropdownMenu key={itemId}>
|
|
162
|
-
<DropdownMenuTrigger asChild>
|
|
163
|
-
<MoreVertical className="w-4 h-4 text-gray-500 hover:text-gray-700" />
|
|
164
|
-
</DropdownMenuTrigger>
|
|
165
|
-
<DropdownMenuContent
|
|
166
|
-
className="w-fit bg-white shadow-lg rounded-md border-4 z-[100] border-white"
|
|
167
|
-
style={{
|
|
168
|
-
position: "absolute",
|
|
169
|
-
top: "100%",
|
|
170
|
-
left: "0",
|
|
171
|
-
marginTop: "0.5rem",
|
|
172
|
-
width: "8rem",
|
|
173
|
-
padding: "0.01rem",
|
|
174
|
-
}}
|
|
175
|
-
>
|
|
176
|
-
<DropdownMenuGroup>
|
|
177
|
-
{isLeafNode && (
|
|
178
|
-
<DropdownMenuItem
|
|
179
|
-
onClick={() => {
|
|
180
|
-
setRenamingFile(itemId)
|
|
181
|
-
}}
|
|
182
|
-
className="flex items-center px-3 py-1 text-xs text-black hover:bg-gray-100 cursor-pointer"
|
|
183
|
-
>
|
|
184
|
-
<Pencil className="mr-2 h-3 w-3" />
|
|
185
|
-
Rename
|
|
186
|
-
</DropdownMenuItem>
|
|
187
|
-
)}
|
|
188
|
-
<DropdownMenuItem
|
|
189
|
-
onClick={() => {
|
|
190
|
-
const { fileDeleted } = handleDeleteFile({
|
|
191
|
-
filename: itemId,
|
|
192
|
-
onError: (error) => {
|
|
193
|
-
toast({
|
|
194
|
-
title: `Error deleting file ${itemId}`,
|
|
195
|
-
description: error.message,
|
|
196
|
-
})
|
|
197
|
-
},
|
|
198
|
-
})
|
|
199
|
-
if (fileDeleted) {
|
|
200
|
-
setErrorMessage("")
|
|
201
|
-
}
|
|
202
|
-
}}
|
|
203
|
-
className="flex items-center px-3 py-1 text-xs text-red-600 hover:bg-gray-100 cursor-pointer"
|
|
204
|
-
>
|
|
205
|
-
<Trash2 className="mr-2 h-3 w-3" />
|
|
206
|
-
Delete
|
|
207
|
-
</DropdownMenuItem>
|
|
208
|
-
</DropdownMenuGroup>
|
|
209
|
-
</DropdownMenuContent>
|
|
210
|
-
</DropdownMenu>
|
|
211
|
-
</>
|
|
212
|
-
) : undefined,
|
|
213
|
-
}
|
|
214
|
-
}
|
|
215
|
-
|
|
216
|
-
if (!isLeafNode && currentNode[segment].children) {
|
|
217
|
-
currentNode = currentNode[segment].children
|
|
218
|
-
}
|
|
219
|
-
})
|
|
220
|
-
})
|
|
221
|
-
|
|
222
|
-
const convertToArray = (
|
|
223
|
-
items: Record<string, TreeNode>,
|
|
224
|
-
): TreeDataItem[] => {
|
|
225
|
-
return Object.values(items).map((item) => ({
|
|
226
|
-
...item,
|
|
227
|
-
children: item.children ? convertToArray(item.children) : undefined,
|
|
228
|
-
}))
|
|
229
|
-
}
|
|
230
|
-
return convertToArray(root).filter((x) => {
|
|
231
|
-
if (x.children?.length === 0) return false
|
|
232
|
-
return true
|
|
233
|
-
})
|
|
234
|
-
}
|
|
235
|
-
|
|
236
|
-
const treeData = transformFilesToTreeData(files)
|
|
79
|
+
const treeData = transformFilesToTreeData({
|
|
80
|
+
files,
|
|
81
|
+
currentFile,
|
|
82
|
+
renamingFile,
|
|
83
|
+
handleRenameFile,
|
|
84
|
+
handleDeleteFile,
|
|
85
|
+
setRenamingFile,
|
|
86
|
+
onFileSelect,
|
|
87
|
+
onFolderSelect,
|
|
88
|
+
canModifyFiles,
|
|
89
|
+
setErrorMessage,
|
|
90
|
+
setSelectedFolderForCreation,
|
|
91
|
+
})
|
|
237
92
|
|
|
238
93
|
const getCurrentFolderPath = (): string => {
|
|
239
94
|
if (selectedFolderForCreation) {
|
|
@@ -77,7 +77,7 @@ export function PackageBreadcrumb({
|
|
|
77
77
|
{currentPage === "builds" ? (
|
|
78
78
|
<BreadcrumbLink asChild>
|
|
79
79
|
<PrefetchPageLink
|
|
80
|
-
href={`/${packageName}/
|
|
80
|
+
href={`/${packageName}/releases/${releaseVersion}`}
|
|
81
81
|
>
|
|
82
82
|
{releaseVersion}
|
|
83
83
|
</PrefetchPageLink>
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Badge } from "@/components/ui/badge"
|
|
2
|
-
import { GitFork, Star, Settings, LinkIcon, Github } from "lucide-react"
|
|
2
|
+
import { GitFork, Star, Settings, LinkIcon, Github, Plus } from "lucide-react"
|
|
3
3
|
import { Skeleton } from "@/components/ui/skeleton"
|
|
4
4
|
import { useCurrentPackageInfo } from "@/hooks/use-current-package-info"
|
|
5
5
|
import { usePackageReleaseById } from "@/hooks/use-package-release"
|
|
@@ -164,7 +164,7 @@ export default function SidebarAboutSection({
|
|
|
164
164
|
<GitFork className="h-4 w-4 mr-2 text-gray-500 dark:text-[#8b949e]" />
|
|
165
165
|
<span>{(packageInfo as any)?.fork_count ?? "0"} forks</span>
|
|
166
166
|
</div>
|
|
167
|
-
{packageInfo?.github_repo_full_name
|
|
167
|
+
{packageInfo?.github_repo_full_name ? (
|
|
168
168
|
<a
|
|
169
169
|
target="_blank"
|
|
170
170
|
href={`https://github.com/${packageInfo.github_repo_full_name}`}
|
|
@@ -173,6 +173,22 @@ export default function SidebarAboutSection({
|
|
|
173
173
|
<Github className="h-4 w-4 mr-2 text-gray-500 dark:text-[#8b949e]" />
|
|
174
174
|
<span>{packageInfo?.github_repo_full_name.split("/")[1]}</span>
|
|
175
175
|
</a>
|
|
176
|
+
) : (
|
|
177
|
+
<>
|
|
178
|
+
{isOwner && (
|
|
179
|
+
<div
|
|
180
|
+
className="flex items-center hover:underline hover:underline-offset-2 cursor-pointer hover:decoration-gray-500"
|
|
181
|
+
onClick={openEditPackageDetailsDialog}
|
|
182
|
+
title="Connect GitHub"
|
|
183
|
+
>
|
|
184
|
+
<div className="relative mr-2">
|
|
185
|
+
<Github className="h-4 w-4 text-gray-500 dark:text-[#8b949e]" />
|
|
186
|
+
<Plus className="h-2 w-2 absolute -bottom-0.5 -right-0.5 text-gray-500 dark:text-[#8b949e] bg-white dark:bg-[#0d1117] rounded-full" />
|
|
187
|
+
</div>
|
|
188
|
+
<span>Connect GitHub</span>
|
|
189
|
+
</div>
|
|
190
|
+
)}
|
|
191
|
+
</>
|
|
176
192
|
)}
|
|
177
193
|
</div>
|
|
178
194
|
</div>
|
|
@@ -110,7 +110,7 @@ export default function SidebarReleasesSection() {
|
|
|
110
110
|
))}
|
|
111
111
|
{latestBuild && (
|
|
112
112
|
<PrefetchPageLink
|
|
113
|
-
href={
|
|
113
|
+
href={`/${packageInfo?.name}/releases`}
|
|
114
114
|
className="flex items-center gap-2 text-sm text-gray-500 dark:text-[#8b949e]"
|
|
115
115
|
>
|
|
116
116
|
<StatusIcon status={status} />
|
|
@@ -19,16 +19,17 @@ import {
|
|
|
19
19
|
} from "@/components/ui/table"
|
|
20
20
|
import { getBuildStatus, StatusIcon } from "."
|
|
21
21
|
import { formatTimeAgo } from "@/lib/utils/formatTimeAgo"
|
|
22
|
-
import { Package } from "fake-snippets-api/lib/db/schema"
|
|
22
|
+
import { Package, PackageBuild } from "fake-snippets-api/lib/db/schema"
|
|
23
23
|
import { usePackageReleasesByPackageId } from "@/hooks/use-package-release"
|
|
24
24
|
import { useQueries } from "react-query"
|
|
25
25
|
import { useAxios } from "@/hooks/use-axios"
|
|
26
|
+
import { useLocation } from "wouter"
|
|
26
27
|
|
|
27
28
|
export const BuildsList = ({ pkg }: { pkg: Package }) => {
|
|
28
29
|
const { data: releases, isLoading: isLoadingReleases } =
|
|
29
30
|
usePackageReleasesByPackageId(pkg.package_id)
|
|
30
31
|
const axios = useAxios()
|
|
31
|
-
|
|
32
|
+
const [, setLocation] = useLocation()
|
|
32
33
|
// Get the latest build for each release to show status
|
|
33
34
|
const latestBuildQueries = useQueries(
|
|
34
35
|
(releases || [])
|
|
@@ -52,7 +53,8 @@ export const BuildsList = ({ pkg }: { pkg: Package }) => {
|
|
|
52
53
|
isLoadingReleases || latestBuildQueries.some((q) => q.isLoading)
|
|
53
54
|
|
|
54
55
|
// Create a map of release ID to latest build for easy access
|
|
55
|
-
const latestBuildsMap = new Map()
|
|
56
|
+
const latestBuildsMap = new Map<string, PackageBuild>()
|
|
57
|
+
|
|
56
58
|
latestBuildQueries.forEach((query, index) => {
|
|
57
59
|
if (query.data && releases?.[index]) {
|
|
58
60
|
latestBuildsMap.set(releases[index].package_release_id, query.data)
|
|
@@ -110,15 +112,15 @@ export const BuildsList = ({ pkg }: { pkg: Package }) => {
|
|
|
110
112
|
const latestBuild = latestBuildsMap.get(
|
|
111
113
|
release.package_release_id,
|
|
112
114
|
)
|
|
113
|
-
const { status, label } = latestBuild
|
|
114
|
-
? getBuildStatus(latestBuild)
|
|
115
|
-
: { status: "unknown", label: "No builds" }
|
|
115
|
+
const { status, label } = getBuildStatus(latestBuild)
|
|
116
116
|
return (
|
|
117
117
|
<TableRow
|
|
118
118
|
key={release.package_release_id}
|
|
119
119
|
className="cursor-pointer hover:bg-gray-50 no-scrollbar"
|
|
120
120
|
onClick={() => {
|
|
121
|
-
|
|
121
|
+
setLocation(
|
|
122
|
+
`/${pkg.name}/releases/${release.package_release_id}`,
|
|
123
|
+
)
|
|
122
124
|
}}
|
|
123
125
|
>
|
|
124
126
|
<TableCell>
|
|
@@ -196,14 +198,23 @@ export const BuildsList = ({ pkg }: { pkg: Package }) => {
|
|
|
196
198
|
<DropdownMenuContent align="end">
|
|
197
199
|
<DropdownMenuItem
|
|
198
200
|
onClick={() => {
|
|
199
|
-
window.location.href = `/${pkg.name}/
|
|
201
|
+
window.location.href = `/${pkg.name}/releases/${release.package_release_id}`
|
|
200
202
|
}}
|
|
201
203
|
>
|
|
202
204
|
View Release
|
|
203
205
|
</DropdownMenuItem>
|
|
206
|
+
{status !== "error" && (
|
|
207
|
+
<DropdownMenuItem>
|
|
208
|
+
<a
|
|
209
|
+
href={`/${pkg.name}/releases/${latestBuild?.package_release_id}/preview`}
|
|
210
|
+
>
|
|
211
|
+
Preview Release
|
|
212
|
+
</a>
|
|
213
|
+
</DropdownMenuItem>
|
|
214
|
+
)}
|
|
204
215
|
<DropdownMenuItem
|
|
205
216
|
onClick={() => {
|
|
206
|
-
window.location.href = `/${pkg.name}/
|
|
217
|
+
window.location.href = `/${pkg.name}/releases/${release.package_release_id}/builds`
|
|
207
218
|
}}
|
|
208
219
|
>
|
|
209
220
|
View All Builds
|
|
@@ -1,49 +1,63 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { Card, CardContent, CardHeader } from "@/components/ui/card"
|
|
1
|
+
import { Card } from "@/components/ui/card"
|
|
3
2
|
import { Badge } from "@/components/ui/badge"
|
|
4
3
|
import { Button } from "@/components/ui/button"
|
|
5
4
|
import { GitBranch, Rocket, Github } from "lucide-react"
|
|
6
5
|
import { cn } from "@/lib/utils"
|
|
7
6
|
import { PrefetchPageLink } from "../PrefetchPageLink"
|
|
8
7
|
import { formatTimeAgo } from "@/lib/utils/formatTimeAgo"
|
|
9
|
-
import {
|
|
10
|
-
|
|
11
|
-
getLatestBuildForPackage,
|
|
12
|
-
MOCK_PACKAGE_BUILDS,
|
|
13
|
-
StatusIcon,
|
|
14
|
-
} from "."
|
|
15
|
-
import { Package, PackageBuild } from "fake-snippets-api/lib/db/schema"
|
|
8
|
+
import { getBuildStatus, StatusIcon } from "."
|
|
9
|
+
import { Package } from "fake-snippets-api/lib/db/schema"
|
|
16
10
|
import { usePackageBuild } from "@/hooks/use-package-builds"
|
|
17
|
-
import {
|
|
11
|
+
import {
|
|
12
|
+
useLatestPackageRelease,
|
|
13
|
+
usePackageReleaseById,
|
|
14
|
+
} from "@/hooks/use-package-release"
|
|
18
15
|
|
|
19
16
|
export const ConnectedPackageCardSkeleton = () => {
|
|
20
17
|
return (
|
|
21
|
-
<Card
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
18
|
+
<Card
|
|
19
|
+
className={cn(
|
|
20
|
+
"group relative overflow-hidden",
|
|
21
|
+
"border border-gray-200",
|
|
22
|
+
"hover:border-gray-300",
|
|
23
|
+
"bg-white shadow-none",
|
|
24
|
+
"p-6",
|
|
25
|
+
"flex flex-col",
|
|
26
|
+
"min-h-[200px]",
|
|
27
|
+
"animate-pulse",
|
|
28
|
+
)}
|
|
29
|
+
>
|
|
30
|
+
<div className="flex items-start justify-between mb-4">
|
|
31
|
+
<div className="flex items-center gap-3">
|
|
32
|
+
<div className="h-6 w-32 bg-gray-200 rounded" />
|
|
34
33
|
</div>
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
<div className="w-16 h-3 bg-gray-200 rounded" />
|
|
40
|
-
<div className="w-20 h-3 bg-gray-200 rounded" />
|
|
34
|
+
|
|
35
|
+
<div className="flex items-center justify-center gap-2">
|
|
36
|
+
<div className="w-16 h-5 bg-gray-200 rounded-full" />
|
|
37
|
+
<div className="w-4 h-4 bg-gray-200 rounded-full" />
|
|
41
38
|
</div>
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
39
|
+
</div>
|
|
40
|
+
|
|
41
|
+
<div className="flex items-center gap-2 mb-4">
|
|
42
|
+
<div className="w-4 h-4 bg-gray-200 rounded" />
|
|
43
|
+
<div className="w-48 h-5 bg-gray-200 rounded" />
|
|
44
|
+
</div>
|
|
45
|
+
|
|
46
|
+
<div className="mb-6 flex-1">
|
|
47
|
+
<div className="h-5 w-3/4 bg-gray-200 rounded mb-2" />
|
|
48
|
+
<div className="flex items-center gap-2">
|
|
49
|
+
<div className="w-32 h-4 bg-gray-200 rounded" />
|
|
50
|
+
<div className="flex items-center gap-1">
|
|
51
|
+
<div className="w-3 h-3 bg-gray-200 rounded" />
|
|
52
|
+
<div className="w-16 h-4 bg-gray-200 rounded-full" />
|
|
53
|
+
</div>
|
|
45
54
|
</div>
|
|
46
|
-
</
|
|
55
|
+
</div>
|
|
56
|
+
|
|
57
|
+
<div className="flex gap-2 w-full mt-auto">
|
|
58
|
+
<div className="w-full h-9 bg-gray-200 rounded" />
|
|
59
|
+
<div className="w-full h-9 bg-gray-200 rounded" />
|
|
60
|
+
</div>
|
|
47
61
|
</Card>
|
|
48
62
|
)
|
|
49
63
|
}
|
|
@@ -75,6 +89,10 @@ export const ConnectedPackageCard = ({
|
|
|
75
89
|
pkg.package_id,
|
|
76
90
|
)
|
|
77
91
|
|
|
92
|
+
const { data: packageRelease } = usePackageReleaseById(
|
|
93
|
+
latestBuildInfo?.package_release_id,
|
|
94
|
+
)
|
|
95
|
+
|
|
78
96
|
if (isLoading && !latestBuildInfo) {
|
|
79
97
|
return <ConnectedPackageCardSkeleton />
|
|
80
98
|
}
|
|
@@ -89,7 +107,7 @@ export const ConnectedPackageCard = ({
|
|
|
89
107
|
"group relative overflow-hidden",
|
|
90
108
|
"border border-gray-200",
|
|
91
109
|
"hover:border-gray-300",
|
|
92
|
-
"bg-white",
|
|
110
|
+
"bg-white shadow-none",
|
|
93
111
|
"p-6",
|
|
94
112
|
"flex flex-col",
|
|
95
113
|
"min-h-[200px]",
|
|
@@ -135,46 +153,41 @@ export const ConnectedPackageCard = ({
|
|
|
135
153
|
</a>
|
|
136
154
|
</div>
|
|
137
155
|
|
|
138
|
-
|
|
139
|
-
|
|
156
|
+
<div className="mb-6 flex-1">
|
|
157
|
+
{packageRelease?.commit_message && (
|
|
140
158
|
<h4
|
|
141
|
-
title={
|
|
159
|
+
title={packageRelease.commit_message}
|
|
142
160
|
className="text-sm font-medium truncate text-gray-900 mb-2"
|
|
143
161
|
>
|
|
144
|
-
{
|
|
162
|
+
{packageRelease.commit_message}
|
|
145
163
|
</h4>
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
</
|
|
164
|
+
)}
|
|
165
|
+
<div className="flex items-center gap-2 text-xs text-gray-500">
|
|
166
|
+
<span>{formatTimeAgo(String(latestBuildInfo?.created_at))} on</span>
|
|
167
|
+
<div className="flex items-center gap-1">
|
|
168
|
+
<GitBranch className="w-3 h-3" />
|
|
169
|
+
<span className="bg-blue-100 text-blue-800 px-2 py-0.5 rounded-full font-medium">
|
|
170
|
+
{packageRelease?.branch_name || "main"}
|
|
171
|
+
</span>
|
|
154
172
|
</div>
|
|
155
173
|
</div>
|
|
156
|
-
|
|
174
|
+
</div>
|
|
157
175
|
|
|
158
176
|
<div className="flex gap-2 w-full mt-auto">
|
|
159
|
-
|
|
160
|
-
<
|
|
161
|
-
|
|
162
|
-
|
|
177
|
+
<PrefetchPageLink className="w-full" href={`/${pkg.name}/releases`}>
|
|
178
|
+
<Button
|
|
179
|
+
size="sm"
|
|
180
|
+
className="bg-blue-600 w-full hover:bg-blue-700 text-white px-4 py-2"
|
|
163
181
|
>
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
>
|
|
168
|
-
View
|
|
169
|
-
</Button>
|
|
170
|
-
</PrefetchPageLink>
|
|
171
|
-
)}
|
|
182
|
+
View
|
|
183
|
+
</Button>
|
|
184
|
+
</PrefetchPageLink>
|
|
172
185
|
{latestBuildInfo?.preview_url &&
|
|
173
186
|
latestBuildInfo?.package_build_id &&
|
|
174
187
|
status === "success" && (
|
|
175
188
|
<PrefetchPageLink
|
|
176
189
|
className="w-full"
|
|
177
|
-
href={
|
|
190
|
+
href={`/${pkg.name}/releases/${latestBuildInfo.package_release_id}/preview`}
|
|
178
191
|
>
|
|
179
192
|
<Button size="sm" variant="outline" className="px-4 py-2 w-full">
|
|
180
193
|
Preview
|