mirror of
https://github.com/nottinghamtec/PyRIGS.git
synced 2026-01-24 17:02:18 +00:00
Much template wrangling
This commit is contained in:
@@ -51,11 +51,11 @@ class Command(BaseCommand):
|
|||||||
|
|
||||||
def setup_levels(self):
|
def setup_levels(self):
|
||||||
items = self.items.copy()
|
items = self.items.copy()
|
||||||
ta = models.TrainingLevel.objects.create(level=models.TrainingLevel.TA, description="Passion will hatred faithful evil suicide noble battle. Truth aversion gains grandeur noble. Dead play gains prejudice god ascetic grandeur zarathustra dead good. Faithful ultimate justice overcome love will mountains inexpedient.")
|
ta = models.TrainingLevel.objects.create(level=models.TrainingLevel.TA, description="Passion will hatred faithful evil suicide noble battle. Truth aversion gains grandeur noble. Dead play gains prejudice god ascetic grandeur zarathustra dead good. Faithful ultimate justice overcome love will mountains inexpedient.", icon="address-card")
|
||||||
self.levels.append(ta)
|
self.levels.append(ta)
|
||||||
tech_ccs = models.TrainingLevel.objects.create(level=models.TrainingLevel.TECHNICIAN, description="Technician Common Competencies. Spirit abstract endless insofar horror sexuality depths war decrepit against strong aversion revaluation free. Christianity reason joy sea law mountains transvaluation. Sea battle aversion dead ultimate morality self. Faithful morality.")
|
tech_ccs = models.TrainingLevel.objects.create(level=models.TrainingLevel.TECHNICIAN, description="Technician Common Competencies. Spirit abstract endless insofar horror sexuality depths war decrepit against strong aversion revaluation free. Christianity reason joy sea law mountains transvaluation. Sea battle aversion dead ultimate morality self. Faithful morality.", icon="book-reader")
|
||||||
tech_ccs.prerequisite_levels.add(ta)
|
tech_ccs.prerequisite_levels.add(ta)
|
||||||
super_ccs = models.TrainingLevel.objects.create(level=models.TrainingLevel.SUPERVISOR, description="Depths disgust hope faith of against hatred will victorious. Law...")
|
super_ccs = models.TrainingLevel.objects.create(level=models.TrainingLevel.SUPERVISOR, description="Depths disgust hope faith of against hatred will victorious. Law...", icon="user-graduate")
|
||||||
for i in range(0, 5):
|
for i in range(0, 5):
|
||||||
if len(items) == 0:
|
if len(items) == 0:
|
||||||
break
|
break
|
||||||
@@ -65,10 +65,17 @@ class Command(BaseCommand):
|
|||||||
models.TrainingLevelRequirement.objects.create(level=tech_ccs, item=item, depth=random.choice(models.TrainingItemQualification.CHOICES)[0])
|
models.TrainingLevelRequirement.objects.create(level=tech_ccs, item=item, depth=random.choice(models.TrainingItemQualification.CHOICES)[0])
|
||||||
else:
|
else:
|
||||||
models.TrainingLevelRequirement.objects.create(level=super_ccs, item=item, depth=random.choice(models.TrainingItemQualification.CHOICES)[0])
|
models.TrainingLevelRequirement.objects.create(level=super_ccs, item=item, depth=random.choice(models.TrainingItemQualification.CHOICES)[0])
|
||||||
|
icons = {
|
||||||
|
models.TrainingLevel.SOUND: ('microphone', 'microphone-alt'),
|
||||||
|
models.TrainingLevel.LIGHTING: ('lightbulb', 'traffic-light'),
|
||||||
|
models.TrainingLevel.POWER: ('plug', 'bolt'),
|
||||||
|
models.TrainingLevel.RIGGING: ('link', 'pallet'),
|
||||||
|
models.TrainingLevel.HAULAGE: ('truck', 'route'),
|
||||||
|
}
|
||||||
for i,name in models.TrainingLevel.DEPARTMENTS:
|
for i,name in models.TrainingLevel.DEPARTMENTS:
|
||||||
technician = models.TrainingLevel.objects.create(level=models.TrainingLevel.TECHNICIAN, department=i, description="Moral pinnacle derive ultimate war dead. Strong fearful joy contradict battle christian faithful enlightenment prejudice zarathustra moral.")
|
technician = models.TrainingLevel.objects.create(level=models.TrainingLevel.TECHNICIAN, department=i, description="Moral pinnacle derive ultimate war dead. Strong fearful joy contradict battle christian faithful enlightenment prejudice zarathustra moral.", icon=icons[i][0])
|
||||||
technician.prerequisite_levels.add(tech_ccs)
|
technician.prerequisite_levels.add(tech_ccs)
|
||||||
supervisor = models.TrainingLevel.objects.create(level=models.TrainingLevel.SUPERVISOR, department=i, description="Spirit holiest merciful mountains inexpedient reason value. Suicide ultimate hope.")
|
supervisor = models.TrainingLevel.objects.create(level=models.TrainingLevel.SUPERVISOR, department=i, description="Spirit holiest merciful mountains inexpedient reason value. Suicide ultimate hope.", icon=icons[i][1])
|
||||||
supervisor.prerequisite_levels.add(super_ccs, technician)
|
supervisor.prerequisite_levels.add(super_ccs, technician)
|
||||||
|
|
||||||
for i in range(0, 30):
|
for i in range(0, 30):
|
||||||
@@ -87,7 +94,7 @@ class Command(BaseCommand):
|
|||||||
supervisor = models.Profile.objects.create(username="supervisor", first_name="Super", last_name="Visor",
|
supervisor = models.Profile.objects.create(username="supervisor", first_name="Super", last_name="Visor",
|
||||||
initials="SV",
|
initials="SV",
|
||||||
email="supervisor@example.com", is_active=True,
|
email="supervisor@example.com", is_active=True,
|
||||||
is_staff=True)
|
is_staff=True, is_approved=True)
|
||||||
supervisor.set_password('supervisor')
|
supervisor.set_password('supervisor')
|
||||||
supervisor.save()
|
supervisor.save()
|
||||||
models.TrainingLevelQualification.objects.create(trainee=supervisor, level=models.TrainingLevel.objects.filter(level__gte=models.TrainingLevel.SUPERVISOR).exclude(department=models.TrainingLevel.HAULAGE).exclude(department__isnull=True).first(), confirmed_on=timezone.now())
|
models.TrainingLevelQualification.objects.create(trainee=supervisor, level=models.TrainingLevel.objects.filter(level__gte=models.TrainingLevel.SUPERVISOR).exclude(department=models.TrainingLevel.HAULAGE).exclude(department__isnull=True).first(), confirmed_on=timezone.now())
|
||||||
|
|||||||
@@ -42,8 +42,6 @@ class Trainee(Profile, RevisionMixin):
|
|||||||
def get_absolute_url(self):
|
def get_absolute_url(self):
|
||||||
return reverse('trainee_detail', kwargs={'pk': self.pk})
|
return reverse('trainee_detail', kwargs={'pk': self.pk})
|
||||||
|
|
||||||
# Items
|
|
||||||
|
|
||||||
|
|
||||||
class TrainingCategory(models.Model):
|
class TrainingCategory(models.Model):
|
||||||
reference_number = models.CharField(max_length=3)
|
reference_number = models.CharField(max_length=3)
|
||||||
@@ -134,12 +132,16 @@ class TrainingLevel(models.Model, RevisionMixin):
|
|||||||
(TECHNICIAN, 'Technician'),
|
(TECHNICIAN, 'Technician'),
|
||||||
(SUPERVISOR, 'Supervisor'),
|
(SUPERVISOR, 'Supervisor'),
|
||||||
)
|
)
|
||||||
|
SOUND = 0
|
||||||
|
LIGHTING = 1
|
||||||
|
POWER = 2
|
||||||
|
RIGGING = 3
|
||||||
HAULAGE = 4
|
HAULAGE = 4
|
||||||
DEPARTMENTS = (
|
DEPARTMENTS = (
|
||||||
(0, 'Sound'),
|
(SOUND, 'Sound'),
|
||||||
(1, 'Lighting'),
|
(LIGHTING, 'Lighting'),
|
||||||
(2, 'Power'),
|
(POWER, 'Power'),
|
||||||
(3, 'Rigging'),
|
(RIGGING, 'Rigging'),
|
||||||
(HAULAGE, 'Haulage'),
|
(HAULAGE, 'Haulage'),
|
||||||
)
|
)
|
||||||
department = models.IntegerField(choices=DEPARTMENTS, null=True) # N.B. Technical Assistant does not have a department
|
department = models.IntegerField(choices=DEPARTMENTS, null=True) # N.B. Technical Assistant does not have a department
|
||||||
@@ -147,16 +149,17 @@ class TrainingLevel(models.Model, RevisionMixin):
|
|||||||
prerequisite_levels = models.ManyToManyField('self', related_name='prerequisites', symmetrical=False, blank=True)
|
prerequisite_levels = models.ManyToManyField('self', related_name='prerequisites', symmetrical=False, blank=True)
|
||||||
icon = models.CharField(null=True, blank=True, max_length=20)
|
icon = models.CharField(null=True, blank=True, max_length=20)
|
||||||
|
|
||||||
def get_department_colour(self):
|
@property
|
||||||
if self.department == 0:
|
def department_colour(self):
|
||||||
|
if self.department == self.SOUND:
|
||||||
return "info"
|
return "info"
|
||||||
elif self.department == 1:
|
elif self.department == self.LIGHTING:
|
||||||
return "dark"
|
return "dark"
|
||||||
elif self.department == 2:
|
elif self.department == self.POWER:
|
||||||
return "danger"
|
return "danger"
|
||||||
elif self.department == 3:
|
elif self.department == self.RIGGING:
|
||||||
return "warning"
|
return "warning"
|
||||||
elif self.department == 4:
|
elif self.department == self.HAULAGE:
|
||||||
return "light"
|
return "light"
|
||||||
else:
|
else:
|
||||||
return "primary"
|
return "primary"
|
||||||
|
|||||||
@@ -1,11 +1,10 @@
|
|||||||
{% extends 'base_training.html' %}
|
{% extends 'base_training.html' %}
|
||||||
{% load colour_from_level from tags %}
|
|
||||||
|
|
||||||
{% block css %}
|
{% block css %}
|
||||||
<style>
|
<style>
|
||||||
.level-1::after {
|
.level-1::after {
|
||||||
content: "";
|
content: "";
|
||||||
position: relative;
|
position: relative;
|
||||||
left: 50%;
|
left: 50%;
|
||||||
transform: translateX(-50%);
|
transform: translateX(-50%);
|
||||||
width: 2px;
|
width: 2px;
|
||||||
@@ -38,9 +37,9 @@
|
|||||||
<div class="col-6">
|
<div class="col-6">
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<div class="{% if forloop.first %}level-1 row{% elif forloop.counter == 2 %}level-2 row{%endif%}">
|
<div class="{% if forloop.first %}level-1 row{% elif forloop.counter == 2 %}level-2 row{%endif%}">
|
||||||
<div class="card my-3">
|
<div class="card my-3 border-{{level.department_colour}}">
|
||||||
<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 bg-{% colour_from_level level %}">
|
<div class="card-body">
|
||||||
<p>{{ level.description }}</p>
|
<p>{{ level.description }}</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
5
training/templates/partials/add_qualification.html
Normal file
5
training/templates/partials/add_qualification.html
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
{% if request.user.is_supervisor or perms.training.add_trainingitemqualification %}
|
||||||
|
<a type="button" class="btn btn-success" href="{% url 'add_qualification' object.pk %}" id="add_record">
|
||||||
|
<span class="fas fa-plus"></span> Add New Training Record
|
||||||
|
</a>
|
||||||
|
{% endif %}
|
||||||
@@ -45,9 +45,7 @@
|
|||||||
{% block content %}
|
{% block content %}
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-sm-12 text-right">
|
<div class="col-sm-12 text-right">
|
||||||
<a type="button" class="btn btn-success" href="{% url 'edit_record' object.pk %}" id="add_record">
|
{% include 'partials/add_qualification.html' %}
|
||||||
<span class="fas fa-plus"></span> Add New Training Record
|
|
||||||
</a>
|
|
||||||
<a href="{% url 'trainee_item_detail' object.pk %}" class="btn btn-info"><span class="fas fa-info-circle"></span> View Detailed Record</a><br/>
|
<a href="{% url 'trainee_item_detail' object.pk %}" class="btn btn-info"><span class="fas fa-info-circle"></span> View Detailed Record</a><br/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -26,7 +26,3 @@ 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()
|
|
||||||
|
|||||||
@@ -6,19 +6,19 @@ from PyRIGS.decorators import permission_required_with_403
|
|||||||
from training import views
|
from training import views
|
||||||
|
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
path('items/', views.ItemList.as_view(), name='item_list'),
|
path('items/', login_required(views.ItemList.as_view()), name='item_list'),
|
||||||
path('trainee/list/', views.TraineeList.as_view(), name='trainee_list'),
|
path('trainee/list/', login_required(views.TraineeList.as_view()), name='trainee_list'),
|
||||||
path('trainee/', login_required(views.TraineeDetail.as_view()), name='trainee_detail'),
|
path('trainee/', login_required(views.TraineeDetail.as_view()), name='trainee_detail'),
|
||||||
path('trainee/<int:pk>/',
|
path('trainee/<int:pk>/',
|
||||||
permission_required_with_403('RIGS.view_profile')(views.TraineeDetail.as_view()),
|
permission_required_with_403('RIGS.view_profile')(views.TraineeDetail.as_view()),
|
||||||
name='trainee_detail'),
|
name='trainee_detail'),
|
||||||
path('trainee/<int:pk>/edit/', views.AddQualification.as_view(),
|
path('trainee/<int:pk>/add_qualification/', login_required(views.AddQualification.as_view()),
|
||||||
name='edit_record'),
|
name='add_qualification'),
|
||||||
path('session/', views.SessionLog.as_view(), name='session_log'),
|
path('session/', login_required(views.SessionLog.as_view()), name='session_log'),
|
||||||
path('levels/', views.LevelList.as_view(), name='level_list'),
|
path('levels/', login_required(views.LevelList.as_view()), name='level_list'),
|
||||||
path('level/<int:pk>/', views.LevelDetail.as_view(), name='level_detail'),
|
path('level/<int:pk>/', login_required(views.LevelDetail.as_view()), name='level_detail'),
|
||||||
path('level/<int:pk>/add_requirement/', views.AddLevelRequirement.as_view(), name='add_requirement'),
|
path('level/<int:pk>/add_requirement/', login_required(views.AddLevelRequirement.as_view()), name='add_requirement'),
|
||||||
path('level/remove_requirement/<int:pk>/', views.RemoveRequirement.as_view(), name='remove_requirement'),
|
path('level/remove_requirement/<int:pk>/', login_required(views.RemoveRequirement.as_view()), name='remove_requirement'),
|
||||||
path('trainee/<int:pk>/level/<int:level_pk>/confirm', views.ConfirmLevel.as_view(), name='confirm_level'),
|
path('trainee/<int:pk>/level/<int:level_pk>/confirm', login_required(views.ConfirmLevel.as_view()), name='confirm_level'),
|
||||||
path('trainee/<int:pk>/item_record', views.TraineeItemDetail.as_view(), name='trainee_item_detail'),
|
path('trainee/<int:pk>/item_record', login_required(views.TraineeItemDetail.as_view()), name='trainee_item_detail'),
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -61,7 +61,7 @@ class LevelDetail(generic.DetailView):
|
|||||||
|
|
||||||
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"] = "Training Level {} <span class='badge badge-{} badge-pill'><span class='fas fa-{}'></span></span>".format(self.object, self.object.get_department_colour(), self.object.icon)
|
context["page_title"] = "Training Level {} <span class='badge badge-{} badge-pill'><span class='fas fa-{}'></span></span>".format(self.object, self.object.department_colour, self.object.icon)
|
||||||
context["users_with"] = map(lambda qual: qual.trainee, models.TrainingLevelQualification.objects.filter(level=self.object))
|
context["users_with"] = map(lambda qual: qual.trainee, models.TrainingLevelQualification.objects.filter(level=self.object))
|
||||||
return context
|
return context
|
||||||
|
|
||||||
|
|||||||
@@ -146,19 +146,31 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<div class="col mb-2">
|
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<div class="col col-lg-6 mb-2">
|
||||||
<div class="card">
|
<div class="card">
|
||||||
<div class="card-header">Training Record</div>
|
<div class="card-header">Training Record</div>
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
<a href="{% url 'trainee_detail' object.pk %}" class="btn btn-primary"><span class="fas fa-eye"></span> View Training Record</a>
|
<a href="{% url 'trainee_detail' object.pk %}" class="btn btn-primary"><span class="fas fa-eye"></span> View Training Record</a>
|
||||||
|
{% include 'partials/add_qualification.html' %}
|
||||||
|
<ul class="list-group pt-3">
|
||||||
|
<li class="list-group-item active">Achieved Levels:</li>
|
||||||
|
{% for qual in completed_levels %}
|
||||||
|
<a href="{% url 'level_detail' qual.level.pk %}"class="list-group-item list-group-item-action d-flex justify-content-between align-items-center">{{ qual.level }}<span class='badge badge-{{qual.level.department_colour}} badge-pill'><span class='fas fa-{{qual.level.icon|default:"question"}}'></span></span></a>
|
||||||
|
{% endfor %}
|
||||||
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
<div class="col-lg-6">
|
||||||
<div class="card">
|
<div class="card">
|
||||||
<div class="card-header">Events</div>
|
<div class="card-header">Events</div>
|
||||||
{% with object.latest_events as events %}
|
{% with object.latest_events as events %}
|
||||||
{% include 'partials/event_table.html' %}
|
{% include 'partials/event_table.html' %}
|
||||||
{% endwith %}
|
{% endwith %}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ from django.views import generic
|
|||||||
from django.views.decorators.csrf import csrf_exempt
|
from django.views.decorators.csrf import csrf_exempt
|
||||||
|
|
||||||
from RIGS import models
|
from RIGS import models
|
||||||
|
from training.models import Trainee
|
||||||
|
|
||||||
|
|
||||||
# This view should be exempt from requiring CSRF token.
|
# This view should be exempt from requiring CSRF token.
|
||||||
@@ -42,6 +43,7 @@ class ProfileDetail(generic.DetailView):
|
|||||||
def get_context_data(self, **kwargs):
|
def get_context_data(self, **kwargs):
|
||||||
context = super(ProfileDetail, self).get_context_data(**kwargs)
|
context = super(ProfileDetail, self).get_context_data(**kwargs)
|
||||||
context['page_title'] = "Profile: {}".format(self.object)
|
context['page_title'] = "Profile: {}".format(self.object)
|
||||||
|
context["completed_levels"] = Trainee.objects.get(pk=self.object.pk).level_qualifications()
|
||||||
return context
|
return context
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user