This is an automated email from the ASF dual-hosted git repository.

sbp pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/tooling-trusted-releases.git


The following commit(s) were added to refs/heads/main by this push:
     new b94f86e  Move background task polling and committee filtering to 
separate files
b94f86e is described below

commit b94f86e399058daee79a5def20157ccb6ac24cf6
Author: Sean B. Palmer <[email protected]>
AuthorDate: Wed Dec 10 14:54:14 2025 +0000

    Move background task polling and committee filtering to separate files
---
 atr/static/js/committee-directory.js   | 139 ++++++++++++++++++++++++++++++++
 atr/static/js/ongoing-tasks-poll.js    |  99 +++++++++++++++++++++++
 atr/templates/check-selected.html      | 102 +----------------------
 atr/templates/committee-directory.html | 143 +--------------------------------
 4 files changed, 240 insertions(+), 243 deletions(-)

diff --git a/atr/static/js/committee-directory.js 
b/atr/static/js/committee-directory.js
new file mode 100644
index 0000000..9818a10
--- /dev/null
+++ b/atr/static/js/committee-directory.js
@@ -0,0 +1,139 @@
+let allCommitteeCards = [];
+
+function filterCommitteesByText() {
+    const projectFilter = document.getElementById("project-filter").value;
+    const cards = allCommitteeCards;
+    let visibleCount = 0;
+
+    if (participantButton && participantButton.dataset.showing === 
"participant") {
+        participantButton.dataset.showing = "all";
+        participantButton.textContent = "Show my committees";
+        participantButton.setAttribute("aria-pressed", "false");
+    }
+
+    for (let card of cards) {
+        const nameElement = card.querySelector(".card-title");
+        const name = nameElement.textContent.trim();
+        if (!projectFilter) {
+            card.parentElement.hidden = false;
+            visibleCount++;
+        } else {
+            let regex;
+            try {
+                regex = new RegExp(projectFilter, "i");
+            } catch (e) {
+                const escapedFilter = 
projectFilter.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
+                regex = new RegExp(escapedFilter, "i");
+            }
+            card.parentElement.hidden = !name.match(regex);
+            if (!card.parentElement.hidden) {
+                visibleCount++;
+            }
+        }
+    }
+    document.getElementById("committee-count").textContent = visibleCount;
+}
+
+document.getElementById("filter-button").addEventListener("click", 
filterCommitteesByText);
+document.getElementById("project-filter").addEventListener("keydown", 
function(event) {
+    if (event.key === "Enter") {
+        filterCommitteesByText();
+        event.preventDefault();
+    }
+});
+
+const participantButton = document.getElementById("filter-participant-button");
+if (participantButton) {
+    participantButton.addEventListener("click", function() {
+        const showing = this.dataset.showing;
+        const cards = allCommitteeCards;
+        let visibleCount = 0;
+
+        if (showing === "all") {
+            cards.forEach(card => {
+                const isParticipant = card.dataset.isParticipant === "true";
+                card.parentElement.hidden = !isParticipant;
+                if (!card.parentElement.hidden) {
+                    visibleCount++;
+                }
+            });
+            this.textContent = "Show all committees";
+            this.dataset.showing = "participant";
+            this.setAttribute("aria-pressed", "true");
+        } else {
+            cards.forEach(card => {
+                card.parentElement.hidden = false;
+                visibleCount++;
+            });
+            this.textContent = "Show my committees";
+            this.dataset.showing = "all";
+            this.setAttribute("aria-pressed", "false");
+        }
+        document.getElementById("project-filter").value = "";
+        document.getElementById("committee-count").textContent = visibleCount;
+    });
+}
+
+document.addEventListener("DOMContentLoaded", function() {
+    allCommitteeCards = 
Array.from(document.querySelectorAll(".page-project-card"));
+    const cards = allCommitteeCards;
+    const committeeCountSpan = document.getElementById("committee-count");
+    let initialVisibleCount = 0;
+    const initialShowingMode = participantButton ? 
participantButton.dataset.showing : "all";
+
+    if (participantButton) {
+        if (initialShowingMode === "participant") {
+            participantButton.setAttribute("aria-pressed", "true");
+        } else {
+            participantButton.setAttribute("aria-pressed", "false");
+        }
+    }
+
+    if (initialShowingMode === "participant") {
+        cards.forEach(card => {
+            const isParticipant = card.dataset.isParticipant === "true";
+            card.parentElement.hidden = !isParticipant;
+            if (!card.parentElement.hidden) {
+                initialVisibleCount++;
+            }
+        });
+    } else {
+        cards.forEach(card => {
+            card.parentElement.hidden = false;
+            initialVisibleCount++;
+        });
+    }
+    committeeCountSpan.textContent = initialVisibleCount;
+
+    // Add a click listener to project subcards to handle navigation
+    // TODO: Improve accessibility
+    
document.querySelectorAll(".page-project-subcard").forEach(function(subcard) {
+        subcard.addEventListener("click", function(event) {
+            if (this.dataset.projectUrl) {
+                window.location.href = this.dataset.projectUrl;
+            }
+        });
+    });
+
+    // Add a click listener for toggling project visibility within each 
committee
+    
document.querySelectorAll(".page-toggle-committee-projects").forEach(function(button)
 {
+        button.addEventListener("click", function() {
+            const projectListContainer = 
this.closest(".page-project-list-container");
+            if (projectListContainer) {
+                const extraProjects = 
projectListContainer.querySelectorAll(".page-project-extra");
+                extraProjects.forEach(function(proj) {
+                    proj.classList.toggle("d-none");
+                });
+
+                const isExpanded = this.getAttribute("aria-expanded") === 
"true";
+                if (isExpanded) {
+                    this.textContent = this.dataset.textShow;
+                    this.setAttribute("aria-expanded", "false");
+                } else {
+                    this.textContent = this.dataset.textHide;
+                    this.setAttribute("aria-expanded", "true");
+                }
+            }
+        });
+    });
+});
diff --git a/atr/static/js/ongoing-tasks-poll.js 
b/atr/static/js/ongoing-tasks-poll.js
new file mode 100644
index 0000000..348305f
--- /dev/null
+++ b/atr/static/js/ongoing-tasks-poll.js
@@ -0,0 +1,99 @@
+(function() {
+    const banner = document.getElementById("ongoing-tasks-banner");
+    if (!banner) return;
+
+    const apiUrl = banner.dataset.apiUrl;
+    if (!apiUrl) return;
+
+    const countSpan = document.getElementById("ongoing-tasks-count");
+    const textSpan = document.getElementById("ongoing-tasks-text");
+    const voteButton = document.getElementById("start-vote-button");
+    const progress = document.getElementById("poll-progress");
+    const pollInterval = 3000;
+
+    let currentCount = parseInt(countSpan?.textContent || "0", 10);
+    if (currentCount === 0) return;
+
+    function restartProgress() {
+        if (!progress) return;
+        progress.style.animation = "none";
+        progress.offsetHeight;
+        progress.style.animation = `poll-grow ${pollInterval}ms linear 
forwards`;
+    }
+
+    function updateBanner(count) {
+        if (!countSpan || !textSpan) return;
+
+        currentCount = count;
+        countSpan.textContent = count;
+
+        const taskWord = count === 1 ? "task" : "tasks";
+        const isAre = count === 1 ? "is" : "are";
+        // TODO: Migrate away from setting innerHTML
+        textSpan.innerHTML = `There ${isAre} currently <strong 
id="ongoing-tasks-count">${count}</strong> background verification ${taskWord} 
running for the latest revision. Results shown below may be incomplete or 
outdated until the tasks finish.`;
+
+        if (count === 0) {
+            // Banner always exists, but we hide it
+            banner.classList.add("d-none");
+            enableVoteButton();
+        }
+    }
+
+    function enableVoteButton() {
+        if (!voteButton) return;
+        if (!voteButton.classList.contains("disabled")) return;
+
+        const voteHref = voteButton.dataset.voteHref || 
voteButton.getAttribute("href");
+        if (!voteHref || voteHref === "#") return;
+
+        voteButton.classList.remove("disabled");
+        voteButton.removeAttribute("aria-disabled");
+        voteButton.removeAttribute("tabindex");
+        voteButton.removeAttribute("role");
+        voteButton.setAttribute("href", voteHref);
+        voteButton.setAttribute("title", "Start a vote on this draft");
+    }
+
+    function pollOngoingTasks() {
+        if (currentCount === 0) return;
+
+        if (progress) {
+            progress.style.animation = "none";
+            progress.style.width = "100%";
+            progress.classList.remove("bg-warning");
+            progress.classList.add("bg-info", "progress-bar-striped", 
"progress-bar-animated");
+        }
+        fetch(apiUrl)
+            .then(response => {
+                if (!response.ok) throw new Error(`HTTP ${response.status}`);
+                return response.json();
+            })
+            .then(data => {
+                if (progress) {
+                    progress.classList.remove("bg-info", 
"progress-bar-striped", "progress-bar-animated");
+                    progress.classList.add("bg-warning");
+                }
+                const newCount = data.ongoing || 0;
+                if (newCount !== currentCount) {
+                    updateBanner(newCount);
+                }
+                if (newCount > 0) {
+                    restartProgress();
+                    setTimeout(pollOngoingTasks, pollInterval);
+                }
+            })
+            .catch(error => {
+                console.error("Error polling ongoing tasks:", error);
+                if (progress) {
+                    progress.classList.remove("bg-info", 
"progress-bar-striped", "progress-bar-animated");
+                    progress.classList.add("bg-warning");
+                }
+                restartProgress();
+                // Double the interval when there's an error
+                setTimeout(pollOngoingTasks, pollInterval * 2);
+            });
+    }
+
+    restartProgress();
+    setTimeout(pollOngoingTasks, pollInterval);
+})();
diff --git a/atr/templates/check-selected.html 
b/atr/templates/check-selected.html
index 9f86cdd..aefc386 100644
--- a/atr/templates/check-selected.html
+++ b/atr/templates/check-selected.html
@@ -195,105 +195,5 @@
 
 {% block javascripts %}
   {{ super() }}
-  <script>
-    (function() {
-      const banner = document.getElementById("ongoing-tasks-banner");
-      if (!banner) return;
-
-      const apiUrl = banner.dataset.apiUrl;
-      if (!apiUrl) return;
-
-      const countSpan = document.getElementById("ongoing-tasks-count");
-      const textSpan = document.getElementById("ongoing-tasks-text");
-      const voteButton = document.getElementById("start-vote-button");
-      const progress = document.getElementById("poll-progress");
-      const pollInterval = 3000;
-
-      let currentCount = parseInt(countSpan?.textContent || "0", 10);
-      if (currentCount === 0) return;
-
-      function restartProgress() {
-        if (!progress) return;
-        progress.style.animation = "none";
-        progress.offsetHeight;
-        progress.style.animation = `poll-grow ${pollInterval}ms linear 
forwards`;
-      }
-
-      function updateBanner(count) {
-        if (!countSpan || !textSpan) return;
-
-        currentCount = count;
-        countSpan.textContent = count;
-
-        const taskWord = count === 1 ? "task" : "tasks";
-        const isAre = count === 1 ? "is" : "are";
-              // TODO: Migrate away from setting innerHTML
-        textSpan.innerHTML = `There ${isAre} currently <strong 
id="ongoing-tasks-count">${count}</strong> background verification ${taskWord} 
running for the latest revision. Results shown below may be incomplete or 
outdated until the tasks finish.`;
-
-        if (count === 0) {
-                  // Banner always exists, but we hide it
-          banner.classList.add("d-none");
-          enableVoteButton();
-        }
-      }
-
-      function enableVoteButton() {
-        if (!voteButton) return;
-        if (!voteButton.classList.contains("disabled")) return;
-
-        const voteHref = voteButton.dataset.voteHref || 
voteButton.getAttribute("href");
-        if (!voteHref || voteHref === "#") return;
-
-        voteButton.classList.remove("disabled");
-        voteButton.removeAttribute("aria-disabled");
-        voteButton.removeAttribute("tabindex");
-        voteButton.removeAttribute("role");
-        voteButton.setAttribute("href", voteHref);
-        voteButton.setAttribute("title", "Start a vote on this draft");
-      }
-
-      function pollOngoingTasks() {
-        if (currentCount === 0) return;
-
-        if (progress) {
-          progress.style.animation = "none";
-          progress.style.width = "100%";
-          progress.classList.remove("bg-warning");
-          progress.classList.add("bg-info", "progress-bar-striped", 
"progress-bar-animated");
-        }
-        fetch(apiUrl)
-          .then(response => {
-            if (!response.ok) throw new Error(`HTTP ${response.status}`);
-            return response.json();
-          })
-          .then(data => {
-            if (progress) {
-              progress.classList.remove("bg-info", "progress-bar-striped", 
"progress-bar-animated");
-              progress.classList.add("bg-warning");
-            }
-            const newCount = data.ongoing || 0;
-            if (newCount !== currentCount) {
-              updateBanner(newCount);
-            }
-            if (newCount > 0) {
-              restartProgress();
-              setTimeout(pollOngoingTasks, pollInterval);
-            }
-          })
-          .catch(error => {
-            console.error("Error polling ongoing tasks:", error);
-            if (progress) {
-              progress.classList.remove("bg-info", "progress-bar-striped", 
"progress-bar-animated");
-              progress.classList.add("bg-warning");
-            }
-            restartProgress();
-                      // Double the interval when there's an error
-            setTimeout(pollOngoingTasks, pollInterval * 2);
-          });
-      }
-
-      restartProgress();
-      setTimeout(pollOngoingTasks, pollInterval);
-    })();
-  </script>
+  <script src="{{ static_url('js/ongoing-tasks-poll.js') }}"></script>
 {% endblock javascripts %}
diff --git a/atr/templates/committee-directory.html 
b/atr/templates/committee-directory.html
index 23c9e58..6d92852 100644
--- a/atr/templates/committee-directory.html
+++ b/atr/templates/committee-directory.html
@@ -178,146 +178,5 @@
 
 {% block javascripts %}
     {{ super() }}
-    <script>
-        let allCommitteeCards = [];
-
-        function filterCommitteesByText() {
-            const projectFilter = 
document.getElementById("project-filter").value;
-            const cards = allCommitteeCards;
-            let visibleCount = 0;
-
-            if (participantButton && participantButton.dataset.showing === 
"participant") {
-                participantButton.dataset.showing = "all";
-                participantButton.textContent = "Show my committees";
-                participantButton.setAttribute("aria-pressed", "false");
-            }
-
-            for (let card of cards) {
-                const nameElement = card.querySelector(".card-title");
-                const name = nameElement.textContent.trim();
-                if (!projectFilter) {
-                    card.parentElement.hidden = false;
-                    visibleCount++;
-                } else {
-                    let regex;
-                    try {
-                        regex = new RegExp(projectFilter, "i");
-                    } catch (e) {
-                        const escapedFilter = 
projectFilter.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
-                        regex = new RegExp(escapedFilter, "i");
-                    }
-                    card.parentElement.hidden = !name.match(regex);
-                    if (!card.parentElement.hidden) {
-                        visibleCount++;
-                    }
-                }
-            }
-            document.getElementById("committee-count").textContent = 
visibleCount;
-        }
-
-      // Add event listeners
-        document.getElementById("filter-button").addEventListener("click", 
filterCommitteesByText);
-        document.getElementById("project-filter").addEventListener("keydown", 
function(event) {
-            if (event.key === "Enter") {
-                filterCommitteesByText();
-                event.preventDefault();
-            }
-        });
-
-        const participantButton = 
document.getElementById("filter-participant-button");
-        if (participantButton) {
-            participantButton.addEventListener("click", function() {
-                const showing = this.dataset.showing;
-                const cards = allCommitteeCards;
-                let visibleCount = 0;
-
-                if (showing === "all") {
-                    cards.forEach(card => {
-                        const isParticipant = card.dataset.isParticipant === 
"true";
-                        card.parentElement.hidden = !isParticipant;
-                        if (!card.parentElement.hidden) {
-                            visibleCount++;
-                        }
-                    });
-                    this.textContent = "Show all committees";
-                    this.dataset.showing = "participant";
-                    this.setAttribute("aria-pressed", "true");
-                } else {
-                    cards.forEach(card => {
-                        card.parentElement.hidden = false;
-                        visibleCount++;
-                    });
-                    this.textContent = "Show my committees";
-                    this.dataset.showing = "all";
-                    this.setAttribute("aria-pressed", "false");
-                }
-                document.getElementById("project-filter").value = "";
-                document.getElementById("committee-count").textContent = 
visibleCount;
-            });
-        }
-
-        document.addEventListener("DOMContentLoaded", function() {
-            allCommitteeCards = 
Array.from(document.querySelectorAll(".page-project-card"));
-            const cards = allCommitteeCards;
-            const committeeCountSpan = 
document.getElementById("committee-count");
-            let initialVisibleCount = 0;
-            const initialShowingMode = participantButton ? 
participantButton.dataset.showing : "all";
-
-            if (participantButton) {
-                if (initialShowingMode === "participant") {
-                    participantButton.setAttribute("aria-pressed", "true");
-                } else {
-                    participantButton.setAttribute("aria-pressed", "false");
-                }
-            }
-
-            if (initialShowingMode === "participant") {
-                cards.forEach(card => {
-                    const isParticipant = card.dataset.isParticipant === 
"true";
-                    card.parentElement.hidden = !isParticipant;
-                    if (!card.parentElement.hidden) {
-                        initialVisibleCount++;
-                    }
-                });
-            } else {
-                cards.forEach(card => {
-                    card.parentElement.hidden = false;
-                    initialVisibleCount++;
-                });
-            }
-            committeeCountSpan.textContent = initialVisibleCount;
-
-          // Add a click listener to project subcards to handle navigation
-          // TODO: Improve accessibility
-            
document.querySelectorAll(".page-project-subcard").forEach(function(subcard) {
-                subcard.addEventListener("click", function(event) {
-                    if (this.dataset.projectUrl) {
-                        window.location.href = this.dataset.projectUrl;
-                    }
-                });
-            });
-
-          // Add a click listener for toggling project visibility within each 
committee
-            
document.querySelectorAll(".page-toggle-committee-projects").forEach(function(button)
 {
-                button.addEventListener("click", function() {
-                    const projectListContainer = 
this.closest(".page-project-list-container");
-                    if (projectListContainer) {
-                        const extraProjects = 
projectListContainer.querySelectorAll(".page-project-extra");
-                        extraProjects.forEach(function(proj) {
-                            proj.classList.toggle("d-none");
-                        });
-
-                        const isExpanded = this.getAttribute("aria-expanded") 
=== "true";
-                        if (isExpanded) {
-                            this.textContent = this.dataset.textShow;
-                            this.setAttribute("aria-expanded", "false");
-                        } else {
-                            this.textContent = this.dataset.textHide;
-                            this.setAttribute("aria-expanded", "true");
-                        }
-                    }
-                });
-            });
-        });
-    </script>
+    <script src="{{ static_url('js/committee-directory.js') }}"></script>
 {% endblock javascripts %}


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to