diff --git a/packages/core/src/backends/duplicated-job-error.ts b/packages/core/src/backends/duplicated-job-error.ts index 577d4d9..494eabe 100644 --- a/packages/core/src/backends/duplicated-job-error.ts +++ b/packages/core/src/backends/duplicated-job-error.ts @@ -10,8 +10,6 @@ import { JobData } from "../schema"; */ export class DuplicatedJobError extends Error { constructor(job: JobData) { - super( - `Job ${job.class} is duplicated, constructor args: ${JSON.stringify(job.constructor_args)} args: ${JSON.stringify(job.args)}`, - ); + super(`Job #${job.id} - ${job.class} is duplicated`); } } diff --git a/packages/core/src/transitions/cancel-transition.ts b/packages/core/src/transitions/cancel-transition.ts index 72a8723..76555f5 100644 --- a/packages/core/src/transitions/cancel-transition.ts +++ b/packages/core/src/transitions/cancel-transition.ts @@ -1,3 +1,4 @@ +import { logger } from "../logger"; import { JobData } from "../schema"; import { JobTransition } from "./transition"; @@ -15,6 +16,7 @@ import { JobTransition } from "./transition"; */ export class CancelTransition extends JobTransition { apply(job: JobData): JobData { + logger("Core").info(`Cancelling job #${job.id} - ${job.class}`); job.state = "canceled"; job.canceled_at = new Date(); return job; diff --git a/packages/core/src/transitions/complete-transition.ts b/packages/core/src/transitions/complete-transition.ts index a067636..37960c7 100644 --- a/packages/core/src/transitions/complete-transition.ts +++ b/packages/core/src/transitions/complete-transition.ts @@ -24,7 +24,7 @@ export class CompleteTransition extends JobTransition { } apply(job: JobData): JobData { - logger("Core").info(`Job ${job.class} has completed with args: ${JSON.stringify(job.args)}`); + logger("Core").info(`Job #${job.id} - ${job.class} has completed`); job.completed_at = new Date(); job.state = "completed"; job.result = this.result ?? null; diff --git a/packages/core/src/transitions/rerun-transition.ts b/packages/core/src/transitions/rerun-transition.ts index 2616711..93fc4c6 100644 --- a/packages/core/src/transitions/rerun-transition.ts +++ b/packages/core/src/transitions/rerun-transition.ts @@ -11,7 +11,7 @@ import { JobTransition } from "./transition"; */ export class RerunTransition extends JobTransition { apply(job: JobData): JobData { - logger("Core").debug(`Re-running job ${job.class} with args: ${JSON.stringify(job.args)}`); + logger("Core").info(`Re-running job #${job.id} - ${job.class}`); // Reset job state to waiting job.state = "waiting"; diff --git a/packages/core/src/transitions/retry-transition.ts b/packages/core/src/transitions/retry-transition.ts index af53f00..7e12809 100644 --- a/packages/core/src/transitions/retry-transition.ts +++ b/packages/core/src/transitions/retry-transition.ts @@ -43,7 +43,7 @@ export class RetryTransition extends JobTransition { const reason = toErrorData(this.reason); const delay = this.delay ?? this.calculateBackoff(job.attempt); - logger("Core").info(`Retrying failed job ${job.class} in ${delay}ms`); + logger("Core").info(`Retrying failed job #${job.id} - ${job.class} in ${delay}ms`); const errData = { ...reason, diff --git a/packages/core/src/transitions/run-transition.ts b/packages/core/src/transitions/run-transition.ts index 6d60f62..c60d9ba 100644 --- a/packages/core/src/transitions/run-transition.ts +++ b/packages/core/src/transitions/run-transition.ts @@ -14,7 +14,7 @@ import { JobTransition } from "./transition"; */ export class RunTransition extends JobTransition { apply(job: JobData): JobData { - logger("Core").info(`Running job #${job.id} - ${job.class} with args: ${JSON.stringify(job.args)}`); + logger("Core").info(`Running job #${job.id} - ${job.class}`); job.state = "running"; job.attempted_at = new Date(); job.attempt = job.attempt + 1; diff --git a/packages/core/src/transitions/snooze-transition.ts b/packages/core/src/transitions/snooze-transition.ts index 7d2de5a..8bcd5c5 100644 --- a/packages/core/src/transitions/snooze-transition.ts +++ b/packages/core/src/transitions/snooze-transition.ts @@ -26,7 +26,7 @@ export class SnoozeTransition extends JobTransition { } apply(job: JobData): JobData { - logger("Core").info(`Job ${job.class} snoozed by ${this.delay}ms`); + logger("Core").info(`Job #${job.id} - ${job.class} snoozed by ${this.delay}ms`); // Attempts are only decremented if the job is running and has already been attempted // This means that the job will not consider the current run as an attempt diff --git a/packages/dashboard/src/public/js/job.js b/packages/dashboard/src/public/js/job.js index 67f751c..01e8bef 100644 --- a/packages/dashboard/src/public/js/job.js +++ b/packages/dashboard/src/public/js/job.js @@ -1,43 +1,36 @@ +// Global variable to store details state +let globalDetailsStates = {}; + function applySeeMore() { document.querySelectorAll(".sq-code").forEach((container) => { const content = container.querySelector(".code-content"); const btn = container.querySelector(".toggle-btn"); const maxHeight = 240; - let expanded = false; if (content.scrollHeight <= maxHeight) { btn.classList.add("hidden"); } - btn.addEventListener("click", () => { - expanded = !expanded; - + function toggleDetails(expanded) { if (expanded) { content.classList.remove("max-h-[15rem]", "overflow-hidden"); btn.textContent = "See less"; + globalDetailsStates[container.id] = true; // Save state as expanded } else { content.classList.add("max-h-[15rem]", "overflow-hidden"); btn.textContent = "See more"; + globalDetailsStates[container.id] = false; // Save state as not expanded } + } + + toggleDetails(globalDetailsStates[container.id] !== undefined ? globalDetailsStates[container.id] : false); + + btn.addEventListener("click", () => { + toggleDetails(globalDetailsStates[container.id] !== undefined ? !globalDetailsStates[container.id] : true); }); }); } document.addEventListener("DOMContentLoaded", applySeeMore); document.addEventListener("htmx:afterSwap", applySeeMore); - -document.addEventListener("htmx:beforeSwap", (evt) => { - const detailsStates = Array.from(document.querySelectorAll("#job-details details")).map((d) => d.open); - - evt.detail.target.dataset.detailsStates = JSON.stringify(detailsStates); -}); - -document.addEventListener("htmx:afterSwap", (evt) => { - const detailsStates = JSON.parse(evt.detail.target.dataset.detailsStates || "[]"); - - const details = evt.target.querySelectorAll("details"); - detailsStates.forEach((isOpen, idx) => { - if (isOpen) details[idx].open = true; - }); -}); diff --git a/packages/dashboard/src/public/js/jobs.js b/packages/dashboard/src/public/js/jobs.js index 4067476..4430111 100644 --- a/packages/dashboard/src/public/js/jobs.js +++ b/packages/dashboard/src/public/js/jobs.js @@ -28,13 +28,3 @@ document.addEventListener("htmx:configRequest", (evt) => { evt.detail.parameters.end = endDate.toISOString(); } }); - -document.addEventListener("htmx:afterRequest", (evt) => { - const form = document.getElementById("filter-form"); - if (!form) return; - - const params = new URLSearchParams(new FormData(form)).toString(); - - const url = `/jobs?${params}`; - window.history.pushState({}, "", url); -}); diff --git a/packages/dashboard/src/public/js/scroll.js b/packages/dashboard/src/public/js/scroll.js new file mode 100644 index 0000000..4a2a067 --- /dev/null +++ b/packages/dashboard/src/public/js/scroll.js @@ -0,0 +1,12 @@ +let savedScrollY = 0; + +// Save and restore scroll position around HTMX swaps +document.addEventListener("DOMContentLoaded", () => { + document.addEventListener("htmx:beforeSwap", () => { + savedScrollY = document.getElementById("main-section").scrollTop; + }); + + document.addEventListener("htmx:afterSwap", () => { + document.getElementById("main-section").scrollTo({ top: savedScrollY }); + }); +}); diff --git a/packages/dashboard/src/views/layout.ejs b/packages/dashboard/src/views/layout.ejs index 88c8011..6116ab4 100644 --- a/packages/dashboard/src/views/layout.ejs +++ b/packages/dashboard/src/views/layout.ejs @@ -9,6 +9,7 @@ +