From 94788a9c11fffbd2bf960568fef412b39af09eae Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Ji=C5=99=C3=AD=20Setni=C4=8Dka?= <setnicka@seznam.cz>
Date: Sat, 2 Jan 2021 19:02:32 +0100
Subject: [PATCH] =?UTF-8?q?Rozd=C4=9Blen=C3=AD=20vytv=C3=A1=C5=99en=C3=AD,?=
 =?UTF-8?q?=20detaiklu=20a=20editace=20sout=C4=9B=C5=BE=C3=ADc=C3=ADch=20a?=
 =?UTF-8?q?=20org=C5=AF?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

V základu mají sice stejnou backend tabulku, ale dost se liší v tom, co se
s nimi dá dělat. Využívá se společný kód a šablony pro vytváření a editaci,
ale liší se v dalších věcech:
* detail soutěžícího ukazuje soutěže a kola, kterých se účastní
* detail organizátora zobrazuje a nastavuje práva
* seznam soztěžících lze filtrovat podle účastí
* seznam orgů zobrazuje práva (a do budoucna podle nich bude i filtrovat)
---
 mo/web/menu.py                                |  4 +-
 mo/web/org_users.py                           | 71 +++++++++++-----
 mo/web/templates/org_org.html                 | 83 +++++++++++++++++++
 .../{org_users_orgs.html => org_orgs.html}    |  6 +-
 mo/web/templates/org_user.html                | 62 --------------
 mo/web/templates/org_user_edit.html           |  2 +-
 6 files changed, 139 insertions(+), 89 deletions(-)
 create mode 100644 mo/web/templates/org_org.html
 rename mo/web/templates/{org_users_orgs.html => org_orgs.html} (86%)

diff --git a/mo/web/menu.py b/mo/web/menu.py
index e46ee115..db1e8d03 100644
--- a/mo/web/menu.py
+++ b/mo/web/menu.py
@@ -27,8 +27,8 @@ def get_menu():
             MenuItem(url_for('org_index'), "Org"),
             MenuItem(url_for('org_place_root'), "Místa"),
             MenuItem(url_for('org_contest_root'), "Soutěž"),
-            MenuItem(url_for('org_users'), "Soutěžící"),
-            MenuItem(url_for('org_users_orgs'), "Organizátoři"),
+            MenuItem(url_for('org_users'), "Soutěžící", active_prefix="/org/user"),
+            MenuItem(url_for('org_orgs'), "Organizátoři", active_prefix="/org/org"),
         ]
 
     # Login / user settings
diff --git a/mo/web/org_users.py b/mo/web/org_users.py
index 34700c94..1e41c8bd 100644
--- a/mo/web/org_users.py
+++ b/mo/web/org_users.py
@@ -133,8 +133,8 @@ class OrgsFilterForm(PagerForm):
     submit = wtforms.SubmitField("Filtrovat")
 
 
-@app.route('/org/users/orgs/')
-def org_users_orgs():
+@app.route('/org/orgs/')
+def org_orgs():
     sess = db.get_session()
     rr = mo.rights.Rights(g.user)
     rr.get_generic()
@@ -160,7 +160,7 @@ def org_users_orgs():
     users = q.all()
 
     return render_template(
-        'org_users_orgs.html', users=users, count=count,
+        'org_orgs.html', users=users, count=count,
         filter=filter, filter_errors=None,
         can_edit=rr.have_right(mo.rights.Right.edit_orgs),
         can_add=rr.have_right(mo.rights.Right.add_orgs),
@@ -182,20 +182,17 @@ class FormRemoveRole(FlaskForm):
     remove = wtforms.SubmitField('Odebrat roli')
 
 
-@app.route('/org/user/<int:id>/', methods=('GET', 'POST'))
-def org_user(id: int):
+@app.route('/org/org/<int:id>/', methods=('GET', 'POST'))
+def org_org(id: int):
     sess = db.get_session()
     user = sess.query(db.User).get(id)
-    if not user:
+    if not user or (not user.is_org and not user.is_admin):
         raise werkzeug.exceptions.NotFound()
 
     rr = mo.rights.Rights(g.user)
     rr.get_generic()
     can_assign_rights = rr.have_right(mo.rights.Right.assign_rights)
 
-    participants = sess.query(db.Participant).filter_by(user_id=user.user_id)
-    rounds = sess.query(db.Participation).filter_by(user_id=user.user_id)
-
     form_add_role = FormAddRole()
     form_remove_role = FormRemoveRole()
     role_errors = []
@@ -257,9 +254,31 @@ def org_user(id: int):
                 return redirect(url_for('org_user', id=id))
 
     return render_template(
-        'org_user.html', user=user, can_edit=rr.can_edit_user(user), can_assign_rights=can_assign_rights,
-        participants=participants, rounds=rounds, roles_by_type=mo.rights.roles_by_type,
-        form_add_role=form_add_role, form_remove_role=form_remove_role, role_errors=role_errors,
+        'org_org.html', user=user,
+        can_edit=rr.can_edit_user(user), can_assign_rights=can_assign_rights,
+        roles_by_type=mo.rights.roles_by_type, role_errors=role_errors,
+        form_add_role=form_add_role, form_remove_role=form_remove_role,
+    )
+
+
+@app.route('/org/user/<int:id>/', methods=('GET', 'POST'))
+def org_user(id: int):
+    sess = db.get_session()
+    user = sess.query(db.User).get(id)
+    if not user:
+        raise werkzeug.exceptions.NotFound()
+    if user.is_org or user.is_admin:
+        return redirect(url_for('org_org', id=id))
+
+    rr = mo.rights.Rights(g.user)
+    rr.get_generic()
+
+    participants = sess.query(db.Participant).filter_by(user_id=user.user_id)
+    rounds = sess.query(db.Participation).filter_by(user_id=user.user_id)
+
+    return render_template(
+        'org_user.html', user=user, can_edit=rr.can_edit_user(user),
+        participants=participants, rounds=rounds
     )
 
 
@@ -275,6 +294,7 @@ class NewUserForm(UserEditForm):
     submit = wtforms.SubmitField("Vytvořit")
 
 
+@app.route('/org/org/<int:id>/edit', methods=("GET", "POST"), endpoint="org_org_edit")
 @app.route('/org/user/<int:id>/edit', methods=("GET", "POST"))
 def org_user_edit(id: int):
     sess = db.get_session()
@@ -282,6 +302,13 @@ def org_user_edit(id: int):
     if not user:
         raise werkzeug.exceptions.NotFound()
 
+    is_org = request.endpoint == "org_org_edit"
+
+    if not is_org and (user.is_admin or user.is_org):
+        return redirect(url_for("org_org_edit", id=id))
+    if is_org and not (user.is_admin or user.is_org):
+        return redirect(url_for("org_user_edit", id=id))
+
     rr = mo.rights.Rights(g.user)
     rr.get_generic()
     if not rr.can_edit_user(user):
@@ -307,19 +334,19 @@ def org_user_edit(id: int):
 
         return redirect(url_for('org_user', id=id))
 
-    return render_template('org_user_edit.html', user=user, form=form)
+    return render_template('org_user_edit.html', user=user, form=form, is_org=is_org)
 
 
-@app.route('/org/user/new/', defaults={'type': None}, methods=('GET', 'POST'))
-@app.route('/org/user/new/<type>/', methods=('GET', 'POST'))
-def org_user_new(type: Optional[str]):
+@app.route('/org/org/new/', methods=('GET', 'POST'), endpoint="org_org_new")
+@app.route('/org/user/new/', methods=('GET', 'POST'))
+def org_user_new():
     sess = db.get_session()
     rr = mo.rights.Rights(g.user)
     rr.get_generic()
 
-    if type is not None and type != "org":
-        raise werkzeug.exceptions.BadRequest()
-    elif type == 'org' and not rr.have_right(mo.rights.Right.add_orgs):
+    is_org = request.endpoint == "org_org_new"
+
+    if is_org and not rr.have_right(mo.rights.Right.add_orgs):
         raise werkzeug.exceptions.Forbidden()
     elif not rr.have_right(mo.rights.Right.add_users):
         raise werkzeug.exceptions.Forbidden()
@@ -335,7 +362,7 @@ def org_user_new(type: Optional[str]):
         if check:
             new_user = db.User()
             form.populate_obj(new_user)
-            new_user.is_org = (type == 'org')
+            new_user.is_org = is_org
             sess.add(new_user)
             sess.flush()
 
@@ -361,6 +388,8 @@ def org_user_new(type: Optional[str]):
                 app.logger.error('Login: problém při posílání e-mailu: {}'.format(e))
                 flash('Problém při odesílání e-mailu s odkazem pro nastavení hesla', 'danger')
 
+            if is_org:
+                return redirect(url_for('org_org', id=new_user.user_id))
             return redirect(url_for('org_user', id=new_user.user_id))
 
-    return render_template('org_user_new.html', form=form)
+    return render_template('org_user_new.html', form=form, is_org=is_org)
diff --git a/mo/web/templates/org_org.html b/mo/web/templates/org_org.html
new file mode 100644
index 00000000..84b2431e
--- /dev/null
+++ b/mo/web/templates/org_org.html
@@ -0,0 +1,83 @@
+{% extends "base.html" %}
+{% import "bootstrap/wtf.html" as wtf %}
+{% block body %}
+<h2>{% if user.is_admin %}Správce:{% else %}Organizátor:{% endif %} {{ user.first_name }} {{ user.last_name }}</h2>
+
+<table class=data>
+<tr><td>Jméno:</td><td>{{ user.first_name }}</td></tr>
+<tr><td>Příjmení:</td><td>{{ user.last_name }}</td></tr>
+<tr><td>E-mail:</td><td><a href="mailto:{{ user.email }}">{{ user.email }}</a></td></tr>
+{% if user.is_admin %}<tr><td>Správce:</td><td>ano</td></tr>{% endif %}
+{% if user.is_org %}<tr><td>Organizátor:</td><td>ano</td></tr>{% endif %}
+<tr><td>Poznámka:</td><td style="white-space: pre;">{{ user.note }}</td></tr>
+</table>
+
+{% if can_edit %}
+<div class="btn-group" role="group" style="margin: 10px 0px;">
+	<a class="btn btn-primary" href="{{ url_for('org_org_edit', id=user.user_id) }}">Editovat</a>
+</div>
+{% endif %}
+
+{% if user.is_org or user.is_admin %}
+<h3>Role</h3>
+
+{% if can_assign_rights %}
+<h4>Přidělení nové role</h4>
+<p>Lze přidělit jen roli, která je podmnožinou nějaké vlastní role (včetně omezení na oblast, kolo, &hellip;).</p>
+{% if role_errors %}
+<div class="alert alert-danger" role="alert">
+	{{ role_errors|join("<br>") }}
+</div>
+{% endif %}
+
+<form action="" method="POST" class="form form-inline" role="form">
+	{{ form_add_role.csrf_token() }}
+	<div class="form-group">
+		{{ wtf.form_field(form_add_role.role) }}
+	</div>
+	<div class="form-group">
+		{{ wtf.form_field(form_add_role.place_code, placeholder='Kód / #ID', size=8) }}
+	</div>
+	<div class="form-group">
+		{{ wtf.form_field(form_add_role.year, type='number', size=3, maxlength=2) }}
+	</div>
+	<div class="form-group">
+		{{ wtf.form_field(form_add_role.category, size=2, maxlength=2) }}
+	</div>
+	<div class="form-group">
+		{{ wtf.form_field(form_add_role.seq, type='number', size=3, maxlength=2) }}
+	</div>
+	<div class="form-group">
+		{{ wtf.form_field(form_add_role.submit) }}
+	</div>
+</form>
+{% endif %}
+
+<table class="data full">
+	<thead>
+		<tr>
+			<th>Role</th><th>Oblast</th><th>Ročník</th><th>Kategorie</th><th>Kolo</th><th>Akce</th>
+		</tr>
+	</thead>
+{% for role in user.roles %}
+	<tr>
+		<td>{{ roles_by_type[role.role].name }}</td>
+		<td><a href="{{ url_for('org_place', id=role.place_id) }}">{{ role.place.type_name() + ": " + role.place.name or '*' }}</a></td>
+		<td>{{ role.year or '*' }}</td>
+		<td>{{ role.category or '*' }}</td>
+		<td>{{ role.seq or '*' }}</td>
+		<td>
+			{% if can_assign_rights %}
+				<form action="" method="POST">
+					{{ form_remove_role.csrf_token() }}
+					<input type="hidden" name="remove_role_id" value="{{ role.user_role_id }}">
+					<button type="submit" class="btn btn-xs btn-danger">Odebrat</button>
+				</form>
+			{% endif %}
+		</td>
+	</tr>
+{% endfor %}
+</table>
+{% endif %}
+
+{% endblock %}
diff --git a/mo/web/templates/org_users_orgs.html b/mo/web/templates/org_orgs.html
similarity index 86%
rename from mo/web/templates/org_users_orgs.html
rename to mo/web/templates/org_orgs.html
index 2987306b..09e52430 100644
--- a/mo/web/templates/org_users_orgs.html
+++ b/mo/web/templates/org_orgs.html
@@ -2,7 +2,7 @@
 {% import "bootstrap/wtf.html" as wtf %}
 {% block body %}
 {% if can_add %}
-<a class="pull-right btn btn-primary" href="{{ url_for('org_user_new', type='org') }}">Nový organizátor</a>
+<a class="pull-right btn btn-primary" href="{{ url_for('org_org_new') }}">Nový organizátor</a>
 {% endif %}
 
 <h2>Organizátoři</h2>
@@ -55,8 +55,8 @@
 			</ul>
 		{% endif %}</td>
 		<td><div class='btn-group'>
-			<a class="btn btn-xs btn-default" href="{{ url_for('org_user', id=user.user_id) }}">Detail</a>
-			{% if can_edit and not user.is_admin %}<a class="btn btn-xs btn-default" href="{{ url_for('org_user_edit', id=user.user_id) }}">Edit</a>{% endif %}
+			<a class="btn btn-xs btn-default" href="{{ url_for('org_org', id=user.user_id) }}">Detail</a>
+			{% if can_edit and not user.is_admin %}<a class="btn btn-xs btn-default" href="{{ url_for('org_org_edit', id=user.user_id) }}">Edit</a>{% endif %}
 		</div></td>
 	</tr>
 {% endfor %}
diff --git a/mo/web/templates/org_user.html b/mo/web/templates/org_user.html
index fdd07adc..ae19ee0e 100644
--- a/mo/web/templates/org_user.html
+++ b/mo/web/templates/org_user.html
@@ -18,68 +18,6 @@
 </div>
 {% endif %}
 
-{% if user.is_org or user.is_admin %}
-<h3>Role</h3>
-
-{% if can_assign_rights %}
-<h4>Přidělení nové role</h4>
-<p>Lze přidělit jen roli, která je podmnožinou nějaké vlastní role (včetně omezení na oblast, kolo, &hellip;).</p>
-{% if role_errors %}
-<div class="alert alert-danger" role="alert">
-	{{ role_errors|join("<br>") }}
-</div>
-{% endif %}
-
-<form action="" method="POST" class="form form-inline" role="form">
-	{{ form_add_role.csrf_token() }}
-	<div class="form-group">
-		{{ wtf.form_field(form_add_role.role) }}
-	</div>
-	<div class="form-group">
-		{{ wtf.form_field(form_add_role.place_code, placeholder='Kód / #ID', size=8) }}
-	</div>
-	<div class="form-group">
-		{{ wtf.form_field(form_add_role.year, type='number', size=3, maxlength=2) }}
-	</div>
-	<div class="form-group">
-		{{ wtf.form_field(form_add_role.category, size=2, maxlength=2) }}
-	</div>
-	<div class="form-group">
-		{{ wtf.form_field(form_add_role.seq, type='number', size=3, maxlength=2) }}
-	</div>
-	<div class="form-group">
-		{{ wtf.form_field(form_add_role.submit) }}
-	</div>
-</form>
-{% endif %}
-
-<table class="data full">
-	<thead>
-		<tr>
-			<th>Role</th><th>Oblast</th><th>Ročník</th><th>Kategorie</th><th>Kolo</th><th>Akce</th>
-		</tr>
-	</thead>
-{% for role in user.roles %}
-	<tr>
-		<td>{{ roles_by_type[role.role].name }}</td>
-		<td><a href="{{ url_for('org_place', id=role.place_id) }}">{{ role.place.type_name() + ": " + role.place.name or '*' }}</a></td>
-		<td>{{ role.year or '*' }}</td>
-		<td>{{ role.category or '*' }}</td>
-		<td>{{ role.seq or '*' }}</td>
-		<td>
-			{% if can_assign_rights %}
-				<form action="" method="POST">
-					{{ form_remove_role.csrf_token() }}
-					<input type="hidden" name="remove_role_id" value="{{ role.user_role_id }}">
-					<button type="submit" class="btn btn-xs btn-danger">Odebrat</button>
-				</form>
-			{% endif %}
-		</td>
-	</tr>
-{% endfor %}
-</table>
-{% endif %}
-
 <h3>Registrace v ročnících</h3>
 {% if participants.count() %}
 <table class="data full">
diff --git a/mo/web/templates/org_user_edit.html b/mo/web/templates/org_user_edit.html
index 2352db39..d951d508 100644
--- a/mo/web/templates/org_user_edit.html
+++ b/mo/web/templates/org_user_edit.html
@@ -12,7 +12,7 @@
 <tr><td>Poznámka:</td><td style="white-space: pre;">{{ user.note }}</td></tr>
 </table>
 
-<a href='{{ url_for('org_user', id=user.user_id) }}'>Zpět na detail</a>
+<a href='{% if is_org %}{{ url_for('org_org', id=user.user_id) }}{% else %}{{ url_for('org_user', id=user.user_id) }}{% endif %}'>Zpět na detail</a>
 
 <hr>
 
-- 
GitLab