From ee65444717e88cdaee964a8bcade3a341c157dbb Mon Sep 17 00:00:00 2001 From: Sam Chau Date: Sun, 18 Jan 2026 17:32:57 +1030 Subject: [PATCH] refactor: remove old card view for jobs, replace with expandable table. Use table comp for history --- src/routes/settings/jobs/+page.svelte | 237 +++++++++++++++- .../settings/jobs/components/JobCard.svelte | 260 ------------------ .../jobs/components/JobHistory.svelte | 171 +++--------- 3 files changed, 268 insertions(+), 400 deletions(-) delete mode 100644 src/routes/settings/jobs/components/JobCard.svelte diff --git a/src/routes/settings/jobs/+page.svelte b/src/routes/settings/jobs/+page.svelte index ed0dfd3..fbb26be 100644 --- a/src/routes/settings/jobs/+page.svelte +++ b/src/routes/settings/jobs/+page.svelte @@ -1,9 +1,75 @@
@@ -15,17 +81,164 @@

- -
- {#each data.jobs as job (job.id)} - - {:else} -
-

No background jobs configured

-
- {/each} + +
+ job.id} + emptyMessage="No background jobs configured" + flushExpanded + chevronPosition="right" + > + + {#if column.key === 'name'} + {formatJobName(row.name)} + {:else if column.key === 'enabled'} + + {row.enabled ? 'Enabled' : 'Disabled'} + + {:else if column.key === 'scheduleDisplay'} + {row.scheduleDisplay} + {:else if column.key === 'last_run_at'} +
+ {getRelativeTime(row.last_run_at)} + {#if row.last_run_status === 'success'} + Success + {:else if row.last_run_status === 'failure'} + Failed + {/if} +
+ {:else if column.key === 'next_run_at'} + {#if row.enabled} + {getRelativeTime(row.next_run_at)} + {:else} + - + {/if} + {/if} +
+ + +
+ + + + + + +
{ + return async ({ result, update }) => { + if (result.type === 'failure' && result.data) { + alertStore.add( + 'error', + (result.data as { error?: string }).error || 'Failed to trigger job' + ); + } else if (result.type === 'success') { + alertStore.add('success', `Job "${formatJobName(row.name)}" triggered`); + } + await update(); + }; + }} + > + + +
+ + +
{ + return async ({ result, update }) => { + if (result.type === 'failure' && result.data) { + alertStore.add( + 'error', + (result.data as { error?: string }).error || 'Failed to update job' + ); + } else if (result.type === 'success') { + alertStore.add('success', `Job ${row.enabled ? 'disabled' : 'enabled'}`); + } + await update(); + }; + }} + > + + + +
+
+
+ + +
+ + {#if row.description} +

{row.description}

+ {/if} + +
+ +
+
+ Last Run +
+
+ {formatDateTime(row.last_run_at)} +
+
+ + +
+
+ Duration +
+
+ {formatDuration(row.last_run_duration)} +
+
+ + +
+
+ Next Run +
+
+ {#if row.enabled} + {formatDateTime(row.next_run_at)} + {:else} + Disabled + {/if} +
+
+
+ + + {#if row.last_run_error} +
+ +
+
Last Run Error
+
{row.last_run_error}
+
+
+ {/if} +
+
+
diff --git a/src/routes/settings/jobs/components/JobCard.svelte b/src/routes/settings/jobs/components/JobCard.svelte deleted file mode 100644 index a7c0bf4..0000000 --- a/src/routes/settings/jobs/components/JobCard.svelte +++ /dev/null @@ -1,260 +0,0 @@ - - -
- -
-
-
-
-

- {formatJobName(job.name)} -

- - - - {job.enabled ? 'Enabled' : 'Disabled'} - -
- - {#if job.description} -

- {job.description} -

- {/if} -
- - -
- - - - - - -
{ - return async ({ result, update }) => { - if (result.type === 'failure' && result.data) { - alertStore.add( - 'error', - (result.data as { error?: string }).error || 'Failed to trigger job' - ); - } else if (result.type === 'success') { - alertStore.add('success', `Job "${formatJobName(job.name)}" triggered successfully`); - } - await update(); - }; - }} - > - - -
- - -
{ - return async ({ result, update }) => { - if (result.type === 'failure' && result.data) { - alertStore.add( - 'error', - (result.data as { error?: string }).error || 'Failed to update job' - ); - } else if (result.type === 'success') { - alertStore.add('success', `Job ${job.enabled ? 'disabled' : 'enabled'}`); - } - await update(); - }; - }} - > - - - -
-
-
-
- - -
- - - - - - - - - - - - - - - - - - - - -
- Schedule - - Last Run - - Next Run -
- - {job.scheduleDisplay} - - -
-
- - {formatDateTime(job.last_run_at)} - - {#if job.last_run_status === 'success'} - - - Success - - {:else if job.last_run_status === 'failure'} - - - Failed - - {/if} -
- {#if job.last_run_duration} -
- Duration: {formatDuration(job.last_run_duration)} -
- {/if} - {#if job.last_run_error} -
- - {job.last_run_error} -
- {/if} -
-
-
- - {getRelativeTime(job.next_run_at)} - -
- {formatDateTime(job.next_run_at)} -
-
-
-
-
diff --git a/src/routes/settings/jobs/components/JobHistory.svelte b/src/routes/settings/jobs/components/JobHistory.svelte index 6a5dc84..27ff725 100644 --- a/src/routes/settings/jobs/components/JobHistory.svelte +++ b/src/routes/settings/jobs/components/JobHistory.svelte @@ -1,7 +1,10 @@ -
- -
-
- -

Recent Job Runs

-
+
+
+ +

Recent Job Runs

- -
- - - - - - - - - - - - {#each jobRuns as run (run.id)} - - - - - - - - - - - - - - - - +
- Job - - Status - - Started - - Duration - - Output -
- {formatJobName(run.job_name)} - - {#if run.status === 'success'} - - - Success - - {:else} - - - Failed - - {/if} - -
- - {getRelativeTime(run.started_at)} - - - {formatDateTime(run.started_at)} - -
-
- - {formatDuration(run.duration_ms)} - - - {#if run.error} -
- {run.error} -
- {:else if run.output} - {run.output} - {:else} - - - {/if} -
+ + {#if column.key === 'job_name'} + {formatJobName(row.job_name)} + {:else if column.key === 'status'} + {#if row.status === 'success'} + Success {:else} - - - - {/each} - -
- No job runs yet -
-
+ Failed + {/if} + {:else if column.key === 'started_at'} + {getRelativeTime(row.started_at)} + {:else if column.key === 'duration_ms'} + {formatDuration(row.duration_ms)} + {:else if column.key === 'output'} + {#if row.error} + {row.error} + {:else if row.output} + {row.output} + {:else} + - + {/if} + {/if} + +