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:
|
else:
|
||||||
return None
|
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):
|
class CertificationDefinition(models.Model):
|
||||||
certification_identifier = models.AutoField(
|
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(),
|
views.MemberCertificationListView.as_view(),
|
||||||
name="member_certifications",
|
name="member_certifications",
|
||||||
),
|
),
|
||||||
|
path(
|
||||||
|
"certifications/departments/",
|
||||||
|
views.department_certifications,
|
||||||
|
name="department_certifications",
|
||||||
|
),
|
||||||
path(
|
path(
|
||||||
"certifications/<str:cert_name>_Certification.pdf",
|
"certifications/<str:cert_name>_Certification.pdf",
|
||||||
views.certification_pdf,
|
views.certification_pdf,
|
||||||
|
@ -1,14 +1,15 @@
|
|||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from django.contrib import staticfiles
|
from django.contrib import staticfiles
|
||||||
|
from django.contrib.auth.decorators import login_required
|
||||||
from django.http import HttpResponse, HttpResponseBadRequest, HttpResponseNotFound
|
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
|
from django.views.generic import ListView
|
||||||
|
|
||||||
import requests
|
import requests
|
||||||
import weasyprint
|
import weasyprint
|
||||||
|
|
||||||
from membershipworks.models import Member
|
from membershipworks.models import Member
|
||||||
from .models import Certification
|
from .models import Certification, Department
|
||||||
|
|
||||||
WIKI_URL = settings.WIKI_URL
|
WIKI_URL = settings.WIKI_URL
|
||||||
|
|
||||||
@ -29,6 +30,36 @@ class MemberCertificationListView(ListView):
|
|||||||
return Certification.objects.filter(member=self.member)
|
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):
|
def certification_pdf(request, cert_name):
|
||||||
wiki_page = f"{cert_name.replace('_', ' ')} Certification"
|
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">
|
content="width=device-width, initial-scale=1, shrink-to-fit=no">
|
||||||
<!-- Bootstrap CSS -->
|
<!-- Bootstrap CSS -->
|
||||||
<link href="{% static 'bootstrap.min.css' %}" rel="stylesheet">
|
<link href="{% static 'bootstrap.min.css' %}" rel="stylesheet">
|
||||||
|
<!-- Tabulator CSS -->
|
||||||
|
<link href="{% static 'tabulator_bootstrap5.min.css' %}" rel="stylesheet">
|
||||||
<title>
|
<title>
|
||||||
{% block title %}Claremont MakerSpace{% endblock %}
|
{% block title %}Claremont MakerSpace{% endblock %}
|
||||||
</title>
|
</title>
|
||||||
@ -65,5 +67,8 @@
|
|||||||
{% block footer %}{% endblock %}
|
{% block footer %}{% endblock %}
|
||||||
<!-- Bootstrap JS -->
|
<!-- Bootstrap JS -->
|
||||||
<script src="{% static 'bootstrap.bundle.min.js' %}"></script>
|
<script src="{% static 'bootstrap.bundle.min.js' %}"></script>
|
||||||
|
<!-- Tabulator JS -->
|
||||||
|
<script src="{% static 'tabulator.min.js' %}"></script>
|
||||||
|
{% block script %}{% endblock %}
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
Loading…
Reference in New Issue
Block a user