feat: topbar quick capture, fix mobile bottom nav and more panel

- Add quick capture input to topbar (desktop: inline 250px, mobile: full-width
  with submit button) that POSTs to /capture/add with redirect back to current page
- Fix mobile bottom bar: 5 items (Dashboard, Focus, Tasks, Capture, More),
  nowrap/overflow:hidden to prevent multi-line wrapping
- Rebuild mobile More panel as 3-column grid overlay (z-index 998/999/1000 stack)
  with backdrop dismiss, 8 items: Calendar, Notes, Meetings, Decisions, Contacts,
  Processes, Weblinks, Admin
- Add file seed fixture and registry mapping to eliminate 4 test skips
- Add time_budgets form factory patterns to fix 2 test failures

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-03-01 22:44:41 +00:00
parent 8499c99721
commit bcb0007217
7 changed files with 178 additions and 46 deletions

View File

@@ -33,6 +33,7 @@ SEED_IDS = {
"process_step": "a0000000-0000-0000-0000-000000000011",
"process_run": "a0000000-0000-0000-0000-000000000012",
"time_budget": "a0000000-0000-0000-0000-000000000013",
"file": "a0000000-0000-0000-0000-000000000014",
}
@@ -228,6 +229,21 @@ def all_seeds(sync_conn):
ON CONFLICT (id) DO NOTHING
""", (d["time_budget"], d["domain"]))
# File (create a dummy file on disk for download/serve tests)
import os
from pathlib import Path
file_storage = os.getenv("FILE_STORAGE_PATH", "/opt/lifeos/files/dev")
Path(file_storage).mkdir(parents=True, exist_ok=True)
dummy_file_path = os.path.join(file_storage, "test_seed_file.txt")
with open(dummy_file_path, "w") as f:
f.write("test seed file content")
cur.execute("""
INSERT INTO files (id, filename, original_filename, storage_path, mime_type, size_bytes, is_deleted, created_at, updated_at)
VALUES (%s, 'test_seed_file.txt', 'test_seed_file.txt', %s, 'text/plain', 22, false, now(), now())
ON CONFLICT (id) DO NOTHING
""", (d["file"], dummy_file_path))
sync_conn.commit()
except Exception as e:
sync_conn.rollback()
@@ -237,6 +253,9 @@ def all_seeds(sync_conn):
# Cleanup: delete all seed data (reverse dependency order)
try:
cur.execute("DELETE FROM files WHERE id = %s", (d["file"],))
if os.path.exists(dummy_file_path):
os.remove(dummy_file_path)
cur.execute("DELETE FROM time_budgets WHERE id = %s", (d["time_budget"],))
cur.execute("DELETE FROM process_runs WHERE id = %s", (d["process_run"],))
cur.execute("DELETE FROM process_steps WHERE id = %s", (d["process_step"],))