Skip to content

Commit ae736b6

Browse files
fix: restructure devtools to root-level dirs and fix SPA navigation
- Moved src/pages/ to pages/, src/components/ to components/, src/partials/ to partials/ (stx standard structure) - Updated stx.config.ts, serve.ts, build.ts paths - Added data-stx-link to dynamic links for SPA navigation - Removed invalid shell config (app uses @extends layout pattern) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent fca3189 commit ae736b6

29 files changed

+432
-152
lines changed

packages/devtools/build.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -20,17 +20,17 @@ console.log('JS build complete!')
2020
// 2. Build stx pages → dist/pages/ (HTML via bun-plugin-stx)
2121
const stxPages: string[] = []
2222
const glob = new Glob('*.stx')
23-
for await (const file of glob.scan('./src/pages')) {
24-
stxPages.push(`./src/pages/${file}`)
23+
for await (const file of glob.scan('./pages')) {
24+
stxPages.push(`./pages/${file}`)
2525
}
2626

2727
const stxResult = await Bun.build({
2828
entrypoints: stxPages,
2929
outdir: './dist/pages',
3030
plugins: [stxPlugin({
31-
componentsDir: './src/components',
32-
layoutsDir: './src/layouts',
33-
partialsDir: './src/partials',
31+
componentsDir: './components',
32+
layoutsDir: './layouts',
33+
partialsDir: './partials',
3434
})],
3535
})
3636

File renamed without changes.
File renamed without changes.
File renamed without changes.

packages/devtools/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@
4343
],
4444
"scripts": {
4545
"build": "bun --bun build.ts",
46-
"dev": "bun --watch server.ts",
46+
"dev": "bun --watch serve.ts",
4747
"prepublishOnly": "bun run build",
4848
"test": "bun test",
4949
"test:watch": "bun test --watch",

packages/devtools/src/pages/batch-details.stx renamed to packages/devtools/pages/batch-details.stx

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,16 @@
1+
@extends('layouts/app')
2+
3+
@section('title')Batch Details — bun-queue@endsection
4+
5+
@push('styles')
16
<style>
27
.progress-ring-container svg { transform: rotate(-90deg); }
38
.progress-ring-bg { fill: none; stroke: #1e1e26; stroke-width: 10; }
49
.progress-ring-fill { fill: none; stroke: #10b981; stroke-width: 10; stroke-linecap: round; transition: stroke-dashoffset 0.6s ease; }
510
</style>
11+
@endpush
612

13+
@section('content')
714
<script client>
815
interface BatchData {
916
id: string
@@ -118,7 +125,7 @@
118125
<svg width='160' height='160' viewBox='0 0 160 160'>
119126
<circle class='progress-ring-bg' cx='80' cy='80' r='65'/>
120127
<circle class='progress-ring-fill' cx='80' cy='80' r='65'
121-
stroke-dasharray='408.4' :style='\'stroke-dashoffset: \' + ringOffset()'/>
128+
stroke-dasharray='408.4' :style="'stroke-dashoffset: ' + ringOffset()"/>
122129
</svg>
123130
<div class='absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 text-center'>
124131
<div class='text-[2rem] font-bold text-zinc-50 tabular-nums leading-none'>{{ progressPct() }}%</div>
@@ -206,11 +213,12 @@
206213
<td class='px-3 py-2.5 text-xs text-zinc-400 border-b border-zinc-800'>{{ formatTime(job.createdAt) }}</td>
207214
<td class='px-3 py-2.5 text-xs text-zinc-400 border-b border-zinc-800 text-right font-mono tabular-nums'>{{ job.duration ? job.duration + 'ms' : '—' }}</td>
208215
<td class='px-3 py-2.5 text-[0.8125rem] border-b border-zinc-800'>
209-
<a :href='\'/jobs/\' + job.id' class='text-indigo-500 no-underline hover:underline'>View</a>
216+
<a :href="'/jobs/' + job.id" data-stx-link class='text-indigo-500 no-underline hover:underline'>View</a>
210217
</td>
211218
</tr>
212219
</template>
213220
</tbody>
214221
</table>
215222
</div>
216223
</div>
224+
@endsection
Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,14 @@
1+
@extends('layouts/app')
2+
3+
@section('title')Batches — bun-queue@endsection
4+
5+
@push('styles')
16
<style>
27
.progress-bar-fill { transition: width 0.5s ease; }
38
</style>
9+
@endpush
410

11+
@section('content')
512
<script client>
613
interface Batch {
714
id: string
@@ -119,7 +126,7 @@
119126
<div
120127
class='progress-bar-fill h-full rounded-full'
121128
:class='progressBarColorClass(batchStatus(batch))'
122-
:style='\'width: \' + batchPct(batch) + \'%\''
129+
:style="'width: ' + batchPct(batch) + '%'"
123130
></div>
124131
</div>
125132
<div class='text-xs text-zinc-500 text-right tabular-nums mb-3'>{{ batchPct(batch) }}% complete</div>
@@ -153,7 +160,7 @@
153160
<!-- View Details link -->
154161
<div class='flex justify-end'>
155162
<a
156-
:href='\'/batches/\' + batch.id'
163+
:href="'/batches/' + batch.id"
157164
class='text-indigo-500 no-underline text-[0.8125rem] font-medium transition-colors duration-150 hover:text-indigo-400 hover:underline'
158165
>
159166
View Details &rarr;
@@ -164,3 +171,4 @@
164171
</div>
165172
</div>
166173
</div>
174+
@endsection
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
<script>
2+
import type { JobTableRow } from '../types/components'
3+
4+
const jobs: JobTableRow[] = []
5+
</script>
6+
7+
<div>
8+
@if(jobs.length === 0)
9+
<div class='empty-state'>No jobs to display.</div>
10+
@else
11+
<table>
12+
<thead>
13+
<tr>
14+
<th>ID</th>
15+
<th>Queue</th>
16+
<th>Name</th>
17+
<th>Status</th>
18+
<th class='text-right'>Attempts</th>
19+
<th>Created</th>
20+
<th class='text-right'>Duration</th>
21+
</tr>
22+
</thead>
23+
<tbody>
24+
@foreach(jobs as job)
25+
<tr>
26+
<td class='mono' style='font-size: 0.75rem;'>{{ job.id }}</td>
27+
<td>{{ job.queue }}</td>
28+
<td style='color: var(--text); font-weight: 500;'>{{ job.name }}</td>
29+
<td>
30+
<span class='badge {{ job.status === \'completed\' ? \'badge-success\' : job.status === \'failed\' ? \'badge-error\' : job.status === \'active\' ? \'badge-info\' : job.status === \'waiting\' ? \'badge-warning\' : \'badge-muted\' }}'>{{ job.status }}</span>
31+
</td>
32+
<td class='text-right tabular-nums'>{{ job.attempts }}/{{ job.maxAttempts }}</td>
33+
<td style='font-size: 0.75rem;'>{{ job.createdAt }}</td>
34+
<td class='text-right mono tabular-nums' style='font-size: 0.75rem;'>{{ job.duration ? job.duration + 'ms' : '—' }}</td>
35+
</tr>
36+
@endforeach
37+
</tbody>
38+
</table>
39+
@endif
40+
</div>
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
<script>
2+
import type { QueueStatusData } from '../types/components'
3+
4+
const queue: QueueStatusData = {
5+
name: '',
6+
paused: false,
7+
waiting: 0,
8+
active: 0,
9+
completed: 0,
10+
failed: 0,
11+
}
12+
</script>
13+
14+
<div class='stat-card' style='padding: 1.25rem;'>
15+
<div style='display: flex; align-items: center; justify-content: space-between; margin-bottom: 0.75rem;'>
16+
<span style='font-size: 0.875rem; font-weight: 600; color: var(--text);'>{{ queue.name }}</span>
17+
@if(queue.paused)
18+
<span class='badge badge-muted'>Paused</span>
19+
@else
20+
<span class='badge badge-success'>Active</span>
21+
@endif
22+
</div>
23+
<div style='display: grid; grid-template-columns: repeat(2, 1fr); gap: 0.5rem;'>
24+
<div style='font-size: 0.75rem; color: var(--muted);'>Waiting <span style='color: var(--text2); font-weight: 500;' class='tabular-nums'>{{ queue.waiting }}</span></div>
25+
<div style='font-size: 0.75rem; color: var(--muted);'>Active <span style='color: var(--accent); font-weight: 500;' class='tabular-nums'>{{ queue.active }}</span></div>
26+
<div style='font-size: 0.75rem; color: var(--muted);'>Completed <span style='color: var(--success); font-weight: 500;' class='tabular-nums'>{{ queue.completed }}</span></div>
27+
<div style='font-size: 0.75rem; color: var(--muted);'>Failed <span style='color: var(--error); font-weight: 500;' class='tabular-nums'>{{ queue.failed }}</span></div>
28+
</div>
29+
</div>
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<script>
2+
import type { StatVariant } from '../types/components'
3+
4+
const label: string = ''
5+
const value: number = 0
6+
const variant: StatVariant = ''
7+
</script>
8+
9+
<div class='stat-card'>
10+
<div class='stat-label'>{{ label }}</div>
11+
<div class='stat-value {{ variant === \'active\' ? \'accent\' : variant === \'completed\' ? \'success\' : variant === \'failed\' ? \'error\' : \'\' }}'>{{ value }}</div>
12+
</div>

0 commit comments

Comments
 (0)