From b3a60dc7f411dc94ef5f06af33f7b4a88011c611 Mon Sep 17 00:00:00 2001 From: Ben Sima Date: Thu, 13 Nov 2025 15:20:08 -0500 Subject: Add remove button to queue status items - Add 'Remove' button for non-pending queue items (error, processing, cancelled) - Keep 'Cancel' button for pending items - Update delete_queue_item to check referer and return appropriate response - Use HX-Trigger for queue updates from user page, HX-Redirect for admin - Add confirmation dialog for remove action - Allow admins to delete any job, users can only delete their own Amp-Thread-ID: https://ampcode.com/threads/T-8edacbeb-b343-49ca-b524-1c999272acb6 Co-authored-by: Amp --- .tasks/tasks.jsonl | 10 +++++----- Biz/PodcastItLater/Admin.py | 23 +++++++++++++++++++---- Biz/PodcastItLater/Web.py | 25 +++++++++++++++++++++---- 3 files changed, 45 insertions(+), 13 deletions(-) diff --git a/.tasks/tasks.jsonl b/.tasks/tasks.jsonl index 0f5f4aa..8eff7bc 100644 --- a/.tasks/tasks.jsonl +++ b/.tasks/tasks.jsonl @@ -60,10 +60,10 @@ {"taskCreatedAt":"2025-11-13T19:38:34.384489707Z","taskDependencies":[],"taskId":"t-1fbElKv","taskNamespace":null,"taskParent":"t-1f9RIzd","taskStatus":"Open","taskTitle":"Implement change email address functionality","taskType":"WorkTask","taskUpdatedAt":"2025-11-13T19:38:34.384489707Z"} {"taskCreatedAt":"2025-11-13T19:38:34.561871604Z","taskDependencies":[],"taskId":"t-1fbF5Tv","taskNamespace":null,"taskParent":"t-1f9RIzd","taskStatus":"Open","taskTitle":"Add logout button to account page","taskType":"WorkTask","taskUpdatedAt":"2025-11-13T19:38:34.561871604Z"} {"taskCreatedAt":"2025-11-13T19:38:34.777721397Z","taskDependencies":[],"taskId":"t-1fbG02X","taskNamespace":null,"taskParent":"t-1f9RIzd","taskStatus":"Open","taskTitle":"Replace Coming Soon placeholder with full account management UI","taskType":"WorkTask","taskUpdatedAt":"2025-11-13T19:38:34.777721397Z"} -{"taskCreatedAt":"2025-11-13T19:38:34.962196629Z","taskDependencies":[],"taskId":"t-1fbGM2m","taskNamespace":null,"taskParent":"t-1f9SnU7","taskStatus":"Open","taskTitle":"Add remove button to queue status items","taskType":"WorkTask","taskUpdatedAt":"2025-11-13T19:38:34.962196629Z"} -{"taskCreatedAt":"2025-11-13T19:38:35.119686179Z","taskDependencies":[],"taskId":"t-1fbHr0w","taskNamespace":null,"taskParent":"t-1f9Td4U","taskStatus":"InProgress","taskTitle":"Remove button classes from navbar links (make them regular nav links)","taskType":"WorkTask","taskUpdatedAt":"2025-11-13T20:17:22.887631165Z"} -{"taskCreatedAt":"2025-11-13T19:38:35.311151364Z","taskDependencies":[],"taskId":"t-1fbIeOF","taskNamespace":null,"taskParent":"t-1f9Td4U","taskStatus":"Open","taskTitle":"Remove 'Logged in as' text from navbar","taskType":"WorkTask","taskUpdatedAt":"2025-11-13T19:38:35.311151364Z"} -{"taskCreatedAt":"2025-11-13T19:38:35.476139354Z","taskDependencies":[],"taskId":"t-1fbIVJL","taskNamespace":null,"taskParent":"t-1f9Td4U","taskStatus":"Open","taskTitle":"Left-align navbar links instead of right-aligned buttons","taskType":"WorkTask","taskUpdatedAt":"2025-11-13T19:38:35.476139354Z"} -{"taskCreatedAt":"2025-11-13T19:38:35.65125955Z","taskDependencies":[],"taskId":"t-1fbJFic","taskNamespace":null,"taskParent":"t-1f9Td4U","taskStatus":"Open","taskTitle":"Remove logout button from navbar (will be in account page)","taskType":"WorkTask","taskUpdatedAt":"2025-11-13T19:38:35.65125955Z"} +{"taskCreatedAt":"2025-11-13T19:38:34.962196629Z","taskDependencies":[],"taskId":"t-1fbGM2m","taskNamespace":null,"taskParent":"t-1f9SnU7","taskStatus":"InProgress","taskTitle":"Add remove button to queue status items","taskType":"WorkTask","taskUpdatedAt":"2025-11-13T20:18:22.346741808Z"} +{"taskCreatedAt":"2025-11-13T19:38:35.119686179Z","taskDependencies":[],"taskId":"t-1fbHr0w","taskNamespace":null,"taskParent":"t-1f9Td4U","taskStatus":"Done","taskTitle":"Remove button classes from navbar links (make them regular nav links)","taskType":"WorkTask","taskUpdatedAt":"2025-11-13T20:18:17.185088389Z"} +{"taskCreatedAt":"2025-11-13T19:38:35.311151364Z","taskDependencies":[],"taskId":"t-1fbIeOF","taskNamespace":null,"taskParent":"t-1f9Td4U","taskStatus":"Done","taskTitle":"Remove 'Logged in as' text from navbar","taskType":"WorkTask","taskUpdatedAt":"2025-11-13T20:18:17.23552934Z"} +{"taskCreatedAt":"2025-11-13T19:38:35.476139354Z","taskDependencies":[],"taskId":"t-1fbIVJL","taskNamespace":null,"taskParent":"t-1f9Td4U","taskStatus":"Done","taskTitle":"Left-align navbar links instead of right-aligned buttons","taskType":"WorkTask","taskUpdatedAt":"2025-11-13T20:18:17.285578917Z"} +{"taskCreatedAt":"2025-11-13T19:38:35.65125955Z","taskDependencies":[],"taskId":"t-1fbJFic","taskNamespace":null,"taskParent":"t-1f9Td4U","taskStatus":"Done","taskTitle":"Remove logout button from navbar (will be in account page)","taskType":"WorkTask","taskUpdatedAt":"2025-11-13T20:18:17.336546723Z"} {"taskCreatedAt":"2025-11-13T19:54:08.34625259Z","taskDependencies":[],"taskId":"t-1gcR9RV","taskNamespace":"Omni/Bild.nix","taskParent":null,"taskStatus":"Open","taskTitle":"Add ruff to the developer environment, the 'env' attribute in Bild.nix","taskType":"WorkTask","taskUpdatedAt":"2025-11-13T19:54:08.34625259Z"} {"taskCreatedAt":"2025-11-13T20:02:50.914482516Z","taskDependencies":[],"taskId":"t-1gMdNJK","taskNamespace":null,"taskParent":"t-1f9QP23","taskStatus":"Done","taskTitle":"Fix dev mode banner styling and pre-fill login email","taskType":"WorkTask","taskUpdatedAt":"2025-11-13T20:03:45.644107089Z"} diff --git a/Biz/PodcastItLater/Admin.py b/Biz/PodcastItLater/Admin.py index 6892234..d7a0a4e 100644 --- a/Biz/PodcastItLater/Admin.py +++ b/Biz/PodcastItLater/Admin.py @@ -625,7 +625,7 @@ def retry_queue_item(request: Request, job_id: int) -> Response: def delete_queue_item(request: Request, job_id: int) -> Response: """Delete a queue item.""" try: - # Check if user owns this job + # Check if user owns this job or is admin user_id = request.session.get("user_id") if not user_id: return Response("Unauthorized", status_code=401) @@ -633,15 +633,30 @@ def delete_queue_item(request: Request, job_id: int) -> Response: job = Core.Database.get_job_by_id( job_id, ) - if job is None or job.get("user_id") != user_id: + if job is None: + return Response("Job not found", status_code=404) + + # Check ownership or admin status + user = Core.Database.get_user_by_id(user_id) + if job.get("user_id") != user_id and not Core.is_admin(user): return Response("Forbidden", status_code=403) Core.Database.delete_job(job_id) - # Redirect back to admin view + + # Check if request is from admin page via referer header + is_from_admin = "/admin" in request.headers.get("referer", "") + + # Redirect to admin if from admin page, trigger update otherwise + if is_from_admin: + return Response( + "", + status_code=200, + headers={"HX-Redirect": "/admin"}, + ) return Response( "", status_code=200, - headers={"HX-Redirect": "/admin"}, + headers={"HX-Trigger": "queue-updated"}, ) except (ValueError, KeyError) as e: return Response( diff --git a/Biz/PodcastItLater/Web.py b/Biz/PodcastItLater/Web.py index 71970cd..f4c65b1 100644 --- a/Biz/PodcastItLater/Web.py +++ b/Biz/PodcastItLater/Web.py @@ -433,7 +433,7 @@ class QueueStatus(Component[AnyChildren, QueueStatusAttrs]): if item["error_message"] else [] ), - # Add cancel button for pending jobs + # Add cancel button for pending jobs, remove for others html.div( html.button( html.i(classes=["bi", "bi-x-lg", "me-1"]), @@ -451,11 +451,28 @@ class QueueStatus(Component[AnyChildren, QueueStatusAttrs]): "btn-outline-danger", "mt-2", ], + ) + if item["status"] == "pending" + else html.button( + html.i(classes=["bi", "bi-trash", "me-1"]), + "Remove", + hx_delete=f"/queue/{item['id']}", + hx_trigger="click", + hx_confirm="Remove this item from the queue?", + hx_on=( + "htmx:afterRequest: " + "if(event.detail.successful) " + "htmx.trigger('body', 'queue-updated')" + ), + classes=[ + "btn", + "btn-sm", + "btn-outline-secondary", + "mt-2", + ], ), classes=["mt-2"], - ) - if item["status"] == "pending" - else html.div(), + ), classes=["card-body"], ), classes=["card", "mb-2"], -- cgit v1.2.3