Skip to content

Commit

Permalink
Replace Tango icons with Jenkins Symbols (jenkinsci#6307)
Browse files Browse the repository at this point in the history
Co-authored-by: Daniel Beck <[email protected]>
Co-authored-by: Adrien Lecharpentier <[email protected]>
Co-authored-by: Tim Jacomb <[email protected]>
Co-authored-by: Tim Jacomb <[email protected]>
  • Loading branch information
5 people authored Mar 22, 2022
1 parent afb061e commit 5144035
Show file tree
Hide file tree
Showing 81 changed files with 564 additions and 298 deletions.
7 changes: 6 additions & 1 deletion core/src/main/java/hudson/Functions.java
Original file line number Diff line number Diff line change
Expand Up @@ -1266,7 +1266,12 @@ public int compareTo(Tag that) {

public static String getIconFilePath(Action a) {
String name = a.getIconFileName();
if (name == null) return null;
if (name == null) {
return null;
}
if (name.startsWith("symbol-")) {
return name;
}
if (name.startsWith("/"))
return name.substring(1);
else
Expand Down
10 changes: 7 additions & 3 deletions core/src/main/java/jenkins/model/ModelObjectWithContextMenu.java
Original file line number Diff line number Diff line change
Expand Up @@ -99,11 +99,15 @@ public ContextMenu add(Action a) {
String text = a.getDisplayName();
String base = Functions.getIconFilePath(a);
if (base == null) return this;
String icon = Stapler.getCurrentRequest().getContextPath() + (base.startsWith("images/") ? Functions.getResourcePath() : "") + '/' + base;

String url = Functions.getActionUrl(req.findAncestor(ModelObject.class).getUrl(), a);

return add(url, icon, text);
if (base.startsWith("symbol-")) {
Icon icon = Functions.tryGetIcon(base);
return add(url, icon.getClassSpec(), text);
} else {
String icon = Stapler.getCurrentRequest().getContextPath() + (base.startsWith("images/") ? Functions.getResourcePath() : "") + '/' + base;
return add(url, icon, text);
}
}

public ContextMenu add(String url, String icon, String text) {
Expand Down
50 changes: 40 additions & 10 deletions core/src/main/java/org/jenkins/ui/icon/IconSet.java
Original file line number Diff line number Diff line change
Expand Up @@ -77,16 +77,22 @@ private static String prependTitleIfRequired(String icon, String title) {

// for Jelly
@Restricted(NoExternalUse.class)
public static String getSymbol(String name, String title, String classes) {
if (SYMBOLS.containsKey(name)) {
String symbol = SYMBOLS.get(name);
public static String getSymbol(String name, String title, String tooltip, String classes) {
String translatedName = cleanName(name);

if (SYMBOLS.containsKey(translatedName)) {
String symbol = SYMBOLS.get(translatedName);
symbol = symbol.replaceAll("(class=\")[^&]*?(\")", "$1$2");
symbol = symbol.replaceAll("(tooltip=\")[^&]*?(\")", "");
if (!tooltip.isEmpty()) {
symbol = symbol.replaceAll("<svg", "<svg tooltip=\"" + tooltip + "\"");
}
symbol = symbol.replaceAll("<svg", "<svg class=\"" + classes + "\"");
return prependTitleIfRequired(symbol, title);
}

// Load symbol if it exists
InputStream inputStream = IconSet.class.getResourceAsStream("/images/symbols/" + name + ".svg");
InputStream inputStream = IconSet.class.getResourceAsStream("/images/symbols/" + translatedName + ".svg");
String symbol = null;

try {
Expand All @@ -102,11 +108,15 @@ public static String getSymbol(String name, String title, String classes) {

symbol = symbol.replaceAll("(<title>)[^&]*(</title>)", "$1$2");
symbol = symbol.replaceAll("(class=\")[^&]*?(\")", "$1$2");
symbol = symbol.replaceAll("(tooltip=\")[^&]*?(\")", "$1$2");
if (!tooltip.isEmpty()) {
symbol = symbol.replaceAll("<svg", "<svg tooltip=\"" + tooltip + "\"");
}
symbol = symbol.replaceAll("<svg", "<svg aria-hidden=\"true\"");
symbol = symbol.replaceAll("<svg", "<svg class=\"" + classes + "\"");
symbol = symbol.replace("stroke:#000", "stroke:currentColor");

SYMBOLS.put(name, symbol);
SYMBOLS.put(translatedName, symbol);

return prependTitleIfRequired(symbol, title);
}
Expand Down Expand Up @@ -535,19 +545,39 @@ private static void initializeSVGs() {
*/
@Restricted(NoExternalUse.class)
public static String tryTranslateTangoIconToSymbol(String tangoIcon) {
if (tangoIcon != null) {
tangoIcon = tangoIcon.split(" ")[0];
}

Map<String, String> translations = new HashMap<>();
translations.put("icon-application-certificate", "symbol-ribbon");
translations.put("icon-document", "symbol-document-text");
translations.put("icon-clipboard", "symbol-logs");
translations.put("icon-clock", "symbol-play");
translations.put("icon-edit-delete", "symbol-trash");
translations.put("icon-fingerprint", "symbol-fingerprint");
translations.put("icon-folder", "symbol-folder");
translations.put("icon-gear", "symbol-settings");
translations.put("icon-gear2", "symbol-settings");
translations.put("icon-help", "symbol-help-circle");
translations.put("icon-keys", "symbol-key");
translations.put("icon-monitor", "symbol-terminal");
translations.put("icon-new-package", "symbol-add");
translations.put("icon-next", "symbol-arrow-right");
translations.put("icon-plugin", "symbol-plugins");
translations.put("icon-previous", "symbol-arrow-left");
translations.put("icon-search", "symbol-search");
translations.put("icon-setting", "symbol-build");
translations.put("icon-terminal", "symbol-terminal");
translations.put("icon-text", "symbol-details");
translations.put("icon-up", "symbol-arrow-up");
translations.put("icon-help", "symbol-help-circle");
translations.put("icon-user", "symbol-people");

String cleanedTangoIcon = cleanName(tangoIcon);
return translations.getOrDefault(cleanedTangoIcon, null);
}

return translations.getOrDefault(tangoIcon, null);
private static String cleanName(String tangoIcon) {
if (tangoIcon != null) {
tangoIcon = tangoIcon.split(" ")[0];
}
return tangoIcon;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ l.side_panel {
l.task(icon:"icon-up icon-md", href:rootURL+'/', title:_("Back to Dashboard"))
l.task(icon:"symbol-settings", href:"${rootURL}/manage", title:_("Manage Jenkins"))
if (!app.updateCenter.jobs.isEmpty()) {
l.task(icon:"icon-plugin icon-md", href:"${rootURL}/updateCenter/", title:_("Update Center"))
l.task(icon: "symbol-download", href:"${rootURL}/updateCenter/", title:_("Update Center"))
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@ THE SOFTWARE.
<!-- TODO: st:include page="sidepanel.jelly" /-->
<l:main-panel>
<h1>
<l:icon class="icon-monitor icon-xlg"/>
${%JVM Memory Usage}
</h1>
<j:set var="type" value="${request.getParameter('type') ?: 'min'}" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,12 @@ 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">
<l:layout permission="${app.ADMINISTER}" title="${%Configure Log Recorder}">
<st:include page="sidepanel.jelly" />
<l:app-bar title="${%Configure log recorder}">
<a class="jenkins-button" tooltip="${%Additional information on log levels}" href="${%url}">
<l:icon src="symbol-help-circle" />
</a>
</l:app-bar>
<l:main-panel>
<h1>${%Configure log recorder} <t:help iconSize="large" href="https://www.jenkins.io/redirect/log-recorders" /></h1>
<p>
${%Enter the name of the logger you want to enable}.
</p>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ THE SOFTWARE.
<l:layout title="Log" permission="${app.SYSTEM_READ}">
<st:include page="sidepanel.jelly" />
<l:main-panel>
<h1><l:icon class="icon-clipboard icon-xlg"/>${it.displayName}</h1>
<h1>${it.displayName}</h1>
<t:logRecords logRecords="${it.logRecords}"/>
<j:forEach var="entry" items="${it.slaveLogRecords.entrySet()}">
<h2><a href="${rootURL}/${entry.key.url}" class="model-link">${entry.key.displayName}</a></h2>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ THE SOFTWARE.
<l:side-panel>
<l:tasks>
<l:task href=".." icon="icon-up icon-md" title="${%Back to Loggers}"/>
<l:task href="." icon="icon-notepad icon-md" title="${%Log records}"/>
<l:task href="." icon="symbol-file-tray" title="${%Log records}"/>
<l:isAdmin>
<l:task href="configure" icon="symbol-settings" title="${%Configure}"/>
<l:task href="delete" icon="icon-edit-delete icon-md" title="${%Delete}"/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ THE SOFTWARE.
<l:layout title="Log">
<st:include page="sidepanel.jelly" />
<l:main-panel>
<h1><l:icon class="icon-clipboard icon-xlg"/>${%Jenkins Log}</h1>
<h1>${%Jenkins Log}</h1>
<div class="alert alert-info">
Log messages at a level lower than INFO are never recorded in the Jenkins log. Use <a href=".">log recorders</a> to record these log messages.
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,22 +28,19 @@ THE SOFTWARE.
<div align="right">
<a href="rss" class="yui-button link-button">
<span class="leading-icon">
<l:svgIcon class="icon-small" tooltip="Atom feed" viewBox="0 0 16 16"
href="${imagesURL}/material-icons/feed.svg#feed"/>
<l:icon src="symbol-rss" />
</span>
<span>${%All}</span>
</a>
<a href="rss?level=SEVERE" class="yui-button link-button">
<span class="leading-icon">
<l:svgIcon class="icon-small" tooltip="Atom feed" viewBox="0 0 16 16"
href="${imagesURL}/material-icons/feed.svg#feed"/>
<l:icon src="symbol-rss" />
</span>
<span>${%SEVERE}</span>
</a>
<a href="rss?level=WARNING" class="yui-button link-button">
<span class="leading-icon">
<l:svgIcon class="icon-small" tooltip="Atom feed" viewBox="0 0 16 16"
href="${imagesURL}/material-icons/feed.svg#feed"/>
<l:icon src="symbol-rss" />
</span>
<span>${%WARNING}</span>
</a>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,17 +28,19 @@ THE SOFTWARE.
<?jelly escape-by-default='true'?>
<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">
<l:layout title="${%Log}">
<l:app-bar title="${%Log Recorders}">
<l:isAdmin>
<a href="new" class="jenkins-button jenkins-button--primary">
<l:icon src="symbol-add" />
${%Add new log recorder}
</a>
</l:isAdmin>
<a class="jenkins-button" tooltip="${%Additional information on log recorders}" href="https://www.jenkins.io/redirect/log-recorders">
<l:icon src="symbol-help-circle" />
</a>
</l:app-bar>
<st:include page="sidepanel.jelly" />
<l:main-panel xmlns:local="local">
<div class="jenkins-app-bar">
<div class="jenkins-app-bar__content">
<h1>
${%Log Recorders}
<t:help iconSize="large" tooltip="${%Additional information on log recorders}" href="https://www.jenkins.io/redirect/log-recorders"/>
</h1>
</div>
</div>

<d:taglib uri="local">
<d:tag name="row">
<tr>
Expand Down Expand Up @@ -72,13 +74,6 @@ THE SOFTWARE.
</j:forEach>
</tbody>
</table>
<l:isAdmin>
<form method="get" action="new">
<p>
<f:submit value="${%Add new log recorder}" />
</p>
</form>
</l:isAdmin>
</l:main-panel>
</l:layout>
</j:jelly>
Original file line number Diff line number Diff line change
Expand Up @@ -27,14 +27,17 @@ THE SOFTWARE.
-->
<?jelly escape-by-default='true'?>
<j:jelly xmlns:j="jelly:core" xmlns:st="jelly:stapler" xmlns:l="/lib/layout" xmlns:t="/lib/hudson" xmlns:f="/lib/form">
<l:layout title="Log Levels">
<l:layout title="${%Logger Configuration}">
<l:app-bar title="${%Logger Configuration}">
<a class="jenkins-button" tooltip="${%Additional information on log levels}" href="${%url}">
<l:icon src="symbol-help-circle" />
</a>
</l:app-bar>

<st:include page="sidepanel.jelly" />

<l:main-panel>
<h1>
${%Logger Configuration}
<t:help iconSize="large" tooltip="${%Additional information on log levels}" href="${%url}" />
</h1>
<table class="sortable pane jenkins-table" id="logLevels">
<table class="sortable jenkins-table" id="logLevels">
<thead>
<tr>
<th>${%Name}</th>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,12 +32,8 @@ THE SOFTWARE.
<l:tasks>
<l:task href="${rootURL}/" icon="icon-up icon-md" title="${%Back to Dashboard}"/>
<l:task href="${rootURL}/manage" icon="symbol-settings" title="${%Manage Jenkins}"/>
<l:task href="." icon="icon-clipboard icon-md" title="${%Log Recorders}">
<l:isAdmin>
<l:task href="new" icon="icon-new-package icon-md" title="${%New Log Recorder}"/>
</l:isAdmin>
</l:task>
<l:task href="all" icon="icon-notepad icon-md" title="${%All Log Messages}"/>
<l:task href="." icon="icon-clipboard icon-md" title="${%Log Recorders}"/>
<l:task href="all" icon="symbol-file-tray" title="${%All Log Messages}"/>
<l:task href="levels" icon="symbol-settings" title="${%Log Levels}"/>
</l:tasks>
</l:side-panel>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ THE SOFTWARE.
permission="${it.ARTIFACTS}" />

<j:set var="set" value="${it.changeSet}" />
<t:summary icon="notepad.png">
<t:summary icon="symbol-changes">
<j:choose>
<j:when test="${it.hasChangeSetComputed()}">
<st:include it="${set}" page="digest.jelly" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,8 @@ THE SOFTWARE.
<?jelly escape-by-default='true'?>
<j:jelly xmlns:j="jelly:core" xmlns:l="/lib/layout" xmlns:p="/lib/hudson/project">
<l:task contextMenu="false" href="${it.upUrl}" icon="icon-up icon-md" title="${%Back to Project}"/>
<l:task contextMenu="false" href="${buildUrl.baseUrl}/" icon="icon-search icon-md" title="${%Status}"/>
<l:task href="${buildUrl.baseUrl}/changes" icon="icon-notepad icon-md" title="${%Changes}"/>
<l:task contextMenu="false" href="${buildUrl.baseUrl}/" icon="symbol-details" title="${%Status}"/>
<l:task href="${buildUrl.baseUrl}/changes" icon="symbol-changes" title="${%Changes}"/>
<p:console-link/>
<l:task href="${buildUrl.baseUrl}/configure" icon="symbol-settings" title="${h.hasPermission(it,it.UPDATE)?'%Edit Build Information':'%View Build Information'}"/>
</j:jelly>
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ THE SOFTWARE.
<l:layout title="${%Rename}">
<st:include page="sidepanel.jelly" />
<l:main-panel>
<h1><l:icon class="icon-notepad icon-xlg"/> ${%DescribeRename(it.pronoun, it.name)}</h1>
<h1>${%DescribeRename(it.pronoun, it.name)}</h1>
<f:form method="post" action="confirmRename" name="config" tableClass="config-table scrollspy">
<f:entry title="${%NewName}">
<f:textbox name="newName" value="${it.name}" autocomplete="on" checkUrl="checkNewName" checkDependsOn="newName"/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,15 +38,15 @@ THE SOFTWARE.
${act.displayName}
</t:summary>
</j:forEach>
<t:summary icon="folder.png" href="ws/" permission="${it.WORKSPACE}">
<t:summary icon="symbol-folder" href="ws/" permission="${it.WORKSPACE}">
${%Workspace}
</t:summary>

<t:artifactList caption="${%Last Successful Artifacts}"
build="${it.lastSuccessfulBuild}" baseURL="lastSuccessfulBuild/"
permission="${it.lastSuccessfulBuild.ARTIFACTS}"/>

<t:summary icon="notepad.png" href="changes">
<t:summary icon="symbol-changes" href="changes">
${%Recent Changes}
</t:summary>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,10 +45,10 @@ THE SOFTWARE.
<l:task contextMenu="false" href="${rootURL}/${it.parent.url}" icon="icon-up icon-md" title="${%Up}"/>
</j:otherwise>
</j:choose>
<l:task contextMenu="false" href="${url}/" icon="icon-search icon-md" title="${%Status}"/>
<l:task href="${url}/changes" icon="icon-notepad icon-md" title="${%Changes}"/>
<l:task icon="images/svgs/folder.svg" href="${url}/ws/" title="${%Workspace}" permission="${it.WORKSPACE}">
<l:task confirmationMessage="${%wipe.out.confirm}" href="${url}/doWipeOutWorkspace" icon="icon-folder-delete icon-md" permission="${h.isWipeOutPermissionEnabled() ? it.WIPEOUT : it.BUILD}" post="true" requiresConfirmation="true" title="${%Wipe Out Workspace}"/>
<l:task contextMenu="false" href="${url}/" icon="symbol-details" title="${%Status}"/>
<l:task href="${url}/changes" icon="symbol-changes" title="${%Changes}"/>
<l:task icon="symbol-folder" href="${url}/ws/" title="${%Workspace}" permission="${it.WORKSPACE}">
<l:task confirmationMessage="${%wipe.out.confirm}" href="${url}/doWipeOutWorkspace" icon="symbol-trash" permission="${h.isWipeOutPermissionEnabled() ? it.WIPEOUT : it.BUILD}" post="true" requiresConfirmation="true" title="${%Wipe Out Workspace}"/>
</l:task>
<j:if test="${it.configurable}">
<p:configurable/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ THE SOFTWARE.

<?jelly escape-by-default='true'?>
<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">
<t:summary icon="orange-square.png">
<t:summary icon="symbol-trigger">
<j:forEach var="entry" items="${it.causeCounts.entrySet()}">
<p>
<st:include page="description.jelly" it="${entry.key}"/>
Expand Down
1 change: 0 additions & 1 deletion core/src/main/resources/hudson/model/Computer/builds.jelly
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@ THE SOFTWARE.
<st:include page="sidepanel.jelly" />
<l:main-panel>
<h1>
<l:icon class="icon-notepad icon-xlg"/>
${%title(it.displayName)}
</h1>
<p>
Expand Down
8 changes: 4 additions & 4 deletions core/src/main/resources/hudson/model/Computer/sidepanel.jelly
Original file line number Diff line number Diff line change
Expand Up @@ -33,12 +33,12 @@ THE SOFTWARE.
<l:task contextMenu="false" href="${rootURL}/computer" icon="icon-up icon-md" title="${%Back to List}"/>
<l:task contextMenu="false" href="${rootURL}/${it.url}" icon="icon-search icon-md" title="${%Status}"/>
<l:task href="${rootURL}/${it.url}delete" icon="icon-edit-delete icon-md" permission="${it.DELETE}" title="${%Delete Agent}"/>
<l:task href="${rootURL}/${it.url}configure" icon="icon-setting icon-md" permission="${it.EXTENDED_READ}"
<l:task href="${rootURL}/${it.url}configure" icon="symbol-edit" permission="${it.EXTENDED_READ}"
title="${it.hasPermission(it.CONFIGURE) ? '%Configure' : '%View Configuration'}"/>
<l:task href="${rootURL}/${it.url}builds" icon="icon-notepad icon-md" title="${%Build History}"/>
<l:task href="${rootURL}/${it.url}load-statistics" icon="icon-monitor icon-md" title="${%Load Statistics}"/>
<l:task href="${rootURL}/${it.url}builds" icon="symbol-build-history" title="${%Build History}"/>
<l:task href="${rootURL}/${it.url}load-statistics" icon="symbol-analytics" title="${%Load Statistics}"/>
<j:if test="${it.channel!=null}">
<l:task href="${rootURL}/${it.url}script" icon="icon-terminal icon-md" permission="${app.ADMINISTER}" title="${%Script Console}"/>
<l:task href="${rootURL}/${it.url}script" icon="symbol-terminal" permission="${app.ADMINISTER}" title="${%Script Console}"/>
</j:if>
<st:include page="sidepanel2.jelly" optional="true" /><!-- hook for derived class to add more items -->
<t:actions />
Expand Down
Loading

0 comments on commit 5144035

Please sign in to comment.