1 changed files with 124 additions and 0 deletions
@ -0,0 +1,124 @@ |
|||
<script setup lang="ts"> |
|||
const route = useRoute() |
|||
const id = route.params.id as string |
|||
|
|||
const { data, refresh } = await useHttpFetch(`/api/scheduler/tasks/${id}`) |
|||
const task = computed(() => data.value?.task) |
|||
const recentExecutions = computed(() => data.value?.recentExecutions ?? []) |
|||
|
|||
async function handleTrigger() { |
|||
await $fetch(`/api/scheduler/tasks/${id}/trigger`, { method: "POST" }) |
|||
} |
|||
|
|||
async function handleToggle() { |
|||
if (!task.value) return |
|||
await $fetch(`/api/scheduler/tasks/${id}/toggle`, { |
|||
method: "POST", |
|||
body: { enabled: !task.value.enabled }, |
|||
}) |
|||
refresh() |
|||
} |
|||
|
|||
function statusColor(status: string) { |
|||
switch (status) { |
|||
case "success": return "green" |
|||
case "failed": return "red" |
|||
case "running": return "yellow" |
|||
default: return "gray" |
|||
} |
|||
} |
|||
|
|||
function timeAgo(ts: number): string { |
|||
const diff = Date.now() - ts |
|||
const mins = Math.floor(diff / 60000) |
|||
if (mins < 1) return "just now" |
|||
if (mins < 60) return `${mins}m ago` |
|||
const hours = Math.floor(mins / 60) |
|||
if (hours < 24) return `${hours}h ago` |
|||
return `${Math.floor(hours / 24)}d ago` |
|||
} |
|||
</script> |
|||
|
|||
<template> |
|||
<div class="p-6 max-w-4xl mx-auto"> |
|||
<div class="mb-4"> |
|||
<ULink to="/admin/scheduler" class="text-sm text-gray-500">← Back to tasks</ULink> |
|||
</div> |
|||
|
|||
<div v-if="task" class="space-y-6"> |
|||
<!-- Task header --> |
|||
<div class="flex items-center justify-between"> |
|||
<div> |
|||
<h1 class="text-2xl font-bold">{{ task.name }}</h1> |
|||
<p class="text-sm text-gray-500 mt-1"> |
|||
{{ task.cronExpression }} · {{ task.type }} |
|||
</p> |
|||
</div> |
|||
<div class="flex gap-2"> |
|||
<UButton variant="outline" @click="handleTrigger">Trigger Now</UButton> |
|||
<UButton variant="outline" @click="handleToggle"> |
|||
{{ task.enabled ? 'Pause' : 'Resume' }} |
|||
</UButton> |
|||
</div> |
|||
</div> |
|||
|
|||
<!-- Task config --> |
|||
<div class="rounded-lg border p-4"> |
|||
<h2 class="font-semibold mb-3">Configuration</h2> |
|||
<dl class="grid grid-cols-2 gap-2 text-sm"> |
|||
<dt class="text-gray-500">Type</dt> |
|||
<dd>{{ task.type }}</dd> |
|||
<template v-if="task.type === 'function'"> |
|||
<dt class="text-gray-500">Function</dt> |
|||
<dd>{{ task.functionName }}</dd> |
|||
<dt class="text-gray-500">Payload</dt> |
|||
<dd><code>{{ task.functionPayload }}</code></dd> |
|||
</template> |
|||
<template v-if="task.type === 'http'"> |
|||
<dt class="text-gray-500">Method</dt> |
|||
<dd>{{ task.httpMethod }}</dd> |
|||
<dt class="text-gray-500">URL</dt> |
|||
<dd>{{ task.httpUrl }}</dd> |
|||
</template> |
|||
<dt class="text-gray-500">Catch Up</dt> |
|||
<dd>{{ task.catchUp ? 'Yes' : 'No' }}</dd> |
|||
<dt class="text-gray-500">Retries</dt> |
|||
<dd>{{ task.maxRetries }}</dd> |
|||
<dt class="text-gray-500">Timeout</dt> |
|||
<dd>{{ task.timeoutSeconds }}s</dd> |
|||
<dt class="text-gray-500">Created</dt> |
|||
<dd>{{ new Date(task.createdAt).toLocaleString() }}</dd> |
|||
</dl> |
|||
</div> |
|||
|
|||
<!-- Execution history --> |
|||
<div class="rounded-lg border"> |
|||
<h2 class="font-semibold p-4 border-b">Recent Executions</h2> |
|||
<div v-if="recentExecutions.length === 0" class="p-4 text-sm text-gray-400"> |
|||
No executions yet |
|||
</div> |
|||
<div v-else> |
|||
<div |
|||
v-for="log in recentExecutions" |
|||
:key="log.id" |
|||
class="flex items-center gap-3 p-3 border-b last:border-b-0" |
|||
> |
|||
<UBadge :color="statusColor(log.status)" variant="subtle" size="sm"> |
|||
{{ log.status }} |
|||
</UBadge> |
|||
<span class="text-sm text-gray-500 flex-1"> |
|||
{{ timeAgo(log.startedAt) }} |
|||
</span> |
|||
<span v-if="log.resultSummary" class="text-sm text-gray-600"> |
|||
{{ log.resultSummary }} |
|||
</span> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
|
|||
<div v-else-if="data" class="text-gray-400"> |
|||
Task not found. |
|||
</div> |
|||
</div> |
|||
</template> |
|||
Loading…
Reference in new issue