Upgrade UI and statistics/skill component

This commit is contained in:
Gregory Trullemans 2021-12-05 19:41:35 +01:00
parent 07e805970e
commit d247a7a129
6 changed files with 138 additions and 62 deletions

View File

@ -8,8 +8,8 @@ gymnast_urlpatterns = [
path(r"details/<int:gymnastid>/", views.gymnast_details, name="gymnast_details"),
path(
r"<int:gymnastid>/statistics/",
views.gymnast_display_stats,
name="gymnast_display_stats",
views.gymnast_display_skill,
name="gymnast_display_skill",
),
path(
r"<int:gymnastid>/routine/",

View File

@ -59,8 +59,8 @@ def gymnast_details(request, gymnastid):
gymnast = get_object_or_404(Gymnast, pk=gymnastid)
learnedskills_list = LearnedSkill.objects.filter(gymnast=gymnastid).order_by('-date')[:10]
nb_skill = Skill.objects.all().count()
known_skill = LearnedSkill.objects.filter(gymnast=gymnastid).count()
percentage_known_skill = ( known_skill / nb_skill ) * 100
nb_known_skill = LearnedSkill.objects.filter(gymnast=gymnastid).distinct('skill').count()
percentage_known_skill = ( nb_known_skill / nb_skill ) * 100
chronos_list = Chrono.objects.filter(gymnast=gymnastid).order_by('-date')[:10]
straightjump_score = Chrono.objects.filter(gymnast=gymnastid).filter(type=0).order_by('-date')
best_straightjump = Chrono.objects.filter(gymnast=gymnastid).filter(type=0).order_by('-score')[:1]
@ -80,7 +80,7 @@ def gymnast_details(request, gymnastid):
'best_routine': best_routine,
'best_straightjump': best_straightjump,
'nb_skill': nb_skill,
'known_skill': known_skill,
'nb_known_skill': nb_known_skill,
'points_routine_1_list': points_routine_1_list,
'points_routine_2_list': points_routine_2_list,
'points_routine_final_list': points_routine_final_list,
@ -181,7 +181,6 @@ def gymnast_display_routines(request, gymnastid):
gymnast = get_object_or_404(Gymnast, pk=gymnastid)
ghr_list = gymnast.has_routine.prefetch_related("routine")
context = {"ghr_list": ghr_list, "gymnastid": gymnastid}
print(context)
return render(request, "peoples/gymnasts/list_routine.html", context)
@ -199,7 +198,6 @@ def link_routine_to_gymnast(request, gymnastid=None):
data = {"dateend": None}
if request.method == "POST":
print(request.POST)
form = GymnastHasRoutineForm(request.POST)
if form.is_valid():
@ -245,7 +243,7 @@ def gymnast_create_or_update(request, gymnastid=None):
return render(request, "peoples/gymnasts/create.html", context)
def __getInformationsFromLevel(gymnast, total_known_skill):
def __getInformationsFromLevel(gymnast, gymnast_nb_known_skills):
"""
Calcule toutes les statistiques par rapport au niveau.
"""
@ -312,22 +310,22 @@ def __getInformationsFromLevel(gymnast, total_known_skill):
).exclude(known_by__gymnast=gymnast.id)
# Liste des Skill que le gymnaste ne sais PAS faire (ayant un niveau plus grand que le niveau max du gym)
context["new_unknown_skill"] = Skill.objects.filter(
context["unknown_skill"] = Skill.objects.filter(
level__gt=context["max_level_educative"]
).exclude(known_by__gymnast=gymnast.id)
else:
context["max_level_educative"] = 0
context["total_skill"] = Skill.objects.all().count()
context["new_unknown_skill"] = Skill.objects.all()
context["unknown_skill"] = Skill.objects.all()
# Calcul des statistiques
if context["total_skill"] != 0:
context["completude"] = "%s%%" % (
int((total_known_skill / context["total_skill"]) * 100)
int((gymnast_nb_known_skills / context["total_skill"]) * 100)
)
context["evaluated_level"] = int(
context["max_level_educative"] * (total_known_skill / context["total_skill"])
context["max_level_educative"] * (gymnast_nb_known_skills / context["total_skill"])
)
else:
context["completude"] = 0
@ -336,7 +334,7 @@ def __getInformationsFromLevel(gymnast, total_known_skill):
return context
def __getInformationsFromRank(gymnast, total_known_skill):
def __getInformationsFromRank(gymnast, gymnast_nb_known_skills):
"""
Calcule toutes les statistiques par rapport au rang.
"""
@ -421,22 +419,22 @@ def __getInformationsFromRank(gymnast, total_known_skill):
# Liste des Skill que le gymnaste ne sais PAS faire (ayant un niveau
# plus grand que le niveau max du gym)
context["new_unknown_skill"] = Skill.objects.filter(
context["unknown_skill"] = Skill.objects.filter(
level__gt=context["max_rank_educative"]
).exclude(known_by__gymnast=gymnast.id)
else:
context["max_rank_educative"] = 0
context["total_skill"] = Skill.objects.all().count()
context["new_unknown_skill"] = Skill.objects.all()
context["unknown_skill"] = Skill.objects.all()
# Calcul des statistiques
if context["total_skill"] != 0:
context["completude"] = "%s%%" % (
int((total_known_skill / context["total_skill"]) * 100)
int((gymnast_nb_known_skills / context["total_skill"]) * 100)
)
context["evaluated_level"] = (min_rank - 1) + (
int(context["max_rank_educative"] * (total_known_skill / context["total_skill"]))
int(context["max_rank_educative"] * (gymnast_nb_known_skills / context["total_skill"]))
)
else:
context["completude"] = 0
@ -447,9 +445,9 @@ def __getInformationsFromRank(gymnast, total_known_skill):
@login_required
@require_http_methods(["GET"])
def gymnast_display_stats(request, gymnastid):
def gymnast_display_skill(request, gymnastid):
"""
Tag affichant les statistiques d'un gymnaste : le nombre de saut qu'il sait faire (total,
Tag affichant les statistiques de skill d'un gymnaste : le nombre de saut qu'il sait faire (total,
par niveau, par rank, ), calcule la complétude,
.. todo:: Générer UNE fois la liste de skill que le gymnaste ne sait pas faire (1 query)
@ -457,11 +455,11 @@ def gymnast_display_stats(request, gymnastid):
affiche conditionnellement (par age, par rank, ...)
"""
gymnast = get_object_or_404(Gymnast, pk=gymnastid)
# Nombre de Skill que le gymnaste sait faire
gymnast_known_skills = gymnast.known_skills.count()
gymnast_nb_known_skills = gymnast.known_skills.distinct('skill').count()
context = {}
context = __getInformationsFromLevel(gymnast, gymnast_known_skills)
context.update(__getInformationsFromRank(gymnast, gymnast_known_skills))
context = __getInformationsFromLevel(gymnast, gymnast_nb_known_skills)
context.update(__getInformationsFromRank(gymnast, gymnast_nb_known_skills))
if gymnast.gender:
context["skill_by_age"] = Skill.objects.filter(age_girl__lte=gymnast.age).exclude(
@ -472,7 +470,18 @@ def gymnast_display_stats(request, gymnastid):
known_by__gymnast=gymnast.id
)
context["gymnast"] = gymnast
context["total_known_skill"] = gymnast_known_skills
# skill_whith_help = Skill.objects.filter(known_by__gymnast=gymnastid).filter(known_by__cando=1).exclude(known_by__gymnast=gymnastid, known_by__cando=2)
skill_whith_help = Skill.objects.filter(known_by__gymnast=gymnastid, known_by__cando=1).exclude(
known_by__gymnast=gymnast.id, known_by__cando__gte=2
).distinct()
return render(request, "peoples/gymnasts/statistics.html", context)
skill_not_chained = Skill.objects.filter(known_by__gymnast=gymnastid, known_by__cando=2).exclude(
known_by__gymnast=gymnast.id, known_by__cando=3
).distinct()
context["skill_whith_help"] = skill_whith_help
context["skill_not_chained"] = skill_not_chained
context["gymnast"] = gymnast
context["gymnast_nb_known_skills "] = gymnast_nb_known_skills
return render(request, "peoples/gymnasts/list_skill.html", context)

View File

@ -25,9 +25,9 @@
<thead>
<tr>
<th style="width: 3%"></th>
<th class="header text-left" style="width: 25%">Jumper</th>
<th class="header text-left" style="width: 25%">Gymnast</th>
<th class="header text-left" style="width: 35%">Date</th>
<th class="header text-left" style="width: 15%">ToF</th>
<th class="header text-left" style="width: 15%">Time of Flight</th>
</tr>
</thead>
<tbody>

View File

@ -24,7 +24,7 @@
<div class="card-description">
{{ gymnast.age }} years ({{ gymnast.birthdate | date:"d F Y" }})<span class="text-info"><b>{{ gymnast.get_orientation_display }}</b></span><br />
{{ gymnast.club.name }} - {{ gymnast.club.place.city }}<br />
{{ gymnast.trainings_by_week }} training/week - {{ gymnast.hours_by_week }} hours/week<br />
{{ gymnast.trainings_by_week }} training/week for {{ gymnast.hours_by_week }} hours/week<br />
<br />
{% if best_routine or best_straightjump %}
<h5><u>Bests Scores</u></h5>
@ -42,15 +42,12 @@
<div class="progress-bar progress-bar-warning" role="progressbar" aria-valuenow="60" aria-valuemin="0" aria-valuemax="100" style="width: {{ percentage_known_skill }}%;"></div>
</div>
</div>
{{ known_skill }} known skill on {{ nb_skill }} skills.
{{ nb_known_skill }} known skills on {{ nb_skill }} skills.
</div>
<div class="row">
<div class="col-3">
<a href="{% url 'chrono_create_for_gymnast' gymnast.id %}" class="nav-item dropdown-item">New <i class="far fa-stopwatch"></i></a>
</div>
<!-- <div class="col-2">
<a href="{% url 'learnedskill_create' gymnast.id %}" class="nav-item dropdown-item">New <i class="tim-icons icon-molecule-40"></i></a>
</div> -->
<div class="col-3">
<a href="{% url 'score_create_for_gymnast' gymnast.id %}" class="nav-item dropdown-item">New <i class="fal fa-crosshairs"></i></a>
</div>
@ -95,7 +92,7 @@
{% endif %}
</div>
<div class="col-12 col-sm-4 col-md-4 card">
<div class="col-12 col-sm-4 col-md-4 card mb-3">
<div class="table-responsive pb-0">
{% if chronos_list %}
<table class="table tablesorter table-striped table-condensed" data-sort="table" id="chronotable">
@ -161,16 +158,6 @@
<i class="fal fa-comment-alt-medical"></i> Accidents
</a>
</li>
<!-- <li class="nav-item">
<a class="nav-link get-info {% if tab == 'program' %}active{% endif %}" data-toggle="tab" href="#program" data-ref="#program" data-url="program/" id="display_program">
<i class="tim-icons icon-calendar-60"></i> Program
</a>
</li> -->
<!-- <li class="nav-item">
<a class="nav-link get-info {% if tab == 'routine' %}active{% endif %}" data-toggle="tab" href="#routine" data-ref="#routine" data-url="routine/" id="display_routines">
<i class="tim-icons icon-components"></i> Routines
</a>
</li> -->
<li class="nav-item">
<a class="nav-link get-info {% if tab == 'event' %}active{% endif %}" data-toggle="tab" href="#event" data-ref="#event" data-url="event/" id="display_event">
<i class="fal fa-calendar-day"></i> Events
@ -181,8 +168,6 @@
<div class="col-12 col-sm-10 col-md-10 col-lg-11">
<div class="tab-content">
<div class="tab-pane {% if tab is None or tab == 'level' %}active{% endif %}" id="statistics"></div>
<!-- <div class="tab-pane {% if tab == 'program' %}active{% endif %}" id="program"></div> -->
<div class="tab-pane {% if tab == 'routine' %}active{% endif %}" id="routine"></div>
@ -208,9 +193,6 @@
{% if tab is None or tab == 'level' %}
tab_url = default_url + 'statistics/';
var tab_div = '#statistics';
{% elif tab == 'program' %}
tab_url = default_url + 'program/';
var tab_div = '#program';
{% elif tab == 'routine' %}
tab_url = default_url + 'routine/';
var tab_div = '#routine';

View File

@ -1,7 +1,7 @@
<div class="row justify-content-center ml-3 pr-0">
<div class="col-md-12 pr-0">
<div class="card">
<div class="card mb-3">
<div class="card-header">
<h4>Scores</h4>
</div>

View File

@ -3,11 +3,27 @@
<div class="col-md-12 pr-0">
<div class="card">
<div class="card-body">
{% if skill_by_rank or skill_by_level or skill_by_age or new_unknown_skill %}
{% if skill_whith_help or skill_not_chained or skill_by_rank or skill_by_level or skill_by_age or unknown_skill %}
<ul class="nav nav-pills nav-pills-warning nav-pills-icons justify-content-center">
{% if skill_whith_help %}
<li class="nav-item">
<a class="nav-link active" data-toggle="tab" href="#skill_whith_help">
With help ({{ skill_whith_help|length }})
</a>
</li>
{% endif %}
{% if skill_not_chained %}
<li class="nav-item">
<a class="nav-link active" data-toggle="tab" href="#skill_not_chained">
Not chained ({{ skill_not_chained|length }})
</a>
</li>
{% endif %}
{% if skill_by_rank %}
<li class="nav-item">
<a class="nav-link active" data-toggle="tab" href="#skillbyrank">
<a class="nav-link active" data-toggle="tab" href="#skill_by_rank">
By rank ({{ skill_by_rank|length }})
</a>
</li>
@ -15,7 +31,7 @@
{% if skill_by_level %}
<li class="nav-item">
<a class="nav-link" data-toggle="tab" href="#skillbylevel">
<a class="nav-link" data-toggle="tab" href="#skill_by_level">
By level ({{ skill_by_level|length }})
</a>
</li>
@ -23,23 +39,92 @@
{% if skill_by_age %}
<li class="nav-item">
<a class="nav-link" data-toggle="tab" href="#skillbyage">
<a class="nav-link" data-toggle="tab" href="#skill_by_age">
By Age ({{ skill_by_age|length }})
</a>
</li>
{% endif %}
{% if new_unknown_skill %}
{% if unknown_skill %}
<li class="nav-item">
<a class="nav-link" data-toggle="tab" href="#newunknownskill">
<a class="nav-link" data-toggle="tab" href="#unknown_skill">
All skill
</a>
</li>
{% endif %}
</ul>
<div class="tab-content tab-space tab-subcategories pt-0 pb-0">
{% if skill_whith_help %}
<div class="tab-pane active" id="skill_whith_help">
<table class="table table-striped table-condensed tablesorter" id="table-skill-with-help">
<thead>
<tr>
<th style="width: 10%"></th>
<th class="header text-left" style="width: 55%">Label</th>
<th class="header" style="width: 7%">Diff.</th>
<th class="header" style="width: 7%">Level</th>
<th class="header" style="width: 7%">Rank</th>
<th style="width: 10%">Notation</th>
</tr>
</thead>
<tbody>
{% for skill in skill_whith_help %}
<tr>
<td>
<button type="button" rel="tooltip" class="btn btn-success btn-link btn-sm btn-icon checkUnknownSkill" data-gymnastid="{{ gymnast.id }}" data-skillid="{{ skill.id }}" data-link="2">
<i class="far fa-check-double"></i>
</button>
<button type="button" rel="tooltip" class="btn btn-success btn-link btn-sm btn-icon checkUnknownSkill" data-gymnastid="{{ gymnast.id }}" data-skillid="{{ skill.id }}" data-link="3">
<i class="far fa-link"></i>
</button>
</td>
<td class="text-left"><a href="{% url 'skill_details' skill.id %}">{{ skill.long_label }}</a></td>
<td>{{ skill.difficulty }}</td>
<td>{{ skill.level }}</td>
<td>{{ skill.rank }}</td>
<td>{{ skill.notation }}</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
{% endif %}
{% if skill_not_chained %}
<div class="tab-pane active" id="skill_not_chained">
<table class="table table-striped table-condensed tablesorter" id="table-skill-with-help">
<thead>
<tr>
<th style="width: 10%"></th>
<th class="header text-left" style="width: 55%">Label</th>
<th class="header" style="width: 7%">Diff.</th>
<th class="header" style="width: 7%">Level</th>
<th class="header" style="width: 7%">Rank</th>
<th style="width: 10%">Notation</th>
</tr>
</thead>
<tbody>
{% for skill in skill_not_chained %}
<tr>
<td>
<button type="button" rel="tooltip" class="btn btn-success btn-link btn-sm btn-icon checkUnknownSkill" data-gymnastid="{{ gymnast.id }}" data-skillid="{{ skill.id }}" data-link="3">
<i class="far fa-link"></i>
</button>
</td>
<td class="text-left"><a href="{% url 'skill_details' skill.id %}">{{ skill.long_label }}</a></td>
<td>{{ skill.difficulty }}</td>
<td>{{ skill.level }}</td>
<td>{{ skill.rank }}</td>
<td>{{ skill.notation }}</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
{% endif %}
{% if skill_by_rank %}
<div class="tab-pane active" id="skillbyrank">
<div class="tab-pane active" id="skill_by_rank">
<table class="table table-striped table-condensed tablesorter" id="table-by-rank">
<thead>
<tr>
@ -78,7 +163,7 @@
{% endif %}
{% if skill_by_level %}
<div class="tab-pane" id="skillbylevel">
<div class="tab-pane" id="skill_by_level">
<table class="table table-striped table-condensed tablesorter" id="table-by-level">
<thead>
<tr>
@ -117,7 +202,7 @@
{% endif %}
{% if skill_by_age %}
<div class="tab-pane" id="skillbyage">
<div class="tab-pane" id="skill_by_age">
<table class="table table-striped table-condensed tablesorter" id="table-by-age">
<thead>
<tr>
@ -155,8 +240,8 @@
</div>
{% endif %}
{% if new_unknown_skill %}
<div class="tab-pane" id="newunknownskill">
{% if unknown_skill %}
<div class="tab-pane" id="unknown_skill">
<table class="table table-striped table-condensed tablesorter" id="table-other">
<thead>
<tr>
@ -169,7 +254,7 @@
</tr>
</thead>
<tbody>
{% for skill in new_unknown_skill %}
{% for skill in unknown_skill %}
<tr>
<td>
<button type="button" rel="tooltip" class="btn btn-success btn-link btn-sm btn-icon checkUnknownSkill" data-gymnastid="{{ gymnast.id }}" data-skillid="{{ skill.id }}" data-link="1">