Skip to content

Commit 772a5a1

Browse files
committed
chore: wip
1 parent 2a3ddaf commit 772a5a1

File tree

3 files changed

+366
-86
lines changed

3 files changed

+366
-86
lines changed

storage/framework/defaults/views/dashboard/jobs/[id].vue

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,11 @@ interface JobDetails {
3131
file: string
3232
line: number
3333
}
34+
logs?: Array<{
35+
timestamp: string
36+
level: 'info' | 'warning' | 'error'
37+
message: string
38+
}>
3439
}
3540
3641
const job = ref<JobDetails | null>(null)
@@ -53,6 +58,18 @@ const getJobStatusColor = (status: string): string => {
5358
return jobStatusColors[status] || 'text-gray-700 dark:text-gray-300 bg-gray-50 dark:bg-gray-900/50 ring-gray-600/20'
5459
}
5560
61+
const getLogLevelColor = (level: string | undefined): string => {
62+
if (!level) return 'text-gray-600 dark:text-gray-400'
63+
switch (level) {
64+
case 'error':
65+
return 'text-red-600 dark:text-red-400'
66+
case 'warning':
67+
return 'text-yellow-600 dark:text-yellow-400'
68+
default:
69+
return 'text-gray-600 dark:text-gray-400'
70+
}
71+
}
72+
5673
const handleRetry = async () => {
5774
// Implement retry logic
5875
console.log('Retrying job:', route.params.id)
@@ -122,6 +139,12 @@ onMounted(async () => {
122139
'#2 /vendor/laravel/framework/src/Illuminate/Queue/Jobs/Job.php(88): CallQueuedHandler->call()',
123140
]
124141
},
142+
logs: [
143+
{ timestamp: '2024-03-14 10:15:23', level: 'info', message: 'Starting payment processing' },
144+
{ timestamp: '2024-03-14 10:15:24', level: 'info', message: 'Validating payment details' },
145+
{ timestamp: '2024-03-14 10:15:25', level: 'warning', message: 'Slow response from payment gateway' },
146+
{ timestamp: '2024-03-14 10:15:28', level: 'error', message: 'Connection timeout while processing payment' }
147+
],
125148
}
126149
} catch (error) {
127150
console.error('Failed to load job details:', error)
@@ -268,6 +291,24 @@ onMounted(async () => {
268291
</div>
269292
</div>
270293

294+
<!-- Logs -->
295+
<div v-if="job.logs?.length" class="bg-white dark:bg-blue-gray-700 shadow rounded-lg">
296+
<div class="px-4 py-5 sm:p-6">
297+
<h3 class="text-base font-semibold leading-6 text-gray-900 dark:text-gray-100 mb-4">Logs</h3>
298+
<div class="space-y-2">
299+
<div
300+
v-for="log in job.logs"
301+
:key="log.timestamp"
302+
class="flex items-start gap-2 text-sm font-mono"
303+
>
304+
<span class="text-gray-500 dark:text-gray-400 shrink-0">{{ log.timestamp }}</span>
305+
<span :class="getLogLevelColor(log.level)" class="shrink-0">[{{ log.level }}]</span>
306+
<span class="text-gray-900 dark:text-gray-100">{{ log.message }}</span>
307+
</div>
308+
</div>
309+
</div>
310+
</div>
311+
271312
<!-- Performance -->
272313
<div class="bg-white dark:bg-blue-gray-700 shadow rounded-lg">
273314
<div class="px-4 py-5 sm:p-6">

storage/framework/defaults/views/dashboard/jobs/index.vue

Lines changed: 163 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -40,50 +40,100 @@ interface JobStats {
4040
runtime?: number
4141
error?: string
4242
payload: any
43+
priority: number
44+
tags: string[]
45+
dependencies?: string[]
46+
retry_history?: {
47+
attempted_at: string
48+
failed_at: string
49+
error: string
50+
}[]
51+
stack_trace?: string
52+
}
53+
54+
interface RetryAttempt {
55+
attempted_at: string
56+
error: string
4357
}
4458
4559
interface Job {
4660
id: string
4761
name: string
62+
status: 'queued' | 'processing' | 'completed' | 'failed'
4863
queue: string
49-
status: 'queued' | 'processing' | 'failed' | 'completed'
50-
runtime?: number
64+
payload: any
65+
created_at: string
5166
started_at?: string
67+
completed_at?: string
68+
error?: string
69+
stack_trace?: string
70+
tags?: string[]
71+
priority?: number
72+
dependencies?: string[]
73+
retry_history?: RetryAttempt[]
74+
attempts: number
75+
runtime?: number
76+
logs?: Array<{
77+
timestamp: string
78+
level: 'info' | 'warning' | 'error'
79+
message: string
80+
}>
5281
}
5382
54-
const recentJobs = ref<JobStats[]>([
83+
const recentJobs = ref<Job[]>([
5584
{
5685
id: '1',
57-
name: 'ProcessPayment',
58-
queue: 'high',
59-
attempts: 1,
86+
name: 'ProcessPodcast',
6087
status: 'completed',
61-
started_at: '2024-03-14 10:15:23',
62-
finished_at: '2024-03-14 10:15:25',
63-
runtime: 2.3,
64-
payload: { order_id: '12345' },
88+
queue: 'default',
89+
payload: { podcast_id: 123 },
90+
created_at: '2024-03-14 10:00:00',
91+
started_at: '2024-03-14 10:00:01',
92+
completed_at: '2024-03-14 10:00:05',
93+
attempts: 1,
94+
runtime: 4.2,
95+
tags: ['podcast', 'media'],
96+
priority: 1,
97+
logs: [
98+
{ timestamp: '2024-03-14 10:00:01', level: 'info', message: 'Starting podcast processing' },
99+
{ timestamp: '2024-03-14 10:00:03', level: 'info', message: 'Transcoding audio file' },
100+
{ timestamp: '2024-03-14 10:00:05', level: 'info', message: 'Podcast processing completed' }
101+
]
65102
},
66103
{
67104
id: '2',
68-
name: 'SendWelcomeEmail',
69-
queue: 'default',
70-
attempts: 3,
105+
name: 'SendNewsletter',
71106
status: 'failed',
72-
started_at: '2024-03-14 10:14:00',
73-
finished_at: '2024-03-14 10:14:05',
74-
runtime: 5.1,
107+
queue: 'high',
108+
payload: { newsletter_id: 456 },
109+
created_at: '2024-03-14 10:01:00',
110+
started_at: '2024-03-14 10:01:01',
75111
error: 'SMTP connection failed',
76-
payload: { user_id: '789' },
77-
},
78-
{
79-
id: '3',
80-
name: 'GenerateReport',
81-
queue: 'low',
82-
attempts: 1,
83-
status: 'processing',
84-
started_at: '2024-03-14 10:16:00',
85-
payload: { report_type: 'monthly' },
86-
},
112+
stack_trace: 'Error: SMTP connection failed\n at SMTPClient.connect (/app/vendor/smtp.js:123)\n at Newsletter.send (/app/app/Jobs/SendNewsletter.php:45)',
113+
attempts: 3,
114+
tags: ['email', 'newsletter'],
115+
priority: 2,
116+
retry_history: [
117+
{
118+
attempted_at: '2024-03-14 10:01:01',
119+
error: 'SMTP connection timeout'
120+
},
121+
{
122+
attempted_at: '2024-03-14 10:02:01',
123+
error: 'SMTP authentication failed'
124+
},
125+
{
126+
attempted_at: '2024-03-14 10:03:01',
127+
error: 'SMTP connection failed'
128+
}
129+
],
130+
logs: [
131+
{ timestamp: '2024-03-14 10:01:01', level: 'info', message: 'Starting newsletter delivery' },
132+
{ timestamp: '2024-03-14 10:01:01', level: 'warning', message: 'SMTP connection timeout' },
133+
{ timestamp: '2024-03-14 10:02:01', level: 'warning', message: 'SMTP authentication failed' },
134+
{ timestamp: '2024-03-14 10:03:01', level: 'error', message: 'SMTP connection failed' }
135+
]
136+
}
87137
])
88138
89139
const timeRange = ref<'hour' | 'day' | 'week'>('hour')
@@ -214,9 +264,50 @@ onMounted(async () => {
214264
isLoading.value = false
215265
})
216266
217-
const handleRetry = async (job: Job) => {
218-
// Implement retry logic
219-
console.log('Retrying job:', job.id)
267+
const retryJob = async (jobId: string) => {
268+
isLoading.value = true
269+
await new Promise(resolve => setTimeout(resolve, 1000))
270+
const job = recentJobs.value.find(j => j.id === jobId)
271+
if (job) {
272+
job.status = 'queued'
273+
job.attempts += 1
274+
}
275+
isLoading.value = false
276+
}
277+
278+
const cancelJob = async (jobId: string) => {
279+
isLoading.value = true
280+
await new Promise(resolve => setTimeout(resolve, 1000))
281+
const job = recentJobs.value.find(j => j.id === jobId)
282+
if (job) {
283+
job.status = 'failed'
284+
job.error = 'Job cancelled by user'
285+
}
286+
isLoading.value = false
287+
}
288+
289+
// Add state for expanded job rows
290+
const expandedJobs = ref<Set<string>>(new Set())
291+
292+
// Toggle job expansion
293+
const toggleJobExpansion = (jobId: string) => {
294+
if (expandedJobs.value.has(jobId)) {
295+
expandedJobs.value.delete(jobId)
296+
} else {
297+
expandedJobs.value.add(jobId)
298+
}
299+
}
300+
301+
// Get log level color classes
302+
const getLogLevelColor = (level: string): string => {
303+
switch (level) {
304+
case 'error':
305+
return 'text-red-600 dark:text-red-400'
306+
case 'warning':
307+
return 'text-yellow-600 dark:text-yellow-400'
308+
default:
309+
return 'text-gray-600 dark:text-gray-400'
310+
}
220311
}
221312
</script>
222313

@@ -371,45 +462,54 @@ const handleRetry = async (job: Job) => {
371462
<th scope="col" class="px-3 py-3.5 text-left text-sm font-semibold text-gray-900 dark:text-gray-100">Queue</th>
372463
<th scope="col" class="px-3 py-3.5 text-left text-sm font-semibold text-gray-900 dark:text-gray-100">Status</th>
373464
<th scope="col" class="px-3 py-3.5 text-left text-sm font-semibold text-gray-900 dark:text-gray-100">Runtime</th>
374-
<th scope="col" class="px-3 py-3.5 text-right text-sm font-semibold text-gray-900 dark:text-gray-100">Started</th>
465+
<th scope="col" class="px-3 py-3.5 text-left text-sm font-semibold text-gray-900 dark:text-gray-100">Started</th>
375466
<th scope="col" class="relative py-3.5 pl-3 pr-4 sm:pr-0">
376467
<span class="sr-only">Actions</span>
377468
</th>
378469
</tr>
379470
</thead>
380471
<tbody class="divide-y divide-gray-200 dark:divide-blue-gray-600">
381-
<tr v-for="job in recentJobs" :key="job.id">
382-
<td class="whitespace-nowrap py-4 pl-4 pr-3 text-sm font-medium text-gray-900 dark:text-gray-100 sm:pl-0">{{ job.name }}</td>
383-
<td class="whitespace-nowrap px-3 py-4 text-sm text-gray-500 dark:text-gray-400">{{ job.queue }}</td>
384-
<td class="whitespace-nowrap px-3 py-4 text-sm">
385-
<span
386-
class="inline-flex items-center rounded-md px-2 py-1 text-xs font-medium ring-1 ring-inset"
387-
:class="getJobStatusColor(job.status)"
388-
>
389-
{{ job.status }}
390-
</span>
391-
</td>
392-
<td class="whitespace-nowrap px-3 py-4 text-sm text-gray-500 dark:text-gray-400 font-mono">{{ job.runtime ? `${job.runtime.toFixed(1)}s` : '-' }}</td>
393-
<td class="whitespace-nowrap px-3 py-4 text-sm text-gray-500 dark:text-gray-400 text-right">{{ job.started_at }}</td>
394-
<td class="relative whitespace-nowrap py-4 pl-3 pr-4 text-right text-sm font-medium sm:pr-0">
395-
<div class="flex justify-end space-x-2">
396-
<router-link
397-
:to="`/jobs/${job.id}`"
398-
class="text-blue-600 hover:text-blue-900 dark:text-blue-400 dark:hover:text-blue-300"
399-
>
400-
View
401-
</router-link>
402-
<button
403-
v-if="job.status === 'failed'"
404-
type="button"
405-
class="text-blue-600 hover:text-blue-900 dark:text-blue-400 dark:hover:text-blue-300"
406-
@click="handleRetry(job)"
407-
>
408-
Retry
409-
</button>
410-
</div>
411-
</td>
412-
</tr>
472+
<template v-for="job in recentJobs" :key="job.id">
473+
<tr>
474+
<td class="whitespace-nowrap py-4 pl-4 pr-3 text-sm sm:pl-0">
475+
<div class="font-medium text-gray-900 dark:text-gray-100">{{ job.name }}</div>
476+
<div class="mt-1 flex items-center gap-1">
477+
<span v-for="tag in job.tags" :key="tag" class="inline-flex items-center rounded-md px-2 py-1 text-xs font-medium ring-1 ring-inset bg-blue-50 text-blue-700 ring-blue-600/20 dark:bg-blue-900/50 dark:text-blue-300">
478+
{{ tag }}
479+
</span>
480+
</div>
481+
</td>
482+
<td class="whitespace-nowrap px-3 py-4 text-sm">
483+
<div class="text-gray-900 dark:text-gray-100">{{ job.queue }}</div>
484+
<div class="mt-1 text-gray-500 dark:text-gray-400">Priority: {{ job.priority }}</div>
485+
</td>
486+
<td class="whitespace-nowrap px-3 py-4 text-sm">
487+
<span class="inline-flex items-center rounded-md px-2 py-1 text-xs font-medium ring-1 ring-inset" :class="getJobStatusColor(job.status)">
488+
{{ job.status }}
489+
</span>
490+
<div v-if="job.status === 'failed'" class="mt-1 text-xs text-red-600 dark:text-red-400">
491+
Attempts: {{ job.attempts }}
492+
</div>
493+
</td>
494+
<td class="whitespace-nowrap px-3 py-4 text-sm">
495+
<div class="font-mono text-gray-900 dark:text-gray-100">{{ job.runtime ? `${job.runtime.toFixed(1)}s` : '-' }}</div>
496+
</td>
497+
<td class="whitespace-nowrap px-3 py-4 text-sm text-gray-500 dark:text-gray-400">
498+
<div>Started: {{ job.started_at || '-' }}</div>
499+
<div>Completed: {{ job.completed_at || '-' }}</div>
500+
</td>
501+
<td class="relative whitespace-nowrap py-4 pl-3 pr-4 text-right text-sm font-medium sm:pr-0">
502+
<div class="flex justify-end space-x-2">
503+
<router-link
504+
:to="`/jobs/${job.id}`"
505+
class="text-blue-600 hover:text-blue-900 dark:text-blue-400 dark:hover:text-blue-300"
506+
>
507+
View
508+
</router-link>
509+
</div>
510+
</td>
511+
</tr>
512+
</template>
413513
</tbody>
414514
</table>
415515
</div>

0 commit comments

Comments
 (0)