1 changed files with 128 additions and 0 deletions
@ -0,0 +1,128 @@ |
|||||
|
<script setup lang="ts"> |
||||
|
const { data, refresh } = await useHttpFetch("/api/scheduler/tasks") |
||||
|
const stats = await useHttpFetch("/api/scheduler/stats") |
||||
|
|
||||
|
const showCreateModal = ref(false) |
||||
|
const editingTask = ref<any>(null) |
||||
|
|
||||
|
const columns = [ |
||||
|
{ key: "name", label: "Name" }, |
||||
|
{ key: "cronExpression", label: "Cron" }, |
||||
|
{ key: "type", label: "Type" }, |
||||
|
{ key: "enabled", label: "Status" }, |
||||
|
{ key: "actions", label: "" }, |
||||
|
] |
||||
|
|
||||
|
function statusBadge(enabled: number) { |
||||
|
return enabled ? { label: "Active", color: "green" } : { label: "Paused", color: "gray" } |
||||
|
} |
||||
|
|
||||
|
async function handleDelete(id: string) { |
||||
|
await $fetch(`/api/scheduler/tasks/${id}`, { method: "DELETE" }) |
||||
|
refresh() |
||||
|
} |
||||
|
|
||||
|
async function handleToggle(id: string, enabled: boolean) { |
||||
|
await $fetch(`/api/scheduler/tasks/${id}/toggle`, { |
||||
|
method: "POST", |
||||
|
body: { enabled }, |
||||
|
}) |
||||
|
refresh() |
||||
|
} |
||||
|
|
||||
|
async function handleTrigger(id: string) { |
||||
|
await $fetch(`/api/scheduler/tasks/${id}/trigger`, { method: "POST" }) |
||||
|
} |
||||
|
|
||||
|
function openEdit(task: any) { |
||||
|
editingTask.value = task |
||||
|
showCreateModal.value = true |
||||
|
} |
||||
|
|
||||
|
function openCreate() { |
||||
|
editingTask.value = null |
||||
|
showCreateModal.value = true |
||||
|
} |
||||
|
|
||||
|
function onModalClose() { |
||||
|
showCreateModal.value = false |
||||
|
editingTask.value = null |
||||
|
refresh() |
||||
|
} |
||||
|
</script> |
||||
|
|
||||
|
<template> |
||||
|
<div class="p-6 max-w-6xl mx-auto"> |
||||
|
<div class="flex items-center justify-between mb-6"> |
||||
|
<h1 class="text-2xl font-bold">Scheduled Tasks</h1> |
||||
|
<UButton @click="openCreate">Create Task</UButton> |
||||
|
</div> |
||||
|
|
||||
|
<!-- Stats bar --> |
||||
|
<div class="grid grid-cols-4 gap-4 mb-6"> |
||||
|
<div class="rounded-lg border p-4"> |
||||
|
<div class="text-sm text-gray-500">Total</div> |
||||
|
<div class="text-2xl font-bold">{{ stats?.data?.totalTasks ?? 0 }}</div> |
||||
|
</div> |
||||
|
<div class="rounded-lg border p-4"> |
||||
|
<div class="text-sm text-gray-500">Active</div> |
||||
|
<div class="text-2xl font-bold">{{ stats?.data?.enabledTasks ?? 0 }}</div> |
||||
|
</div> |
||||
|
<div class="rounded-lg border p-4"> |
||||
|
<div class="text-sm text-gray-500">Jobs Running</div> |
||||
|
<div class="text-2xl font-bold">{{ stats?.data?.activeJobs ?? 0 }}</div> |
||||
|
</div> |
||||
|
<div class="rounded-lg border p-4"> |
||||
|
<div class="text-sm text-gray-500">24h Executions</div> |
||||
|
<div class="text-2xl font-bold">{{ stats?.data?.last24hExecutions ?? 0 }}</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
|
||||
|
<!-- Task table --> |
||||
|
<div class="rounded-lg border"> |
||||
|
<UTable :rows="data?.list ?? []" :columns="columns"> |
||||
|
<template #enabled-data="{ row }"> |
||||
|
<UBadge :color="statusBadge(row.enabled).color" variant="subtle"> |
||||
|
{{ statusBadge(row.enabled).label }} |
||||
|
</UBadge> |
||||
|
</template> |
||||
|
<template #actions-data="{ row }"> |
||||
|
<div class="flex gap-1 justify-end"> |
||||
|
<UButton |
||||
|
size="xs" |
||||
|
variant="ghost" |
||||
|
@click="handleTrigger(row.id)" |
||||
|
>Trigger</UButton> |
||||
|
<UButton |
||||
|
size="xs" |
||||
|
variant="ghost" |
||||
|
@click="handleToggle(row.id, !row.enabled)" |
||||
|
> |
||||
|
{{ row.enabled ? "Pause" : "Resume" }} |
||||
|
</UButton> |
||||
|
<UButton |
||||
|
size="xs" |
||||
|
variant="ghost" |
||||
|
:to="`/admin/scheduler/${row.id}`" |
||||
|
>Detail</UButton> |
||||
|
<UButton size="xs" variant="ghost" @click="openEdit(row)">Edit</UButton> |
||||
|
<UButton |
||||
|
size="xs" |
||||
|
variant="ghost" |
||||
|
color="red" |
||||
|
@click="handleDelete(row.id)" |
||||
|
>Delete</UButton> |
||||
|
</div> |
||||
|
</template> |
||||
|
</UTable> |
||||
|
</div> |
||||
|
|
||||
|
<!-- Create/Edit Modal --> |
||||
|
<SchedulerTaskModal |
||||
|
v-if="showCreateModal" |
||||
|
:task="editingTask" |
||||
|
:registered-functions="data?.registeredFunctions ?? []" |
||||
|
@close="onModalClose" |
||||
|
/> |
||||
|
</div> |
||||
|
</template> |
||||
Loading…
Reference in new issue