Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 6 additions & 5 deletions design/docs-md/spec.md

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion design/docs-md/xrc-windows.md
Original file line number Diff line number Diff line change
Expand Up @@ -427,7 +427,7 @@ Close

`wxID_CLOSE (right-justified — a leading spacer keeps the stock Close alone at the window's right, since wxStdDialogButtonSizer positions only the stock Close; the four export buttons that shared this row retired with the UI-removals batch, so the Results menu's own mi_export_* rows are the single export surface and the dialog carries no export at all)`

⚠ code-side: standings rows — the presenter feeds each list its own kind (the notebook's two pages on a MIXED ride, the lone standings_list on a SOLO one, Phase 3, R-65); "draw required" tie rows highlighted with a ⚠ badge in the Place cell (the seven pinned columns), the badge explained on activation — double-click or Enter opens an OK-only `std_dialogs.show_info` alert carrying the row's own tie note ("draw required" plus the sentence explaining that the configured tie-break order could not separate the hands and the venue decides: `results_win.DRAW_EXPLANATION`), since a DataViewCtrl has no per-row tooltip and hover is keyboard-unreachable; the Draw column beside Hand shows the card an entry drew for the venue's high-card tie-break (`StandingsRow.tiebreak_card`, blank when it drew none) — a drawn tie is *resolved*, so only the residual tie carries the badge; one code-side InfoBar (`stale_infobar` — built in code, named with SetName()) carries the dialog's two notes, the stale-export flag after reopened corrections (`results_win.STALE_NOTE`) taking precedence over E6.4.3's "Self-test unverified" note (`results_win.SELF_TEST_NOTE`) for a ride the operator finished over a failed evaluator self-test. G6 moved the five publish options out of this dialog onto checkable Results-menu items (each persisting in `AppSettings.publish_*`), so the dialog carries no checkbox and the show-times setting no longer hides any column here. The window is a modal wxDialog opened through dialogs.run_dialog — a transient over the console, so its title bar carries the ✕ alone (no ▢), and the tie-break panel and Reopen ride button left with the frame: tie-break order is ride_setup_dlg's own tiebreak_list and nothing else, and reopening a ride is the menu's Ride ▸ Reopen Ride (mi_reopen_ride). Standings is always available — the Results ▸ Standings row (F5) is never gated on a ride open; with none open the dialog renders its empty state. The Teams list hides its Plate column under `rider_pooled` (a pooled team's plate is derived from its members, so the column would only repeat one) and keeps it under `team_relay`, where the plate is the entry's identity; the solo list keeps it always. It floors at 800 px wide (MIN_SIZE = 800×442, code-side: the seven pinned columns total 750 px plus the list's scrollbar and the notebook/sizer borders — the publish-checkbox row that used to set the 755 px floor is gone), with each of the three standings lists (`standings_list`/`teams_standings_list`/`solo_standings_list`) floored at 198 px high — a 28 px header plus 10 × 17 px rows (measured on wxPython 4.3.1), so ten standings rows are visible. The window lives in results.xrc (§15b).
⚠ code-side: standings rows — the presenter feeds each list its own kind (the notebook's two pages on a MIXED ride, the lone standings_list on a SOLO one, Phase 3, R-65); "draw required" tie rows highlighted with a ⚠ badge in the Place cell (the seven pinned columns), the badge explained on activation — double-click or Enter opens an OK-only `std_dialogs.show_info` alert carrying the row's own tie note ("draw required" plus the sentence explaining that the configured tie-break order could not separate the hands and the venue decides: `results_win.DRAW_EXPLANATION`), since a DataViewCtrl has no per-row tooltip and hover is keyboard-unreachable; the Draw column beside Hand shows the card an entry drew for the venue's high-card tie-break (`StandingsRow.tiebreak_card`, blank when it drew none) — a drawn tie is *resolved*, so only the residual tie carries the badge; one code-side InfoBar (`stale_infobar` — built in code, named with SetName()) carries the dialog's two notes, the stale-export flag after reopened corrections (`results_win.STALE_NOTE`) taking precedence over E6.4.3's "Self-test unverified" note (`results_win.SELF_TEST_NOTE`) for a ride the operator finished over a failed evaluator self-test. G6 moved the five publish options out of this dialog onto checkable Results-menu items (each persisting in `AppSettings.publish_*`), so the dialog carries no checkbox and the show-times setting no longer hides any column here. The window is a modal wxDialog opened through dialogs.run_dialog — a transient over the console, so its title bar carries the ✕ alone (no ▢), and the tie-break panel and Reopen ride button left with the frame: tie-break order is ride_setup_dlg's own tiebreak_list and nothing else, and reopening a ride is the menu's Ride ▸ Reopen Ride (mi_reopen_ride). Standings is always available — the Results ▸ Standings row (F5) is never gated on a ride open; with none open the dialog renders its empty state. The Teams list hides its Plate column under `rider_pooled` (a pooled team's plate is derived from its members, so the column would only repeat one) and keeps it under `team_relay`, where the plate is the entry's identity; the solo list keeps it always. It floors at 800 px wide (MIN_SIZE = 800×442, code-side: the seven pinned columns total 750 px plus the list's scrollbar and the notebook/sizer borders — the publish-checkbox row that used to set the 755 px floor is gone), with each of the three standings lists (`standings_list`/`teams_standings_list`/`solo_standings_list`) floored at 198 px high — a 28 px header plus 10 × 17 px rows (measured on wxPython 4.3.1), so ten standings rows are visible. The window lives in results.xrc (§15b). Phase 7 adds the DNS row: a FINISHED ride's 0-lap ACTIVE entry is appended, unplaced, at the bottom of its own section (Teams or Solo) with a blank Place cell, the literal `DNS` in the Laps cell and a blank Draw cell — no tie-break badge, the entry having never joined the ranking — and the Results menu's Show DNS Riders toggle (`mi_show_dns_riders`, on by default) shows or hides those rows; a live or REOPENED ride ranks its whole field, so it renders none.

Ride Library`ride_library_dlg`✕

Expand Down
4 changes: 2 additions & 2 deletions design/exports/epic-2026-results-no-times.html
Original file line number Diff line number Diff line change
Expand Up @@ -67,8 +67,8 @@ <h1 class="font-head font-semibold text-4xl sm:text-5xl leading-none">GORBA EPIC
<p class="mt-1 text-sm text-ink/60">Sunday September 20, 2026 · Guelph Lake MTB Trails · 8 km closed loop · riding 10:00–16:00</p>
</div>
<div class="ms-auto text-right hidden sm:block">
<div class="font-head font-semibold text-3xl leading-none">180 · 1124 · 1092</div>
<div class="text-xs text-ink/55 mt-1">entries · laps · cards dealt</div>
<div class="font-head font-semibold text-3xl leading-none">180 · 1124 · 1092 · 262</div>
<div class="text-xs text-ink/55 mt-1">entries · laps · cards dealt · unique riders</div>
</div>
</div>
</header>
Expand Down
4 changes: 2 additions & 2 deletions design/exports/epic-2026-results-solo.html
Original file line number Diff line number Diff line change
Expand Up @@ -67,8 +67,8 @@ <h1 class="font-head font-semibold text-4xl sm:text-5xl leading-none">GORBA EPIC
<p class="mt-1 text-sm text-ink/60">Sunday September 20, 2026 · Guelph Lake MTB Trails · 8 km closed loop · riding 10:00–16:00</p>
</div>
<div class="ms-auto text-right hidden sm:block">
<div class="font-head font-semibold text-3xl leading-none">180 · 1124 · 1092</div>
<div class="text-xs text-ink/55 mt-1">entries · laps · cards dealt</div>
<div class="font-head font-semibold text-3xl leading-none">180 · 1124 · 1092 · 180</div>
<div class="text-xs text-ink/55 mt-1">entries · laps · cards dealt · unique riders</div>
</div>
</div>
</header>
Expand Down
4 changes: 2 additions & 2 deletions design/exports/epic-2026-results.html
Original file line number Diff line number Diff line change
Expand Up @@ -67,8 +67,8 @@ <h1 class="font-head font-semibold text-4xl sm:text-5xl leading-none">GORBA EPIC
<p class="mt-1 text-sm text-ink/60">Sunday September 20, 2026 · Guelph Lake MTB Trails · 8 km closed loop · riding 10:00–16:00</p>
</div>
<div class="ms-auto text-right hidden sm:block">
<div class="font-head font-semibold text-3xl leading-none">180 · 1124 · 1092</div>
<div class="text-xs text-ink/55 mt-1">entries · laps · cards dealt</div>
<div class="font-head font-semibold text-3xl leading-none">180 · 1124 · 1092 · 262</div>
<div class="text-xs text-ink/55 mt-1">entries · laps · cards dealt · unique riders</div>
</div>
</div>
</header>
Expand Down
12 changes: 6 additions & 6 deletions design/templates/macros.html.j2
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,8 @@
<p class="mt-1 text-sm text-ink/60">{{ event.meta }}</p>
</div>
<div class="ms-auto text-right hidden sm:block">
<div class="font-head font-semibold text-3xl leading-none">{{ event.entries }} · {{ event.laps }} · {{ event.cards }}</div>
<div class="text-xs text-ink/55 mt-1">entries · laps · cards dealt</div>
<div class="font-head font-semibold text-3xl leading-none">{{ event.entries }} · {{ event.laps }} · {{ event.cards }} · {{ event.riders }}</div>
<div class="text-xs text-ink/55 mt-1">entries · laps · cards dealt · unique riders</div>
</div>
</div>
</header>
Expand All @@ -58,11 +58,11 @@
{%- endmacro %}

{% macro standings_row(r, options) -%}
<tr class="border-b border-ink/8{{ ' bg-steel-500/10' if r.place == 1 }}"><td class="py-2 pr-3 font-bold">{{ r.place }}</td><td class="py-2 pr-3 font-bold">{{ r.plate }}</td><td class="py-2 pr-3">{% if r.logo %}<img src="{{ r.logo }}" alt="" class="team-logo h-5 w-auto align-middle me-1.5">{% endif %}{{ r.entry }}{% if r.tie %} <span class="text-[10px] uppercase border border-steel-600 text-steel-700 px-1.5 py-0.5">tie-break</span>{% endif %}{% if r.draw %} {{ draw_badge(r) }}{% endif %}</td><td class="py-2 pr-3">{{ r.laps }}</td>{% if options.show_times %}<td class="py-2 pr-3 t-col">{{ r.total }}</td>{% endif %}<td class="py-2 pr-3">{{ chips(r.cards) }}</td><td class="py-2 font-head font-semibold uppercase">{{ r.hand }}</td></tr>
<tr class="border-b border-ink/8{{ ' bg-steel-500/10' if r.place == 1 }}"><td class="py-2 pr-3 font-bold">{{ '' if r.dns else r.place }}</td><td class="py-2 pr-3 font-bold">{{ r.plate }}</td><td class="py-2 pr-3">{% if r.logo %}<img src="{{ r.logo }}" alt="" class="team-logo h-5 w-auto align-middle me-1.5">{% endif %}{{ r.entry }}{% if r.tie %} <span class="text-[10px] uppercase border border-steel-600 text-steel-700 px-1.5 py-0.5">tie-break</span>{% endif %}{% if r.draw %} {{ draw_badge(r) }}{% endif %}</td><td class="py-2 pr-3">{{ 'DNS' if r.dns else r.laps }}</td>{% if options.show_times %}<td class="py-2 pr-3 t-col">{{ r.total }}</td>{% endif %}<td class="py-2 pr-3">{{ chips(r.cards) }}</td><td class="py-2 font-head font-semibold uppercase">{{ r.hand }}</td></tr>
{%- endmacro %}

{% macro team_standings_row(r, options) -%}
<tr class="border-b border-ink/8{{ ' bg-steel-500/10' if r.place == 1 }}"><td class="py-2 pr-3 font-bold">{{ r.place }}</td><td class="py-2 pr-3">{% if r.logo %}<img src="{{ r.logo }}" alt="" class="team-logo h-5 w-auto align-middle me-1.5">{% endif %}{{ r.entry }}{% if r.tie %} <span class="text-[10px] uppercase border border-steel-600 text-steel-700 px-1.5 py-0.5">tie-break</span>{% endif %}{% if r.draw %} {{ draw_badge(r) }}{% endif %}</td><td class="py-2 pr-3">{{ r.laps }}</td>{% if options.show_times %}<td class="py-2 pr-3 t-col">{{ r.total }}</td>{% endif %}<td class="py-2 pr-3">{{ chips(r.cards) }}</td><td class="py-2 font-head font-semibold uppercase">{{ r.hand }}</td></tr>
<tr class="border-b border-ink/8{{ ' bg-steel-500/10' if r.place == 1 }}"><td class="py-2 pr-3 font-bold">{{ '' if r.dns else r.place }}</td><td class="py-2 pr-3">{% if r.logo %}<img src="{{ r.logo }}" alt="" class="team-logo h-5 w-auto align-middle me-1.5">{% endif %}{{ r.entry }}{% if r.tie %} <span class="text-[10px] uppercase border border-steel-600 text-steel-700 px-1.5 py-0.5">tie-break</span>{% endif %}{% if r.draw %} {{ draw_badge(r) }}{% endif %}</td><td class="py-2 pr-3">{{ 'DNS' if r.dns else r.laps }}</td>{% if options.show_times %}<td class="py-2 pr-3 t-col">{{ r.total }}</td>{% endif %}<td class="py-2 pr-3">{{ chips(r.cards) }}</td><td class="py-2 font-head font-semibold uppercase">{{ r.hand }}</td></tr>
{%- endmacro %}

{% macro laps_board(rows, options, title='Most laps', show_plate=true) -%}
Expand All @@ -74,11 +74,11 @@
{%- endmacro %}

{% macro field_row(r, options) -%}
<tr class="border-b border-ink/8{{ ' opacity-60' if r.dnf }}"><td class="py-1.5 pr-3">{{ r.place }}</td><td class="py-1.5 pr-3 font-bold">{{ r.plate }}</td><td class="py-1.5 pr-3">{% if r.logo %}<img src="{{ r.logo }}" alt="" class="team-logo h-5 w-auto align-middle me-1.5">{% endif %}{{ r.entry }}{% if r.sex %}<span class="text-xs text-ink/55"> · {{ r.sex }}</span>{% endif %}{% if r.dnf %} <span class="text-[10px] uppercase border border-ink/30 px-1.5 py-0.5">dnf</span>{% endif %}{% if r.draw %} {{ draw_badge(r) }}{% endif %}</td><td class="py-1.5 pr-3 text-xs uppercase text-ink/55">{{ r.type }}</td><td class="py-1.5 pr-3">{{ r.laps }}</td>{% if options.show_times %}<td class="py-1.5 pr-3 t-col">{{ r.total }}</td><td class="py-1.5 pr-3 t-col">{{ r.best_lap }}</td>{% endif %}<td class="py-1.5">{{ chips(r.cards) }} <span class="ms-1 font-head font-semibold uppercase text-xs">{{ r.hand }}</span></td></tr>
<tr class="border-b border-ink/8{{ ' opacity-60' if r.dnf }}"><td class="py-1.5 pr-3">{{ '' if r.dns else r.place }}</td><td class="py-1.5 pr-3 font-bold">{{ r.plate }}</td><td class="py-1.5 pr-3">{% if r.logo %}<img src="{{ r.logo }}" alt="" class="team-logo h-5 w-auto align-middle me-1.5">{% endif %}{{ r.entry }}{% if r.sex %}<span class="text-xs text-ink/55"> · {{ r.sex }}</span>{% endif %}{% if r.dnf %} <span class="text-[10px] uppercase border border-ink/30 px-1.5 py-0.5">dnf</span>{% endif %}{% if r.draw %} {{ draw_badge(r) }}{% endif %}</td><td class="py-1.5 pr-3 text-xs uppercase text-ink/55">{{ r.type }}</td><td class="py-1.5 pr-3">{{ 'DNS' if r.dns else r.laps }}</td>{% if options.show_times %}<td class="py-1.5 pr-3 t-col">{{ '' if r.dns else r.total }}</td><td class="py-1.5 pr-3 t-col">{{ '' if r.dns else r.best_lap }}</td>{% endif %}<td class="py-1.5">{{ chips(r.cards) }} <span class="ms-1 font-head font-semibold uppercase text-xs">{{ r.hand }}</span></td></tr>
{%- endmacro %}

{% macro team_field_row(r, options) -%}
<tr class="border-b border-ink/8{{ ' opacity-60' if r.dnf }}"><td class="py-1.5 pr-3">{{ r.place }}</td><td class="py-1.5 pr-3">{% if r.logo %}<img src="{{ r.logo }}" alt="" class="team-logo h-5 w-auto align-middle me-1.5">{% endif %}{{ r.entry }}{% if r.dnf %} <span class="text-[10px] uppercase border border-ink/30 px-1.5 py-0.5">dnf</span>{% endif %}{% if r.draw %} {{ draw_badge(r) }}{% endif %}</td><td class="py-1.5 pr-3">{{ r.laps }}</td>{% if options.show_times %}<td class="py-1.5 pr-3 t-col">{{ r.total }}</td><td class="py-1.5 pr-3 t-col">{{ r.best_lap }}</td>{% endif %}<td class="py-1.5 pr-3">{{ chips(r.cards) }}</td><td class="py-1.5 font-head font-semibold uppercase text-xs">{{ r.hand }}</td></tr>
<tr class="border-b border-ink/8{{ ' opacity-60' if r.dnf }}"><td class="py-1.5 pr-3">{{ '' if r.dns else r.place }}</td><td class="py-1.5 pr-3">{% if r.logo %}<img src="{{ r.logo }}" alt="" class="team-logo h-5 w-auto align-middle me-1.5">{% endif %}{{ r.entry }}{% if r.dnf %} <span class="text-[10px] uppercase border border-ink/30 px-1.5 py-0.5">dnf</span>{% endif %}{% if r.draw %} {{ draw_badge(r) }}{% endif %}</td><td class="py-1.5 pr-3">{{ 'DNS' if r.dns else r.laps }}</td>{% if options.show_times %}<td class="py-1.5 pr-3 t-col">{{ '' if r.dns else r.total }}</td><td class="py-1.5 pr-3 t-col">{{ '' if r.dns else r.best_lap }}</td>{% endif %}<td class="py-1.5 pr-3">{{ chips(r.cards) }}</td><td class="py-1.5 font-head font-semibold uppercase text-xs">{{ r.hand }}</td></tr>
{%- endmacro %}

{% macro drawn_row(r, span) -%}
Expand Down
Loading
Loading