atr/templates/committee-directory.html (90 lines of code) (raw):
{% extends "layouts/base.html" %}
{% block title %}
Committee directory ~ ATR
{% endblock title %}
{% block description %}
List of all ASF committees and their associated projects.
{% endblock description %}
{% block content %}
<h1>Committee directory</h1>
<p>Current ASF committees and their projects:</p>
<div class="mb-3">
<input type="text"
id="project-filter"
class="form-control d-inline-block w-auto" />
<button type="button" class="btn btn-primary" id="filter-button">Filter</button>
</div>
<div class="mb-3">
<p>Total count: {{ committees|length }}</p>
</div>
<div class="row row-cols-1 row-cols-md-2 row-cols-lg-3 g-4">
{% for committee in committees %}
<div class="col">
<div class="card h-100 shadow-sm atr-cursor-pointer page-project-card"
data-project-url="{{ as_url(routes.committees.view, name=committee.name) }}">
<div class="card-body">
<h3 class="card-title fs-4 mb-3">{{ committee.display_name }}</h3>
<div class="row g-3">
<div class="col-4">
<div class="card h-100 bg-light border-0">
<div class="card-body p-2 d-flex flex-column justify-content-between text-center">
<small class="text-secondary">PMC members</small>
<span class="fs-4 fw-medium mt-2">{{ committee.committee_members|length }}</span>
</div>
</div>
</div>
<div class="col-4">
<div class="card h-100 bg-light border-0">
<div class="card-body p-2 d-flex flex-column justify-content-between text-center">
<small class="text-secondary">Committers</small>
<span class="fs-4 fw-medium mt-2">{{ committee.committers|length }}</span>
</div>
</div>
</div>
<div class="col-4">
<div class="card h-100 bg-light border-0">
<div class="card-body p-2 d-flex flex-column justify-content-between text-center">
<small class="text-secondary">Projects</small>
<span class="fs-4 fw-medium mt-2">{{ committee.projects|length }}</span>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
{% endfor %}
</div>
{% endblock content %}
{% block javascripts %}
{{ super() }}
<script>
function filter() {
const projectFilter = document.getElementById("project-filter").value;
const cards = document.querySelectorAll(".page-project-card");
for (let card of cards) {
const nameElement = card.querySelector(".card-title");
const name = nameElement.innerHTML;
if (!projectFilter) {
card.parentElement.hidden = false;
} else {
card.parentElement.hidden = !name.match(new RegExp(projectFilter, 'i'));
}
}
}
// Add event listeners
document.getElementById("filter-button").addEventListener("click", filter);
document.getElementById("project-filter").addEventListener("keydown", function(event) {
if (event.key === "Enter") {
filter();
event.preventDefault();
}
});
// Add click handlers for project cards
document.querySelectorAll(".page-project-card").forEach(function(card) {
card.addEventListener("click", function() {
window.location.href = this.getAttribute("data-project-url");
});
});
</script>
{% endblock javascripts %}