Adding functionnality : binding gymnast <-> skill

This commit is contained in:
Trullemans Gregory 2021-11-13 14:45:02 +01:00
parent c6294546ba
commit 61f2427799
9 changed files with 252 additions and 13 deletions

View File

@ -35,6 +35,7 @@ urlpatterns = [
# Follow-up management
path(r"chrono/", include(followup.urls.chrono_urlpatterns)),
path(r"skill/", include(followup.urls.skill_urlpatterns)),
path(r"learnedskill/", include(followup.urls.learnedskill_urlpatterns)),
# path(r"search/", config.views.search, name="global_search"),

View File

@ -2,7 +2,10 @@
from django import forms
from datetime import date
from .models import Chrono
from django.db import models
from django.forms import fields, widgets
from .models import Chrono, LearnedSkill
class ChronoForm(forms.ModelForm):
class Meta:
@ -33,3 +36,42 @@ class ChronoForm(forms.ModelForm):
}
)
)
class LearnedSkillForm(forms.ModelForm):
class Meta:
model = LearnedSkill
fields = ('jumper', 'skill', 'cando', 'date')
widgets = {
"jumper": forms.HiddenInput(),
"skill": forms.HiddenInput(),
"date": forms.TextInput(
attrs={
"class": "form-control datepicker",
"placeholder": date.today().strftime("%Y-%m-%d"),
"value": date.today().strftime("%Y-%m-%d"),
}
),
"cando": forms.Select(attrs={"class": "form-control"}),
}
jumper_related = forms.CharField(
widget=forms.TextInput(
attrs={
"class": "form-control",
"placeholder": "Searching gymnast…",
"data-ref": "#id_jumper",
}
)
)
skill_related = forms.CharField(
widget=forms.TextInput(
attrs={
"class": "form-control",
"placeholder": "Searching skill…",
"data-ref": "#id_skill",
}
)
)

View File

@ -10,11 +10,17 @@ chrono_urlpatterns = [
]
skill_urlpatterns = [
path(r"", views.skill_listing, name='skill_list'),
path(r"<int:skillid>/", views.skill_details, name="skill_details"),
path(r"lookup/", views.skill_lookup),
re_path(
r"^(?P<field>(level|rank|difficulty))/(?P<expression>[\w]+)/(?P<value>[\w]+)$",
views.skill_listing,
name="skill_listing_by_key",
),
path(r"<int:skillid>/", views.skill_details, name="skill_details"),
path(r"", views.skill_listing, name='skill_list'),
]
learnedskill_urlpatterns = [
path(r"create/", views.learnedskill_create_or_update, name="learnedskill_create"),
path(r"create/<int:jumperid>/", views.learnedskill_create_or_update, name='learnedskill_create'),
]

View File

@ -6,7 +6,9 @@ from django.db.models import Q
from jumpers.models import Jumper
from .models import Chrono, Skill
from .forms import ChronoForm
from .forms import ChronoForm, LearnedSkillForm
import simplejson
@login_required
@require_http_methods(["GET"])
@ -65,6 +67,28 @@ def chrono_create_or_update(request, chronoid=None, jumperid=None):
return render(request, "chronos/create.html", context)
@login_required
@require_http_methods(["GET"])
def skill_lookup(request):
"""
Récupère la liste des skill à la volée suivant des caractères de
recherche entrés. (min 3 caractères)
"""
results = []
pattern = request.GET.get("pattern", None)
# Ignore queries shorter than length 3
if pattern is not None and len(pattern) > 3:
model_results = Skill.objects.filter(
Q(short_label__icontains=pattern) | Q(long_label__icontains=pattern)
)
results = [{"ID": x.id, "Name": str(x)} for x in model_results]
json = simplejson.dumps(results)
return HttpResponse(json, content_type="application/json")
@login_required
@require_http_methods(["GET"])
def skill_listing(request, field=None, expression=None, value=None, level=None):
@ -105,4 +129,35 @@ def skill_details(request, skillid):
:return: skill
"""
context = {"skill": get_object_or_404(Skill, pk=skillid)}
return render(request, "skills/details.html", context)
return render(request, "skills/details.html", context)
@login_required
@require_http_methods(["GET", "POST"])
def learnedskill_create_or_update(request, jumperid=None):
"""
Formulaire de creation et modification d'un lien skill/gymnaste.
"""
if jumperid:
jumper = get_object_or_404(Jumper, pk=jumperid)
data = {
"jumper": jumper.id,
"jumper_related": str(jumper),
}
else:
data = {}
if request.method == "POST":
learnedskill_form = LearnedSkillForm(request.POST)
if learnedskill_form.is_valid():
learnedskill_form.save()
return HttpResponseRedirect("/jumper/details/" + str(learnedskill_form.cleaned_data['jumper'].id))
else:
print(learnedskill_form.errors)
form = LearnedSkillForm(initial=data)
context = {"form": form, "jumperid": jumperid}
return render(request, "learnedskills/create.html", context)

View File

@ -7,7 +7,7 @@ from django.db.models import Q
from django.contrib import messages
from .models import Club, Jumper
from followup.models import Chrono, LearnedSkill
from followup.models import Chrono, LearnedSkill, Skill
from .forms import JumperForm
import simplejson
@ -83,8 +83,10 @@ def jumper_details(request, jumperid):
"""Récupère toutes les informations d'un gymnaste.
"""
jumper = get_object_or_404(Jumper, pk=jumperid)
learnedskills_list = LearnedSkill.objects.filter(jumper=jumperid).order_by('-date')[:8]
chronos_list = Chrono.objects.filter(jumper=jumperid).order_by('-date')[:8]
learnedskills_list = LearnedSkill.objects.filter(jumper=jumperid).order_by('-date')[:10]
nb_skill = Skill.objects.all().count()
known_skill = LearnedSkill.objects.filter(jumper=jumperid).count()
chronos_list = Chrono.objects.filter(jumper=jumperid).order_by('-date')[:10]
straightjump_score = Chrono.objects.filter(jumper=jumperid).filter(type=0).order_by('-date')
best_straightjump = Chrono.objects.filter(jumper=jumperid).filter(type=0).order_by('-score')[:1]
best_routine = Chrono.objects.filter(jumper=jumperid).filter(type=1).order_by('-score')[:1]
@ -96,7 +98,9 @@ def jumper_details(request, jumperid):
'straightjump_score': straightjump_score,
'routine_score': routine_score,
'best_routine': best_routine,
'best_straightjump': best_straightjump
'best_straightjump': best_straightjump,
'nb_skill': nb_skill,
'known_skill': known_skill
}
return render(request, "jumpers/details.html", context)

View File

@ -154,7 +154,7 @@
<!-- <footer class="footer">
<div class="container-fluid">
<div class="copyright">
© Flying Acrobatics Trampoline.
© Avengers - GymFed
</div>
</div>
</footer> -->
@ -260,6 +260,7 @@
{% else %}
sidebar_mini_active = false;
{% endif %}
{% if request.session.template == 0 %}
white_color = false;
{% else %}
@ -267,7 +268,6 @@
{% endif %}
window_width = $(window).width();
fixed_plugin_open = $('.sidebar .sidebar-wrapper .nav li.active a p').html();
{% if request.session.sidebar == 1 %}

View File

@ -43,7 +43,7 @@
<div class="col-md-4">
<div class="card">
<div class="card-header">
<h4 class="">(line 2 celle 2)</h4>
<h4 class="">(line 2 cadre 2)</h4>
</div>
<div class="card-body">

View File

@ -36,8 +36,16 @@
{% endif %}
</ul>
{% endif %}
{{ known_skill }} known skill on {{ nb_skill }} skills.
</div>
<div class="row">
<div class="col-6">
<a href="{% url 'chrono_create' jumper.id %}" class="nav-item dropdown-item">New <i class="far fa-stopwatch"></i></a>
</div>
<div class="col-6">
<a href="{% url 'learnedskill_create' jumper.id %}" class="nav-item dropdown-item">New <i class="tim-icons icon-molecule-40"></i></a>
</div>
</div>
<a href="{% url 'chrono_create' jumper.id %}" class="nav-item dropdown-item">New <i class="far fa-stopwatch"></i></a>
</div>
</div>
</div>

View File

@ -0,0 +1,123 @@
{% extends "base.html" %}
{% block content %}
<div class="row justify-content-center">
<div class="col-12 col-sm-12 col-md-12 col-lg-8 col-xl-8">
<div class="card">
<div class="card-header">
<h4 class="card-title">Add Jumper/Skill link</h4>
</div>
<div class="card-body">
<form action="{% url 'learnedskill_create' %}" method="post" class="form-horizontal" id="formulaire" name="formulaire">
{% csrf_token %}
<div class="form-group row ">
<label for="id_date" class="col-4 col-sm-3 col-form-label">Date</label>
<div class="col-sm-6 col-md-5 col-lg-4 col-xl-3 {% if form.date.errors %}has-danger{% endif %}">
{{ form.date }}
{% if form.date.errors %}<span class="btn btn-sm btn-danger-outline">{% for error in form.date.errors %}{{error}}{% endfor %}</span>{% endif %}
</div>
</div>
<div class="form-group row ">
<label for="id_jumper" class="col-4 col-sm-3 col-form-label">Jumper</label>
<div class="col-8 col-md-9 col-lg-6 {% if form.jumper.errors %}has-danger{% endif %}">
{{ form.jumper }}
{{ form.jumper_related }}
{% if form.jumper.errors %}&nbsp;<span class="btn btn-sm btn-danger-outline">{% for error in form.jumper.errors %}{{error}}{% endfor %}</span>{% endif %}
</div>
</div>
<div class="form-group row ">
<label for="id_skill" class="col-4 col-sm-3 col-form-label">Skill</label>
<div class="col-8 col-md-9 col-lg-6 {% if form.skill.errors %}has-danger{% endif %}">
{{ form.skill }}
{{ form.skill_related }}
{% if form.skill.errors %}&nbsp;<skilln class="btn btn-sm btn-danger-outline">{% for error in form.skill.errors %}{{error}}{% endfor %}</span>{% endif %}
</div>
</div>
<div class="form-group row ">
<label for="id_type" class="col-4 col-sm-3 col-form-label">Type</label>
<div class="col-8 col-sm-4 col-md-3 {% if form.type.errors %}has-danger{% endif %}">
{{ form.cando }}
{% if form.cando.errors %}&nbsp;<span class="btn btn-sm btn-danger-outline">{% for error in form.cando.errors %}{{error}}{% endfor %}</span>{% endif %}
</div>
</div>
<div class="form-group text-center">
<input type="submit" value="Save" class="btn btn-fill btn-warning" />
</div>
</form>
</div>
</div>
</div>
</div>
<script type="text/javascript" >
$(function(){
$('#id_birthdate').datetimepicker({
format: 'YYYY-MM-DD'
});
blackDashboard.initDateTimePicker();
$('#id_jumper_related').autocomplete({
source: function(request, response) {
$.ajax({
url: '/jumper/lookup/?pattern=' + $('#id_jumper_related').val(),
dataType: "json",
success: function(data) {
if(data.length != 0) {
response($.map(data, function(item) {
return {
label: item.Name,
value: item.Name,
gymnastid: item.ID
}
}))
} else {
response([{ label: 'No result found.', value: '' }]);
};
},
error: function (exception) {
console.log(exception);
}
});
},
minLength: 3,
select: function (event, ui) {
$($(this).data('ref')).val(ui.item.gymnastid);
}
});
$('#id_skill_related').autocomplete({
source: function(request, response) {
$.ajax({
url: '/skill/lookup/?pattern=' + $('#id_skill_related').val(),
dataType: "json",
success: function(data) {
if(data.length != 0) {
response($.map(data, function(item) {
return {
label: item.Name,
value: item.Name,
clubid: item.ID
}
}))
} else {
response([{ label: 'No result found.', value: '' }]);
};
},
error: function (exception) {
console.log(exception);
}
});
},
minLength: 3,
select: function (event, ui) {
$($(this).data('ref')).val(ui.item.clubid);
}
});
});
</script>
{% endblock %}