mirror of
https://github.com/nottinghamtec/PyRIGS.git
synced 2026-03-23 12:25:56 +00:00
Compare commits
4 Commits
cddb76bf7e
...
081c33ebc8
| Author | SHA1 | Date | |
|---|---|---|---|
| 081c33ebc8 | |||
| 75410db752 | |||
| 06c6b9a36e | |||
| 13b1cea28b |
@@ -44,9 +44,9 @@
|
|||||||
<h4 class="card-header">Training Database</h4>
|
<h4 class="card-header">Training Database</h4>
|
||||||
<div class="list-group list-group-flush">
|
<div class="list-group list-group-flush">
|
||||||
<a class="list-group-item list-group-item-action text-info" href="{% url 'trainee_detail' %}"><span class="fas fa-file-signature align-middle"></span><span class="align-middle"> My Training Record</span></a>
|
<a class="list-group-item list-group-item-action text-info" href="{% url 'trainee_detail' %}"><span class="fas fa-file-signature align-middle"></span><span class="align-middle"> My Training Record</span></a>
|
||||||
<a class="list-group-item list-group-item-action" href="{% url 'trainee_list' %}"><span class="fas fa-clipboard-list align-middle"></span><span class="align-middle"> View Training Records</span></a>
|
<a class="list-group-item list-group-item-action" href="{% url 'trainee_list' %}"><span class="fas fa-users"></span> Trainee List</a>
|
||||||
<a class="list-group-item list-group-item-action" href="{% url 'item_list' %}"><span class="fas fa-eye align-middle"></span><span class="align-middle"> View Training Items</span></a>
|
<a class="list-group-item list-group-item-action" href="{% url 'item_list' %}"><span class="fas fa-layer-group"></span> Level List</a></a>
|
||||||
<a class="list-group-item list-group-item-action" href="{% url 'session_log' %}"><span class="fas fa-plus align-middle"></span><span class="align-middle"> Log Training Session</span></a>
|
<a class="list-group-item list-group-item-action" href="{% url 'session_log' %}"><span class="fas fa-sitemap"></span> Item List</a></a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -10,13 +10,18 @@ class Trainee(Profile):
|
|||||||
class Meta:
|
class Meta:
|
||||||
proxy = True
|
proxy = True
|
||||||
|
|
||||||
|
def started_levels(self):
|
||||||
|
return [level for level in TrainingLevel.objects.all() if level.percentage_complete(self) > 0]
|
||||||
|
|
||||||
|
def level_qualifications(self, only_confirmed=False):
|
||||||
|
levels = self.levels.all()
|
||||||
|
if only_confirmed:
|
||||||
|
levels = levels.filter(confirmed_on__isnull=False)
|
||||||
|
return levels.select_related('level')
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def is_supervisor(self):
|
def is_supervisor(self):
|
||||||
# FIXME Efficiency
|
return self.level_qualifications(True).filter(level__gte=TrainingLevel.SUPERVISOR).exists()
|
||||||
for level_qualification in self.levels.select_related('level').all():
|
|
||||||
if level_qualification.confirmed_on is not None and level_qualification.level.level >= TrainingLevel.SUPERVISOR:
|
|
||||||
return True
|
|
||||||
return False
|
|
||||||
|
|
||||||
def get_records_of_depth(self, depth):
|
def get_records_of_depth(self, depth):
|
||||||
return self.qualifications_obtained.filter(depth=depth).select_related('item', 'trainee', 'supervisor')
|
return self.qualifications_obtained.filter(depth=depth).select_related('item', 'trainee', 'supervisor')
|
||||||
@@ -138,6 +143,8 @@ class TrainingLevel(models.Model, RevisionMixin):
|
|||||||
elif self.department == 2:
|
elif self.department == 2:
|
||||||
return "danger"
|
return "danger"
|
||||||
elif self.department == 3:
|
elif self.department == 3:
|
||||||
|
return "warning"
|
||||||
|
elif self.department == 4:
|
||||||
return "light"
|
return "light"
|
||||||
else:
|
else:
|
||||||
return "primary"
|
return "primary"
|
||||||
@@ -215,7 +222,7 @@ class TrainingLevelQualification(models.Model):
|
|||||||
reversion_hide = True
|
reversion_hide = True
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return "{} qualified as a {}".format(self.trainee, self.level)
|
return "{} is qualified as a {}".format(self.trainee, self.level)
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
unique_together = ["trainee", "level"]
|
unique_together = ["trainee", "level"]
|
||||||
|
|||||||
@@ -1,4 +1,21 @@
|
|||||||
{% extends 'base_training.html' %}
|
{% extends 'base_training.html' %}
|
||||||
|
{% load colour_from_level from tags %}
|
||||||
|
|
||||||
|
{% block css %}
|
||||||
|
<style>
|
||||||
|
.level-1::after {
|
||||||
|
content: "";
|
||||||
|
position: relative;
|
||||||
|
left: 50%;
|
||||||
|
transform: translateX(-50%);
|
||||||
|
width: 2px;
|
||||||
|
height: 50px;
|
||||||
|
margin-top: -15px;
|
||||||
|
margin-bottom: -15px;
|
||||||
|
background: black;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<div class="alert alert-info" role="alert">
|
<div class="alert alert-info" role="alert">
|
||||||
@@ -10,15 +27,28 @@
|
|||||||
</ul>
|
</ul>
|
||||||
<sup>Correct as of 3rd September 2021, check the Training Policy.</sup>
|
<sup>Correct as of 3rd September 2021, check the Training Policy.</sup>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="chart">
|
||||||
<div class="card-columns">
|
{% for level in levels %}
|
||||||
{% for level in levels %}
|
{% if forloop.counter == 3 %}
|
||||||
<div class="card my-3">
|
<div class="row">
|
||||||
<h3 class="card-header"><a href="{% url 'level_detail' level.pk %}">{{ level }}</a></h3>
|
<div class="col-6">
|
||||||
<div class="card-body">
|
{% endif %}
|
||||||
<p>{{ level.description }}</p>
|
{% if level.level == 2 and level.department is None %}
|
||||||
|
</div>
|
||||||
|
<div class="col-6">
|
||||||
|
{% endif %}
|
||||||
|
<div class="{% if forloop.first %}level-1 row{% elif forloop.counter == 2 %}level-2 row{%endif%}">
|
||||||
|
<div class="card my-3">
|
||||||
|
<h3 class="card-header"><a href="{% url 'level_detail' level.pk %}">{{ level }}</a></h3>
|
||||||
|
<div class="card-body bg-{% colour_from_level level %}">
|
||||||
|
<p>{{ level.description }}</p>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{% endfor %}
|
{% if forloop.last %}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
{% endfor %}
|
||||||
</div>
|
</div>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|||||||
@@ -48,19 +48,24 @@
|
|||||||
<a type="button" class="btn btn-success" href="{% url 'edit_record' object.pk %}" id="add_record">
|
<a type="button" class="btn btn-success" href="{% url 'edit_record' object.pk %}" id="add_record">
|
||||||
<span class="fas fa-plus"></span> Add New Training Record
|
<span class="fas fa-plus"></span> Add New Training Record
|
||||||
</a>
|
</a>
|
||||||
<a type="button" class="btn btn-warning" href="#" id="add_external">
|
<a href="{% url 'trainee_item_detail' object.pk %}" class="btn btn-info"><span class="fas fa-info-circle"></span> View Detailed Record</a><br/>
|
||||||
<span class="fas fa-building"></span> Log External Training
|
|
||||||
</a>
|
|
||||||
<a href="{% url 'trainee_item_detail' object.pk %}" class="btn btn-info col-2"><span class="fas fa-info-circle"></span> View Detailed Record</a><br/>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row mb-3">
|
<div class="row mb-3">
|
||||||
<h2 class="col-12">Training Levels</h2>
|
<h2 class="col-12">Training Levels</h2>
|
||||||
|
{% for level in completed_levels %}
|
||||||
|
{% if forloop.first %}<div class="card-columns">{% endif %}
|
||||||
|
<div class="card my-3 border-success">
|
||||||
|
<h3 class="card-header"><a href="{% url 'level_detail' level.pk %}">{{ level }}</a></h3>
|
||||||
|
</div>
|
||||||
|
{% if forloop.last %}</div>{%endif%}
|
||||||
|
{% empty %}
|
||||||
|
<span class="badge badge-warning">No qualifications in any levels yet...did someone forget to fill out the paperwork?</span>
|
||||||
|
{% endfor %}
|
||||||
<div class="card-columns">
|
<div class="card-columns">
|
||||||
{% for level in levels %}
|
{% for level in started_levels %}
|
||||||
{% percentage_complete level object as completion %}
|
{% percentage_complete level object as completion %}
|
||||||
{% if completion > 0 %}
|
<div class="card my-3 border-warning">
|
||||||
<div class="card my-3">
|
|
||||||
<h3 class="card-header"><a href="{% url 'level_detail' level.pk %}">{{ level }}</a></h3>
|
<h3 class="card-header"><a href="{% url 'level_detail' level.pk %}">{{ level }}</a></h3>
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
<p>{{ level.description|truncatewords:30 }}</p>
|
<p>{{ level.description|truncatewords:30 }}</p>
|
||||||
@@ -85,15 +90,14 @@
|
|||||||
{% endif %}
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<h2 class="col-10">Training Items</h2>
|
<h2 class="col-10">Training Items</h2>
|
||||||
<div class="alert alert-info" role="alert"><h3 class="col-12">Key: <span class="badge badge-warning">Training Started</span> <span class="badge badge-success">Training Complete</span> <span class="badge badge-info">Passed Out</span></h3></div>
|
<div class="alert alert-info col-12" role="alert"><h3>Key: <span class="badge badge-warning">Training Started</span> <span class="badge badge-success">Training Complete</span> <span class="badge badge-info">Passed Out</span></h3></div>
|
||||||
<div class="card-deck">
|
|
||||||
{% for category in categories %}
|
{% for category in categories %}
|
||||||
|
{% if forloop.first or forloop.counter|divisibleby:3 %}<div class="card-deck col-12">{% endif %}
|
||||||
<div class="card mb-3">
|
<div class="card mb-3">
|
||||||
<h3 class="card-header">{{ category }}</h3>
|
<h3 class="card-header">{{ category }}</h3>
|
||||||
<div class="list-group list-group-flush">
|
<div class="list-group list-group-flush">
|
||||||
@@ -101,9 +105,12 @@
|
|||||||
{% if q.item.category == category %}
|
{% if q.item.category == category %}
|
||||||
<li class="list-group-item list-group-item-{% colour_from_depth q.depth %}">{{q.item}} ({{q.date}})</li>
|
<li class="list-group-item list-group-item-{% colour_from_depth q.depth %}">{{q.item}} ({{q.date}})</li>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
{% empty %}
|
||||||
|
<li class="list-group-item text-muted">None yet...</li>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
{% if forloop.counter|add:"1"|divisibleby:3 %}</div>{% endif %}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -22,7 +22,7 @@
|
|||||||
<tbody>
|
<tbody>
|
||||||
{% for object in object_list %}
|
{% for object in object_list %}
|
||||||
<tr id="row_item">
|
<tr id="row_item">
|
||||||
<th scope="row" class="align-middle" id="cell_name">{{ object.name }} {% if request.user.pk == object.pk %}<span class="fas fa-user text-success"></span>{%endif%}</th>
|
<th scope="row" class="align-middle" id="cell_name"><a href="{% url 'trainee_detail' object.pk %}">{{ object.name }} {% if request.user.pk == object.pk %}<span class="fas fa-user text-success"></span>{%endif%}</a></th>
|
||||||
<td {% if object.is_supervisor %}class="table-success"{%endif%}>{{ object.is_supervisor|yesno|title }}</td>
|
<td {% if object.is_supervisor %}class="table-success"{%endif%}>{{ object.is_supervisor|yesno|title }}</td>
|
||||||
<td>{{ object.qualifications_obtained.all|length }}</td>
|
<td>{{ object.qualifications_obtained.all|length }}</td>
|
||||||
<td>
|
<td>
|
||||||
|
|||||||
@@ -26,3 +26,7 @@ def percentage_complete(level, user):
|
|||||||
@register.simple_tag
|
@register.simple_tag
|
||||||
def colour_from_depth(depth):
|
def colour_from_depth(depth):
|
||||||
return models.TrainingItemQualification.get_colour_from_depth(depth)
|
return models.TrainingItemQualification.get_colour_from_depth(depth)
|
||||||
|
|
||||||
|
@register.simple_tag
|
||||||
|
def colour_from_level(level):
|
||||||
|
return level.get_department_colour()
|
||||||
|
|||||||
@@ -27,9 +27,12 @@ class TraineeDetail(views.ProfileDetail, ModalURLMixin):
|
|||||||
|
|
||||||
def get_context_data(self, **kwargs):
|
def get_context_data(self, **kwargs):
|
||||||
context = super(TraineeDetail, self).get_context_data(**kwargs)
|
context = super(TraineeDetail, self).get_context_data(**kwargs)
|
||||||
context["page_title"] = "{}'s Training Record".format(self.object.first_name + " " + self.object.last_name)
|
if self.request.user.pk == self.object.pk:
|
||||||
# TODO Filter this to levels the user has
|
context["page_title"] = "Your Training Record"
|
||||||
context["levels"] = models.TrainingLevel.objects.all()
|
else:
|
||||||
|
context["page_title"] = "{}'s Training Record".format(self.object.first_name + " " + self.object.last_name)
|
||||||
|
context["started_levels"] = self.object.started_levels()
|
||||||
|
context["completed_levels"] = self.object.level_qualifications()
|
||||||
context["categories"] = models.TrainingCategory.objects.all().prefetch_related('items')
|
context["categories"] = models.TrainingCategory.objects.all().prefetch_related('items')
|
||||||
choices = models.TrainingItemQualification.CHOICES
|
choices = models.TrainingItemQualification.CHOICES
|
||||||
context["depths"] = choices
|
context["depths"] = choices
|
||||||
@@ -61,7 +64,7 @@ class LevelList(generic.ListView):
|
|||||||
def get_context_data(self, **kwargs):
|
def get_context_data(self, **kwargs):
|
||||||
context = super().get_context_data(**kwargs)
|
context = super().get_context_data(**kwargs)
|
||||||
context["page_title"] = "All Training Levels"
|
context["page_title"] = "All Training Levels"
|
||||||
context["levels"] = models.TrainingLevel.objects.all()
|
context["levels"] = models.TrainingLevel.objects.all().order_by('level','department')
|
||||||
return context
|
return context
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user