UI/UX pass: readability, feedback, safer actions, DRK branding
Items 1–12 of the interface review: - Larger UI font (UI_FONT_SIZE) across widgets, menus, dialogs, Treeview rows. - DRK-red header bar; window title shows entry count; runtime-drawn red-cross icon (also written to data/icon.png for the launcher). - Status bar colour-coded by severity; transient messages auto-clear after 8 s, queue-count messages stay. - Tab 1: more form spacing, digits-only PLZ, explicit "Auswahl entfernen" + Delete key for queue rows, confirm on "Warteschlange leeren", modal on duplicate save. - Tab 2: raw lat/lon columns replaced by one "Karte" column (checkmark / red "fehlt"); ▲/▼ arrow on the active sort column; hint line always shows the saved-entry count. - "Karte öffnen" with no coordinates shows a dialog, not just a status line. - Window size/position remembered between sessions (data/window.json). Verified by building and driving the window under Homebrew Python 3.12 / Tk 9; non-GUI smoke tests still pass. Docs updated (changelog, overview, improvements, data-model, setup, dev-notes). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
+1
-1
@@ -28,7 +28,7 @@ code) and plots them on an interactive map.
|
||||
- **Storage:** one CSV file, `data/orte.csv`
|
||||
- **Map:** generated on demand as `data/karte.html` with [Folium](https://python-visualization.github.io/folium/) (Leaflet), opened in the default browser
|
||||
- **Geocoding:** OpenStreetMap Nominatim via [`geopy`](https://geopy.readthedocs.io/), rate-limited to 1 request/second on a background thread
|
||||
- **UI language:** German
|
||||
- **UI language:** German; DRK-red header, enlarged font, colour-coded status bar, window position remembered
|
||||
- **Persistence:** atomic CSV writes + rotating backups in `data/backups/`; log at `data/app.log`
|
||||
- **Tests:** non-GUI smoke checks only (not yet a committed `tests/` suite)
|
||||
- **Version control:** git initialized 2026-09-07
|
||||
|
||||
+28
-2
@@ -2,6 +2,32 @@
|
||||
|
||||
Notable changes to the app. Newest first.
|
||||
|
||||
## 2026-09-07 — UI/UX pass
|
||||
|
||||
A round of usability improvements aimed at the non-technical user
|
||||
(see [improvements.md](improvements.md#uiux-review-2026-09-07)).
|
||||
|
||||
- **Larger UI font** (`UI_FONT_SIZE = 11`) applied to all default fonts, menus,
|
||||
dialogs and the Treeview (taller rows).
|
||||
- **DRK-red header bar** with the app name; window title shows the total count
|
||||
("… · 142 Einsätze"); simple red-cross window icon drawn at runtime (also
|
||||
written to `data/icon.png` for the launcher).
|
||||
- **Status bar** is now colour-coded by severity (grey/green/orange/red), and
|
||||
transient messages auto-clear after 8 s back to a neutral state; queue-count
|
||||
messages stay put.
|
||||
- **Tab 1:** more spacing in the form; PLZ field accepts digits only;
|
||||
"+ Hinzufügen" is a solid button; explicit **"Auswahl entfernen"** button and
|
||||
<kbd>Delete</kbd> key for queue rows; **"Warteschlange leeren"** now asks for
|
||||
confirmation; **duplicate save shows a modal** (list + "trotzdem speichern?")
|
||||
instead of a transient hint.
|
||||
- **Tab 2:** the raw `lat`/`lon` columns are replaced by a single **"Karte"**
|
||||
column (`✓` / red `fehlt`); active sort column shows a ▲/▼ arrow; the hint
|
||||
line always shows the saved-entry count.
|
||||
- **"Karte öffnen"** with no coordinates now shows a dialog, not just a status
|
||||
line.
|
||||
- **Window size & position** are remembered between sessions
|
||||
(`data/window.json`).
|
||||
|
||||
## 2026-09-07 — data safety, robustness, easier input
|
||||
|
||||
Addressed the top three findings from [improvements.md](improvements.md).
|
||||
@@ -43,5 +69,5 @@ Addressed the top three findings from [improvements.md](improvements.md).
|
||||
|
||||
### Verification
|
||||
Non-GUI smoke tests (helpers, `DataStore` backup/atomic/recovery, geocoder
|
||||
resilience) pass. **The GUI could not be run on the development Mac** — see
|
||||
[dev-notes.md](dev-notes.md).
|
||||
resilience) pass. The GUI now *can* be built and driven on the dev Mac via a
|
||||
Homebrew Python with Tk 9 — see [dev-notes.md](dev-notes.md).
|
||||
|
||||
@@ -59,3 +59,14 @@ closed.
|
||||
|
||||
Rotating log file (512 KB × 3 generations). Git-ignored. Records saves, map
|
||||
generation, geocoding failures, and uncaught exceptions.
|
||||
|
||||
## `data/window.json`
|
||||
|
||||
`{"geometry": "<w>x<h>+<x>+<y>"}` – the window size and position, saved on close
|
||||
and restored on start. Git-ignored, per-machine. Safe to delete (window opens at
|
||||
its default size).
|
||||
|
||||
## `data/icon.png`
|
||||
|
||||
The red-cross window icon, drawn at first run and written here so the `.desktop`
|
||||
launcher can point at it. Git-ignored (regenerated). Delete to force a redraw.
|
||||
|
||||
+20
-12
@@ -3,23 +3,31 @@
|
||||
Running list so the same mistakes aren't repeated. Add to it whenever reality
|
||||
contradicts an assumption.
|
||||
|
||||
## The GUI does not run on the development Mac (2026-09-07)
|
||||
## The macOS system Python can't run the GUI; use a Homebrew Python (2026-09-07)
|
||||
|
||||
The macOS **CommandLineTools** Python 3.9 (`/Library/Developer/CommandLineTools/
|
||||
.../python3.9`) ships **Tk 8.5.9**. `ttkbootstrap` 1.10.1 requires **Tk 8.6+**.
|
||||
Symptoms: `TclError: couldn't recognize image data` (window icon) and
|
||||
`TclError: unknown option "-style"` on `ttk.Scrollbar`.
|
||||
|
||||
Symptoms when trying to launch `App()` there:
|
||||
- `_tkinter.TclError: couldn't recognize image data` (ttkbootstrap's window icon
|
||||
is a PNG; Tk 8.5 can't decode it), and
|
||||
- `_tkinter.TclError: unknown option "-style"` on `ttk.Scrollbar`.
|
||||
**Fix for local GUI testing:** `brew install python-tk@3.12` (pulls `tcl-tk`,
|
||||
gives Python 3.12 + **Tk 9.0**), then:
|
||||
|
||||
Consequences:
|
||||
- `app.py` **cannot be smoke-tested through the GUI on this machine.** Logic is
|
||||
covered by a non-GUI script (constructs `DataStore`, exercises helpers and the
|
||||
worker with monkey-patched paths).
|
||||
- The **Linux Mint target is unaffected** — its system Tk is 8.6.
|
||||
- If GUI testing on macOS is ever needed, install a Homebrew
|
||||
`python-tk@3.x` / `tcl-tk` combo, or use `pyenv` with `--with-tcltk`.
|
||||
```bash
|
||||
/opt/homebrew/bin/python3.12 -m venv venv
|
||||
venv/bin/pip install -r requirements.txt
|
||||
venv/bin/python app.py
|
||||
```
|
||||
|
||||
`ttkbootstrap` 1.10.1 runs fine on Tk 9.0 in practice (verified: window builds,
|
||||
Treeview sort, DateEntry, LabelFrame, custom styles all work).
|
||||
|
||||
- The **Linux Mint target** uses its own `python3-tk` (Tk 8.6+) and is
|
||||
unaffected either way.
|
||||
- `screencapture` from a non-GUI shell fails ("could not create image from
|
||||
display") without Screen-Recording permission — automated screenshots of the
|
||||
running app aren't available here; verify by building the widget tree and
|
||||
driving it programmatically instead.
|
||||
|
||||
## `pandas` reads everything as strings by design
|
||||
|
||||
|
||||
+24
-1
@@ -188,9 +188,32 @@ tile pack — larger effort).
|
||||
|
||||
---
|
||||
|
||||
## UI/UX review (2026-09-07)
|
||||
|
||||
Second review, focused on the interface. Items 1–12 implemented; 13 deferred.
|
||||
|
||||
| # | Change | Status |
|
||||
|---|--------|--------|
|
||||
| 1 | Larger base font + taller Treeview rows (`UI_FONT_SIZE`) | ✅ |
|
||||
| 2 | Colour-coded status bar + 8 s auto-clear to a neutral state | ✅ |
|
||||
| 3 | "Warteschlange leeren" asks for confirmation; more form spacing | ✅ |
|
||||
| 4 | ▲/▼ arrow on the active sort column in Tab 2 | ✅ |
|
||||
| 5 | Dropped the now-redundant `(JJJJ-MM-TT)` hint | ✅ |
|
||||
| 6 | Tab 2: single **"Karte"** column (`✓` / red `fehlt`) instead of raw lat/lon | ✅ |
|
||||
| 7 | Explicit "Auswahl entfernen" button + <kbd>Delete</kbd> key for queue rows | ✅ |
|
||||
| 8 | Duplicate save shows a modal with the list, not a transient hint | ✅ |
|
||||
| 9 | Persistent entry count (window title + Tab 2 hint line) | ✅ |
|
||||
| 10 | "Karte öffnen" with no coordinates shows a dialog | ✅ |
|
||||
| 11 | Remember window size & position (`data/window.json`) | ✅ |
|
||||
| 12 | DRK-red header bar + runtime-drawn red-cross icon (`data/icon.png`) | ✅ |
|
||||
| 13 | One-click "Hinzufügen & sofort speichern" | ⬜ deferred |
|
||||
|
||||
Full custom DRK-red *theme* (recolouring `primary` etc.) was **not** done — the
|
||||
red header bar gives the branding without fighting ttkbootstrap's theme system.
|
||||
|
||||
## Suggested order of remaining work
|
||||
|
||||
1. Initial git commit (item 4), then decide on committing `orte.csv`.
|
||||
2. Pinned deps + `run.sh` / `.desktop` launcher in the repo (item 5).
|
||||
3. Stable `id` column (item 7) and a modal duplicate prompt (item 8).
|
||||
3. Stable `id` column (item 7 of the first review).
|
||||
4. Formalize tests (item 10); offline map (item 9) only if offline use becomes real.
|
||||
|
||||
+23
-12
@@ -1,6 +1,11 @@
|
||||
# Overview – what the app does
|
||||
|
||||
The app is a single window with a status bar at the bottom and two tabs.
|
||||
The app is a single window: a **DRK-red header bar**, two tabs, and a
|
||||
**colour-coded status bar** at the bottom (grey = neutral, green = success,
|
||||
orange = warning, red = error; transient messages fade back to neutral after
|
||||
~8 s). The window title shows the total entry count, and the window remembers
|
||||
its size and position between sessions (`data/window.json`). The UI font is
|
||||
enlarged for readability (`UI_FONT_SIZE`).
|
||||
|
||||
## Tab 1 – "Neuer Eintrag" (new entry)
|
||||
|
||||
@@ -12,28 +17,34 @@ then save the whole batch at once.
|
||||
`TT.MM.JJJJ` and **validated** – an invalid date is rejected with a dialog),
|
||||
city (autocomplete combobox), postal code (optional). Pressing `Return` in any
|
||||
field, or the **+ Hinzufügen** button, adds the row to the queue.
|
||||
The PLZ field only accepts digits.
|
||||
2. **Queue table** – shows date, city, PLZ, and a live coordinate column that
|
||||
updates from `⏳ wird gesucht…` to either `lat / lon` or `⚠ nicht gefunden`
|
||||
as the background geocoder works through the queue.
|
||||
- Left-click the `✕` cell to remove a row.
|
||||
- Select a row and press <kbd>Delete</kbd>, use the **"Auswahl entfernen"**
|
||||
button, or click the `✕` cell.
|
||||
- Right-click a row for *Löschen* / *Koordinaten erneut suchen*.
|
||||
3. **Action bar**
|
||||
- **Alle speichern** – appends every queued row to `orte.csv`. If a row looks
|
||||
like a duplicate of an existing entry (same date + city + PLZ) a hint is
|
||||
shown in the status bar, but the row is **still saved**.
|
||||
- **Leeren** – discards the queue without saving.
|
||||
- **Alle speichern** – appends every queued row to `orte.csv`. If any row
|
||||
looks like a duplicate (same date + city + PLZ), a **modal** lists them and
|
||||
asks whether to save anyway.
|
||||
- **Warteschlange leeren** – discards the queue (asks for confirmation).
|
||||
- **Karte öffnen** – regenerates `karte.html` and opens it in the browser.
|
||||
|
||||
## Tab 2 – "Einträge verwalten" (manage entries)
|
||||
|
||||
A table view of everything in `orte.csv`.
|
||||
|
||||
- **Columns:** Datum, Ort, PLZ, and **Karte** – a status column showing `✓` when
|
||||
the row has coordinates or a red `fehlt` when it doesn't (the whole row is red
|
||||
too). The raw lat/lon numbers live in the edit dialog, not this table.
|
||||
- **Search box** – live filter across date, city, and PLZ (substring match).
|
||||
- **Sortable columns** – click a header to sort; clicking again reverses.
|
||||
Default sort is by date, newest first.
|
||||
- **Sortable columns** – click a header to sort; clicking again reverses. The
|
||||
active column shows a ▲/▼ arrow. Default sort is by date, newest first.
|
||||
Sorting by **Karte** groups the rows without coordinates together.
|
||||
- **"Nur ohne Koordinaten"** toggle – filters to entries that have no
|
||||
coordinates yet. Such rows are also shown in **red** in the full list, and the
|
||||
hint line reports how many there are.
|
||||
coordinates yet. The hint line always shows the total count, plus how many are
|
||||
missing coordinates.
|
||||
- **Edit** – double-click a row (or *Bearbeiten*) opens a modal dialog to change
|
||||
date (calendar picker, validated) / city / PLZ. Two ways to fix coordinates:
|
||||
a "Koordinaten automatisch neu suchen" toggle re-runs geocoding after saving,
|
||||
@@ -58,8 +69,8 @@ Generated by `generate_map()`:
|
||||
(`5 + count / max_count * 20` px), colour is DRK red (`#CC0000`).
|
||||
- Popup shows the city and the visit count; tooltip shows the city.
|
||||
- Rows with missing/blank coordinates are silently excluded.
|
||||
- If there are no usable coordinates at all, a `ValueError` is raised and shown
|
||||
in the status bar.
|
||||
- If there are no usable coordinates at all, a dialog says so (and the status
|
||||
bar shows a warning).
|
||||
|
||||
> The generated HTML pulls Leaflet, jQuery and Bootstrap from CDNs, so the map
|
||||
> needs an internet connection to render even though the data is local.
|
||||
|
||||
+5
-4
@@ -73,14 +73,15 @@ Type=Application
|
||||
Name=DRK Blutspende – Arbeitsorte
|
||||
Comment=Einsatzorte protokollieren und auf der Karte anzeigen
|
||||
Exec=/home/USER/Apps/DRK_Blutspende_Orte/run.sh
|
||||
Icon=/home/USER/Apps/DRK_Blutspende_Orte/icon.png
|
||||
Icon=/home/USER/Apps/DRK_Blutspende_Orte/data/icon.png
|
||||
Terminal=false
|
||||
Categories=Utility;
|
||||
```
|
||||
|
||||
Replace `USER` with the real username. Add any PNG as `icon.png` (the DRK logo
|
||||
works well). The entry then shows up in the Mint menu and can be pinned to the
|
||||
panel or the desktop.
|
||||
Replace `USER` with the real username. The app writes a simple red-cross
|
||||
`data/icon.png` on first run; drop in the real DRK logo at that path if you have
|
||||
one. The entry then shows up in the Mint menu and can be pinned to the panel or
|
||||
the desktop.
|
||||
|
||||
## Python / Tk version
|
||||
|
||||
|
||||
Reference in New Issue
Block a user