Skip to content

[JENKINS-75832] Support actions with Badges in the Hamburger Menu - #10791

Merged
MarkEWaite merged 5 commits into
jenkinsci:masterfrom
jtnord:WIP_ACTIONS-HEADER
Jul 6, 2025
Merged

[JENKINS-75832] Support actions with Badges in the Hamburger Menu#10791
MarkEWaite merged 5 commits into
jenkinsci:masterfrom
jtnord:WIP_ACTIONS-HEADER

Conversation

@jtnord

@jtnord jtnord commented Jul 1, 2025

Copy link
Copy Markdown
Member

See JENKINS-75832.

Previously RootActions that had a badge would not render the badge (correctly in the case of a an action.jelly using l:task or at all when using the inbuilt rendering using dd:item) when in a new Header and collapsed (either in the previous overflow or in the newer hamburger menu).

This fixes the dom structure for l:task and adds the correct plumbing for dropdown menu items.

Additionally to call out there is a badge in the hamburger the status is rolled up to the hambuger menu.

Testing done

Using a custom plugin with an action both with and without action.jelly with and without a badge being present.

Screenshots

image

Action with Badge and a tooltip hover.
image

Proposed changelog entries

  • Actions with Alerts now show correctly in the new header when in the hamburger menu.

Proposed changelog category

/label regression-fix

Proposed upgrade guidelines

N/A

Submitter checklist

  • The Jira issue, if it exists, is well-described.
  • The changelog entries and upgrade guidelines are appropriate for the audience affected by the change (users or developers, depending on the change) and are in the imperative mood (see examples). Fill in the Proposed upgrade guidelines section only if there are breaking changes or changes that may require extra steps from users during upgrade.
  • There is automated testing or an explanation as to why this change has no tests.
  • New public classes, fields, and methods are annotated with @Restricted or have @since TODO Javadocs, as appropriate.
  • New deprecations are annotated with @Deprecated(since = "TODO") or @Deprecated(forRemoval = true, since = "TODO"), if applicable.
  • New or substantially changed JavaScript is not defined inline and does not call eval to ease future introduction of Content Security Policy (CSP) directives (see documentation).
  • For dependency updates, there are links to external changelogs and, if possible, full differentials.
  • For new APIs and extension points, there is a link to at least one consumer.

Desired reviewers

@mention

Before the changes are marked as ready-for-merge:

Maintainer checklist

  • There are at least two (2) approvals for the pull request and no outstanding requests for change.
  • Conversations in the pull request are over, or it is explicit that a reviewer is not blocking the change.
  • Changelog entries in the pull request title and/or Proposed changelog entries are accurate, human-readable, and in the imperative mood.
  • Proper changelog labels are set so that the changelog can be generated automatically.
  • If the change needs additional upgrade steps from users, the upgrade-guide-needed label is set and there is a Proposed upgrade guidelines section in the pull request title (see example).
  • If it would make sense to backport the change to LTS, a Jira issue must exist, be a Bug or Improvement, and be labeled as lts-candidate to be considered (see query).

jtnord added 2 commits July 1, 2025 19:49
This adds support for Badges from RootActions in the Hamburger Menu (but
more generically within dropdowns).
@comment-ops-bot comment-ops-bot Bot added the regression-fix Pull request that fixes a regression in one of the previous Jenkins releases label Jul 1, 2025
@jtnord
jtnord requested review from a team, MarkEWaite and scherler July 1, 2025 18:58
@MarkEWaite MarkEWaite added the web-ui The PR includes WebUI changes which may need special expertise label Jul 2, 2025
</j:when>
</j:choose>
</j:set>
<l:overflowButton icon="symbol-menu-hamburger" id="header-more-actions" html="${hamburgerBadge}">

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

passes the badge as HTML to the overflow button. whilst we could allow the overflow button to take a badge I felt that this was a bit specialized for an overflow button given that badges are for RootActions only (and management links), so took the generic approach of allowing arbitrary HTML.

<j:set var="hamburgerBadge">
<j:choose>
<j:when test="${hamburgerHasBadgeWithSeverityError}">
<span class="jenkins-badge jenkins-!-danger-color" />

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this actually reveals a UX issue with the current design that is out of scope of this PR as it does exactly what is already done in the rest of the header.
Namely the visual indication of severity is only differentiated by colour. A colour blind user can not easily tell at a glance what the severity of the action is.

Comment thread core/src/main/resources/lib/layout/header/actions.jelly

@alecharp alecharp left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder if we could improve this later on by having the count of each severity and not just the higher severity.
This could help when users deliberately leave one warning but a second one appears.

However this is good to show badge in the hamburger menu.

@jtnord

jtnord commented Jul 2, 2025

Copy link
Copy Markdown
Member Author

I wonder if we could improve this later on by having the count of each severity and not just the higher severity. This could help when users deliberately leave one warning but a second one appears.

However this is good to show badge in the hamburger menu.

I initially started with an approach like that, however the badge could get quite big "1 error, 3 warnings and 2 info", and showing this info in a tooltip would not solve the discoverability issue.

There is certainly many UX improvements that could be made in the header, but doing it just in the hamburger but not addressing the Manage Jenkins cog (or others) would make it a bit disjointed.

As such I think this is an improvement that is outside of this PR.

@judithlr

judithlr commented Jul 2, 2025

Copy link
Copy Markdown

Hi everyone!
Could we consider implementing something like this? We could address it in a separate Ticket/PR so it doesn’t block this one.
The main benefits would be:
• Improving accessibility by helping color-blind users distinguish alerts and warnings without relying solely on color
• Providing more useful and clear information when hovering over the hamburger menu
Let me know what you think!

Screenshot 2025-07-02 at 19 06 47

@jtnord

jtnord commented Jul 3, 2025

Copy link
Copy Markdown
Member Author

Hi everyone! Could we consider implementing something like this? We could address it in a separate Ticket/PR so it doesn’t block this one. The main benefits would be: • Improving accessibility by helping color-blind users distinguish alerts and warnings without relying solely on color • Providing more useful and clear information when hovering over the hamburger menu Let me know what you think!

Screenshot 2025-07-02 at 19 06 47

Whilst I agree that is a nicer UX, this will be at odds with the alerts on other actions in the header and I would say they all should be aligned. changing this across all the elements using badges is out of scope of this ticket.

@uhafner

uhafner commented Jul 3, 2025

Copy link
Copy Markdown
Member

From a UI perspective I would recommend to not differentiate between different badge types. So I think it would be simpler and more consistent if this is a boolean toggle: one of the containing elements has a badge or not. This also makes the UI much simpler: we just have one color (and icon) that shows that there is something important in the menu.

This is the way others are doing it (see IntelliJ, GitHub, Element, MacOS, etc.): just one indicator that something needs your attention. When we use the suggested 3 types SeverityWarning ... then it will take just a couple of weeks until the next one wants to show an indicator for something new, for something unread, etc.

@jtnord

jtnord commented Jul 3, 2025

Copy link
Copy Markdown
Member Author

From a UI perspective

A great looking UI can have a really bad UX. I am hoping this was just an accidental miss-use of terms as we need to make the UX of Jenkins better not worse.

I would recommend to not differentiate between different badge types. So I think it would be simpler and more consistent if this is a boolean toggle: one of the containing elements has a badge or not. This also makes the UI much simpler: we just have one color (and icon) that shows that there is something important in the menu.

Define important?

A badge can have an INFO so I would say calling out that something is broken and needs your attention at a glance is much better than calling out hey something has some extra info.. (We already do this on the Manage Jenkins cog). Additionally if there is an INFO you may choose to ignore it for a while, and then if an error comes along, you will not know something has become suddenly worse.

This is the way others are doing it (see IntelliJ, GitHub, Element, MacOS, etc.): just one indicator that something needs your attention.

Jira (not a great UX, but neither is GH) )at least gives you a number and not just a single blob.
Windows in the main taskbar also give you a count for slack, and slack gives you a count in the app too.

When we use the suggested 3 types SeverityWarning ... then it will take just a couple of weeks until the next one wants to show an indicator for something new, for something unread, etc.

Its an defined enum in Jenkins core that has been in use for many years. It is already rendered differently in Jenkins core.

Anyway - this discussion about future UX changes should not be happening in this ticket. The whole UX of Jenkins including the new header needs to be looked at holistically. I am not updating this PR to change the UI / badges as this is currently what Jenkins already does in the header for primary actions. Changing this is out of scope.

@uhafner

uhafner commented Jul 3, 2025

Copy link
Copy Markdown
Member

I must admit that I don't understand your reply. My comment is about the overlay point in the upper right corner of the hamburger menu item.

Bildschirmfoto 2025-07-03 um 16 11 57

Here I would propose one overlay icon with one color. No different colors, no different icons.

@jtnord

jtnord commented Jul 3, 2025

Copy link
Copy Markdown
Member Author

I must admit that I don't understand your reply. My comment is about the overlay point in the upper right corner of the hamburger menu item.

Bildschirmfoto 2025-07-03 um 16 11 57

Here I would propose one overlay icon with one color. No different colors, no different icons.

This is exactly the same as the overlay as in the "manage Jenkins" cog (ref jelly), or any other primary actions with badges, I do not follow why the overlay badge here should be different?

Either the overlay is globally bad, or it is globally OK. having different overlays meaning different things in different parts of the system would be confusing to users no?

@jtnord

jtnord commented Jul 3, 2025

Copy link
Copy Markdown
Member Author

Either the overlay is globally bad, or it is globally OK. having different overlays meaning different things in different parts of the system would be confusing to users no?

Personally at present I am of the belief it is globally bad as it is not accessible for colour blind users. However removing the status to me would be a step backwards and any change to badges in the header to align them all to something new (whatever that new is) is to me out of scope of this PR which fixes the badge where it is currently missing

@uhafner

uhafner commented Jul 3, 2025

Copy link
Copy Markdown
Member

I have never seen those colored "point" badges without text in Jenkins before. But maybe that is because I am using Jenkins differently. If I had seen that earlier, I would have complained earlier (see the WCAG argument earlier by Judith). All badges I have seen in Jenkins (and other systems) have a number inside the badge or use a point overlay in a single color (without having a meaning for the color).

<h:secondaryAction action="${action}"/>
<j:set var="currentBadge" value="${action.badge}"/>
<j:if test="${currentBadge != null}">
<j:choose>

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

untested but wouldn't this be a lot simpler:

diff --git i/core/src/main/resources/lib/layout/header/actions.jelly w/core/src/main/resources/lib/layout/header/actions.jelly
index 0bc9197cd7..0b42c6aba5 100644
--- i/core/src/main/resources/lib/layout/header/actions.jelly
+++ w/core/src/main/resources/lib/layout/header/actions.jelly
@@ -33,13 +33,13 @@
           <j:if test="${currentBadge != null}">
             <j:choose>
               <j:when test="${currentBadge.severity == 'danger'}">
-                <j:set var="hamburgerHasBadgeWithSeverityError" value="true" />
+                <j:set var="badgeColor" value="danger" />
               </j:when>
               <j:when test="${currentBadge.severity == 'warning'}">
-                <j:set var="hamburgerHasBadgeWithSeverityWarning" value="true" />
+                <j:set var="badgeColor" value="warning" />
               </j:when>
               <j:otherwise>
-                <j:set var="hamburgerHasBadgeWithSeverityInfo" value="true" />
+                <j:set var="badgeColor" value="info" />
               </j:otherwise>
             </j:choose>
           </j:if>
@@ -48,17 +48,7 @@
     </j:set>
     <j:if test="${hamburgerEntries.length() gt 0}">
       <j:set var="hamburgerBadge">
-        <j:choose>
-          <j:when test="${hamburgerHasBadgeWithSeverityError}">
-            <span class="jenkins-badge jenkins-!-danger-color" />
-          </j:when>
-          <j:when test="${hamburgerHasBadgeWithSeverityWarning}">
-            <span class="jenkins-badge jenkins-!-warning-color" />
-          </j:when>
-          <j:when test="${hamburgerHasBadgeWithSeverityInfo}">
-            <span class="jenkins-badge jenkins-!-info-color" />
-          </j:when>
-        </j:choose>
+        <span class="jenkins-badge jenkins-!-${badgeColor}-color" />
       </j:set>
       <l:overflowButton icon="symbol-menu-hamburger" id="header-more-actions" html="${hamburgerBadge}">
         <j:out value="${hamburgerEntries}" />

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

untested but wouldn't this be a lot simpler:

> -                <j:set var="hamburgerHasBadgeWithSeverityError" value="true" />
> +                <j:set var="badgeColor" value="danger" />
>                </j:when>
>                <j:when test="${currentBadge.severity == 'warning'}">
> -                <j:set var="hamburgerHasBadgeWithSeverityWarning" value="true" />
> +                <j:set var="badgeColor" value="warning" />

It would not work, as you would get the colour of the last badge seen from all the actions with badges, not the highest severity one.

e.g.

Action1 - no badge
Action2 - Badge:ERROR
Action3 - Badge:INFO
Action4 - no badge

when processing the list of actions

  1. (Action1 - no badge) - colour = null
  2. (Action2 - Badge:ERROR) colour = danger
  3. (Action3 - Badge:INFO) third action - colour = info
  4. (Action4 - no badge) colour = info

In orther words this is to find the highest severity badge of all the badges to show in the button, not the individual actions that appear in the

For whatever reason Badge takes a severity enum in the constructor, but the getSeverity returns a String. Otherwise yes it could be made simpler usign something like: severity = severity == null ? badge.getSeverityEnum() : severity.isHigherSeverity(badge.severity) ? severity : badge.severity (or the like)

But I did not want to introduce a new API at this point in time (esp as this needs to make the LTS), nor did I think doing String comparisons here would be a wise move.

Comment thread core/src/main/resources/lib/layout/overflowButton.jelly Outdated
Co-authored-by: Tim Jacomb <21194782+timja@users.noreply.github.com>
@jtnord

jtnord commented Jul 4, 2025

Copy link
Copy Markdown
Member Author

I have never seen those colored "point" badges without text in Jenkins before. But maybe that is because I am using Jenkins differently.

It was #10245 (the redesigned header) so unless you are using a weekly you would not have seen them.

@jtnord
jtnord requested a review from timja July 4, 2025 09:53
@jtnord

jtnord commented Jul 4, 2025

Copy link
Copy Markdown
Member Author

I would have complained earlier

Filed https://issues.jenkins.io/browse/JENKINS-75856

@github-actions

github-actions Bot commented Jul 5, 2025

Copy link
Copy Markdown
Contributor

Please take a moment and address the merge conflicts of your pull request. Thanks!

@github-actions github-actions Bot added the unresolved-merge-conflict There is a merge conflict with the target branch. label Jul 5, 2025
@github-actions github-actions Bot removed the unresolved-merge-conflict There is a merge conflict with the target branch. label Jul 5, 2025

@MarkEWaite MarkEWaite left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Works well in my interactive testing.

This PR is now ready for merge. We will merge it after approximately 24 hours if there is no negative feedback.

/label ready-for-merge

@comment-ops-bot comment-ops-bot Bot added the ready-for-merge The PR is ready to go, and it will be merged soon if there is no negative feedback label Jul 5, 2025
MarkEWaite pushed a commit to MarkEWaite/jenkins that referenced this pull request Jul 5, 2025
This adds support for Badges from RootActions in the Hamburger Menu (but
more generically within dropdowns).

(cherry picked from commit 76eeaf1)

From pull request:

* jenkinsci#10791
MarkEWaite pushed a commit to MarkEWaite/jenkins that referenced this pull request Jul 5, 2025
(cherry picked from commit 0af57ba)

Merge conflict resolved from commit 06d9b39

From pull request:

* jenkinsci#10791
MarkEWaite pushed a commit to MarkEWaite/jenkins that referenced this pull request Jul 5, 2025
Co-authored-by: Tim Jacomb <21194782+timja@users.noreply.github.com>

(cherry picked from commit 88d6a48)

From pull request:

* jenkinsci#10791

@A1exKH A1exKH left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM.

@MarkEWaite
MarkEWaite merged commit 2c90505 into jenkinsci:master Jul 6, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ready-for-merge The PR is ready to go, and it will be merged soon if there is no negative feedback regression-fix Pull request that fixes a regression in one of the previous Jenkins releases web-ui The PR includes WebUI changes which may need special expertise

Projects

None yet

Development

Successfully merging this pull request may close these issues.

8 participants