paperwork: Add a view to show shop leads issued certifications in their shops
This commit is contained in:
parent
86000be17b
commit
4aaa1db3a8
@ -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(
|
||||
|
134
paperwork/templates/paperwork/department_certifications.dj.html
Normal file
134
paperwork/templates/paperwork/department_certifications.dj.html
Normal 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 %}
|
@ -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,
|
||||
|
@ -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
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
2
static/tabulator_bootstrap5.min.css
vendored
Normal file
File diff suppressed because one or more lines are too long
@ -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>
|
||||
|
Loading…
Reference in New Issue
Block a user