Compare commits

...

3 Commits

Author SHA1 Message Date
732affa0b2 SQL optimisation of detailed training record 2021-12-28 12:13:08 +00:00
7c830ee7e5 Fix sorting of items
W.T.F past self. Char field for a reference number?!
2021-12-28 11:46:52 +00:00
d47d00d79b Rework item list display 2021-12-28 11:36:46 +00:00
8 changed files with 86 additions and 63 deletions

View File

@@ -28,6 +28,9 @@
color: $gray-100 !important;
border-color: $darktheme;
}
.btn-link {
color: white;
}
.bs-popover-right > .arrow::after {
border-right-color: $darktheme;
}

View File

@@ -0,0 +1,23 @@
# Generated by Django 3.1.13 on 2021-12-28 11:44
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('training', '0009_auto_20211221_1539'),
]
operations = [
migrations.AlterField(
model_name='trainingcategory',
name='reference_number',
field=models.IntegerField(unique=True),
),
migrations.AlterField(
model_name='trainingitem',
name='reference_number',
field=models.IntegerField(),
),
]

View File

@@ -46,7 +46,7 @@ class Trainee(Profile, RevisionMixin):
class TrainingCategory(models.Model):
reference_number = models.CharField(max_length=3, unique=True)
reference_number = models.IntegerField(unique=True)
name = models.CharField(max_length=50)
def __str__(self):
@@ -57,7 +57,7 @@ class TrainingCategory(models.Model):
class TrainingItem(models.Model):
reference_number = models.CharField(max_length=3)
reference_number = models.IntegerField()
category = models.ForeignKey('TrainingCategory', related_name='items', on_delete=models.RESTRICT)
name = models.CharField(max_length=50)
active = models.BooleanField(default = True)
@@ -67,7 +67,10 @@ class TrainingItem(models.Model):
return "{}.{}".format(self.category.reference_number, self.reference_number)
def __str__(self):
return "{} {}".format(self.number, self.name)
name = "{} {}".format(self.number, self.name)
if not self.active:
name += " (inactive)"
return name
@staticmethod
def user_has_qualification(item, user, depth):

View File

@@ -1,18 +1,28 @@
{% extends 'base_training.html' %}
{% block content %}
<div class="row">
{% for category in categories %}
<div class="col">
<div class="card mb-3">
<h4 class="card-header">{{ category.name }}</h4>
<div class="list-group list-group-flush">
{% for item in category.items.all %}
<li class="list-group-item">{{ item }}</li>
{% endfor %}
</div>
</div>
<div id="accordion">
{% for category in categories %}
<div class="card">
<div class="card-header" id="heading{{forloop.counter}}">
<button class="btn btn-link collapsed" data-toggle="collapse" data-target="#collapse{{forloop.counter}}" aria-expanded="true" aria-controls="collapse{{forloop.counter}}">
{{ category }}
</button>
</div>
{% endfor %}
<div id="collapse{{forloop.counter}}" class="collapse" aria-labelledby="heading{{forloop.counter}}" data-parent="#accordion">
<div class="card-body">
<div class="list-group list-group-flush">
{% for item in category.items.all %}
{% if item.active %}
<li class="list-group-item">{{ item }}</li>
{% elif request.user.is_superuser %}
<li class="list-group-item text-warning">{{ item }} (inactive)</li>
{% endif %}
{% endfor %}
</div>
</div>
</div>
</div>
{% endfor %}
</div>
{% endblock %}

View File

@@ -57,32 +57,6 @@
<p>{{ object.description|markdown }}</p>
</div>
</div>
<div class="card mb-3 d-none d-md-block">
<h4 class="card-header">Users with this level</h4>
<div class="card-body">
<table class="table table-sm">
<thead>
<tr>
<th scope="col">Person</th>
<th scope="col">Confirmed?</th>
<th scope="col"></th>
</tr>
</thead>
<tbody>
{% for user in users_with %}
{% user_level_if_present user object as level_qualification %}
<tr {% if not level_qualification.confirmed_on %}style="border-style: dashed; opacity: 80%"{%endif%}>
<td><img src="{{user.profile_picture}}" style="width: 50px" class="img-thumbnail"/> {{user}}</td>
<td>{% if level_qualification.confirmed_on %}<p class="card-text"><small>Qualified on {{ level_qualification.confirmed_on }}</small></p>{%else%}Unconfirmed{%endif%}</td>
<td><a href="{% url 'profile_detail' user.pk %}" class="btn btn-primary btn-sm"><span class="fas fa-user"></span> View Profile</a></div></td>
</tr>
{% empty %}
Nobody here but us chickens... <span class="fas fa-egg text-warning"></span>
{% endfor %}
</tbody>
</table>
</div>
</div>
<div class="card">
<h4 class="card-header">Level Requirements</h4>
<table class="table card-body">
@@ -119,6 +93,32 @@
</ul>
</div>
</div>
<div class="card mb-3 d-none d-md-block">
<h4 class="card-header">Users with this level</h4>
<div class="card-body">
<table class="table table-sm">
<thead>
<tr>
<th scope="col">Person</th>
<th scope="col">Confirmed?</th>
<th scope="col"></th>
</tr>
</thead>
<tbody>
{% for user in users_with %}
{% user_level_if_present user object as level_qualification %}
<tr {% if not level_qualification.confirmed_on %}style="border-style: dashed; opacity: 80%"{%endif%}>
<td><img src="{{user.profile_picture}}" style="width: 50px" class="img-thumbnail"/> {{user}}</td>
<td>{% if level_qualification.confirmed_on %}<p class="card-text"><small>Qualified on {{ level_qualification.confirmed_on }}</small></p>{%else%}Unconfirmed{%endif%}</td>
<td><a href="{% url 'profile_detail' user.pk %}" class="btn btn-primary btn-sm"><span class="fas fa-user"></span> View Profile</a></div></td>
</tr>
{% empty %}
Nobody here but us chickens... <span class="fas fa-egg text-warning"></span>
{% endfor %}
</tbody>
</table>
</div>
</div>
<div class="row">
<div class="col text-right">
{% include 'partials/last_edited.html' with target="traininglevel_history" %}

View File

@@ -54,24 +54,6 @@ ul.tree>li:first-child::before {
ul.tree>li:first-child::after {
border-radius:5px 0 0 0;
}
.tree li a {
border: 1px #ccc solid;
border-radius: 5px;
padding:2px 5px;
}
.tree li a:hover, .tree li a:hover+ul li a,
.tree li a:focus, .tree li a:focus+ul li a {
background: #ccc; color: #000; border: 1px solid #000;
}
.tree li a:hover+ul li::after, .tree li a:focus+ul li::after,
.tree li a:hover+ul li::before, .tree li a:focus+ul li::before
.tree li a:hover+ul::before, .tree li a:focus+ul::before
.tree li a:hover+ul ul::before, .tree li a:focus+ul ul::before{
border-color: #000; /*connector color on hover*/
}
</style>
{% endblock %}
@@ -89,9 +71,11 @@ ul.tree>li:first-child::after {
<li><div class="card"><div class="card-header">{{ta}}</div><div class="card-body">{{ta.description|markdown}}</div></div>
<ul>
{% for level in tech %}
<li><div class="card"><div class="card-header">{{level}}</div><div class="card-body">{{level.description|markdown}}</div></div>
<li><div class="card"><div class="card-header"><a href="{{level.get_absolute_url}}">{{level}}</a></div><div class="card-body">{{level.description|markdown}}</div></div>
<ul>
<li><div class="card p-3">{{level|get_supervisor}}</div></li>
{% with level|get_supervisor as super %}
<li><div class="card"><div class="card-header"><a href="{{super.get_absolute_url}}">{{super}}</a></div><div class="card-body">{{super.description|markdown}}</div></div></li>
{% endwith %}
</ul>
</li>
{% endfor %}

View File

@@ -22,7 +22,7 @@
</thead>
<tbody>
{% for object in object_list %}
<tr id="row_item">
<tr id="row_item" {% if request.user.is_superuser and not object.item.active %}class="text-warning"{%endif%}>
<th scope="row" class="align-middle" id="cell_name">{{ object.item }}</th>
<td class="table-{% colour_from_depth object.depth %}">{{ object.get_depth_display }}</td>
<td>{{ object.date }}</td>

View File

@@ -51,7 +51,7 @@ class TraineeItemDetail(generic.ListView):
template_name = 'trainee_item_list.html'
def get_queryset(self):
return models.Trainee.objects.get(pk=self.kwargs['pk']).qualifications_obtained.all()
return models.Trainee.objects.get(pk=self.kwargs['pk']).qualifications_obtained.all().order_by('-date').select_related('item', 'trainee', 'supervisor', 'item__category')
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)