ML-169.10: add optimistic delete UI fix task
This commit is contained in:
@@ -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
|
||||
|
||||
<!-- SECTION:DESCRIPTION:BEGIN -->
|
||||
|
||||
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
|
||||
```
|
||||
|
||||
<!-- SECTION:DESCRIPTION:END -->
|
||||
|
||||
## Acceptance Criteria
|
||||
|
||||
<!-- AC:BEGIN -->
|
||||
|
||||
- [ ] #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
|
||||
<!-- AC:END -->
|
||||
Reference in New Issue
Block a user