Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[JENKINS-71345] Remove 'undefined' from system dropdown menu #8052

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
7 changes: 3 additions & 4 deletions core/src/main/java/hudson/model/ManageJenkinsAction.java
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@
import hudson.Extension;
import hudson.Util;
import java.io.IOException;
import jenkins.management.Badge;
import jenkins.model.Jenkins;
import jenkins.model.ModelObjectWithContextMenu;
import org.apache.commons.jelly.JellyException;
Expand Down Expand Up @@ -79,13 +78,13 @@ public ContextMenu doContextMenu(StaplerRequest request, StaplerResponse respons
* menu.
*/
@Restricted(NoExternalUse.class)
public void addContextMenuItem(ContextMenu menu, String url, String icon, String iconXml, String text, boolean post, boolean requiresConfirmation, Badge badge) {
public void addContextMenuItem(ContextMenu menu, String url, String icon, String iconXml, String text, boolean post, boolean requiresConfirmation) {
if (Stapler.getCurrentRequest().findAncestorObject(this.getClass()) != null || !Util.isSafeToRedirectTo(url)) {
// Default behavior if the URL is absolute or scheme-relative, or the current object is an ancestor (i.e. would resolve correctly)
menu.add(url, icon, iconXml, text, post, requiresConfirmation, badge);
menu.add(url, icon, iconXml, text, post, requiresConfirmation);
return;
}
// If neither is the case, rewrite the relative URL to point to inside the /manage/ URL space
menu.add("manage/" + url, icon, iconXml, text, post, requiresConfirmation, badge);
menu.add("manage/" + url, icon, iconXml, text, post, requiresConfirmation);
}
}
47 changes: 0 additions & 47 deletions core/src/main/java/hudson/model/UpdateCenter.java
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,6 @@
import jenkins.MissingDependencyException;
import jenkins.RestartRequiredException;
import jenkins.install.InstallUtil;
import jenkins.management.Badge;
import jenkins.model.Jenkins;
import jenkins.security.stapler.StaplerDispatchable;
import jenkins.util.SystemProperties;
Expand Down Expand Up @@ -378,52 +377,6 @@ public InstallationJob getJob(Plugin plugin) {
return null;
}

@Restricted(NoExternalUse.class)
public Badge getBadge() {
if (!isSiteDataReady()) {
// Do not display message during this page load, but possibly later.
return null;
}
List<Plugin> plugins = getUpdates();
int size = plugins.size();
if (size > 0) {
StringBuilder tooltip = new StringBuilder();
Badge.Severity severity = Badge.Severity.WARNING;
int securityFixSize = (int) plugins.stream().filter(plugin -> plugin.fixesSecurityVulnerabilities()).count();
int incompatibleSize = (int) plugins.stream().filter(plugin -> !plugin.isCompatibleWithInstalledVersion()).count();
if (size > 1) {
tooltip.append(jenkins.management.Messages.PluginsLink_updatesAvailable(size));
} else {
tooltip.append(jenkins.management.Messages.PluginsLink_updateAvailable());
}
switch (incompatibleSize) {
case 0:
break;
case 1:
tooltip.append("\n").append(jenkins.management.Messages.PluginsLink_incompatibleUpdateAvailable());
break;
default:
tooltip.append("\n").append(jenkins.management.Messages.PluginsLink_incompatibleUpdatesAvailable(incompatibleSize));
break;
}
switch (securityFixSize) {
case 0:
break;
case 1:
tooltip.append("\n").append(jenkins.management.Messages.PluginsLink_securityUpdateAvailable());
severity = Badge.Severity.DANGER;
break;
default:
tooltip.append("\n").append(jenkins.management.Messages.PluginsLink_securityUpdatesAvailable(securityFixSize));
severity = Badge.Severity.DANGER;
break;
}
return new Badge(Integer.toString(size), tooltip.toString(), severity);
}
return null;

}

/**
* Get the current connection status.
* <p>
Expand Down
5 changes: 0 additions & 5 deletions core/src/main/java/jenkins/management/Badge.java
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,6 @@
import hudson.model.AdministrativeMonitor;
import hudson.model.ManagementLink;
import java.util.Locale;
import org.kohsuke.stapler.export.Exported;
import org.kohsuke.stapler.export.ExportedBean;

/**
* Definition of a badge that can be returned by a {@link ManagementLink} implementation.
Expand All @@ -50,7 +48,6 @@
*
* @since 2.385
*/
@ExportedBean
public class Badge {

private final String text;
Expand Down Expand Up @@ -78,7 +75,6 @@ public Badge(@NonNull String text, @NonNull String tooltip, @NonNull Severity se
*
* @return badge text
*/
@Exported(visibility = 999)
public String getText() {
return text;
}
Expand All @@ -88,7 +84,6 @@ public String getText() {
*
* @return tooltip
*/
@Exported(visibility = 999)
public String getTooltip() {
return tooltip;
}
Expand Down
44 changes: 43 additions & 1 deletion core/src/main/java/jenkins/management/PluginsLink.java
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,9 @@
import hudson.Extension;
import hudson.model.ManagementLink;
import hudson.model.UpdateCenter;
import hudson.model.UpdateSite.Plugin;
import hudson.security.Permission;
import java.util.List;
import jenkins.model.Jenkins;
import org.jenkinsci.Symbol;

Expand Down Expand Up @@ -73,6 +75,46 @@ public Category getCategory() {
@Override
public Badge getBadge() {
final UpdateCenter updateCenter = Jenkins.get().getUpdateCenter();
return updateCenter.getBadge();
if (!updateCenter.isSiteDataReady()) {
// Do not display message during this page load, but possibly later.
return null;
}
List<Plugin> plugins = updateCenter.getUpdates();
int size = plugins.size();
if (size > 0) {
StringBuilder tooltip = new StringBuilder();
Badge.Severity severity = Badge.Severity.WARNING;
int securityFixSize = (int) plugins.stream().filter(plugin -> plugin.fixesSecurityVulnerabilities()).count();
int incompatibleSize = (int) plugins.stream().filter(plugin -> !plugin.isCompatibleWithInstalledVersion()).count();
if (size > 1) {
tooltip.append(Messages.PluginsLink_updatesAvailable(size));
} else {
tooltip.append(Messages.PluginsLink_updateAvailable());
}
switch (incompatibleSize) {
case 0:
break;
case 1:
tooltip.append("\n").append(Messages.PluginsLink_incompatibleUpdateAvailable());
break;
default:
tooltip.append("\n").append(Messages.PluginsLink_incompatibleUpdatesAvailable(incompatibleSize));
break;
}
switch (securityFixSize) {
case 0:
break;
case 1:
tooltip.append("\n").append(Messages.PluginsLink_securityUpdateAvailable());
severity = Badge.Severity.DANGER;
break;
default:
tooltip.append("\n").append(Messages.PluginsLink_securityUpdatesAvailable(securityFixSize));
severity = Badge.Severity.DANGER;
break;
}
return new Badge(Integer.toString(size), tooltip.toString(), severity);
}
return null;
}
}
25 changes: 0 additions & 25 deletions core/src/main/java/jenkins/model/ModelObjectWithContextMenu.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@
import java.util.Collection;
import java.util.List;
import javax.servlet.ServletException;
import jenkins.management.Badge;
import org.apache.commons.jelly.JellyContext;
import org.apache.commons.jelly.JellyException;
import org.apache.commons.jelly.JellyTagException;
Expand Down Expand Up @@ -150,19 +149,6 @@ public ContextMenu add(String url, String icon, String iconXml, String text, boo
return this;
}

/** @since TODO */
public ContextMenu add(String url, String icon, String iconXml, String text, boolean post, boolean requiresConfirmation, Badge badge) {
if (text != null && icon != null && url != null) {
MenuItem item = new MenuItem(url, icon, text);
item.iconXml = iconXml;
item.post = post;
item.requiresConfirmation = requiresConfirmation;
item.badge = badge;
items.add(item);
}
return this;
}

/**
* Add a header row (no icon, no URL, rendered in header style).
*
Expand Down Expand Up @@ -331,8 +317,6 @@ class MenuItem {
public boolean requiresConfirmation;


private Badge badge;

/**
* The type of menu item
* @since 2.340
Expand All @@ -353,15 +337,6 @@ public String getIconXml() {
return iconXml;
}

/**
* The badge to display for the context menu item
* @since TODO
*/
@Exported
public Badge getBadge() {
return badge;
}

public MenuItem(String url, String icon, String displayName) {
withUrl(url).withIcon(icon).withDisplayName(displayName);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ THE SOFTWARE.
<j:jelly xmlns:j="jelly:core" xmlns:st="jelly:stapler" xmlns:d="jelly:define" xmlns:l="/lib/layout" xmlns:t="/lib/hudson" xmlns:f="/lib/form" xmlns:i="jelly:fmt">
<l:side-panel>
<l:tasks>
<l:task href="${rootURL}/manage/pluginManager/" icon="symbol-download" title="${%Updates}" badge="${app.updateCenter.badge}"/>
<l:task href="${rootURL}/manage/pluginManager/" icon="symbol-download" title="${%Updates}"/>
<l:task href="${rootURL}/manage/pluginManager/available" icon="symbol-shopping-bag" title="${%Available plugins}"/>
<l:task href="${rootURL}/manage/pluginManager/installed" icon="symbol-plugins" title="${%Installed plugins}"/>
<l:task href="${rootURL}/manage/pluginManager/advanced" icon="symbol-settings" title="${%Advanced settings}"/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ THE SOFTWARE.
<j:set var="iconXml">
<l:icon src="${m.iconFileName}" />
</j:set>
${taskTags!=null and attrs.contextMenu!='false' ? it.addContextMenuItem(taskTags, m.urlName, iconSrc, iconXml, m.displayName, m.requiresPOST, m.requiresConfirmation, m.badge) : null}
${taskTags!=null and attrs.contextMenu!='false' ? it.addContextMenuItem(taskTags, m.urlName, iconSrc, iconXml, m.displayName, m.requiresPOST, m.requiresConfirmation) : null}
<j:choose>
<j:when test="${m.requiresConfirmation}">
<l:confirmationLink href="${m.urlName}" post="${m.requiresPOST}" message="${%are.you.sure(m.displayName)}">
Expand Down
60 changes: 7 additions & 53 deletions core/src/main/resources/lib/layout/breadcrumbs.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,51 +22,15 @@ window.breadcrumbs = (function () {
var logger = function () {};
// logger = function() { console.log.apply(console,arguments) }; // uncomment this line to enable logging

// TODO - Use util/security.js xmlEscape in #7474
function xmlEscape(str) {
if (!str) {
return;
}

return str.replace(/[<>&'"]/g, (match) => {
switch (match) {
case "<":
return "&lt;";
case ">":
return "&gt;";
case "&":
return "&amp;";
case "'":
return "&apos;";
case '"':
return "&quot;";
}
});
}

function makeMenuHtml(icon, iconXml, displayName, badge) {
function makeMenuHtml(icon, iconXml, displayName) {
var displaynameSpan = "<span>" + displayName + "</span>";
let badgeText;
let badgeTooltip;
if (badge) {
badgeText = xmlEscape(badge.text);
badgeTooltip = xmlEscape(badge.tooltip);
}
const badgeSpan =
badge === null
? ""
: `<span class="yui-menu-badge" tooltip="${badgeTooltip}">${badgeText}</span>`;

if (iconXml != null) {
return iconXml + displaynameSpan + badgeSpan;
return iconXml + displaynameSpan;
}

if (icon === null) {
return (
"<span style='margin: 2px 4px 2px 2px;' />" +
displaynameSpan +
badgeSpan
);
return "<span style='margin: 2px 4px 2px 2px;' />" + displaynameSpan;
}

// TODO: move this to the API response in a clean way
Expand All @@ -77,13 +41,11 @@ window.breadcrumbs = (function () {
icon +
"' />" +
"</svg>" +
displaynameSpan +
badgeSpan
displaynameSpan
: "<img src='" +
icon +
"' width=24 height=24 style='margin: 2px 4px 2px 2px;' alt=''>" +
displaynameSpan +
badgeSpan;
displaynameSpan;
}

Event.observe(window, "load", function () {
Expand Down Expand Up @@ -194,8 +156,6 @@ window.breadcrumbs = (function () {
menu.addItems(items);
menu.render("breadcrumb-menu-target");
menu.show();

Behaviour.applySubtree(menu.body);
}

// ignore the currently pending call
Expand All @@ -220,20 +180,14 @@ window.breadcrumbs = (function () {
e.text = makeMenuHtml(
e.icon,
e.iconXml,
"<span class='header'>" + e.displayName + "</span>",
e.badge
"<span class='header'>" + e.displayName + "</span>"
);
e.disabled = true;
} else if (e.type === "SEPARATOR") {
e.text = "<span class='separator'>--</span>";
e.disabled = true;
} else {
e.text = makeMenuHtml(
e.icon,
e.iconXml,
e.displayName,
e.badge
);
e.text = makeMenuHtml(e.icon, e.iconXml, e.displayName);
}
if (e.subMenu != null) {
e.subMenu = {
Expand Down
18 changes: 0 additions & 18 deletions core/src/main/resources/lib/layout/task.jelly
Original file line number Diff line number Diff line change
Expand Up @@ -75,9 +75,6 @@ THE SOFTWARE.
Generally used with post="true".
(onclick supersedes this except in the context menu.)
</st:attribute>
<st:attribute name="badge" since="TODO">
If set, displays the value as a small badge on the right side of the sidepanel item.
</st:attribute>
<st:attribute name="confirmationMessage" since="1.512">
Message to use for confirmation, if requested; defaults to title.
</st:attribute>
Expand Down Expand Up @@ -136,11 +133,6 @@ THE SOFTWARE.
<l:icon src="${icon}" />
</span>
<span class="task-link-text">${title}</span>
<j:if test="${attrs.badge != null}">
<span class="task-icon-badge" tooltip="${attrs.badge.tooltip}">
${attrs.badge.text}
</span>
</j:if>
</span>
</span>
</div>
Expand Down Expand Up @@ -172,11 +164,6 @@ THE SOFTWARE.
<l:icon src="${icon}" />
</span>
<span>${title}</span>
<j:if test="${attrs.badge != null}">
<span class="task-icon-badge" tooltip="${attrs.badge.tooltip}">
${attrs.badge.text}
</span>
</j:if>
</l:confirmationLink>
</j:when>

Expand All @@ -186,11 +173,6 @@ THE SOFTWARE.
<l:icon src="${icon}" />
</span>
<span class="task-link-text">${title}</span>
<j:if test="${attrs.badge != null}">
<span class="task-icon-badge" tooltip="${attrs.badge.tooltip}">
${attrs.badge.text}
</span>
</j:if>
</a>
</j:otherwise>
</j:choose>
Expand Down