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 81b13d6  Update check results when polling for tasks remaining
81b13d6 is described below

commit 81b13d68ad60c9fa7b6e83ef7cc3434200ad46ed
Author: Sean B. Palmer <[email protected]>
AuthorDate: Mon Dec 29 16:07:52 2025 +0000

    Update check results when polling for tasks remaining
---
 atr/get/checks.py                       | 75 +++++++++++++++++++++++++++++++++
 atr/static/js/src/ongoing-tasks-poll.js | 30 +++++++++++--
 atr/templates/check-selected.html       | 23 +++++-----
 3 files changed, 115 insertions(+), 13 deletions(-)

diff --git a/atr/get/checks.py b/atr/get/checks.py
index 35b5585..6363b25 100644
--- a/atr/get/checks.py
+++ b/atr/get/checks.py
@@ -21,9 +21,12 @@ from typing import NamedTuple
 
 import asfquart.base as base
 import htpy
+import quart
 
 import atr.blueprints.get as get
 import atr.db as db
+import atr.db.interaction as interaction
+import atr.form as form
 import atr.get.download as download
 import atr.get.ignores as ignores
 import atr.get.report as report
@@ -31,7 +34,9 @@ import atr.get.sbom as sbom
 import atr.get.vote as vote
 import atr.htm as htm
 import atr.models.sql as sql
+import atr.post as post
 import atr.shared as shared
+import atr.shared.draft as draft
 import atr.storage as storage
 import atr.template as template
 import atr.util as util
@@ -130,6 +135,76 @@ async def selected(session: web.Committer | None, 
project_name: str, version_nam
     )
 
 
[email protected]("/checks/<project_name>/<version_name>/<revision_number>")
+async def selected_revision(
+    session: web.Committer,
+    project_name: str,
+    version_name: str,
+    revision_number: str,
+) -> web.QuartResponse:
+    """Return JSON with ongoing count and HTML fragments for dynamic 
updates."""
+    async with db.session() as data:
+        release = await data.release(
+            project_name=project_name,
+            version=version_name,
+            _committee=True,
+            _project=True,
+        ).demand(base.ASFQuartException("Release does not exist", 
errorcode=404))
+
+    base_path = util.release_directory(release)
+    paths = [path async for path in util.paths_recursive(base_path)]
+    paths.sort()
+
+    async with storage.read(session) as read:
+        ragp = read.as_general_public()
+        info = await ragp.releases.path_info(release, paths)
+
+    ongoing_count = await interaction.tasks_ongoing(project_name, 
version_name, revision_number)
+
+    checks_summary_elem = shared._render_checks_summary(info, project_name, 
version_name)
+    checks_summary_html = str(checks_summary_elem) if checks_summary_elem else 
""
+
+    delete_file_forms: dict[str, str] = {}
+    if release.phase == sql.ReleasePhase.RELEASE_CANDIDATE_DRAFT:
+        for path in paths:
+            delete_file_forms[str(path)] = str(
+                form.render(
+                    model_cls=draft.DeleteFileForm,
+                    action=util.as_url(post.draft.delete_file, 
project_name=project_name, version_name=version_name),
+                    form_classes=".d-inline-block.m-0",
+                    submit_classes="btn-sm btn-outline-danger",
+                    submit_label="Delete",
+                    empty=True,
+                    defaults={"file_path": str(path)},
+                    confirm=(
+                        "Are you sure you want to delete this file? "
+                        "This will also delete any associated metadata files. "
+                        "This cannot be undone."
+                    ),
+                )
+            )
+
+    files_table_html = await quart.render_template(
+        "check-selected-path-table.html",
+        paths=paths,
+        info=info,
+        project_name=project_name,
+        version_name=version_name,
+        release=release,
+        phase=release.phase.value,
+        delete_file_forms=delete_file_forms,
+        csrf_input=str(form.csrf_input()),
+    )
+
+    return quart.jsonify(
+        {
+            "ongoing": ongoing_count,
+            "checks_summary_html": checks_summary_html,
+            "files_table_html": files_table_html,
+        }
+    )
+
+
 async def _compute_stats(  # noqa: C901
     release: sql.Release,
     paths: list[pathlib.Path],
diff --git a/atr/static/js/src/ongoing-tasks-poll.js 
b/atr/static/js/src/ongoing-tasks-poll.js
index ea86e65..f0b8f35 100644
--- a/atr/static/js/src/ongoing-tasks-poll.js
+++ b/atr/static/js/src/ongoing-tasks-poll.js
@@ -18,11 +18,13 @@
  */
 
 (() => {
+       function handleCollapseToggle() {
+               this.textContent = this.textContent.trim() === "More" ? "Less" 
: "More";
+       }
+
        // Handle More and Less toggle buttons for collapse sections
        document.querySelectorAll(".page-collapse-toggle").forEach((button) => {
-               button.addEventListener("click", function () {
-                       this.textContent = this.textContent.trim() === "More" ? 
"Less" : "More";
-               });
+               button.addEventListener("click", handleCollapseToggle);
        });
 
        const banner = document.getElementById("ongoing-tasks-banner");
@@ -35,6 +37,10 @@
        const textSpan = document.getElementById("ongoing-tasks-text");
        const voteButton = document.getElementById("start-vote-button");
        const progress = document.getElementById("poll-progress");
+       const checksSummaryContainer = document.getElementById(
+               "checks-summary-container",
+       );
+       const filesTableContainer = 
document.getElementById("files-table-container");
        const pollInterval = 3000;
 
        let currentCount = parseInt(countSpan?.textContent || "0", 10);
@@ -110,6 +116,23 @@
                voteButton.setAttribute("title", "Start a vote on this draft");
        }
 
+       function updatePageContent(data) {
+               if (checksSummaryContainer && data.checks_summary_html !== 
undefined) {
+                       checksSummaryContainer.innerHTML = 
data.checks_summary_html;
+               }
+               if (filesTableContainer && data.files_table_html !== undefined) 
{
+                       filesTableContainer.innerHTML = data.files_table_html;
+                       reattachCollapseToggleListeners();
+               }
+       }
+
+       function reattachCollapseToggleListeners() {
+               
document.querySelectorAll(".page-collapse-toggle").forEach((button) => {
+                       button.removeEventListener("click", 
handleCollapseToggle);
+                       button.addEventListener("click", handleCollapseToggle);
+               });
+       }
+
        function pollOngoingTasks() {
                if (currentCount === 0) return;
 
@@ -125,6 +148,7 @@
                                if (newCount !== currentCount) {
                                        updateBanner(newCount);
                                }
+                               updatePageContent(data);
                                if (newCount > 0) {
                                        restartProgress();
                                        setTimeout(pollOngoingTasks, 
pollInterval);
diff --git a/atr/templates/check-selected.html 
b/atr/templates/check-selected.html
index a435da7..c8164f6 100644
--- a/atr/templates/check-selected.html
+++ b/atr/templates/check-selected.html
@@ -89,7 +89,7 @@
   <div id="ongoing-tasks-banner"
        class="alert alert-warning{% if ongoing_tasks_count == 0 %} d-none{% 
endif %}"
        role="alert"
-       {% if revision_number %}data-api-url="/api/checks/ongoing/{{ 
release.project.name }}/{{ release.version }}/{{ revision_number }}"{% endif %}>
+       {% if revision_number %}data-api-url="/checks/{{ release.project.name 
}}/{{ release.version }}/{{ revision_number }}"{% endif %}>
     <i class="bi bi-exclamation-triangle me-2"></i>
     <span id="ongoing-tasks-text">There {{ 'is' if ongoing_tasks_count == 1 
else 'are' }} currently <strong id="ongoing-tasks-count">{{ ongoing_tasks_count 
}}</strong> background verification {{ 'task' if ongoing_tasks_count == 1 else 
'tasks' }} running for the latest revision. Results shown below may be 
incomplete or outdated until the tasks finish.</span>
     <div id="poll-progress-container" class="progress mt-2">
@@ -97,9 +97,11 @@
     </div>
   </div>
 
-  {% if checks_summary_html %}
-    {{ checks_summary_html|safe }}
-  {% endif %}
+  <div id="checks-summary-container">
+    {% if checks_summary_html %}
+      {{ checks_summary_html|safe }}
+    {% endif %}
+  </div>
 
   <div class="card mb-4">
     <div class="card-header d-flex justify-content-between align-items-center">
@@ -113,12 +115,13 @@
       </h5>
     </div>
     <div class="card-body">
-      {% if paths|length > 0 %}
-        {% include "check-selected-path-table.html" %}
-
-      {% else %}
-        <div class="alert alert-info">This draft does not have any files 
yet.</div>
-      {% endif %}
+      <div id="files-table-container">
+        {% if paths|length > 0 %}
+          {% include "check-selected-path-table.html" %}
+        {% else %}
+          <div class="alert alert-info">This draft does not have any files 
yet.</div>
+        {% endif %}
+      </div>
     </div>
   </div>
   {% if phase == "release_candidate_draft" %}


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

Reply via email to