paperwork: Add a view to show shop leads issued certifications in their shops

This commit is contained in:
Adam Goldsmith 2023-02-02 15:08:48 -05:00
parent 86000be17b
commit 4aaa1db3a8
7 changed files with 189 additions and 2 deletions

View File

@ -77,6 +77,13 @@ class Department(models.Model):
else:
return None
@property
def list_address(self):
if self.has_mailing_list:
return self.list_name + "@claremontmakerspace.org"
else:
return None
class CertificationDefinition(models.Model):
certification_identifier = models.AutoField(

View File

@ -0,0 +1,134 @@
{% extends "base.dj.html" %}
{% block content %}
{% if departments %}
<h2>Departments for which you are a lead</h2>
<table class="table table-bordered table-striped table-hover" border="1">
<thead>
<tr>
<th>Department</th>
<th>Shop Leads</th>
<th>Mailing list</th>
</tr>
</thead>
<tbody>
{% for department in departments %}
<tr>
<td>{{ department.name }}</td>
<td>{{ department.shop_lead_flag.members.all|join:", " }}</td>
<td>{{ department.list_address }}</td>
</tr>
{% endfor %}
</tbody>
</table>
<div class="d-flex flex-wrap justify-content-between">
<h2>Certifications in those departments</h2>
<div class="form-check form-switch">
<label class="form-check-label" for="flexSwitchCheckDefault">
<input id="showOutdated"
class="form-check-input"
type="checkbox"
role="switch">
Show Outdated
</label>
</div>
</div>
<table class="certifications">
<thead>
<tr>
<th>Department</th>
<th>Certification</th>
<th>Member/Name</th>
<th>Version</th>
<th>Certified By</th>
<th>Date</th>
</tr>
</thead>
<tbody>
{% for certification in certifications %}
<tr>
<td>{{ certification.certification_version.definition.department.name }}</td>
<td>{{ certification.certification_version.definition.certification_name }}</td>
<td>{{ certification.member|default:certification.name }}</td>
<td>
{% if not certification.certification_version.is_current %}[OUTDATED]{% endif %}
{{ certification.certification_version.semantic_version }}
</td>
<td>{{ certification.certified_by }}</td>
<td>{{ certification.date.isoformat }}</td>
</tr>
{% endfor %}
</tbody>
{% else %}
<p>You are not a lead for any departments</p>
{% endif %}
</table>
{% endblock %}
{% block script %}
<script>
const certification_table_el = document.querySelector('table.certifications');
const certification_table = new Tabulator(certification_table_el, {
layout: "fitDataFill",
responsiveLayout: "collapse",
pagination: true,
paginationSize: 50,
columnDefaults: {
headerFilter: true
},
rowFormatter: function(row) {
const data = row.getData();
if (data.version.includes("[OUTDATED]")) {
row.getElement().classList.add("table-warning");
}
},
columns: [{
title: "Department",
headerFilter: "list",
headerFilterParams: {
valuesLookup: true,
autocomplete: true,
listOnEmpty: true,
clearable: true,
},
}, {
title: "Certification",
headerFilter: "list",
headerFilterParams: {
valuesLookup: true,
autocomplete: true,
listOnEmpty: true,
clearable: true,
},
}, {
title: "Member/Name"
}, {
title: "Version",
headerFilter: "list",
headerFilterParams: {
valuesLookup: true,
autocomplete: true,
listOnEmpty: true,
clearable: true,
},
}, ]
});
function outdatedFilter(data) {
return !data.version.includes("[OUTDATED]");
}
function setOutdatedFilter(showOutdated) {
if (showOutdated) {
certification_table.removeFilter(outdatedFilter);
} else {
certification_table.addFilter(outdatedFilter);
}
}
certification_table.on("tableBuilt", () => {
const outdatedToggle = document.getElementById("showOutdated");
setOutdatedFilter(outdatedFilter.checked);
outdatedToggle.addEventListener("change", (event) => setOutdatedFilter(event.target.checked));
});
</script>
{% endblock %}

View File

@ -10,6 +10,11 @@ urlpatterns = [
views.MemberCertificationListView.as_view(),
name="member_certifications",
),
path(
"certifications/departments/",
views.department_certifications,
name="department_certifications",
),
path(
"certifications/<str:cert_name>_Certification.pdf",
views.certification_pdf,

View File

@ -1,14 +1,15 @@
from django.conf import settings
from django.contrib import staticfiles
from django.contrib.auth.decorators import login_required
from django.http import HttpResponse, HttpResponseBadRequest, HttpResponseNotFound
from django.shortcuts import get_object_or_404
from django.shortcuts import get_object_or_404, render
from django.views.generic import ListView
import requests
import weasyprint
from membershipworks.models import Member
from .models import Certification
from .models import Certification, Department
WIKI_URL = settings.WIKI_URL
@ -29,6 +30,36 @@ class MemberCertificationListView(ListView):
return Certification.objects.filter(member=self.member)
@login_required
def department_certifications(request):
departments = Department.objects.prefetch_related("shop_lead_flag__members")
if request.user.is_superuser:
departments = departments.all()
elif hasattr(request.user, "ldap_user"):
user_member = Member.objects.get(
uid=request.user.ldap_user.attrs["employeeNumber"][0]
)
# TODO: could be a lot simpler if membershipworks was in the same database
# TODO: should also select children
member_flags = list(user_member.flags.all().values_list("pk", flat=True))
departments = departments.filter(shop_lead_flag__in=member_flags)
else:
departments = []
certifications = Certification.objects.filter(
certification_version__definition__department__in=departments
).prefetch_related(
"certification_version__definition__department",
"member",
)
return render(
request,
"paperwork/department_certifications.dj.html",
{"departments": departments, "certifications": certifications},
)
def certification_pdf(request, cert_name):
wiki_page = f"{cert_name.replace('_', ' ')} Certification"

3
static/tabulator.min.js vendored Normal file

File diff suppressed because one or more lines are too long

2
static/tabulator_bootstrap5.min.css vendored Normal file

File diff suppressed because one or more lines are too long

View File

@ -7,6 +7,8 @@
content="width=device-width, initial-scale=1, shrink-to-fit=no">
<!-- Bootstrap CSS -->
<link href="{% static 'bootstrap.min.css' %}" rel="stylesheet">
<!-- Tabulator CSS -->
<link href="{% static 'tabulator_bootstrap5.min.css' %}" rel="stylesheet">
<title>
{% block title %}Claremont MakerSpace{% endblock %}
</title>
@ -65,5 +67,8 @@
{% block footer %}{% endblock %}
<!-- Bootstrap JS -->
<script src="{% static 'bootstrap.bundle.min.js' %}"></script>
<!-- Tabulator JS -->
<script src="{% static 'tabulator.min.js' %}"></script>
{% block script %}{% endblock %}
</body>
</html>