Update passe form, migrations, …
This commit is contained in:
parent
b026edbb27
commit
51ac7fc5fb
|
@ -1,6 +1,6 @@
|
|||
from django import forms
|
||||
|
||||
from .models import Skill, Routine, RoutineSkill
|
||||
from .models import Skill, Routine, RoutineSkill, Passe
|
||||
|
||||
|
||||
class SkillForm(forms.ModelForm):
|
||||
|
@ -64,3 +64,48 @@ class CombinationSkillForm(forms.ModelForm):
|
|||
"skill": forms.HiddenInput(),
|
||||
"rank": forms.NumberInput(),
|
||||
}
|
||||
|
||||
|
||||
class PasseForm(forms.ModelForm):
|
||||
class Meta:
|
||||
model = Passe
|
||||
fields = ("label", "educative", "repetition", "regexp", "informations")
|
||||
widgets = {
|
||||
"label": forms.TextInput(
|
||||
attrs={
|
||||
"class": "form-control",
|
||||
"placeholder": "Label (not mandatory)",
|
||||
"maxlength": 30,
|
||||
}
|
||||
),
|
||||
"repetition": forms.NumberInput(
|
||||
attrs={
|
||||
"class": "form-control",
|
||||
"placeholder": "x",
|
||||
"min": "0",
|
||||
"max": "1000",
|
||||
"step": "1",
|
||||
}
|
||||
),
|
||||
"regexp": forms.TextInput(
|
||||
attrs={"class": "form-control", "placeholder": "[2-8]"}
|
||||
),
|
||||
"informations": forms.Textarea(
|
||||
attrs={
|
||||
"class": "form-control",
|
||||
"placeholder": "Informations about the passe…", # pylint: disable=line-too-long
|
||||
}
|
||||
),
|
||||
"educative": forms.HiddenInput(),
|
||||
}
|
||||
|
||||
educative_related = forms.CharField(
|
||||
required=False,
|
||||
widget=forms.TextInput(
|
||||
attrs={
|
||||
"class": "form-control",
|
||||
"placeholder": "Searching educative",
|
||||
"data-ref": "#id_educative",
|
||||
}
|
||||
),
|
||||
)
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
# Generated by Django 4.2 on 2024-02-25 07:33
|
||||
# Generated by Django 4.2 on 2024-02-25 18:38
|
||||
|
||||
from django.db import migrations, models
|
||||
import django.db.models.deletion
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
@ -22,14 +23,30 @@ class Migration(migrations.Migration):
|
|||
verbose_name="ID",
|
||||
),
|
||||
),
|
||||
("label", models.CharField(blank=True, max_length=25, null=True)),
|
||||
("repetition", models.PositiveSmallIntegerField()),
|
||||
(
|
||||
"informations",
|
||||
models.TextField(
|
||||
blank=True,
|
||||
help_text="Only MarkDown is authorized",
|
||||
null=True,
|
||||
verbose_name="Comments",
|
||||
),
|
||||
),
|
||||
("label", models.CharField(blank=True, max_length=30, null=True)),
|
||||
("repetition", models.PositiveSmallIntegerField(default=1)),
|
||||
("regexp", models.CharField(blank=True, max_length=50, null=True)),
|
||||
("number_of_skill", models.PositiveSmallIntegerField()),
|
||||
("difficulty", models.DecimalField(decimal_places=1, max_digits=4)),
|
||||
(
|
||||
"educative",
|
||||
models.ManyToManyField(
|
||||
related_name="passes", to="objective.educative"
|
||||
models.ForeignKey(
|
||||
on_delete=django.db.models.deletion.CASCADE,
|
||||
to="objective.educative",
|
||||
),
|
||||
),
|
||||
],
|
||||
options={
|
||||
"abstract": False,
|
||||
},
|
||||
),
|
||||
]
|
||||
|
|
|
@ -1,38 +0,0 @@
|
|||
# Generated by Django 4.2 on 2024-02-25 08:54
|
||||
|
||||
from django.db import migrations, models
|
||||
import django.db.models.deletion
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
("objective", "0017_passe"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name="passe",
|
||||
name="regexp",
|
||||
field=models.CharField(blank=True, max_length=50, null=True),
|
||||
),
|
||||
migrations.RemoveField(
|
||||
model_name="passe",
|
||||
name="educative",
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name="passe",
|
||||
name="label",
|
||||
field=models.CharField(blank=True, max_length=30, null=True),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name="passe",
|
||||
name="educative",
|
||||
field=models.ForeignKey(
|
||||
default=None,
|
||||
on_delete=django.db.models.deletion.CASCADE,
|
||||
to="objective.educative",
|
||||
),
|
||||
preserve_default=False,
|
||||
),
|
||||
]
|
|
@ -458,13 +458,59 @@ class RoutineSkill(models.Model):
|
|||
return f"{self.rank} - {self.routine.short_label} : {self.skill.short_label}"
|
||||
|
||||
|
||||
class Passe(models.Model):
|
||||
class Passe(Markdownizable):
|
||||
"""Classe représentant les passages (à faire pendant un entraînement)."""
|
||||
|
||||
label = models.CharField(max_length=30, null=True, blank=True)
|
||||
educative = models.ForeignKey(Educative, on_delete=models.CASCADE)
|
||||
repetition = models.PositiveSmallIntegerField()
|
||||
repetition = models.PositiveSmallIntegerField(default=1)
|
||||
regexp = models.CharField(max_length=50, null=True, blank=True)
|
||||
number_of_skill = models.PositiveSmallIntegerField()
|
||||
difficulty = models.DecimalField(max_digits=4, decimal_places=1)
|
||||
|
||||
def save(self, *args, **kwargs):
|
||||
"""Sauve les informations de la personne et initialise les champs nettoyés."""
|
||||
is_skill = False
|
||||
try:
|
||||
educative = Routine.objects.get(pk=self.educative)
|
||||
except Routine.DoesNotExist:
|
||||
educative = Skill.objects.get(pk=self.educative)
|
||||
is_skill = True
|
||||
|
||||
if is_skill:
|
||||
self.number_of_skill = self.repetition
|
||||
self.difficulty = educative.difficulty * self.repetition
|
||||
else:
|
||||
if self.regexp is not None:
|
||||
regexp = self.regexp.replace("[", "").replace("]", "")
|
||||
position = regexp.find("-")
|
||||
|
||||
start = regexp[:position]
|
||||
if start == "":
|
||||
start = 0
|
||||
else:
|
||||
start = int(start)
|
||||
|
||||
end = regexp[position + 1 :]
|
||||
if end == "":
|
||||
end = educative.jumps.all().count()
|
||||
else:
|
||||
end = int(end)
|
||||
|
||||
self.number_of_skill = (end - (start - 1)) * self.repetition
|
||||
list_of_skill = educative.skill_links.filter(
|
||||
rank__gte=start, rank__lte=end
|
||||
)
|
||||
# .aggregate(total=Sum("value"))
|
||||
self.difficulty = 0
|
||||
for routine_skill in list_of_skill:
|
||||
self.difficulty += routine_skill.skill.difficulty
|
||||
self.difficulty *= self.repetition
|
||||
|
||||
else:
|
||||
self.number_of_skill = educative.jumps.all().count() * self.repetition
|
||||
self.difficulty = educative.difficulty * self.repetition
|
||||
super().save(*args, **kwargs)
|
||||
|
||||
def __str__(self):
|
||||
if self.label:
|
||||
|
|
|
@ -14,30 +14,30 @@
|
|||
{{ hidden }}
|
||||
{% endfor %}
|
||||
<div class="form-group row {% if form.long_label.errors %}has-error has-feedback{% endif %}">
|
||||
<label for="id_date" class="col-4 col-sm-2 col-md-3 col-lg-3 col-xl-3 col-form-label">Long label <span class="text-danger"><b>*</b></span></label>
|
||||
<div class="col-8 col-sm-9 col-md-9 col-lg-9 col-xl-9">
|
||||
<label for="id_long_label" class="col-4 col-sm-2 col-md-2 col-lg-2 col-xl-2 col-form-label">Long label <span class="text-danger"><b>*</b></span></label>
|
||||
<div class="col-8 col-sm-10 col-md-10 col-lg-10 col-xl-10">
|
||||
{{ form.long_label }} {% if form.long_label.errors %}
|
||||
{% for error in form.long_label.errors %}{{ error }}{% endfor %}</span>{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group row {% if form.short_label.errors %}has-error has-feedback{% endif %}">
|
||||
<label for="id_date" class="col-4 col-sm-2 col-md-3 col-lg-3 col-xl-3 col-form-label">Short label <span class="text-danger"><b>*</b></span></label>
|
||||
<div class="col-8 col-sm-6 col-md-6 col-lg-6 col-xl-6">
|
||||
<label for="id_short_label" class="col-4 col-sm-2 col-md-2 col-lg-2 col-xl-2 col-form-label">Short label <span class="text-danger"><b>*</b></span></label>
|
||||
<div class="col-8 col-sm-10 col-md-10 col-lg-10 col-xl-10">
|
||||
{{ form.short_label }} {% if form.short_label.errors %}<span class="btn btn-sm btn-danger-outline">{% for error in form.short_label.errors %}{{ error }}{% endfor %}</span>{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group row {% if form.is_routine.errors %}has-error has-feedback{% endif %}">
|
||||
<label for="id_date" class="col-4 col-sm-2 col-md-3 col-lg-3 col-xl-3 col-form-label">Is routine ? <span class="text-danger"><b>*</b></span></label>
|
||||
<div class="col-6 col-sm-5 col-md-4 col-lg-3 col-xl-2">
|
||||
<label for="id_is_routine" class="col-4 col-sm-2 col-md-2 col-lg-2 col-xl-2 col-form-label">Is routine ? <span class="text-danger"><b>*</b></span></label>
|
||||
<div class="col-8 col-sm-10 col-md-10 col-lg-10 col-xl-10">
|
||||
{{ form.is_routine }} {% if form.is_routine.errors %}<span class="btn btn-sm btn-danger-outline">{% for error in form.is_routine.errors %}{{ error }}{% endfor %}</span>{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group row {% if form.is_competitive.errors %}has-error has-feedback{% endif %}">
|
||||
<label for="id_date" class="col-4 col-sm-2 col-md-3 col-lg-3 col-xl-3 col-form-label">Is Competitive ? <span class="text-danger"><b>*</b></span></label>
|
||||
<div class="col-6 col-sm-5 col-md-4 col-lg-3 col-xl-2">
|
||||
<label for="id_is_competitive" class="col-4 col-sm-2 col-md-2 col-lg-2 col-xl-2 col-form-label">Is Competitive ? <span class="text-danger"><b>*</b></span></label>
|
||||
<div class="col-8 col-sm-10 col-md-10 col-lg-10 col-xl-10">
|
||||
{{ form.is_competitive }} {% if form.is_competitive.errors %}<span class="btn btn-sm btn-danger-outline">{% for error in form.is_competitive.errors %}{{ error }}{% endfor %}</span>{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -0,0 +1,117 @@
|
|||
{% extends "base.html" %}
|
||||
|
||||
{% block content %}
|
||||
<div class="row justify-content-center">
|
||||
<div class="col-12 col-sm-12 col-md-8 col-lg-7 col-xl-6">
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<h4 class="">{% if passe_id %}Edit{% else %}Add{% endif %} Passe</h4>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<form action="{% if passe_id %}{% url 'passe_update' passe_id %}{% else %}{% url 'passe_create' %}{% endif %}" method="post" class="form-horizontal" id="formulaire" name="formulaire">
|
||||
|
||||
{% csrf_token %}
|
||||
{% for hidden in form.hidden_fields %}
|
||||
{{ hidden }}
|
||||
{% endfor %}
|
||||
|
||||
<div class="form-group row {% if form.long_label.errors %}has-error has-feedback{% endif %}">
|
||||
<label for="id_label" class="col-4 col-sm-2 col-md-2 col-lg-2 col-xl-2 col-form-label">Label</label>
|
||||
<div class="col-8 col-sm-10 col-md-10 col-lg-10 col-xl-10">
|
||||
{{ form.label }}
|
||||
{% if form.label.errors %} <span class="btn btn-sm btn-danger-outline">{% for error in form.label.errors %}{{ error }}{% endfor %}</span>{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group row ">
|
||||
<label for="id_educative" class="col-4 col-sm-2 col-md-2 col-lg-2 col-xl-2 col-form-label">Educative <span class="text-danger"><b>*</b></span></label>
|
||||
<div class="col-8 col-sm-8 col-md-6 col-lg-6 col-xl-6 {% if form.educative.errors %}has-danger{% endif %}">
|
||||
{{ form.educative_related }}
|
||||
{% if form.educative.errors %} <span class="btn btn-sm btn-danger-outline">{% for error in form.educative.errors %}{{ error }}{% endfor %}</span>{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group row {% if form.repetition.errors %}has-error has-feedback{% endif %}">
|
||||
<label for="id_repetition" class="col-4 col-sm-2 col-md-2 col-lg-2 col-xl-2 col-form-label">{{ form.repetition.label }} <span class="text-danger"><b>*</b></span></label>
|
||||
<div class="col-4 col-sm-4 col-md-4 col-lg-4 col-xl-3">
|
||||
{{ form.repetition }}
|
||||
{% if form.repetition.errors %} <span class="btn btn-sm btn-danger-outline">{% for error in form.repetition.errors %}{{ error }}{% endfor %}</span>{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group row {% if form.regexp.errors %}has-error has-feedback{% endif %}">
|
||||
<label for="id_regexp" class="col-4 col-sm-2 col-md-2 col-lg-2 col-xl-2 col-form-label">{{ form.regexp.label }}<span class="text-danger"><b>*</b></span></label>
|
||||
<div class="col-4 col-sm-4 col-md-4 col-lg-4 col-xl-3">
|
||||
{{ form.regexp }}
|
||||
{% if form.regexp.errors %} <span class="btn btn-sm btn-danger-outline">{% for error in form.regexp.errors %}{{ error }}{% endfor %}</span>{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group row ">
|
||||
<label for="id_informations" class="col-4 col-sm-2 col-md-2 col-lg-2 col-xl-2 col-form-label">Informations</label>
|
||||
<div class="col-8 col-sm-9 col-md-9 col-lg-9 col-xl-9 {% if form.id_information.errors %}has-danger{% endif %}">
|
||||
{{ form.informations }}
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group text-center">
|
||||
<input type="submit" value="Save" class="btn btn-warning" />
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% endblock %}
|
||||
|
||||
{% block footerscript %}
|
||||
<script type="text/javascript" >
|
||||
$(function(){
|
||||
const csrf_token = "{{ csrf_token|escapejs }}";
|
||||
const educative_lookup = "{% url 'educative_lookup' %}";
|
||||
|
||||
$('#id_educative_related').autocomplete({
|
||||
source: function(request, response) {
|
||||
$.ajax({
|
||||
url: educative_lookup,
|
||||
method: "POST",
|
||||
data: {
|
||||
pattern: $('#id_educative_related').val(),
|
||||
csrfmiddlewaretoken: csrf_token
|
||||
},
|
||||
dataType: "json",
|
||||
success: function(data) {
|
||||
if(data.length != 0) {
|
||||
response($.map(data, function(item) {
|
||||
return {
|
||||
label: item.long_label,
|
||||
value: item.short_label,
|
||||
educativeid: 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.educativeid);
|
||||
},
|
||||
{% if request.session.template == 0 %}
|
||||
classes: {
|
||||
"ui-widget-content": "custom_autocomplete_ul",
|
||||
"ui-autocomplete": "custom_autocomplete_ul",
|
||||
"ui-menu-item-wrapper": "custom_autocomplete_li",
|
||||
"ui-menu-item": "custom_autocomplete_li",
|
||||
},
|
||||
{% endif %}
|
||||
});
|
||||
});
|
||||
</script>
|
||||
{% endblock %}
|
|
@ -7,71 +7,13 @@
|
|||
<div class="row justify-content-center">
|
||||
<div class="col-12 col-sm-12 col-md-8 col-lg-8 col-xl-6">
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<h4 class="mb-0">{{ combination.short_label }}</h3>
|
||||
<h5 class="card-category mb-0">{{ combination.long_label }}</h4>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
{% if skill_link_list %}
|
||||
<table class="table table-striped table-condensed col-6 offset-3" id="list_skill_table">
|
||||
{% for link in skill_link_list %}
|
||||
<tr>
|
||||
<td></td>
|
||||
<td><a href="{% url 'skill_details' link.skill.id %}">{{ link.skill.notation }}</a></td>
|
||||
<td><a href="{% url 'skill_details' link.skill.id %}">{{ link.skill.short_label }}</a></td>
|
||||
<td class="text-center">{% if link.skill.difficulty != 0.0 %}{{ link.skill.difficulty }}{% endif %}</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
<tr>
|
||||
<td colspan="3" class="text-right"></td>
|
||||
<td class="text-center"><b>{{ combination.difficulty }}</b></td>
|
||||
</tr>
|
||||
</table>
|
||||
<div class="row">
|
||||
<div class="col-3 text-center">Niveau : <a href="#">{{ combination.level }}</a></div>
|
||||
<div class="col-3 text-center">Rank : <a href="#">{{ combination.rank }}</a></div>
|
||||
<div class="col-3 text-center">Age Boy : <a href="#">{{ combination.age_boy_masterised }}</a></div>
|
||||
<div class="col-3 text-center">Age Girl : <a href="#">{{ combination.age_girl_masterised }}</a></div>
|
||||
</div>
|
||||
{{ combination_string }}
|
||||
{% else %}
|
||||
<p>No skill defined for this combination.</p>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
{% if combination.informations %}
|
||||
<div class="col-md-12">
|
||||
<hr class="m-t">
|
||||
<h4>Informations</h4>
|
||||
<!-- <p>{{ skill.educative }}</p> -->
|
||||
<span id="comment">
|
||||
{{ combination.to_markdown | safe }}
|
||||
</span>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
<div class="card-footer row pt-0">
|
||||
<div class="col-6">
|
||||
<a href="{% url 'routine_listing' %}">
|
||||
<button type="submit" value="add" class="btn btn-icon btn-warning ">
|
||||
<i class="tim-icons icon-double-left"></i>
|
||||
</button>
|
||||
</a>
|
||||
</div>
|
||||
<div class="col-6 text-right">
|
||||
{% if request.user|has_group:"trainer" %}
|
||||
<a href="{% url 'compose_combination' combination.id %}">
|
||||
<button type="submit" value="add" class="btn btn-icon btn-warning ">
|
||||
<i class="tim-icons icon-molecule-40"></i>
|
||||
</button>
|
||||
</a>
|
||||
<a href="{% url 'combination_update' combination.id %}">
|
||||
<button type="submit" value="add" class="btn btn-icon btn-warning ">
|
||||
<i class="tim-icons icon-pencil"></i>
|
||||
</button>
|
||||
</a>
|
||||
{% endif %}
|
||||
</div>
|
||||
<b><u>Label :</b></u> {{ passe.label }}<br />
|
||||
<b><u>Educatif :</b></u> {{ passe.educative }}<br />
|
||||
<b><u>Répétition :</b></u> {{ passe.repetition }}<br />
|
||||
<b><u>RegExp :</b></u> {{ passe.regexp }}<br /><br />
|
||||
<a href="{% url 'combination_details' passe.educative.id %}">{{ passe.label }}{% if passe.regexp %}{{ passe.regexp }}{% endif %}</a> {{ passe.repetition }}<br /><br />
|
||||
{{ number_of_skill }} - {{ difficulty }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -1,73 +1,42 @@
|
|||
{% extends "listing.html" %}
|
||||
{% load has_group %}
|
||||
|
||||
{% block datacontent %}
|
||||
<div class="card mb-0">
|
||||
<div class="card-header">
|
||||
<div class="row">
|
||||
<div class="col-8">
|
||||
<h4 class=""> {{ title }} Listing {% if gymnast_id %}for <i>{{ gymnast }}</i>{% endif %}</h4>
|
||||
<h4 class=""> Passes Listing</h4>
|
||||
</div>
|
||||
<div class="col-1 ml-auto">
|
||||
<div class="text-right">
|
||||
{% if request.user|has_group:"trainer" %}
|
||||
<a href="{% url 'combination_create' %}">
|
||||
<button type="submit" value="add" class="btn btn-icon btn-warning mb-0">
|
||||
<i class="fas fa-plus"></i>
|
||||
</button>
|
||||
</a>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div class="table-responsive">
|
||||
{% if routine_list %}
|
||||
<table class="table tablesorter table-striped" data-sort="table" id="routine_table">
|
||||
<thead>
|
||||
<tr>
|
||||
{% if request.user|has_group:"trainer" %}
|
||||
<th style="width: 3%"></th>
|
||||
{% endif %}
|
||||
<th class="header text-left" style="width: 35%"> Long Label</th>
|
||||
<th class="header text-left" style="width: 20%"> Short Label</th>
|
||||
<th class="text-center" style="width: 10%">Competitive ?</th>
|
||||
<th class="header text-center"><i class="far fa-venus"></i></th>
|
||||
<th class="header text-center"><i class="far fa-mars"></i></th>
|
||||
<th class="header text-center" style="width: 7%">Diff.</th>
|
||||
<th class="header text-center" style="width: 7%">Level</th>
|
||||
<th class="header text-center" style="width: 7%">Rank</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for routine in routine_list %}
|
||||
<tr role="row" class="{% cycle 'odd' 'even' %}">
|
||||
{% if request.user|has_group:"trainer" %}
|
||||
<td>
|
||||
<a href="{% url 'combination_update' routine.id %}">
|
||||
<span class="tim-icons icon-pencil text-warning"></span>
|
||||
</a>
|
||||
</td>
|
||||
{% endif %}
|
||||
<td class="text-left"><a href="{% url 'combination_details' routine.id %}">{{ routine.long_label }}</a></td>
|
||||
<td class="text-left"><a href="{% url 'combination_details' routine.id %}">{{ routine.short_label }}</a></td>
|
||||
<td class="text-center">
|
||||
{% if routine.is_competitive %}<i class="fa fa-check text-success" aria-hidden="true"></i>
|
||||
{% else %}<i class="fa fa-times text-danger" aria-hidden="true"></i>
|
||||
{% endif %}
|
||||
</td>
|
||||
<td class="text-center">{{ routine.age_girl_masterised }}</td>
|
||||
<td class="text-center">{{ routine.age_boy_masterised }}</td>
|
||||
<td class="text-center">{{ routine.difficulty }}</td>
|
||||
<td class="text-center">{{ routine.level }}</td>
|
||||
<td class="text-center">{{ routine.rank }}</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
{% if passes_list %}
|
||||
<table class="table tablesorter table-striped" data-sort="table" id="routine_table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="text-center" style="width: 10%">label</th>
|
||||
<th class="header text-center" style="width: 7%">educative</th>
|
||||
<th class="header text-center" style="width: 7%">repetition</th>
|
||||
<th class="header text-center" style="width: 7%">regexp</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for passe in passes_list %}
|
||||
<tr role="row" class="{% cycle 'odd' 'even' %}">
|
||||
<td class="text-center">{{ passe.label }}</td>
|
||||
<td class="text-center">{{ passe.educative }}</td>
|
||||
<td class="text-center">{{ passe.repetition }}</td>
|
||||
<td class="text-center">{{ passe.regexp }}</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
{% else %}
|
||||
<p class="muted-text">There are no {{ title|lower }} corresponding to your criterias.</p>
|
||||
<p class="muted-text">There are no passe corresponding to your criterias.</p>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
|
@ -76,26 +45,26 @@
|
|||
|
||||
{% block footerscript %}
|
||||
<script type="text/javascript">
|
||||
$(document).ready(function () {
|
||||
$('routine_table').tablesorter({
|
||||
{% if request.user|has_group:"trainer" %}
|
||||
headers: {
|
||||
0: { sorter: false },
|
||||
},
|
||||
sortList: [[1, 0]],
|
||||
{% else %}
|
||||
sortList: [[0, 0]],
|
||||
{% endif %}
|
||||
});
|
||||
// $(document).ready(function () {
|
||||
// $('routine_table').tablesorter({
|
||||
// {% if request.user|has_group:"trainer" %}
|
||||
// headers: {
|
||||
// 0: { sorter: false },
|
||||
// },
|
||||
// sortList: [[1, 0]],
|
||||
// {% else %}
|
||||
// sortList: [[0, 0]],
|
||||
// {% endif %}
|
||||
// });
|
||||
|
||||
$('#routine_table').DataTable({
|
||||
scrollY: '50vh',
|
||||
scrollCollapse: true,
|
||||
paging: false,
|
||||
searching: false,
|
||||
ordering: false,
|
||||
"bInfo": false,
|
||||
});
|
||||
});
|
||||
// $('#routine_table').DataTable({
|
||||
// scrollY: '50vh',
|
||||
// scrollCollapse: true,
|
||||
// paging: false,
|
||||
// searching: false,
|
||||
// ordering: false,
|
||||
// "bInfo": false,
|
||||
// });
|
||||
// });
|
||||
</script>
|
||||
{% endblock %}
|
|
@ -0,0 +1,29 @@
|
|||
{% extends "base.html" %}
|
||||
{% load has_group %}
|
||||
|
||||
{% block page_title %}{{ combination.short_label }}{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="row justify-content-center">
|
||||
<div class="col-12 col-sm-12 col-md-8 col-lg-8 col-xl-6">
|
||||
<div class="card">
|
||||
<div class="card-body">
|
||||
{% if trainingprogram_list %}
|
||||
<table>
|
||||
<thead>
|
||||
<td colspan="3" class="text-center">--DATE--</td>
|
||||
</thead>
|
||||
{% for trainingprogram in trainingprogram_list %}
|
||||
<tr>
|
||||
<td>{{ trainingprogram.passe.label }} {{ trainingprogram.passe.repetition }}</td>
|
||||
<td><b>{{ trainingprogram.passe.number_of_skill}}</b></td>
|
||||
<td>{{ trainingprogram.passe.difficulty }}</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</table>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
|
@ -3,6 +3,10 @@ from . import views
|
|||
|
||||
|
||||
urlpatterns = [
|
||||
#
|
||||
#
|
||||
#
|
||||
path(r"educative/lookup/", views.educative_lookup, name="educative_lookup"),
|
||||
#
|
||||
# SKILLS
|
||||
#
|
||||
|
@ -85,4 +89,14 @@ urlpatterns = [
|
|||
#
|
||||
path(r"passe/<int:passe_id>/", views.passe_details, name="passe_details"),
|
||||
path(r"passe/", views.passe_listing, name="passe_listing"),
|
||||
path(
|
||||
r"passe/add/",
|
||||
views.passe_create_or_update,
|
||||
name="passe_create",
|
||||
),
|
||||
path(
|
||||
r"passe/edit/<int:passe_id>/",
|
||||
views.passe_create_or_update,
|
||||
name="passe_update",
|
||||
),
|
||||
]
|
||||
|
|
|
@ -9,6 +9,7 @@ from jarvis.people.models import Gymnast
|
|||
|
||||
from .forms import (
|
||||
SkillForm,
|
||||
PasseForm,
|
||||
CombinationForm,
|
||||
CombinationSkillForm,
|
||||
)
|
||||
|
@ -16,11 +17,35 @@ from .models import (
|
|||
Skill,
|
||||
Passe,
|
||||
Routine,
|
||||
Educative,
|
||||
RoutineSkill,
|
||||
PrerequisiteClosure,
|
||||
)
|
||||
|
||||
|
||||
@login_required
|
||||
@require_http_methods(["POST"])
|
||||
def educative_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.POST.get("pattern", None)
|
||||
|
||||
# Ignore queries shorter than length 2
|
||||
if pattern is not None and len(pattern) > 2:
|
||||
model_results = Educative.objects.filter(
|
||||
Q(short_label__icontains=pattern) | Q(long_label__icontains=pattern)
|
||||
)
|
||||
results = [
|
||||
{"ID": x.id, "long_label": x.long_label, "short_label": x.short_label}
|
||||
for x in model_results
|
||||
]
|
||||
|
||||
return JsonResponse(results, safe=False)
|
||||
|
||||
|
||||
@login_required
|
||||
@require_http_methods(["POST"])
|
||||
def skill_lookup(request):
|
||||
|
@ -486,9 +511,78 @@ def passe_details(request, passe_id):
|
|||
"""Détails d'un passage."""
|
||||
|
||||
passe = get_object_or_404(Passe, pk=passe_id)
|
||||
educative = passe.educative
|
||||
|
||||
try:
|
||||
educative = Routine.objects.get(pk=passe.educative)
|
||||
is_skill = False
|
||||
except Routine.DoesNotExist:
|
||||
educative = Skill.objects.get(pk=passe.educative)
|
||||
is_skill = True
|
||||
|
||||
if is_skill:
|
||||
number_of_skill = passe.repetition
|
||||
difficulty = educative.difficulty * passe.repetition
|
||||
else:
|
||||
if passe.regexp is not None:
|
||||
regexp = passe.regexp.replace("[", "").replace("]", "")
|
||||
position = regexp.find("-")
|
||||
|
||||
start = regexp[:position]
|
||||
if start == "":
|
||||
start = 0
|
||||
else:
|
||||
start = int(start)
|
||||
|
||||
end = regexp[position + 1 :]
|
||||
if end == "":
|
||||
end = educative.jumps.all().count()
|
||||
else:
|
||||
end = int(end)
|
||||
|
||||
number_of_skill = (end - (start - 1)) * passe.repetition
|
||||
list_of_skill = educative.skill_links.filter(rank__gte=start, rank__lte=end)
|
||||
# .aggregate(total=Sum("value"))
|
||||
difficulty = 0
|
||||
for routine_skill in list_of_skill:
|
||||
difficulty += routine_skill.skill.difficulty
|
||||
difficulty *= passe.repetition
|
||||
|
||||
else:
|
||||
number_of_skill = educative.jumps.all().count() * passe.repetition
|
||||
difficulty = educative.difficulty * passe.repetition
|
||||
|
||||
context = {
|
||||
"passe": passe,
|
||||
"is_skill": is_skill,
|
||||
"educative": educative,
|
||||
"difficulty": difficulty,
|
||||
"number_of_skill": number_of_skill,
|
||||
}
|
||||
return render(request, "passes/details.html", context)
|
||||
|
||||
|
||||
@login_required
|
||||
@require_http_methods(["GET", "POST"])
|
||||
def passe_create_or_update(request, passe_id=None):
|
||||
"""Création d'un passage.
|
||||
|
||||
Args:
|
||||
passe_id (int) identifiant d'un object de classe <Passe>.
|
||||
"""
|
||||
if passe_id:
|
||||
passe = get_object_or_404(Passe, pk=passe_id)
|
||||
else:
|
||||
passe = None
|
||||
|
||||
if request.method == "POST":
|
||||
form = PasseForm(request.POST, instance=passe)
|
||||
|
||||
if form.is_valid():
|
||||
passe = form.save()
|
||||
return HttpResponseRedirect(reverse("passe_details", args=(passe.pk,)))
|
||||
|
||||
return render(request, "passes/create.html", {"form": form})
|
||||
|
||||
form = PasseForm(instance=passe)
|
||||
context = {"form": form, "passe_id": passe_id}
|
||||
return render(request, "passes/create.html", context)
|
||||
|
|
Loading…
Reference in New Issue