feat: event detail page styling and deleted events indicator
- Fix event detail page for direct navigation by using FastHTML's idiomatic htmx parameter instead of manual header check - Add custom toaster.py with HTML support using NotStr to render clickable links in toast messages - Add hx_preserve to toast container to survive HTMX body swaps - Add is_deleted column to event_log_by_location table - Update event_log projection revert() to set is_deleted flag instead of deleting rows - Add strikethrough styling for deleted events in event log 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -405,19 +405,23 @@ class TestEventLogProjectionRevert:
|
||||
event = make_product_collected_event(event_id, location_id, animal_ids)
|
||||
projection.apply(event)
|
||||
|
||||
# Verify row exists
|
||||
count = seeded_db.execute("SELECT COUNT(*) FROM event_log_by_location").fetchone()[0]
|
||||
assert count == 1
|
||||
# Verify row exists and is not deleted
|
||||
row = seeded_db.execute(
|
||||
"SELECT is_deleted FROM event_log_by_location WHERE event_id = ?", (event_id,)
|
||||
).fetchone()
|
||||
assert row[0] == 0
|
||||
|
||||
# Revert
|
||||
projection.revert(event)
|
||||
|
||||
# Verify row removed
|
||||
count = seeded_db.execute("SELECT COUNT(*) FROM event_log_by_location").fetchone()[0]
|
||||
assert count == 0
|
||||
# Verify row is marked as deleted (not removed)
|
||||
row = seeded_db.execute(
|
||||
"SELECT is_deleted FROM event_log_by_location WHERE event_id = ?", (event_id,)
|
||||
).fetchone()
|
||||
assert row[0] == 1
|
||||
|
||||
def test_revert_only_affects_specific_event(self, seeded_db):
|
||||
"""Revert only removes the specific event log entry."""
|
||||
"""Revert only marks the specific event log entry as deleted."""
|
||||
row = seeded_db.execute("SELECT id FROM locations WHERE name = 'Strip 1'").fetchone()
|
||||
location_id = row[0]
|
||||
|
||||
@@ -439,16 +443,23 @@ class TestEventLogProjectionRevert:
|
||||
)
|
||||
projection.apply(event2)
|
||||
|
||||
# Verify both exist
|
||||
# Verify both exist and are not deleted
|
||||
count = seeded_db.execute("SELECT COUNT(*) FROM event_log_by_location").fetchone()[0]
|
||||
assert count == 2
|
||||
|
||||
# Revert only event1
|
||||
projection.revert(event1)
|
||||
|
||||
# Event2 should still exist
|
||||
count = seeded_db.execute("SELECT COUNT(*) FROM event_log_by_location").fetchone()[0]
|
||||
assert count == 1
|
||||
# Event1 should be marked as deleted
|
||||
row = seeded_db.execute(
|
||||
"SELECT is_deleted FROM event_log_by_location WHERE event_id = ?",
|
||||
("01ARZ3NDEKTSV4RRFFQ69G5001",),
|
||||
).fetchone()
|
||||
assert row[0] == 1
|
||||
|
||||
row = seeded_db.execute("SELECT event_id FROM event_log_by_location").fetchone()
|
||||
assert row[0] == "01ARZ3NDEKTSV4RRFFQ69G5002"
|
||||
# Event2 should still be active (not deleted)
|
||||
row = seeded_db.execute(
|
||||
"SELECT is_deleted FROM event_log_by_location WHERE event_id = ?",
|
||||
("01ARZ3NDEKTSV4RRFFQ69G5002",),
|
||||
).fetchone()
|
||||
assert row[0] == 0
|
||||
|
||||
Reference in New Issue
Block a user