Split frontend model from backend model
All checks were successful
Build Formula10 Docker Image / build-docker (push) Successful in 26s
All checks were successful
Build Formula10 Docker Image / build-docker (push) Successful in 26s
This commit is contained in:
@ -1,15 +1,36 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
|
||||
{# Simple driver dropdown. Requires list of drivers. #}
|
||||
{% macro driver_select(name='', label='', include_none=true) %}
|
||||
{# Active user navbar dropdown #}
|
||||
{% macro active_user_dropdown(page) %}
|
||||
{% if model.all_users() | length > 1 %}
|
||||
<div class="dropdown">
|
||||
<button class="btn btn-outline-danger dropdown-toggle" type="button" data-bs-toggle="dropdown"
|
||||
aria-expanded="false">
|
||||
{{ model.active_user_name_or_everyone() }}
|
||||
</button>
|
||||
<ul class="dropdown-menu">
|
||||
<li><a class="dropdown-item" href="/{{ page }}/Everyone">Everyone</a></li>
|
||||
<li>
|
||||
<hr class="dropdown-divider">
|
||||
</li>
|
||||
|
||||
{% for user in model.all_users() %}
|
||||
<li><a class="dropdown-item" href="/{{ page }}/{{ user.name_sanitized }}">{{ user.name }}</a></li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
</div>
|
||||
{% endif %}
|
||||
{% endmacro %}
|
||||
|
||||
{# Simple driver select for forms #}
|
||||
{% macro driver_select(name, label, include_none, drivers=none) %}
|
||||
<div class="form-floating">
|
||||
<select name="{{ name }}" id="{{ name }}" class="form-select" aria-label="{{ name }}">
|
||||
<option value="" selected disabled hidden></option>
|
||||
{% if include_none == true %}
|
||||
{% set drivers = model.all_drivers() %}
|
||||
{% else %}
|
||||
{% set drivers = model.all_drivers_except_none() %}
|
||||
|
||||
{% if drivers == none %}
|
||||
{% set drivers = model.all_drivers(include_none=include_none) %}
|
||||
{% endif %}
|
||||
|
||||
{% for driver in drivers %}
|
||||
@ -20,34 +41,32 @@
|
||||
</div>
|
||||
{% endmacro %}
|
||||
|
||||
{# Driver dropdown where a value might be preselected. Requires list of drivers. #}
|
||||
{% macro driver_select_with_preselect(match='', name='', label='', include_none=true) %}
|
||||
{# Driver select for forms where a value might be preselected #}
|
||||
{% macro driver_select_with_preselect(driver_match, name, label, include_none, drivers=none) %}
|
||||
<div class="form-floating">
|
||||
<select name="{{ name }}" id="{{ name }}" class="form-select" aria-label="{{ name }}">
|
||||
{# Use namespace wrapper to persist scope between loop iterations #}
|
||||
{% set user_has_chosen = namespace(driverpre="false") %}
|
||||
{% set user_has_chosen = namespace(driverpre=false) %}
|
||||
|
||||
{% if include_none == true %}
|
||||
{% set drivers = model.all_drivers() %}
|
||||
{% else %}
|
||||
{% set drivers = model.all_drivers_except_none() %}
|
||||
{% if drivers == none %}
|
||||
{% set drivers = model.all_drivers(include_none=include_none) %}
|
||||
{% endif %}
|
||||
|
||||
{% for driver in drivers %}
|
||||
{% if match == driver.abbr %}
|
||||
{% set user_has_chosen.driverpre = "true" %}
|
||||
{% if driver_match == driver %}
|
||||
{% set user_has_chosen.driverpre = true %}
|
||||
<option selected="selected" value="{{ driver.name }}">{{ driver.abbr }}</option>
|
||||
{% else %}
|
||||
<option value="{{ driver.name }}">{{ driver.abbr }}</option>
|
||||
{% endif %}
|
||||
|
||||
{% if (include_none == true) and (driver.abbr == "None") %}
|
||||
{% if (include_none == true) and (driver == model.none_driver()) %}
|
||||
<option disabled>──────────</option>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
|
||||
{# Add an empty default if nothing has been chosen #}
|
||||
{% if user_has_chosen.driverpre == "false" %}
|
||||
{% if user_has_chosen.driverpre == false %}
|
||||
<option value="" selected="selected" disabled="disabled" hidden="hidden"></option>
|
||||
{% endif %}
|
||||
</select>
|
||||
@ -55,12 +74,17 @@
|
||||
</div>
|
||||
{% endmacro %}
|
||||
|
||||
{# Simple team dropdown. Requires list of teams. #}
|
||||
{% macro team_select(name='', label='') %}
|
||||
{# Simple team select for forms #}
|
||||
{% macro team_select(name, label, include_none, teams=none) %}
|
||||
<div class="form-floating">
|
||||
<select name="{{ name }}" id="{{ name }}" class="form-select" aria-label="{{ name }}">
|
||||
<option value="" selected disabled hidden></option>
|
||||
{% for team in model.all_teams() %}
|
||||
|
||||
{% if teams == none %}
|
||||
{% set teams = model.all_teams(include_none=include_none) %}
|
||||
{% endif %}
|
||||
|
||||
{% for team in teams %}
|
||||
<option value="{{ team.name }}">{{ team.name }}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
@ -68,24 +92,32 @@
|
||||
</div>
|
||||
{% endmacro %}
|
||||
|
||||
{# Team dropdown where a value might be preselected. Requires list of teams. #}
|
||||
{% macro team_select_with_preselect(match='', name='', label='') %}
|
||||
{# Team select for forms where a value might be preselected #}
|
||||
{% macro team_select_with_preselect(team_match, name, label, include_none, teams=none) %}
|
||||
<div class="form-floating">
|
||||
<select name="{{ name }}" id="{{ name }}" class="form-select" aria-label="{{ name }}">
|
||||
{# Use namespace wrapper to persist scope between loop iterations #}
|
||||
{% set user_has_chosen = namespace(teampre="false") %}
|
||||
{% set user_has_chosen = namespace(teampre=false) %}
|
||||
|
||||
{% for team in model.all_teams() %}
|
||||
{% if match == team.name %}
|
||||
{% set user_has_chosen.teampre = "true" %}
|
||||
{% if teams == none %}
|
||||
{% set teams = model.all_teams(include_none=include_none) %}
|
||||
{% endif %}
|
||||
|
||||
{% for team in teams %}
|
||||
{% if team_match == team %}
|
||||
{% set user_has_chosen.teampre = true %}
|
||||
<option selected="selected" value="{{ team.name }}">{{ team.name }}</option>
|
||||
{% else %}
|
||||
<option value="{{ team.name }}">{{ team.name }}</option>
|
||||
{% endif %}
|
||||
|
||||
{% if (include_none == true) and (team == model.none_team()) %}
|
||||
<option disabled>──────────</option>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
|
||||
{# Add an empty default if nothing has been chosen #}
|
||||
{% if user_has_chosen.teampre == "false" %}
|
||||
{% if user_has_chosen.teampre == false %}
|
||||
<option value="" selected="selected" disabled="disabled" hidden="hidden"></option>
|
||||
{% endif %}
|
||||
</select>
|
||||
@ -94,44 +126,43 @@
|
||||
{% endmacro %}
|
||||
|
||||
{# Easy nav-bar entries. When a page sets the active_page variable, the current entry will be underlined #}
|
||||
{% macro nav_selector(page='', text='') %}
|
||||
{% macro nav_selector(page, text) %}
|
||||
<a class="nav-link text-nowrap" href="{{ page }}">{% if active_page == page %}<u>{% endif %} {{ text }}
|
||||
{# NOTE: This should be set at the top of each template #}
|
||||
{# NOTE: active_page should be set at the top of each template #}
|
||||
{% if active_page == page %}</u>{% endif %}</a>
|
||||
{% endmacro %}
|
||||
|
||||
{#@formatter:off#}
|
||||
{% macro pxx_guess_colorization(driver_abbr='', result=none) -%}
|
||||
{% if (driver_abbr == result.pxx_driver(-3).abbr) and (driver_abbr != "None") %}fw-bold
|
||||
{% elif (driver_abbr == result.pxx_driver(-2).abbr) and (driver_abbr != "None") %}text-danger fw-bold
|
||||
{% elif (driver_abbr == result.pxx_driver(-1).abbr) and (driver_abbr != "None") %}text-warning fw-bold
|
||||
{% elif (driver_abbr == result.pxx_driver(0).abbr) %}text-success fw-bold
|
||||
{% elif (driver_abbr == result.pxx_driver(1).abbr) and (driver_abbr != "None") %}text-warning fw-bold
|
||||
{% elif (driver_abbr == result.pxx_driver(2).abbr) and (driver_abbr != "None") %}text-danger fw-bold
|
||||
{% elif (driver_abbr == result.pxx_driver(3).abbr) and (driver_abbr != "None") %}fw-bold{% endif %}
|
||||
{% endmacro %}
|
||||
|
||||
{% macro pxx_points_tooltip_text(driver_abbr='', result=none) -%}
|
||||
{% if (driver_abbr == result.pxx_driver(-3).abbr) and (driver_abbr != "None") %}1 Point
|
||||
{% elif (driver_abbr == result.pxx_driver(-2).abbr) and (driver_abbr != "None") %}3 Points
|
||||
{% elif (driver_abbr == result.pxx_driver(-1).abbr) and (driver_abbr != "None") %}6 Points
|
||||
{% elif (driver_abbr == result.pxx_driver(0).abbr) %}10 Points
|
||||
{% elif (driver_abbr == result.pxx_driver(1).abbr) and (driver_abbr != "None") %}6 Points
|
||||
{% elif (driver_abbr == result.pxx_driver(2).abbr) and (driver_abbr != "None") %}3 Points
|
||||
{% elif (driver_abbr == result.pxx_driver(3).abbr) and (driver_abbr != "None") %}1 Point
|
||||
{% else %}0 Points{% endif %}
|
||||
{% macro pxx_guess_colorization(guessed_driver, result) -%}
|
||||
{% if (guessed_driver == result.offset_from_place_to_guess(-3)) and (guessed_driver != model.none_driver()) %}
|
||||
fw-bold
|
||||
{% elif (guessed_driver == result.offset_from_place_to_guess(-2)) and (guessed_driver != model.none_driver()) %}
|
||||
text-danger fw-bold
|
||||
{% elif (guessed_driver == result.offset_from_place_to_guess(-1)) and (guessed_driver != model.none_driver()) %}
|
||||
text-warning fw-bold
|
||||
{% elif (guessed_driver == result.offset_from_place_to_guess( 0)) %}text-success fw-bold
|
||||
{% elif (guessed_driver == result.offset_from_place_to_guess( 1)) and (guessed_driver != model.none_driver()) %}
|
||||
text-warning fw-bold
|
||||
{% elif (guessed_driver == result.offset_from_place_to_guess( 2)) and (guessed_driver != model.none_driver()) %}
|
||||
text-danger fw-bold
|
||||
{% elif (guessed_driver == result.offset_from_place_to_guess( 3)) and (guessed_driver != model.none_driver()) %}
|
||||
fw-bold
|
||||
{% endif %}
|
||||
{%- endmacro %}
|
||||
|
||||
{% macro pxx_standing_tooltip_text(result=none) -%}
|
||||
P{{ result.race.pxx - 3 }}: {{ result.pxx_driver(-3).abbr }}
|
||||
P{{ result.race.pxx - 2 }}: {{ result.pxx_driver(-2).abbr }}
|
||||
P{{ result.race.pxx - 1 }}: {{ result.pxx_driver(-1).abbr }}
|
||||
P{{ result.race.pxx }}: {{ result.pxx_driver(0).abbr }}
|
||||
P{{ result.race.pxx + 1 }}: {{ result.pxx_driver(1).abbr }}
|
||||
P{{ result.race.pxx + 2 }}: {{ result.pxx_driver(2).abbr }}
|
||||
P{{ result.race.pxx + 3 }}: {{ result.pxx_driver(3).abbr }}
|
||||
{% endmacro %}
|
||||
{#@formatter:on#}
|
||||
{% macro dnf_guess_colorization(guessed_driver, result) -%}
|
||||
{% if guessed_driver in result.initial_dnf %}text-success fw-bold
|
||||
{% elif (guessed_driver == model.none_driver()) and (result.initial_dnf | length == 0) %}text-success fw-bold
|
||||
{% endif %}
|
||||
{%- endmacro %}
|
||||
|
||||
{# @formatter:off #}
|
||||
{% macro pxx_standing_tooltip_text(result) %}
|
||||
{%- for position in range(-3, 4) %}
|
||||
{%- set driver = result.offset_from_place_to_guess(position, respect_nc=false) %}
|
||||
{{- driver.abbr ~ result.driver_standing_position_string(driver) }}
|
||||
{% endfor %}
|
||||
{%- endmacro %}
|
||||
{# @formatter:on #}
|
||||
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
@ -170,18 +201,18 @@ P{{ result.race.pxx + 3 }}: {{ result.pxx_driver(3).abbr }}
|
||||
|
||||
<div class="collapse navbar-collapse" id="navbarCollapse">
|
||||
<div class="navbar-nav me-2">
|
||||
{{ nav_selector("/race/" ~ (active_user.name_sanitized if active_user is not none else "Everyone"), "Race Picks") }}
|
||||
{{ nav_selector("/season/" ~ (active_user.name_sanitized if active_user is not none else "Everyone"), "Season Picks") }}
|
||||
{{ nav_selector("/graphs", "Statistics") }}
|
||||
{{ nav_selector("/rules", "Rules") }}
|
||||
{{ nav_selector(page="/race/" ~ model.active_user_name_sanitized_or_everyone(), text="Race Picks") }}
|
||||
{{ nav_selector(page="/season/" ~ model.active_user_name_sanitized_or_everyone(), text="Season Picks") }}
|
||||
{{ nav_selector(page="/graphs", text="Statistics") }}
|
||||
{{ nav_selector(page="/rules", text="Rules") }}
|
||||
</div>
|
||||
|
||||
{% block navbar_center %}{% endblock navbar_center %}
|
||||
<div class="flex-grow-1"></div>
|
||||
|
||||
<div class="navbar-nav">
|
||||
{{ nav_selector("/result", "Enter Race Result") }}
|
||||
{{ nav_selector("/user", "Manage Users") }}
|
||||
{{ nav_selector(page="/result", text="Enter Race Result") }}
|
||||
{{ nav_selector(page="/user", text="Manage Users") }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -3,33 +3,25 @@
|
||||
{% block title %}Formula 10 - Race Result{% endblock title %}
|
||||
|
||||
{% set active_page = "/result" %}
|
||||
{% set active_user = none %}
|
||||
|
||||
{% block head_extra %}
|
||||
<link href="../style/draggable.css" rel="stylesheet">
|
||||
<script src="../script/draggable.js" defer></script>
|
||||
<link href="../static/style/draggable.css" rel="stylesheet">
|
||||
<script src="../static/script/draggable.js" defer></script>
|
||||
{% endblock head_extra %}
|
||||
|
||||
{% set current_race = model.first_race_without_result() %}
|
||||
|
||||
{% block navbar_center %}
|
||||
|
||||
{% if model.all_race_results() | length > 0 %}
|
||||
<div class="dropdown">
|
||||
<button class="btn btn-outline-danger dropdown-toggle" type="button" data-bs-toggle="dropdown"
|
||||
aria-expanded="false">
|
||||
{% if active_result is not none %}
|
||||
{{ active_result.race.name }}
|
||||
{% elif current_race is not none %}
|
||||
{{ current_race.name }}
|
||||
{% else %}
|
||||
{{ model.all_race_results()[0].race.name }}
|
||||
{% endif %}
|
||||
{{ model.active_result_race_name_or_current_race_name() }}
|
||||
</button>
|
||||
<ul class="dropdown-menu">
|
||||
{% if model.first_race_without_result() is not none %}
|
||||
{% if model.current_race is not none %}
|
||||
<li>
|
||||
<a class="dropdown-item" href="/result/{{ current_race.name }}">{{ current_race.name }}</a>
|
||||
<a class="dropdown-item"
|
||||
href="/result/{{ model.current_race.name_sanitized }}">{{ model.current_race.name }}</a>
|
||||
</li>
|
||||
<li>
|
||||
<hr class="dropdown-divider">
|
||||
@ -39,7 +31,7 @@
|
||||
{% for result in model.all_race_results() %}
|
||||
<li>
|
||||
<a class="dropdown-item"
|
||||
href="/result/{{ result.race.name }}">{{ result.race.name }}</a>
|
||||
href="/result/{{ result.race.name_sanitized }}">{{ result.race.name }}</a>
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
@ -56,28 +48,14 @@
|
||||
<div class="card-body">
|
||||
|
||||
<h5 class="card-title">
|
||||
{% if active_result is not none %}
|
||||
{{ active_result.race.name }}
|
||||
{% elif current_race is not none %}
|
||||
{{ current_race.name }}
|
||||
{% else %}
|
||||
{{ model.all_race_results()[0].race.name }}
|
||||
{% endif %}
|
||||
{{ model.active_result_race_name_or_current_race_name() }}
|
||||
</h5>
|
||||
|
||||
{# @formatter:off #}
|
||||
<form action="/result-enter/{%- if active_result is not none %}{{ active_result.race.name }}{% else %}{{ current_race.name }}{% endif %}"
|
||||
<form action="/result-enter/{{ model.active_result_race_name_or_current_race_name_sanitized() }}"
|
||||
method="post">
|
||||
{# @formatter:on #}
|
||||
<ul id="columns" class="list-group list-group-flush">
|
||||
|
||||
{% if active_result is not none %}
|
||||
{% set drivers = active_result.all_positions %}
|
||||
{% else %}
|
||||
{% set drivers = model.all_drivers_except_none() %}
|
||||
{% endif %}
|
||||
|
||||
{% for driver in drivers %}
|
||||
{% for driver in model.all_drivers_or_active_result_standing_drivers() %}
|
||||
<li class="list-group-item column p-1" draggable="true">
|
||||
{{ driver.name }}
|
||||
|
||||
@ -86,7 +64,7 @@
|
||||
<div class="form-check form-check-reverse d-inline-block">
|
||||
<input type="checkbox" class="form-check-input" value="{{ driver.name }}"
|
||||
id="first-dnf-{{ driver.name }}" name="first-dnf-drivers"
|
||||
{% if (active_result is not none) and (driver in active_result.first_dnf_drivers) %}checked{% endif %}>
|
||||
{% if (model.active_result is not none) and (driver in model.active_result.initial_dnf) %}checked{% endif %}>
|
||||
<label for="first-dnf-{{ driver.name }}"
|
||||
class="form-check-label text-muted">1. DNF</label>
|
||||
</div>
|
||||
@ -95,7 +73,7 @@
|
||||
<div class="form-check form-check-reverse d-inline-block mx-2">
|
||||
<input type="checkbox" class="form-check-input" value="{{ driver.name }}"
|
||||
id="dnf-{{ driver.name }}" name="dnf-drivers"
|
||||
{% if (active_result is not none) and (driver in active_result.dnf_drivers) %}checked{% endif %}>
|
||||
{% if (model.active_result is not none) and (driver in model.active_result.all_dnfs) %}checked{% endif %}>
|
||||
<label for="dnf-{{ driver.name }}"
|
||||
class="form-check-label text-muted">DNF</label>
|
||||
</div>
|
||||
@ -104,7 +82,7 @@
|
||||
<div class="form-check form-check-reverse d-inline-block">
|
||||
<input type="checkbox" class="form-check-input" value="{{ driver.name }}"
|
||||
id="exclude-{{ driver.name }}" name="excluded-drivers"
|
||||
{% if (active_result is not none) and (driver in active_result.excluded_drivers) %}checked{% endif %}>
|
||||
{% if (model.active_result is not none) and (driver in model.active_result.standing_exclusions) %}checked{% endif %}>
|
||||
<label for="exclude-{{ driver.name }}"
|
||||
class="form-check-label text-muted" data-bs-toggle="tooltip"
|
||||
title="Driver is not counted for standing">NC</label>
|
||||
|
@ -2,31 +2,10 @@
|
||||
|
||||
{% block title %}Formula 10 - Race{% endblock title %}
|
||||
|
||||
{% set active_page = "/race/" ~ (active_user.name_sanitized if active_user is not none else "Everyone") %}
|
||||
{% set active_page = "/race/" ~ model.active_user_name_sanitized_or_everyone() %}
|
||||
|
||||
{% block navbar_center %}
|
||||
{% if model.all_users() | length > 1 %}
|
||||
<div class="dropdown">
|
||||
<button class="btn btn-outline-danger dropdown-toggle" type="button" data-bs-toggle="dropdown"
|
||||
aria-expanded="false">
|
||||
{% if active_user is none %}
|
||||
Everyone
|
||||
{% else %}
|
||||
{{ active_user.name }}
|
||||
{% endif %}
|
||||
</button>
|
||||
<ul class="dropdown-menu">
|
||||
<li><a class="dropdown-item" href="/race/Everyone">Everyone</a></li>
|
||||
<li>
|
||||
<hr class="dropdown-divider">
|
||||
</li>
|
||||
|
||||
{% for user in model.all_users() %}
|
||||
<li><a class="dropdown-item" href="/race/{{ user.name_sanitized }}">{{ user.name }}</a></li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
</div>
|
||||
{% endif %}
|
||||
{{ active_user_dropdown(page='race') }}
|
||||
{% endblock navbar_center %}
|
||||
|
||||
{% block body %}
|
||||
@ -36,7 +15,7 @@
|
||||
<tr>
|
||||
<th scope="col" rowspan="2" class="text-center" style="width: 200px;">Race</th>
|
||||
|
||||
<th scope="col" {% if active_user is none %}colspan="{{ model.all_users() | length }}"{% endif %}
|
||||
<th scope="col" {% if model.active_user is none %}colspan="{{ model.all_users() | length }}"{% endif %}
|
||||
class="text-center">Call
|
||||
</th>
|
||||
|
||||
@ -50,41 +29,40 @@
|
||||
<tr>
|
||||
<td> </td>
|
||||
|
||||
{% if active_user is none %}
|
||||
{# Link should only be visible if all users are visible #}
|
||||
{% if model.active_user is not none %}
|
||||
<td class="text-center text-nowrap" style="min-width: 100px;">{{ model.active_user.name }}</td>
|
||||
{% else %}
|
||||
{% for user in model.all_users() %}
|
||||
<td class="text-center text-nowrap" style="min-width: 100px;">
|
||||
<a href="/race/{{ user.name_sanitized }}" class="link-dark">{{ user.name }}</a>
|
||||
</td>
|
||||
{% endfor %}
|
||||
{% else %}
|
||||
<td class="text-center text-nowrap" style="min-width: 100px;">{{ active_user.name }}</td>
|
||||
{% endif %}
|
||||
|
||||
<td> </td>
|
||||
</tr>
|
||||
|
||||
{% set current_race = model.first_race_without_result() %}
|
||||
|
||||
{# Current Result, only displayed for all users overview and if guess is remaining #}
|
||||
{% if (active_user is none) and (model.first_race_without_result() is not none) %}
|
||||
{% if (model.active_user is none) and (model.current_race is not none) %}
|
||||
|
||||
<tr class="table-danger">
|
||||
<td class="text-nowrap">
|
||||
<span class="fw-bold">{{ current_race.number }}:</span> {{ current_race.name }}<br>
|
||||
<small><span class="fw-bold">Guess:</span> P{{ current_race.pxx }}</small>
|
||||
<span class="fw-bold">{{ model.current_race.number }}:</span> {{ model.current_race.name }}<br>
|
||||
<small><span class="fw-bold">Guess:</span> P{{ model.current_race.place_to_guess }}</small>
|
||||
</td>
|
||||
|
||||
{% for user in model.all_users() %}
|
||||
{% set user_guess = model.race_guesses_by(user_name=user.name, race_name=current_race.name) %}
|
||||
{% set user_guess = model.race_guesses_by(user_name=user.name, race_name=model.current_race.name) %}
|
||||
|
||||
<td class="text-center text-nowrap">
|
||||
{% if user_guess is not none %}
|
||||
<ul class="list-group list-group-flush">
|
||||
<li class="list-group-item" style="background-color: inherit;">
|
||||
{{ user_guess.pxx.abbr }}
|
||||
{{ user_guess.pxx_guess.abbr }}
|
||||
</li>
|
||||
<li class="list-group-item" style="background-color: inherit;">
|
||||
{{ user_guess.dnf.abbr }}
|
||||
{{ user_guess.dnf_guess.abbr }}
|
||||
</li>
|
||||
</ul>
|
||||
{% else %}
|
||||
@ -98,28 +76,30 @@
|
||||
{% endif %}
|
||||
|
||||
{# Enter Guess, only displayed for single user focused view and if guess is remaining #}
|
||||
{% if (active_user is not none) and (model.first_race_without_result() is not none) %}
|
||||
{% if (model.active_user is not none) and (model.current_race is not none) %}
|
||||
<tr class="table-danger">
|
||||
<td class="text-nowrap">
|
||||
<span class="fw-bold">{{ current_race.number }}:</span> {{ current_race.name }}<br>
|
||||
<small><span class="fw-bold">Guess:</span> P{{ current_race.pxx }}</small>
|
||||
<span class="fw-bold">{{ model.current_race.number }}:</span> {{ model.current_race.name }}<br>
|
||||
<small><span class="fw-bold">Guess:</span> P{{ model.current_race.place_to_guess }}</small>
|
||||
</td>
|
||||
|
||||
<td>
|
||||
<form action="/race-guess/{{ current_race.name_sanitized }}/{{ active_user.name_sanitized }}" method="post">
|
||||
{% set user_guess = model.race_guesses_by(user_name=active_user.name, race_name=current_race.name) %}
|
||||
<form action="/race-guess/{{ model.current_race.name_sanitized }}/{{ model.active_user.name_sanitized }}"
|
||||
method="post">
|
||||
{% set user_guess = model.race_guesses_by(user_name=model.active_user.name, race_name=model.current_race.name) %}
|
||||
|
||||
{# Driver PXX Select #}
|
||||
{{ driver_select_with_preselect(user_guess.pxx.abbr if user_guess is not none else "", "pxxselect", "P" ~ current_race.pxx ~ ":") }}
|
||||
{{ driver_select_with_preselect(driver_match=user_guess.pxx_guess, name="pxxselect", label="P" ~ model.current_race.place_to_guess ~ ":", include_none=true) }}
|
||||
|
||||
<div class="mt-2"></div>
|
||||
|
||||
{# Driver DNF Select #}
|
||||
{{ driver_select_with_preselect(user_guess.dnf.abbr if user_guess is not none else "", "dnfselect", "DNF:") }}
|
||||
{{ driver_select_with_preselect(driver_match=user_guess.dnf_guess, name="dnfselect", label="DNF:", include_none=true) }}
|
||||
|
||||
<input type="submit" class="btn btn-danger mt-2 w-100" value="Save">
|
||||
</form>
|
||||
<form action="/race-guess-delete/{{ current_race.name_sanitized }}/{{ active_user.name_sanitized }}" method="post">
|
||||
<form action="/race-guess-delete/{{ model.current_race.name_sanitized }}/{{ model.active_user.name_sanitized }}"
|
||||
method="post">
|
||||
<input type="submit" class="btn btn-dark mt-2 w-100" value="Delete">
|
||||
</form>
|
||||
</td>
|
||||
@ -133,29 +113,25 @@
|
||||
<tr>
|
||||
<td class="text-nowrap">
|
||||
<span class="fw-bold">{{ past_result.race.number }}:</span> {{ past_result.race.name }}<br>
|
||||
<small><span class="fw-bold">Guessed:</span> P{{ past_result.race.pxx }}</small>
|
||||
<small><span class="fw-bold">Guessed:</span> P{{ past_result.race.place_to_guess }}</small>
|
||||
</td>
|
||||
|
||||
{% if active_user is none %}
|
||||
{% set users = model.all_users() %}
|
||||
{% else %}
|
||||
{% set users = [active_user] %}
|
||||
{% endif %}
|
||||
|
||||
{% for user in users %}
|
||||
{% for user in model.all_users_or_active_user() %}
|
||||
<td class="text-center text-nowrap">
|
||||
{% set user_guess = model.race_guesses_by(user_name=user.name, race_name=past_result.race.name) %}
|
||||
|
||||
{% if user_guess is not none %}
|
||||
<ul class="list-group list-group-flush">
|
||||
<li class="list-group-item {{ pxx_guess_colorization(user_guess.pxx.abbr, past_result) }}">
|
||||
<span data-bs-toggle="tooltip" title="{{ pxx_points_tooltip_text(user_guess.pxx.abbr, past_result) }}">
|
||||
{{ user_guess.pxx.abbr }}{% if user_guess.pxx.abbr != "None" %} ({{ past_result.pxx_driver_position_string(user_guess.pxx.name) }}){% endif %}
|
||||
<li class="list-group-item {{ pxx_guess_colorization(guessed_driver=user_guess.pxx_guess, result=past_result) }}">
|
||||
<span data-bs-toggle="tooltip"
|
||||
title="{{ past_result.driver_standing_points_string(user_guess.pxx_guess) }}">
|
||||
{{ user_guess.pxx_guess.abbr ~ past_result.driver_standing_position_string(user_guess.pxx_guess) }}
|
||||
</span>
|
||||
</li>
|
||||
<li class="list-group-item {% if user_guess.dnf.name in past_result.first_dnf_driver_names %}text-success fw-bold{% endif %}">
|
||||
<span data-bs-toggle="tooltip" title="{% if user_guess.dnf.name in past_result.first_dnf_driver_names %}10 Points{% else %}0 Points{% endif %}">
|
||||
{{ user_guess.dnf.abbr }}
|
||||
<li class="list-group-item {{ dnf_guess_colorization(guessed_driver=user_guess.dnf_guess, result=past_result) }}">
|
||||
<span data-bs-toggle="tooltip"
|
||||
title="{{ past_result.driver_dnf_points_string(user_guess.dnf_guess) }}">
|
||||
{{ user_guess.dnf_guess.abbr }}
|
||||
</span>
|
||||
</li>
|
||||
</ul>
|
||||
@ -165,15 +141,16 @@
|
||||
</td>
|
||||
{% endfor %}
|
||||
|
||||
{# Actual result #}
|
||||
<td class="text-center text-nowrap">
|
||||
<ul class="list-group list-group-flush">
|
||||
<li class="list-group-item">
|
||||
<span data-bs-toggle="tooltip" title="{{ pxx_standing_tooltip_text(past_result) }}">
|
||||
P{{ past_result.race.pxx }}: {{ past_result.pxx_driver().abbr }}
|
||||
<span data-bs-toggle="tooltip" title="{{ pxx_standing_tooltip_text(result=past_result) }}">
|
||||
P{{ past_result.race.place_to_guess }}: {{ past_result.offset_from_place_to_guess(0).abbr }}
|
||||
</span>
|
||||
</li>
|
||||
<li class="list-group-item">
|
||||
DNF: {% for dnf_driver in past_result.first_dnf_drivers %}{{ dnf_driver.abbr }} {% endfor %}</li>
|
||||
DNF: {{ past_result.initial_dnf_string() }}</li>
|
||||
</ul>
|
||||
</td>
|
||||
</tr>
|
||||
|
@ -2,52 +2,28 @@
|
||||
|
||||
{% block title %}Formula 10 - Season{% endblock title %}
|
||||
|
||||
{% set active_page = "/season/" ~ (active_user.name_sanitized if active_user is not none else "Everyone") %}
|
||||
{% set active_page = "/season/" ~ model.active_user_name_sanitized_or_everyone() %}
|
||||
|
||||
{% block navbar_center %}
|
||||
{% if model.all_users() | length > 1 %}
|
||||
<div class="dropdown">
|
||||
<button class="btn btn-outline-danger dropdown-toggle" type="button" data-bs-toggle="dropdown"
|
||||
aria-expanded="false">
|
||||
{% if active_user is none %}
|
||||
Everyone
|
||||
{% else %}
|
||||
{{ active_user.name }}
|
||||
{% endif %}
|
||||
</button>
|
||||
<ul class="dropdown-menu">
|
||||
<li><a class="dropdown-item" href="/season/Everyone">Everyone</a></li>
|
||||
<li>
|
||||
<hr class="dropdown-divider">
|
||||
</li>
|
||||
|
||||
{% for user in model.all_users() %}
|
||||
<li><a class="dropdown-item" href="/season/{{ user.name }}">{{ user.name }}</a></li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
</div>
|
||||
{% endif %}
|
||||
{{ active_user_dropdown(page='season') }}
|
||||
{% endblock navbar_center %}
|
||||
|
||||
{% block body %}
|
||||
|
||||
<div class="grid" style="grid-template-columns: repeat(auto-fit, minmax(450px, 1fr));">
|
||||
|
||||
{% if active_user is none %}
|
||||
{% set users = model.all_users() %}
|
||||
{% else %}
|
||||
{% set users = [active_user] %}
|
||||
{% endif %}
|
||||
{% for user in users %}
|
||||
{% for user in model.all_users_or_active_user() %}
|
||||
|
||||
<div class="card mb-2 shadow-sm" style="width: 450px;">
|
||||
<div class="card-body">
|
||||
{% if active_user is none %}
|
||||
|
||||
{# Link should only be visible if all users are visible #}
|
||||
{% if model.active_user is not none %}
|
||||
<h5 class="card-title">{{ user.name }}</h5>
|
||||
{% else %}
|
||||
<a href="/season/{{ user.name }}" class="link-dark">
|
||||
<h5 class="card-title">{{ user.name }}</h5>
|
||||
</a>
|
||||
{% else %}
|
||||
<h5 class="card-title">{{ user.name }}</h5>
|
||||
{% endif %}
|
||||
|
||||
{% set user_guess = model.season_guesses_by(user_name=user.name) %}
|
||||
@ -58,7 +34,7 @@
|
||||
<div class="form-floating">
|
||||
{% if user_guess is not none %}
|
||||
<textarea class="form-control" id="hot-take-input-{{ user.name }}" name="hottakeselect"
|
||||
style="height: 50px">{{ user_guess.hot_take }}</textarea>
|
||||
style="height: 50px">{{ user_guess.hot_take_string() }}</textarea>
|
||||
{% else %}
|
||||
<textarea class="form-control" id="hot-take-input-{{ user.name }}" name="hottakeselect"
|
||||
style="height: 50px"></textarea>
|
||||
@ -69,42 +45,40 @@
|
||||
|
||||
{# P2 Constructor #}
|
||||
<div class="mt-2">
|
||||
{{ team_select_with_preselect(user_guess.p2_team.name if user_guess is not none else "",
|
||||
"p2select", "P2 in WCC:") }}
|
||||
{{ team_select_with_preselect(team_match=user_guess.p2_wcc, name="p2select", label="P2 in WCC:", include_none=false) }}
|
||||
</div>
|
||||
|
||||
{# Most Overtakes + DNFs #}
|
||||
<div class="input-group mt-2">
|
||||
{{ driver_select_with_preselect(user_guess.overtake_driver.abbr if user_guess is not none else "",
|
||||
"overtakeselect", "Most overtakes:", false) }}
|
||||
{{ driver_select_with_preselect(user_guess.dnf_driver.abbr if user_guess is not none else "",
|
||||
"dnfselect", "Most DNFs:", false) }}
|
||||
{{ driver_select_with_preselect(driver_match=user_guess.most_overtakes, name="overtakeselect", label="Most overtakes:", include_none=false) }}
|
||||
{{ driver_select_with_preselect(driver_match=user_guess.most_dnfs, name="dnfselect", label="Most DNFs:", include_none=false) }}
|
||||
</div>
|
||||
|
||||
{# Most Gained + Lost #}
|
||||
<div class="input-group mt-2" data-bs-toggle="tooltip" title="Which driver will gain/lose the most places in comparison to last season's results?">
|
||||
{{ driver_select_with_preselect(user_guess.gained_driver.abbr if user_guess is not none else "",
|
||||
"gainedselect", "Most WDC places gained:", false) }}
|
||||
{{ driver_select_with_preselect(user_guess.lost_driver.abbr if user_guess is not none else "",
|
||||
"lostselect", "Most WDC places lost:", false) }}
|
||||
<div class="input-group mt-2" data-bs-toggle="tooltip"
|
||||
title="Which driver will gain/lose the most places in comparison to last season's results?">
|
||||
{{ driver_select_with_preselect(driver_match=user_guess.most_wdc_gained, name="gainedselect", label="Most WDC places gained:", include_none=false, drivers=model.drivers_for_wdc_gained()) }}
|
||||
{{ driver_select_with_preselect(driver_match=user_guess.most_wdc_lost, name="lostselect", label="Most WDC places lost:", include_none=false) }}
|
||||
</div>
|
||||
|
||||
{# Team-internal Winners #}
|
||||
<h6 class="card-subtitle mt-2" data-bs-toggle="tooltip" title="Which driver will finish the season higher than his teammate?">Teammate battle winners:</h6>
|
||||
<h6 class="card-subtitle mt-2" data-bs-toggle="tooltip"
|
||||
title="Which driver will finish the season higher than his teammate?">Teammate battle
|
||||
winners:</h6>
|
||||
<div class="grid mt-2" style="width: 450px; row-gap: 0;">
|
||||
{% for team in model.all_teams() %}
|
||||
{% set driver_a_name = model.drivers_by(team_name=team.name)[0].name %}
|
||||
{% set driver_b_name = model.drivers_by(team_name=team.name)[1].name %}
|
||||
{% for team in model.all_teams(include_none=false) %}
|
||||
{% set driver_a = model.drivers_by(team_name=team.name)[0] %}
|
||||
{% set driver_b = model.drivers_by(team_name=team.name)[1] %}
|
||||
|
||||
<div class="g-col-6">
|
||||
<div class="form-check form-check-inline">
|
||||
<input class="form-check-input" type="radio"
|
||||
name="teamwinner-{{ team.name }}"
|
||||
id="teamwinner-{{ team.name }}-1-{{ user.name }}"
|
||||
value="{{ driver_a_name }}"
|
||||
{% if (user_guess is not none) and (driver_a_name in user_guess.team_winners.teamwinner_driver_names) %}checked="checked"{% endif %}>
|
||||
value="{{ driver_a.name }}"
|
||||
{% if (user_guess is not none) and (driver_a in user_guess.team_winners) %}checked="checked"{% endif %}>
|
||||
<label class="form-check-label"
|
||||
for="teamwinner-{{ team.name }}-1-{{ user.name }}">{{ driver_a_name }}</label>
|
||||
for="teamwinner-{{ team.name }}-1-{{ user.name }}">{{ driver_a.name }}</label>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -113,31 +87,32 @@
|
||||
<input class="form-check-input" type="radio"
|
||||
name="teamwinner-{{ team.name }}"
|
||||
id="teamwinner-{{ team.name }}-2-{{ user.name }}"
|
||||
value="{{ driver_b_name }}"
|
||||
{% if (user_guess is not none) and (driver_b_name in user_guess.team_winners.teamwinner_driver_names) %}checked="checked"{% endif %}>
|
||||
value="{{ driver_b.name }}"
|
||||
{% if (user_guess is not none) and (driver_b in user_guess.team_winners) %}checked="checked"{% endif %}>
|
||||
<label class="form-check-label"
|
||||
for="teamwinner-{{ team.name }}-2-{{ user.name }}">{{ driver_b_name }}</label>
|
||||
for="teamwinner-{{ team.name }}-2-{{ user.name }}">{{ driver_b.name }}</label>
|
||||
</div>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
|
||||
{# Drivers with Podiums #}
|
||||
<h6 class="card-subtitle mt-2" data-bs-toggle="tooltip" title="Which driver will reach at least a single podium?">Drivers with podium(s):</h6>
|
||||
<h6 class="card-subtitle mt-2" data-bs-toggle="tooltip"
|
||||
title="Which driver will reach at least a single podium?">Drivers with podium(s):</h6>
|
||||
<div class="grid mt-2" style="width: 450px; row-gap: 0;">
|
||||
{% for team in model.all_teams() %}
|
||||
{% set driver_a_name = model.drivers_by(team_name=team.name)[0].name %}
|
||||
{% set driver_b_name = model.drivers_by(team_name=team.name)[1].name %}
|
||||
{% for team in model.all_teams(include_none=false) %}
|
||||
{% set driver_a = model.drivers_by(team_name=team.name)[0] %}
|
||||
{% set driver_b = model.drivers_by(team_name=team.name)[1] %}
|
||||
|
||||
<div class="g-col-6">
|
||||
<div class="form-check form-check-inline">
|
||||
<input class="form-check-input" type="checkbox"
|
||||
name="podiumdrivers"
|
||||
id="podium-{{ driver_a_name }}-{{ user.name }}"
|
||||
value="{{ driver_a_name }}"
|
||||
{% if (user_guess is not none) and (driver_a_name in user_guess.podium_drivers.podium_driver_names) %}checked="checked"{% endif %}>
|
||||
id="podium-{{ driver_a.name }}-{{ user.name }}"
|
||||
value="{{ driver_a.name }}"
|
||||
{% if (user_guess is not none) and (driver_a in user_guess.podiums) %}checked="checked"{% endif %}>
|
||||
<label class="form-check-label"
|
||||
for="podium-{{ driver_a_name }}-{{ user.name }}">{{ driver_a_name }}</label>
|
||||
for="podium-{{ driver_a.name }}-{{ user.name }}">{{ driver_a.name }}</label>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -145,11 +120,11 @@
|
||||
<div class="form-check form-check-inline">
|
||||
<input class="form-check-input" type="checkbox"
|
||||
name="podiumdrivers"
|
||||
id="podium-{{ driver_b_name }}-{{ user.name }}"
|
||||
value="{{ driver_b_name }}"
|
||||
{% if (user_guess is not none) and (driver_b_name in user_guess.podium_drivers.podium_driver_names) %}checked="checked"{% endif %}>
|
||||
id="podium-{{ driver_b.name }}-{{ user.name }}"
|
||||
value="{{ driver_b.name }}"
|
||||
{% if (user_guess is not none) and (driver_b in user_guess.podiums) %}checked="checked"{% endif %}>
|
||||
<label class="form-check-label"
|
||||
for="podium-{{ driver_b_name }}-{{ user.name }}">{{ driver_b_name }}</label>
|
||||
for="podium-{{ driver_b.name }}-{{ user.name }}">{{ driver_b.name }}</label>
|
||||
</div>
|
||||
</div>
|
||||
{% endfor %}
|
||||
|
@ -3,7 +3,6 @@
|
||||
{% block title %}Formula 10 - Users{% endblock title %}
|
||||
|
||||
{% set active_page = "/users" %}
|
||||
{% set active_user = none %}
|
||||
|
||||
{% block body %}
|
||||
|
||||
@ -58,8 +57,7 @@
|
||||
|
||||
<div class="form-text">
|
||||
"Deleting" a user just hides it from the user interface without deleting any inputs, your
|
||||
"pERsoNaL
|
||||
DaTa" belongs to ME now.<br>
|
||||
"pERsoNaL DaTa" is not yours anyway.<br>
|
||||
Re-adding a user with the same name will "restore" it. That doesn't mean you're allowed to
|
||||
remove everyone though.
|
||||
</div>
|
||||
@ -68,16 +66,16 @@
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
<div class="card mt-2 border-danger shadow-sm">
|
||||
<div class="card-body">
|
||||
<h5 class="card-title">Functions that should not be public</h5>
|
||||
<h6 class="card-subtitle mb-2">(F you if you click this without knowing what it does)</h6>
|
||||
{# <div class="card mt-2 border-danger shadow-sm">#}
|
||||
{# <div class="card-body">#}
|
||||
{# <h5 class="card-title">Functions that should not be public</h5>#}
|
||||
{# <h6 class="card-subtitle mb-2">(F you if you click this without knowing what it does)</h6>#}
|
||||
|
||||
<a class="btn btn-outline-danger" href="/save/all">Save all data</a>
|
||||
<a class="btn btn-outline-danger" href="/load/all">Load all data</a>
|
||||
<a class="btn btn-outline-danger" href="/load/static">Load static data</a>
|
||||
<a class="btn btn-outline-danger" href="/load/dynamic">Load dynamic data</a>
|
||||
</div>
|
||||
</div>
|
||||
{# <a class="btn btn-outline-danger" href="/save/all">Save all data</a>#}
|
||||
{# <a class="btn btn-outline-danger" href="/load/all">Load all data</a>#}
|
||||
{# <a class="btn btn-outline-danger" href="/load/static">Load static data</a>#}
|
||||
{# <a class="btn btn-outline-danger" href="/load/dynamic">Load dynamic data</a>#}
|
||||
{# </div>#}
|
||||
{# </div>#}
|
||||
|
||||
{% endblock body %}
|
||||
|
Reference in New Issue
Block a user