From e42e28992ae250153410b10b6f49cd7e1e89ab54 Mon Sep 17 00:00:00 2001 From: Claudio Ortolina Date: Tue, 19 May 2026 12:51:19 +0100 Subject: [PATCH] ML-169.10: add optimistic delete UI fix task --- ...ing-optimistic-UI-for-delete-operations.md | 69 +++++++++++++++++++ 1 file changed, 69 insertions(+) create mode 100644 backlog/tasks/ml-169.10 - Fix-Missing-optimistic-UI-for-delete-operations.md diff --git a/backlog/tasks/ml-169.10 - Fix-Missing-optimistic-UI-for-delete-operations.md b/backlog/tasks/ml-169.10 - Fix-Missing-optimistic-UI-for-delete-operations.md new file mode 100644 index 00000000..d0384df7 --- /dev/null +++ b/backlog/tasks/ml-169.10 - Fix-Missing-optimistic-UI-for-delete-operations.md @@ -0,0 +1,69 @@ +--- +id: ML-169.10 +title: "Fix: Missing optimistic UI for delete operations" +status: To Do +assignee: [] +created_date: "2026-05-19 11:48" +labels: + - perf + - fix + - ux +dependencies: [] +references: + - >- + backlog/documents/doc-27 - + Phase-4-Performance-Audit-Low-Hanging-Fruit-Findings.md +modified_files: + - lib/music_library_web/live_helpers/index_actions.ex + - lib/music_library_web/live/collection_live/show.ex + - lib/music_library_web/live/scrobbled_tracks_live/index.ex +parent_task_id: ML-169 +priority: medium +ordinal: 31000 +--- + +## Description + + + +Add optimistic UI for delete operations so the UI removes items immediately without waiting for the database transaction. + +## Problem + +All delete operations wait for the database transaction to complete before updating the UI. `stream_delete` is already used in some places, but the pattern is inconsistent. CollectionLive.Show deletes don't use `stream_delete` at all (they navigate away). + +## Files + +- `lib/music_library_web/live_helpers/index_actions.ex:94-98` — `handle_delete` +- `lib/music_library_web/live/collection_live/show.ex:381-385` — `handle_event("delete")` +- `lib/music_library_web/live/scrobbled_tracks_live/index.ex:305-310` — `handle_event("delete")` + +## Impact + +Adds unnecessary latency to delete operations that could feel instant. While delete failures are rare, the benefit of snappy UI is worth the minimal risk. + +## Fix + +Use `stream_delete` immediately, then perform the DB operation async. If DB fails, re-insert the item and show error toast. + +```elixir +def handle_delete(socket, id) do + record = Records.get_record!(id) + socket = stream_delete(socket, :records, record) + Task.start(fn -> Records.delete_record(record) end) + {:noreply, socket} +end +``` + + + +## Acceptance Criteria + + + +- [ ] #1 Delete operations remove items from UI immediately (no DB wait) +- [ ] #2 Database delete still executes successfully in background +- [ ] #3 If DB delete fails, item is re-inserted into stream and error toast shown +- [ ] #4 Existing delete confirmation modal still works correctly +- [ ] #5 No orphaned UI state after failed delete +