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]