Fix list templates

TODO: Sensible place to define the 'expected answer' stuff.
This commit is contained in:
2020-09-03 12:38:52 +01:00
parent c1182efa54
commit e602058771
12 changed files with 128 additions and 222 deletions

View File

@@ -4,6 +4,7 @@ from django.utils import timezone
from django.http import HttpResponseRedirect
from django.urls import reverse_lazy
from reversion import revisions as reversion
from django.db.models import AutoField, ManyToOneRel
class EventRiskAssessmentCreate(generic.CreateView):
@@ -70,7 +71,17 @@ class EventRiskAssessmentDetail(generic.DetailView):
class EventRiskAssessmentList(generic.ListView):
paginate_by = 20
model = models.RiskAssessment
template_name = 'risk_assessment_list.html'
template_name = 'hs_object_list.html'
def get_context_data(self, **kwargs):
context = super(EventRiskAssessmentList, self).get_context_data(**kwargs)
context['title'] = 'Risk Assessment'
context['view'] = 'ra_detail'
context['edit'] = 'ra_edit'
context['review'] = 'ra_review'
context['perm'] = 'perms.RIGS.review_riskassessment'
context['fields'] = [n.name for n in list(self.model._meta.get_fields()) if n.name != 'reviewed_at' and n.name != 'reviewed_by' and not n.is_relation and not n.auto_created ]
return context
class EventRiskAssessmentReview(generic.View):
@@ -149,7 +160,17 @@ class EventChecklistCreate(generic.CreateView):
class EventChecklistList(generic.ListView):
paginate_by = 20
model = models.EventChecklist
template_name = 'event_checklist_list.html'
template_name = 'hs_object_list.html'
def get_context_data(self, **kwargs):
context = super(EventChecklistList, self).get_context_data(**kwargs)
context['title'] = 'Event Checklist'
context['view'] = 'ec_detail'
context['edit'] = 'ec_edit'
context['review'] = 'ec_review'
context['perm'] = 'perms.RIGS.review_eventchecklist'
context['fields'] = [n.name for n in list(self.model._meta.get_fields()) if n.name != 'reviewed_at' and n.name != 'reviewed_by' and not n.is_relation and not n.auto_created ]
return context
class EventChecklistReview(generic.View):

View File

@@ -465,7 +465,7 @@ class Event(models.Model, RevisionMixin):
return reverse_lazy('event_detail', kwargs={'pk': self.pk})
def __str__(self):
return str(self.pk) + ": " + self.name
return self.display_id + ": " + self.name
def clean(self):
if self.end_date and self.start_date > self.end_date:
@@ -585,14 +585,6 @@ class Payment(models.Model):
return "%s: %d" % (self.get_method_display(), self.amount)
# Probably shouldn't be doing HTML at the python level but hey...they say not to do logic in templates! :P
def get_review_string(obj, review_link):
if obj.reviewed_by:
return "<span class='badge badge-success py-2'>Reviewed by <a href='{}'>{}</a> at {}</span>".format(reverse_lazy('profile_detail', kwargs={'pk': obj.reviewed_by.pk}), obj.reviewed_by, obj.reviewed_at.strftime("%d/%m/%Y %H:%M"))
else:
return "<a class='btn btn-success my-2' href='{}'>Mark Reviewed</a>".format(reverse_lazy(review_link, kwargs={'pk': obj.pk}))
@reversion.register
class RiskAssessment(models.Model, RevisionMixin):
event = models.OneToOneField('Event', on_delete=models.CASCADE)
@@ -637,10 +629,14 @@ class RiskAssessment(models.Model, RevisionMixin):
reviewed_by = models.ForeignKey(settings.AUTH_USER_MODEL, blank=True, null=True,
verbose_name="Reviewer", on_delete=models.CASCADE)
inverted_fields = ['nonstandard_equipment','nonstandard_use', 'contractors', 'other_companies', 'crew_fatigue', 'big_power',
'generators', 'other_companies_power', 'nonstandard_equipment_power','multiple_electrical_environments','noise_monitoring'
'special_structures', 'suspended_structures']
class Meta:
ordering = ['event']
permissions = [
('riskassessment_review', 'Can review RAs')
('review_riskassessment', 'Review Risk Assessments')
]
def clean(self):
@@ -652,10 +648,6 @@ class RiskAssessment(models.Model, RevisionMixin):
if errdict != {}: # If there was an error when validation
raise ValidationError(errdict)
@property
def review_string(self):
return get_review_string(self, 'ra_review')
@property
def activity_feed_string(self):
return str(self.event)
@@ -725,10 +717,12 @@ class EventChecklist(models.Model, RevisionMixin):
reviewed_by = models.ForeignKey(settings.AUTH_USER_MODEL, blank=True, null=True,
verbose_name="Reviewer", on_delete=models.CASCADE)
inverted_fields = []
class Meta:
ordering = ['event']
permissions = [
('eventchecklist_review', 'Can review ECs')
('review_eventchecklist', 'Review Event Checklists')
]
def clean(self):
@@ -749,10 +743,6 @@ class EventChecklist(models.Model, RevisionMixin):
if errdict != {}: # If there was an error when validation
raise ValidationError(errdict)
@property
def review_string(self):
return get_review_string(self, 'ec_review')
@property
def activity_feed_string(self):
return str(self.event)

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -42,7 +42,7 @@
a {
color: $blue;
}
.badge, .btn-success {
.badge, .btn-success, .bg-warning {
color: black;
}
.badge-dark, .badge-secondary, .btn-primary {

View File

@@ -114,6 +114,11 @@ svg {
white-space: no-wrap;
}
input[required]::after,select[required]::after {
content: '*';
color: red;
}
html.embedded {
display: flex;
flex-direction: column;
@@ -158,8 +163,3 @@ html.embedded {
max-width: 3em;
}
}
(input,select)[required]::after {
content: '*';
color: red;
}

View File

@@ -1,67 +0,0 @@
{% extends 'base_rigs.html' %}
{% load paginator from filters %}
{% load help_text from filters %}
{% load verbose_name from filters %}
{% block title %}Event Checklist List{% endblock %}
{% block content %}
<div class="row">
<div class="col-12">
<h2>Event Checklist List</h2>
</div>
</div>
<div class="row">
<div class="col-12">
<div class="table-responsive">
<table class="table mb-0">
<thead>
<tr>
<th scope="col">Event</th>
{# mmm hax #}
{% if object_list.0 %}
<th scope="col" class="">{{ object_list.0|verbose_name:'power_mic'|title }}</th>
<th scope="col">{{ object_list.0|verbose_name:'vehicles'|title }}</th>
<th scope="col">{{ object_list.0|verbose_name:'safe_parking'|title }}</th>
<th scope="col">{{ object_list.0|verbose_name:'safe_packing'|title }}</th>
<th scope="col">{{ object_list.0|verbose_name:'exits'|title }}</th>
<th scope="col">{{ object_list.0|verbose_name:'trip_hazard'|title }}</th>
<th scope="col">{{ object_list.0|verbose_name:'warning_signs'|title }}</th>
<th scope="col">{{ object_list.0|verbose_name:'ear_plugs'|title }}</th>
<th scope="col">{{ object_list.0|verbose_name:'hs_location'|title }}</th>
<th scope="col">{{ object_list.0|verbose_name:'extinguishers_location'|title }}</th>
<th scope="col">{{ object_list.0|verbose_name:'rcds'|title }}</th>
<th scope="col">{{ object_list.0|verbose_name:'supply_test'|title }}</th>
<th scope="col">{{ object_list.0|verbose_name:'earthing'|title }}</th>
<th scope="col">{{ object_list.0|verbose_name:'pat'|title }}</th>
{% endif %}
</tr>
</thead>
<tbody>
{% for object in object_list %}
<tr>
{# General #}
<th scope="row" class="{% if object.reviewed_by %}bg-success{%endif%}"><a href="{% url 'event_detail' object.event.pk %}">N{{ object.event.pk|stringformat:"05d" }} {{ object.event.name }}</a></th>
<td>{{object.power_mic.name}}</td>
{# Buttons #}
<td>
<a class="btn btn-primary" href="{% url 'ra_detail' object.pk %}">View</a>
{{ object.review_string|safe }}
</td>
</tr>
{% empty %}
<tr class="bg-warning text-dark">
<td colspan="6">No checklists found</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
</div>
{% if is_paginated %}
<div class="row justify-content-center">
{% paginator %}
</div>
{% endif %}
{% endblock %}

View File

@@ -25,8 +25,8 @@
<br><span><strong>{{ event.end_date|date:"D d/m/Y" }}</strong></span>
{% endif %}
</td>
<td>{% include 'partials/hs_status.html' with event=event object=event.riskassessment view='ra_detail' edit='ra_edit' create='event_ra' %}</td>
<td>{% include 'partials/hs_status.html' with event=event object=event.eventchecklist view='ec_detail' edit='ec_edit' create='event_ec' %}</td>
<td>{% include 'partials/hs_status.html' with event=event object=event.riskassessment view='ra_detail' edit='ra_edit' create='event_ra' review='ra_review' perm=perms.RIGS.review_riskassessment %}</td>
<td>{% include 'partials/hs_status.html' with event=event object=event.eventchecklist view='ec_detail' edit='ec_edit' create='event_ec' review='ec_review' perm=perms.RIGS.review_eventchecklist %}</td>
</tr>
{% empty %}
<tr class="bg-warning text-dark">

View File

@@ -0,0 +1,57 @@
{% extends 'base_rigs.html' %}
{% load paginator from filters %}
{% load help_text from filters %}
{% load verbose_name from filters %}
{% load get_field from filters %}
{% block title %}{{ title }} List{% endblock %}
{% block content %}
<div class="row">
<div class="col-12">
<h2>{{title}} List</h2>
</div>
</div>
<div class="row">
<div class="col-12">
<div class="table-responsive">
<table class="table mb-0">
<thead>
<tr>
<th scope="col">Event</th>
{# mmm hax #}
{% for field in fields %}
<th scope="col">{{ object_list.0|verbose_name:field|title }}</th>
{% endfor %}
<th scope="col"></th>
</tr>
</thead>
<tbody>
{% for object in object_list %}
<tr class="{% if object.reviewed_by %}table-success{%endif%}">
{# General #}
<th scope="row"><a href="{% url 'event_detail' object.event.pk %}">{{ object.event }}</a></th>
{% for field in fields %}
<td>{{ object|get_field:field }}</td>
{% endfor %}
{# Buttons #}
<td>
{% include 'partials/hs_status.html' %}
</td>
</tr>
{% empty %}
<tr class="bg-warning">
<td colspan="6">Nothing found</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
</div>
{% if is_paginated %}
<div class="row justify-content-center">
{% paginator %}
</div>
{% endif %}
{% endblock %}

View File

@@ -1,12 +1,14 @@
{% load to_class_name from filters %}
{% if object.pk != None %}
{#<span class="badge badge-success my-3"><span class="fas fa-check"></span> Completed</span><br/>#}
<div class="btn-group">
<a href="{% url view object.pk %}" class="btn btn-primary"><span class="fas fa-eye"></span> <span class="hidden-xs"> View</span>
<a href="{% url edit object.pk %}" class="btn btn-warning"><span class="fas fa-edit"></span><span class="hidden-xs"> Edit</span></a>
</div>
{{ object.review_string|safe }}
{% else %}
<div class="btn-group">
<a href="{% url view object.pk %}" class="btn btn-primary"><span class="fas fa-eye"></span> <span class="hidden-xs"> View</span>
<a href="{% url edit object.pk %}" class="btn btn-warning"><span class="fas fa-edit"></span><span class="hidden-xs"> Edit</span></a>
</div>
{% if object.reviewed_by %}
<span class='badge badge-success py-2'>Reviewed by <a href='{% url 'profile_detail' object.reviewed_by.pk %}'>{{object.reviewed_by}}</a> at {{object.reviewed_at}}</span>
{% elif perm %}
<a class='btn btn-success my-2' href='{% url review object.pk %}'>Mark Reviewed</a>
{% endif %}
{% elif event != None %}
<a href="{% url create event.pk %}" class="btn btn-info"><span class="fas fa-paperclip"></span> <span
class="hidden-xs">Create</span></a>
{% endif %}

View File

@@ -1,105 +0,0 @@
{% extends 'base_rigs.html' %}
{% load paginator from filters %}
{% load help_text from filters %}
{% load verbose_name from filters %}
{% block title %}Risk Assessment List{% endblock %}
{% block content %}
<div class="row">
<div class="col-12">
<h2>Risk Assessment List</h2>
</div>
</div>
<div class="row">
<div class="col-12">
<div class="table-responsive">
<table class="table mb-0">
<thead>
<tr>
<th scope="col">Event</th>
{# mmm hax #}
{% if object_list.0 %}
<th scope="col" class="">{{ object_list.0|verbose_name:'nonstandard_equipment'|title }}</th>
<th scope="col">{{ object_list.0|verbose_name:'nonstandard_use'|title }}</th>
<th scope="col">{{ object_list.0|verbose_name:'contractors'|title }}</th>
<th scope="col">{{ object_list.0|verbose_name:'other_companies'|title }}</th>
<th scope="col">{{ object_list.0|verbose_name:'crew_fatigue'|title }}</th>
<th scope="col">{{ object_list.0|verbose_name:'general_notes'|title }}</th>
<th scope="col">{{ object_list.0|verbose_name:'big_power'|title }}</th>
<th scope="col">{{ object_list.0|verbose_name:'power_mic'|title }}</th>
<th scope="col">{{ object_list.0|verbose_name:'generators'|title }}</th>
<th scope="col">{{ object_list.0|verbose_name:'other_companies_power'|title }}</th>
<th scope="col">{{ object_list.0|verbose_name:'nonstandard_equipment_power'|title }}</th>
<th scope="col">{{ object_list.0|verbose_name:'multiple_electrical_environments'|title }}</th>
<th scope="col">{{ object_list.0|verbose_name:'power_notes'|title }}</th>
<th scope="col">{{ object_list.0|verbose_name:'noise_monitoring'|title }}</th>
<th scope="col">{{ object_list.0|verbose_name:'sound_notes'|title }}</th>
<th scope="col">{{ object_list.0|verbose_name:'known_venue'|title }}</th>
<th scope="col">{{ object_list.0|verbose_name:'safe_loading'|title }}</th>
<th scope="col">{{ object_list.0|verbose_name:'safe_storage'|title }}</th>
<th scope="col">{{ object_list.0|verbose_name:'area_outside_of_control'|title }}</th>
<th scope="col">{{ object_list.0|verbose_name:'nonstandard_emergency_procedure'|title }}</th>
<th scope="col">{{ object_list.0|verbose_name:'barrier_required'|title }}</th>
<th scope="col">{{ object_list.0|verbose_name:'special_structures'|title }}</th>
<th scope="col">{{ object_list.0|verbose_name:'persons_responsible_structures'|title }}</th>
<th scope="col">{{ object_list.0|verbose_name:'suspended_structures'|title }}</th>
<th scope="col"></th>
{% endif %}
</tr>
</thead>
<tbody>
{% for object in object_list %}
<tr>
{# General #}
<th scope="row" class="{% if object.reviewed_by %}bg-success{%endif%}"><a href="{% url 'event_detail' object.event.pk %}">N{{ object.event.pk|stringformat:"05d" }} {{ object.event.name }}</a></th>
<td class="{% if object.nonstandard_equipment%}bg-danger text-white{%endif%}">{{object.nonstandard_equipment|yesno|title}}</td>
<td class="{% if object.nonstandard_use%}bg-danger text-white{%endif%}">{{object.nonstandard_use|yesno|title}}</td>
<td class="{% if object.contractors%}bg-danger text-white{%endif%}">{{object.contractors|yesno|title}}</td>
<td class="{% if object.other_companies%}bg-danger text-white{%endif%}">{{object.other_companies|yesno|title}}</td>
<td class="{% if object.crew_fatigue%}bg-danger text-white{%endif%}">{{object.crew_fatigue|yesno|title}}</td>
<td><span class="text-truncate d-inline-block">{{ object.general_notes|default:'N/A'|linebreaks }}</span></td>
{# Power #}
<td class="{% if object.big_power%}bg-danger text-white{%endif%}">{{object.big_power|yesno|title}}</td>
<td>{{ object.power_mic.name|default:'N/A' }}</td>
<td class="{% if object.generators%}bg-danger text-white{%endif%}">{{object.generators|yesno|title}}</td>
<td class="{% if object.other_companies_power%}bg-danger text-white{%endif%}">{{object.other_companies_power|yesno|title}}</td>
<td class="{% if object.nonstandard_equipment_power%}bg-danger text-white{%endif%}">{{object.nonstandard_equipment_power|yesno|title}}</td>
<td class="{% if object.multiple_electrical_environments%}bg-danger text-white{%endif%}">{{object.multiple_electrical_environments|yesno|title}}</td>
<td><span class="text-truncate d-inline-block">{{ object.power_notes|default:'N/A'|linebreaks }}</span></td>
{# Sound #}
<td class="{% if object.noise_monitoring%}bg-danger text-white{%endif%}">{{object.noise_monitoring|yesno|title}}</td>
<td><span class="text-truncate d-inline-block">{{ object.sound_notes|default:'N/A'|linebreaks }}</span></td>
{# Venue #}
<td class="{% if not object.known_venue%}bg-danger text-white{%endif%}">{{object.known_venue|yesno|title}}</td>
<td class="{% if not object.safe_loading%}bg-danger text-white{%endif%}">{{object.safe_loading|yesno|title}}</td>
<td class="{% if object.safe_storage%}bg-danger text-white{%endif%}">{{object.safe_storage|yesno|title}}</td>
<td class="{% if object.area_outside_of_control%}bg-danger text-white{%endif%}">{{object.area_outside_of_control|yesno|title}}</td>
<td class="{% if object.nonstandard_emergency_procedure%}bg-danger text-white{%endif%}">{{object.nonstandard_emergency_procedure|yesno|title}}</td>
<td class="{% if object.barrier_required%}bg-danger text-white{%endif%}">{{object.barrier_required|yesno|title}}</td>
{# Rigging #}
<td class="{% if object.special_structures%}bg-danger text-white{%endif%}">{{object.special_structures|yesno|title}}</td>
<td>{{ object.persons_responsible_structures|default:'N/A'|linebreaks }}</td>
<td class="{% if object.suspended_structures%}bg-danger text-white{%endif%}">{{object.suspended_structures|yesno|title}}</td>
{# Buttons #}
<td>
<a class="btn btn-primary" href="{% url 'ra_detail' object.pk %}">View</a>
{{ object.review_string|safe }}
</td>
</tr>
{% empty %}
<tr class="bg-warning text-dark">
<td colspan="6">No risk assessments found</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
</div>
{% if is_paginated %}
<div class="row justify-content-center">
{% paginator %}
</div>
{% endif %}
{% endblock %}

View File

@@ -8,7 +8,7 @@ from django.utils.safestring import SafeData, mark_safe
from django.utils.html import escape
from RIGS import models
import json
from django.template.defaultfilters import yesno, title
from django.template.defaultfilters import yesno, title, truncatewords
from django.urls import reverse_lazy
register = template.Library()
@@ -119,6 +119,15 @@ def orderby(request, field, attr):
# Used for accessing outside of a form, i.e. in detail views of RiskAssessment and EventChecklist
@register.filter(needs_autoescape=True)
def get_field(obj, field, autoescape=True):
value = getattr(obj, field)
if(type(value)==bool):
value = yesnoi(value, field in obj.inverted_fields)
elif(type(value)==str):
value = truncatewords(value, 20)
return mark_safe(value)
@register.filter
def help_text(obj, field):
if hasattr(obj, '_meta'):
@@ -127,8 +136,8 @@ def help_text(obj, field):
@register.filter
def verbose_name(obj, field):
return obj._meta.get_field(field).verbose_name
if hasattr(obj._meta.get_field(field), 'verbose_name'):
return obj._meta.get_field(field).verbose_name
@register.filter
def get_list(dictionary, key):
@@ -157,8 +166,7 @@ def next(alist, current_index):
@register.filter(needs_autoescape=True)
def yesnoi(boolean, invert=False, autoescape=True):
value = yesno(boolean)
value = title(value)
value = title(yesno(boolean))
if invert:
boolean = not boolean
if boolean: