Skip to content

Commit 1af3013

Browse files
Feat: Add builds procedures & UI (#193)
<!-- CURSOR_SUMMARY --> > [!NOTE] > Introduce template Builds tab with filtering and live status, backed by new TRPC builds endpoints; add Turbopack fs stubs and update deps. > > - **Frontend (Templates UI)**: > - **Tabbed layout** under `templates` with `@list` and new `@builds` routes (`layout.tsx`, `page.tsx`, defaults). > - **Builds**: header filters (`status`, `Build ID/Template`), table with infinite pagination and live status polling, empty/loader states (`features/dashboard/templates/builds/*`). > - **Layout/UX**: split dashboard layout into `DefaultDashboardLayout`/`CustomDashboardLayout`; improved loader, checkbox, dropdown, button sizing, table/label styles. > - **Utilities**: add `formatDurationCompact`, `formatTimeAgoCompact`; new `cn` util in `lib/utils/ui`. > - **URLs**: add `TEMPLATES_LIST` and `TEMPLATES_BUILDS`. > - **Backend (TRPC + Repos)**: > - New `builds` router: `list`, `runningStatuses`, `getBuildStatus`. > - Supabase repo for listing builds and running statuses with status/DTO mappers (`models`, `repositories`). > - Telemetry: attach inferred `template_id`/`sandbox_id` span attrs. > - Remove legacy `teams` router from app router. > - **Config/Build**: > - Turbopack `resolveAlias` to stub Node `fs`/`fs/promises` for browser (`stubs/fs.ts`, `stubs/fs-promises.ts`); include stubs in `tsconfig`. > - **Tests/Scripts**: > - Add dev test `template-build.test.ts`; adjust dev test scripts. > - **Dependencies**: > - Bump `e2b` to `^2.7.0`, `@tanstack/react-virtual`, `tailwind-merge`; lockfile updates. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit 5b96dd9. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY -->
1 parent 7913cd5 commit 1af3013

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

50 files changed

+1664
-170
lines changed

bun.lock

Lines changed: 36 additions & 16 deletions
Large diffs are not rendered by default.

next.config.mjs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,16 @@ const config = {
1414
authInterrupts: true,
1515
clientSegmentCache: true,
1616
},
17+
turbopack: {
18+
resolveAlias: {
19+
// Stub Node.js modules for browser builds
20+
// e2b package bundles these packages. when dealing with browser chunks,
21+
// we need to stub these packages for builds.
22+
fs: { browser: './stubs/fs.ts' },
23+
'node:fs': { browser: './stubs/fs.ts' },
24+
'node:fs/promises': { browser: './stubs/fs-promises.ts' },
25+
},
26+
},
1727
logging: {
1828
fetches: {
1929
fullUrl: true,

package.json

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,8 @@
2828
"scripts:create-migration": "bun scripts/create-migration.ts",
2929
"<<<<<<< Development": "",
3030
"shad": "bunx shadcn@canary",
31-
"test:development:traffic": "vitest run src/__test__/development/traffic.test.ts",
31+
"test:dev:traffic": "vitest run src/__test__/development/traffic.test.ts",
32+
"test:dev:build": "vitest run src/__test__/development/template-build.test.ts",
3233
"clean": "rm -rf .next node_modules && bun install",
3334
"<<<<<<< Testing": "",
3435
"test:run": "bun scripts:check-all-env && vitest run",
@@ -81,7 +82,7 @@
8182
"@tanstack/match-sorter-utils": "^8.19.4",
8283
"@tanstack/react-query": "^5.90.7",
8384
"@tanstack/react-table": "^8.20.6",
84-
"@tanstack/react-virtual": "^3.11.3",
85+
"@tanstack/react-virtual": "^3.13.12",
8586
"@theguild/remark-mermaid": "^0.2.0",
8687
"@trpc/client": "^11.7.1",
8788
"@trpc/react-query": "^11.7.1",
@@ -102,7 +103,7 @@
102103
"date-fns": "^4.1.0",
103104
"date-fns-tz": "^3.2.0",
104105
"deepmerge": "^4.3.1",
105-
"e2b": "1.10.0",
106+
"e2b": "^2.7.0",
106107
"echarts": "^6.0.0",
107108
"echarts-for-react": "^3.0.2",
108109
"fast-xml-parser": "^4.5.1",
@@ -140,7 +141,7 @@
140141
"styled-components": "^6.1.19",
141142
"superjson": "^2.2.5",
142143
"swr": "^2.3.4",
143-
"tailwind-merge": "^3.3.1",
144+
"tailwind-merge": "^3.4.0",
144145
"tw-animate-css": "^1.3.6",
145146
"usehooks-ts": "^3.1.0",
146147
"vaul": "^1.1.2",
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
/**
2+
* This test builds a basic sandbox template using the E2B SDK,
3+
* useful for development and testing of template building features in the dashboard.
4+
*/
5+
6+
import { Template } from 'e2b'
7+
import { describe, expect, it } from 'vitest'
8+
9+
const l = console
10+
11+
const { TEST_E2B_DOMAIN, TEST_E2B_API_KEY } = import.meta.env
12+
13+
if (!TEST_E2B_DOMAIN || !TEST_E2B_API_KEY) {
14+
throw new Error(
15+
'Missing environment variables: TEST_E2B_DOMAIN and/or TEST_E2B_API_KEY'
16+
)
17+
}
18+
19+
const BUILD_TIMEOUT_MS = 5 * 60 * 1000
20+
21+
describe('E2B Template build test', () => {
22+
it(
23+
'builds a basic template with Node.js',
24+
{ timeout: BUILD_TIMEOUT_MS },
25+
async () => {
26+
const templateName = `test-template-${Date.now()}`
27+
28+
l.info('test:starting_template_build', {
29+
templateName,
30+
startTime: new Date().toISOString(),
31+
})
32+
33+
const template = Template()
34+
.skipCache()
35+
.fromNodeImage('lts')
36+
.setWorkdir('/app')
37+
.runCmd('echo "Hello from template build"')
38+
.setStartCmd('node --version', 'node --version')
39+
40+
const buildInfo = await Template.build(template, {
41+
alias: templateName,
42+
apiKey: TEST_E2B_API_KEY,
43+
domain: TEST_E2B_DOMAIN,
44+
onBuildLogs: (log) => {
45+
l.info('test:build_log', {
46+
level: log.level,
47+
message: log.message,
48+
})
49+
},
50+
})
51+
52+
l.info('test:template_build_completed', {
53+
templateId: buildInfo.templateId,
54+
buildId: buildInfo.buildId,
55+
alias: buildInfo.alias,
56+
endTime: new Date().toISOString(),
57+
})
58+
59+
expect(buildInfo.templateId).toBeDefined()
60+
expect(buildInfo.buildId).toBeDefined()
61+
}
62+
)
63+
})
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
export default function Default() {
2+
return null
3+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
import BuildsHeader from '@/features/dashboard/templates/builds/header'
2+
import BuildsTable from '@/features/dashboard/templates/builds/table'
3+
4+
export default function BuildsPage() {
5+
return (
6+
<div className="h-full min-h-0 flex-1 p-3 md:p-6 flex flex-col gap-3">
7+
<BuildsHeader />
8+
<BuildsTable />
9+
</div>
10+
)
11+
}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
export default function Default() {
2+
return null
3+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
import LoadingLayout from '@/features/dashboard/loading-layout'
2+
import TemplatesTable from '@/features/dashboard/templates/list/table'
3+
import { Suspense } from 'react'
4+
5+
export default async function ListPage() {
6+
return (
7+
<Suspense fallback={<LoadingLayout />}>
8+
<TemplatesTable />
9+
</Suspense>
10+
)
11+
}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
import { DashboardTab, DashboardTabs } from '@/ui/dashboard-tabs'
2+
import { BuildIcon, ListIcon } from '@/ui/primitives/icons'
3+
4+
export default function TemplatesLayout({
5+
list,
6+
builds,
7+
}: LayoutProps<'/dashboard/[teamIdOrSlug]/templates'> & {
8+
list: React.ReactNode
9+
builds: React.ReactNode
10+
}) {
11+
return (
12+
<DashboardTabs
13+
type="query"
14+
layoutKey="tabs-indicator-templates"
15+
className="pt-2 flex-1 md:pt-3"
16+
>
17+
<DashboardTab
18+
id="list"
19+
label="List"
20+
icon={<ListIcon className="size-4" />}
21+
>
22+
{list}
23+
</DashboardTab>
24+
<DashboardTab
25+
id="builds"
26+
label="Builds"
27+
icon={<BuildIcon className="size-4" />}
28+
>
29+
{builds}
30+
</DashboardTab>
31+
</DashboardTabs>
32+
)
33+
}

src/app/dashboard/[teamIdOrSlug]/templates/page.tsx

Lines changed: 0 additions & 25 deletions
This file was deleted.

0 commit comments

Comments
 (0)