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

yao pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/spark.git


The following commit(s) were added to refs/heads/master by this push:
     new 77f05a97a9be [SPARK-55776][UI] Fix data-title to data-bs-title for 
timeline tooltips after Bootstrap 5 upgrade
77f05a97a9be is described below

commit 77f05a97a9be1a24f8c09c8b2b56fd9cccd2426d
Author: Kent Yao <[email protected]>
AuthorDate: Mon Mar 2 22:36:16 2026 +0800

    [SPARK-55776][UI] Fix data-title to data-bs-title for timeline tooltips 
after Bootstrap 5 upgrade
    
    ### What changes were proposed in this pull request?
    
    Fix 7 instances of `data-title` that should be `data-bs-title` after the 
Bootstrap 5 upgrade (SPARK-55753).
    
    Bootstrap 5 Tooltip reads `data-bs-title` or `title` attribute, not 
`data-title` (which was a Bootstrap 4 convention). This caused timeline 
tooltips to show empty content on hover.
    
    ### Why are the changes needed?
    
    The BS5 upgrade (SPARK-55753) migrated most `data-*` attributes to 
`data-bs-*` prefix, but missed `data-title` in timeline HTML string 
interpolations. Affected tooltips:
    - **AllJobsPage.scala** (3): Job timeline content, executor added/removed 
events
    - **JobPage.scala** (3): Stage timeline content, executor added/removed 
events
    - **StagePage.scala** (1): Task assignment timeline content
    
    ### Does this PR introduce _any_ user-facing change?
    
    Yes — timeline tooltips that were broken (showing empty) after the BS5 
upgrade now display their content correctly.
    
    ### How was this patch tested?
    
    - Verified no remaining `data-title=` (without `data-bs-` prefix) in any 
Scala/JS/HTML files
    - This is a trivial string replacement with no logic change
    
    ### Was this patch authored or co-authored using generative AI tooling?
    
    Yes, GitHub Copilot was used.
    
    Closes #54561 from yaooqinn/SPARK-55776.
    
    Authored-by: Kent Yao <[email protected]>
    Signed-off-by: Kent Yao <[email protected]>
---
 core/src/main/scala/org/apache/spark/ui/jobs/AllJobsPage.scala | 6 +++---
 core/src/main/scala/org/apache/spark/ui/jobs/JobPage.scala     | 6 +++---
 core/src/main/scala/org/apache/spark/ui/jobs/StagePage.scala   | 2 +-
 3 files changed, 7 insertions(+), 7 deletions(-)

diff --git a/core/src/main/scala/org/apache/spark/ui/jobs/AllJobsPage.scala 
b/core/src/main/scala/org/apache/spark/ui/jobs/AllJobsPage.scala
index ed9c1cbe17ce..c395c7cca4e3 100644
--- a/core/src/main/scala/org/apache/spark/ui/jobs/AllJobsPage.scala
+++ b/core/src/main/scala/org/apache/spark/ui/jobs/AllJobsPage.scala
@@ -106,7 +106,7 @@ private[ui] class AllJobsPage(parent: JobsTab, store: 
AppStatusStore) extends We
            |  'end': new Date(${completionTime}),
            |  'content': '<div class="application-timeline-content"' +
            |     'data-bs-html="true" data-bs-placement="top" 
data-bs-toggle="tooltip"' +
-           |     'data-title="${jsEscapedDescForTooltip} (Job ${jobId})<br>' +
+           |     'data-bs-title="${jsEscapedDescForTooltip} (Job 
${jobId})<br>' +
            |     'Status: ${status}<br>' +
            |     'Submitted: ${UIUtils.formatDate(new Date(submissionTime))}' +
            |     '${
@@ -137,7 +137,7 @@ private[ui] class AllJobsPage(parent: JobsTab, store: 
AppStatusStore) extends We
            |  'start': new Date(${e.addTime.getTime()}),
            |  'content': '<div class="executor-event-content"' +
            |    'data-bs-toggle="tooltip" data-bs-placement="top"' +
-           |    'data-title="Executor ${e.id}<br>' +
+           |    'data-bs-title="Executor ${e.id}<br>' +
            |    'Added at ${UIUtils.formatDate(e.addTime)}"' +
            |    'data-bs-html="true">Executor ${e.id} added</div>'
            |}
@@ -153,7 +153,7 @@ private[ui] class AllJobsPage(parent: JobsTab, store: 
AppStatusStore) extends We
              |  'start': new Date(${removeTime.getTime()}),
              |  'content': '<div class="executor-event-content"' +
              |    'data-bs-toggle="tooltip" data-bs-placement="top"' +
-             |    'data-title="Executor ${e.id}<br>' +
+             |    'data-bs-title="Executor ${e.id}<br>' +
              |    'Removed at ${UIUtils.formatDate(removeTime)}' +
              |    '${
                       e.removeReason.map { reason =>
diff --git a/core/src/main/scala/org/apache/spark/ui/jobs/JobPage.scala 
b/core/src/main/scala/org/apache/spark/ui/jobs/JobPage.scala
index 8820a7b1661e..a235d5ea30d9 100644
--- a/core/src/main/scala/org/apache/spark/ui/jobs/JobPage.scala
+++ b/core/src/main/scala/org/apache/spark/ui/jobs/JobPage.scala
@@ -88,7 +88,7 @@ private[ui] class JobPage(parent: JobsTab, store: 
AppStatusStore) extends WebUIP
          |  'end': new Date(${completionTime}),
          |  'content': '<div class="job-timeline-content" 
data-bs-toggle="tooltip"' +
          |   'data-bs-placement="top" data-bs-html="true"' +
-         |   'data-title="${jsEscapedNameForTooltip} (Stage 
${stageId}.${attemptId})<br>' +
+         |   'data-bs-title="${jsEscapedNameForTooltip} (Stage 
${stageId}.${attemptId})<br>' +
          |   'Status: ${status.toUpperCase(Locale.ROOT)}<br>' +
          |   'Submitted: ${UIUtils.formatDate(submissionTime)}' +
          |   '${
@@ -117,7 +117,7 @@ private[ui] class JobPage(parent: JobsTab, store: 
AppStatusStore) extends WebUIP
            |  'start': new Date(${e.addTime.getTime()}),
            |  'content': '<div class="executor-event-content"' +
            |    'data-bs-toggle="tooltip" data-bs-placement="top"' +
-           |    'data-title="Executor ${e.id}<br>' +
+           |    'data-bs-title="Executor ${e.id}<br>' +
            |    'Added at ${UIUtils.formatDate(e.addTime)}"' +
            |    'data-bs-html="true">Executor ${e.id} added</div>'
            |}
@@ -133,7 +133,7 @@ private[ui] class JobPage(parent: JobsTab, store: 
AppStatusStore) extends WebUIP
              |  'start': new Date(${removeTime.getTime()}),
              |  'content': '<div class="executor-event-content"' +
              |    'data-bs-toggle="tooltip" data-bs-placement="top"' +
-             |    'data-title="Executor ${e.id}<br>' +
+             |    'data-bs-title="Executor ${e.id}<br>' +
              |    'Removed at ${UIUtils.formatDate(removeTime)}' +
              |    '${
                       e.removeReason.map { reason =>
diff --git a/core/src/main/scala/org/apache/spark/ui/jobs/StagePage.scala 
b/core/src/main/scala/org/apache/spark/ui/jobs/StagePage.scala
index 935eb8bb52cc..08156822b20f 100644
--- a/core/src/main/scala/org/apache/spark/ui/jobs/StagePage.scala
+++ b/core/src/main/scala/org/apache/spark/ui/jobs/StagePage.scala
@@ -363,7 +363,7 @@ private[ui] class StagePage(parent: StagesTab, store: 
AppStatusStore) extends We
                |'content': '<div class="task-assignment-timeline-content"
                  |data-bs-toggle="tooltip" data-bs-placement="top"
                  |data-bs-html="true" data-bs-container="body"
-                 |data-title="${"Task " + index + " (attempt " + attempt + 
")"}<br>
+                 |data-bs-title="${"Task " + index + " (attempt " + attempt + 
")"}<br>
                  |Status: ${taskInfo.status}<br>
                  |Launch Time: ${UIUtils.formatDate(new Date(launchTime))}
                  |${


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

Reply via email to