@ -1,11 +1,28 @@
< script setup lang = "ts" >
< script setup lang = "ts" >
interface TaskRow {
id : string
name : string
cronExpression : string
type : string
enabled : number
}
const { data , refresh } = await useHttpFetch ( "/api/scheduler/tasks" )
const { data , refresh } = await useHttpFetch ( "/api/scheduler/tasks" )
const stats = await useHttpFetch ( "/api/scheduler/stats" )
const stats = await useHttpFetch ( "/api/scheduler/stats" )
const taskList = computed < TaskRow [ ] > ( ( ) => ( data . value as any ) ? . list ? ? [ ] )
const registeredFunctions = computed < string [ ] > ( ( ) => ( data . value as any ) ? . registeredFunctions ? ? [ ] )
const statsData = computed ( ( ) => ( stats . data . value ? ? { } ) as {
totalTasks : number
enabledTasks : number
activeJobs : number
last24hExecutions : number
} )
const showCreateModal = ref ( false )
const showCreateModal = ref ( false )
const editingTask = ref < any > ( null )
const editingTask = ref < TaskRow | null > ( null )
const columns = [
const columns : any [ ] = [
{ key : "name" , label : "Name" } ,
{ key : "name" , label : "Name" } ,
{ key : "cronExpression" , label : "Cron" } ,
{ key : "cronExpression" , label : "Cron" } ,
{ key : "type" , label : "Type" } ,
{ key : "type" , label : "Type" } ,
@ -14,7 +31,9 @@ const columns = [
]
]
function statusBadge ( enabled : number ) {
function statusBadge ( enabled : number ) {
return enabled ? { label : "Active" , color : "green" } : { label : "Paused" , color : "gray" }
return enabled
? { label : "Active" , color : "success" as const }
: { label : "Paused" , color : "neutral" as const }
}
}
async function handleDelete ( id : string ) {
async function handleDelete ( id : string ) {
@ -62,55 +81,55 @@ function onModalClose() {
< div class = "grid grid-cols-4 gap-4 mb-6" >
< div class = "grid grid-cols-4 gap-4 mb-6" >
< div class = "rounded-lg border p-4" >
< div class = "rounded-lg border p-4" >
< div class = "text-sm text-gray-500" > Total < / div >
< div class = "text-sm text-gray-500" > Total < / div >
< div class = "text-2xl font-bold" > { { stats ? . data ? . totalTasks ? ? 0 } } < / div >
< div class = "text-2xl font-bold" > { { statsData . totalTasks ? ? 0 } } < / div >
< / div >
< / div >
< div class = "rounded-lg border p-4" >
< div class = "rounded-lg border p-4" >
< div class = "text-sm text-gray-500" > Active < / div >
< div class = "text-sm text-gray-500" > Active < / div >
< div class = "text-2xl font-bold" > { { stats ? . data ? . enabledTasks ? ? 0 } } < / div >
< div class = "text-2xl font-bold" > { { statsData . enabledTasks ? ? 0 } } < / div >
< / div >
< / div >
< div class = "rounded-lg border p-4" >
< div class = "rounded-lg border p-4" >
< div class = "text-sm text-gray-500" > Jobs Running < / div >
< div class = "text-sm text-gray-500" > Jobs Running < / div >
< div class = "text-2xl font-bold" > { { stats ? . data ? . activeJobs ? ? 0 } } < / div >
< div class = "text-2xl font-bold" > { { statsData . activeJobs ? ? 0 } } < / div >
< / div >
< / div >
< div class = "rounded-lg border p-4" >
< div class = "rounded-lg border p-4" >
< div class = "text-sm text-gray-500" > 24 h Executions < / div >
< div class = "text-sm text-gray-500" > 24 h Executions < / div >
< div class = "text-2xl font-bold" > { { stats ? . data ? . last24hExecutions ? ? 0 } } < / div >
< div class = "text-2xl font-bold" > { { statsData . last24hExecutions ? ? 0 } } < / div >
< / div >
< / div >
< / div >
< / div >
<!-- Task table -- >
<!-- Task table -- >
< div class = "rounded-lg border" >
< div class = "rounded-lg border" >
< UTable : rows = "data?.list ?? [] " :columns ="columns" >
< UTable :rows ="taskList " :columns ="columns" >
< template # enabled -data = " { row } " >
< template # enabled -data = " { row } " >
< UBadge :color ="statusBadge(row .enabled).color" variant = "subtle" >
< UBadge : color = "statusBadge((row as unknown as TaskRow) .enabled).color" variant = "subtle" >
{ { statusBadge ( row . enabled ) . label } }
{ { statusBadge ( ( row as unknown as TaskRow ) . enabled ) . label } }
< / UBadge >
< / UBadge >
< / template >
< / template >
< template # actions -data = " { row } " >
< template # actions -data = " { row : r } " >
< div class = "flex gap-1 justify-end" >
< div class = "flex gap-1 justify-end" >
< UButton
< UButton
size = "xs"
size = "xs"
variant = "ghost"
variant = "ghost"
@ click = "handleTrigger(row.id)"
@ click = "handleTrigger(( r as unkn own as TaskRow) .id)"
> Trigger < / UButton >
> Trigger < / UButton >
< UButton
< UButton
size = "xs"
size = "xs"
variant = "ghost"
variant = "ghost"
@ click = "handleToggle(row.id, !row.enabled)"
@ click = "handleToggle(( r as unkn own as TaskRow) .id, !( r as unkn own as TaskRow) .enabled)"
>
>
{ { row . enabled ? "Pause" : "Resume" } }
{ { ( r as unkn own as TaskRow ) . enabled ? "Pause" : "Resume" } }
< / UButton >
< / UButton >
< UButton
< UButton
size = "xs"
size = "xs"
variant = "ghost"
variant = "ghost"
: to = "`/admin/scheduler/${row.id}`"
: to = "`/admin/scheduler/${( r as unkn own as TaskRow) .id}`"
> Detail < / UButton >
> Detail < / UButton >
< UButton size = "xs" variant = "ghost" @click ="openEdit(row)" > Edit < / UButton >
< UButton size = "xs" variant = "ghost" @ click = "openEdit(r as unknown as TaskRow)" > Edit < / UButton >
< UButton
< UButton
size = "xs"
size = "xs"
variant = "ghost"
variant = "ghost"
color = "red "
color = "error "
@ click = "handleDelete(row.id)"
@ click = "handleDelete(( r as unkn own as TaskRow) .id)"
> Delete < / UButton >
> Delete < / UButton >
< / div >
< / div >
< / template >
< / template >
@ -121,7 +140,7 @@ function onModalClose() {
< SchedulerTaskModal
< SchedulerTaskModal
v - if = "showCreateModal"
v - if = "showCreateModal"
: task = "editingTask"
: task = "editingTask"
: registered - functions = "data?. registeredFunctions ?? [] "
: registered - functions = "registeredFunctions"
@ close = "onModalClose"
@ close = "onModalClose"
/ >
/ >
< / div >
< / div >