From 57c70632ef7f528fe2ae6b358cbc4d1565213a1b Mon Sep 17 00:00:00 2001
From: Martin Mares <mj@ucw.cz>
Date: Sat, 25 Sep 2021 15:43:48 +0200
Subject: [PATCH] =?UTF-8?q?Hierarchie:=20Organiz=C3=A1torsk=C3=A1=20hlavn?=
=?UTF-8?q?=C3=AD=20str=C3=A1nka?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Kromě soutěží odkazuje i na hierarchické stránky kol, pokud jsem
garant vyšší úrovně, než je úroveň kola.
---
mo/web/org.py | 61 ++++++++++++++++++---------------
mo/web/templates/org_index.html | 36 ++++++++++++-------
2 files changed, 58 insertions(+), 39 deletions(-)
diff --git a/mo/web/org.py b/mo/web/org.py
index a07d6261..4830309a 100644
--- a/mo/web/org.py
+++ b/mo/web/org.py
@@ -1,7 +1,8 @@
+from dataclasses import dataclass, field
from flask import render_template, redirect, url_for, request, flash, g
from sqlalchemy import and_, or_
from sqlalchemy.orm import aliased, joinedload
-from typing import List, Set, Dict
+from typing import List, Set, Optional
import mo.config as config
import mo.db as db
@@ -12,6 +13,15 @@ from mo.web.jinja import user_url
from mo.web.table import Table, Row, Column
+@dataclass
+class OrgOverview:
+ round: db.Round
+ place: db.Place
+ contest: Optional[db.Contest]
+ role_set: Set[db.RoleType] = field(default_factory=set)
+ role_list: List[db.RoleType] = field(default_factory=list)
+
+
@app.route('/org/')
def org_index():
if 'place' in request.args:
@@ -33,36 +43,33 @@ def org_index():
flash('ID uživatele musí být číslo', 'danger')
sess = db.get_session()
- ctr = (sess.query(db.Contest, db.UserRole)
- .select_from(db.UserRole, db.Round, db.Contest)
- .filter(and_(db.UserRole.user_id == g.user.user_id,
- or_(db.UserRole.category == None, db.UserRole.category == db.Round.category),
- or_(db.UserRole.year == None, db.UserRole.year == db.Round.year),
- or_(db.UserRole.seq == None, db.UserRole.seq == db.Round.seq),
- db.Round.year == config.CURRENT_YEAR,
- db.Contest.round_id == db.Round.round_id,
- db.Contest.place_id == db.UserRole.place_id))
- .options(joinedload(db.Contest.place))
+ rcu = (sess.query(db.Round, db.Contest, db.UserRole)
+ .select_from(db.UserRole)
+ .join(db.Place)
+ .join(db.Round, and_(db.UserRole.user_id == g.user.user_id,
+ or_(db.UserRole.category == None, db.UserRole.category == db.Round.category),
+ or_(db.UserRole.year == None, db.UserRole.year == db.Round.year),
+ or_(db.UserRole.seq == None, db.UserRole.seq == db.Round.seq),
+ db.Place.level <= db.Round.level))
+ .outerjoin(db.Contest, and_(db.Contest.round_id == db.Round.round_id, db.Contest.place_id == db.UserRole.place_id))
+ .filter(db.Round.year == config.CURRENT_YEAR)
+ .options(joinedload(db.UserRole.place))
.order_by(db.Round.level, db.Round.category, db.Round.seq, db.Round.part,
db.Contest.place_id, db.Contest.contest_id)
.all())
- # Pokud máme pro jednu soutěž více rolí, zkombinujeme je
- contests: List[db.Contest] = []
- contest_role_sets: Dict[db.Contest, Set[db.RoleType]] = {}
- for ct, ur in ctr:
- if len(contests) == 0 or contests[-1] != ct:
- contests.append(ct)
- contest_role_sets[ct.contest_id] = set()
- contest_role_sets[ct.contest_id].add(ur.role)
-
- # Role pro každou soutěž setřídíme podle důležitosti
- contest_roles: Dict[db.Contest, List[db.RoleType]] = {
- ct_id: sorted(list(contest_role_sets[ct_id]), key=lambda r: mo.rights.role_order_by_type[r])
- for ct_id in contest_role_sets.keys()
- }
-
- return render_template('org_index.html', contests=contests, contest_roles=contest_roles, role_type_names=db.role_type_names)
+ overview: List[OrgOverview] = []
+ for r, ct, ur in rcu:
+ o = overview[-1] if overview else None
+ if not (o and o.round == r and o.place == ur.place):
+ o = OrgOverview(round=r, place=ur.place, contest=ct)
+ overview.append(o)
+ o.role_set.add(ur.role)
+
+ for o in overview:
+ o.role_list = sorted(o.role_set, key=lambda r: mo.rights.role_order_by_type[r])
+
+ return render_template('org_index.html', overview=overview, role_type_names=db.role_type_names)
school_export_columns = (
diff --git a/mo/web/templates/org_index.html b/mo/web/templates/org_index.html
index 40cc4eac..8436ddc6 100644
--- a/mo/web/templates/org_index.html
+++ b/mo/web/templates/org_index.html
@@ -2,34 +2,46 @@
{% block title %}Organizátorské rozhraní{% endblock %}
{% block body %}
-{% if contests %}
+{% if overview %}
<h3>Moje soutěže</h3>
<table class="table table-bordered table-condensed greyhead">
{% set curr = namespace(level=-1) %}
- {% for c in contests %}
- {% if curr.level != c.round.level %}
+ {% for o in overview %}
+ {% if curr.level != o.round.level %}
<thead><tr>
<th>ID
<th>Kategorie
<th>Kolo
- <th>{{ c.round.get_level().name|capitalize }}
+ <th>{{ o.round.get_level().name|capitalize }}
<th>Stav
<th>Moje role
<th>Odkazy
</thead>
- {% set curr.level = c.round.level %}
+ {% set curr.level = o.round.level %}
+ {% endif %}
+
+ {% if o.contest %}
+ {% set detail_url = url_for('org_contest', ct_id=o.contest.contest_id) %}
+ {% elif o.place.level == 0 %}
+ {% set detail_url = url_for('org_round', round_id=o.round.round_id) %}
+ {% else %}
+ {% set detail_url = url_for('org_round', round_id=o.round.round_id, hier_id=o.place.place_id) %}
{% endif %}
<tr>
- <td><a href='{{ url_for('org_contest', ct_id=c.contest_id) }}'>{{ c.round.round_code() }}</a>
- <td class="text-center"><b>{{ c.round.category }}</b>
- <td>{{ c.round.name }}
- <td>{{ c.place.name }}
- <td class="rstate-{{c.state.name}}">{{ c.state.friendly_name() }}
- <td>{% for r in contest_roles[c.contest_id] %}{{ role_type_names[r] }}{% if not loop.last %}<br>{% endif %}{% endfor %}
+ <td><a href='{{ detail_url }}'>{{ o.round.round_code() }}</a>
+ <td class="text-center"><b>{{ o.round.category }}</b>
+ <td>{{ o.round.name }}
+ {% if o.contest %}
+ <td>{{ o.place.name }}
+ <td class="rstate-{{o.contest.state.name}}">{{ o.contest.state.friendly_name() }}
+ {% else %}
+ <td><i>{{ o.place.name_locative() }}</i>
<td>
- <a class="btn btn-xs btn-primary" href='{{ url_for('org_contest', ct_id=c.contest_id) }}'>Detail</a>
+ {% endif %}
+ <td>{% for r in o.role_list %}{{ role_type_names[r] }}{% if not loop.last %}<br>{% endif %}{% endfor %}
+ <td><a class="btn btn-xs btn-primary" href='{{ detail_url }}'>Detail</a>
{% endfor %}
</table>
--
GitLab