Skip to content

Commit

Permalink
Modernized projectview and plugin manager (bigtables with tabs) [JENK…
Browse files Browse the repository at this point in the history
  • Loading branch information
tfennelly committed Aug 5, 2014
1 parent 2de93f8 commit 7cdb85d
Show file tree
Hide file tree
Showing 12 changed files with 337 additions and 244 deletions.
12 changes: 11 additions & 1 deletion core/src/main/java/hudson/model/BallColor.java
Expand Up @@ -73,11 +73,13 @@ public enum BallColor implements StatusIcon {
;

private final Localizable description;
private final String iconName;
private final String iconClassName;
private final String image;
private final Color baseColor;

BallColor(String image, Localizable description, Color baseColor) {
this.iconName = Icon.toNormalizedIconName(image);
this.iconClassName = Icon.toNormalizedIconNameClass(image);
this.baseColor = baseColor;
// name() is not usable in the constructor, so I have to repeat the name twice
Expand All @@ -86,6 +88,14 @@ public enum BallColor implements StatusIcon {
this.description = description;
}

/**
* Get the status ball icon name.
* @return The status ball icon name.
*/

This comment has been minimized.

Copy link
@daniel-beck

daniel-beck Aug 19, 2014

Member

Missing @since

public String getIconName() {
return iconName;
}

/**
* Get the status ball icon class spec name.
* @return The status ball icon class spec name.
Expand Down Expand Up @@ -123,7 +133,7 @@ public Color getBaseColor() {
* Returns the {@link #getBaseColor()} in the "#RRGGBB" format.
*/
public String getHtmlBaseColor() {
return String.format("#%06X",baseColor.getRGB()&0xFFFFFF);
return String.format("#%06X", baseColor.getRGB() & 0xFFFFFF);
}

/**
Expand Down
120 changes: 61 additions & 59 deletions core/src/main/resources/hudson/PluginManager/advanced.jelly
Expand Up @@ -31,70 +31,72 @@ THE SOFTWARE.
<st:include page="sidepanel.jelly"/>
<l:main-panel>
<local:tabBar page="advanced" xmlns:local="/hudson/PluginManager" />
<table id="pluginsAdv" class="pane" style="margin-top:0; border-top:none">
<tr style="border-top:none; white-space: normal">
<td>
<l:hasPermission permission="${app.pluginManager.CONFIGURE_UPDATECENTER}">
<h1>${%HTTP Proxy Configuration}</h1>
<f:form method="post" action="proxyConfigure" name="proxyConfigure">
<j:scope>
<j:set var="instance" value="${app.proxy}"/>
<j:set var="descriptor" value="${it.proxyDescriptor}"/>
<st:include from="${descriptor}" page="${descriptor.configPage}" />
</j:scope>
<f:block>
<f:submit value="${%Submit}" />
</f:block>
</f:form>
</l:hasPermission>
<div class="pane-frame">
<table id="pluginsAdv" class="pane" style="margin-top:0; border-top:none">
<tr style="border-top:none; white-space: normal">
<td>
<l:hasPermission permission="${app.pluginManager.CONFIGURE_UPDATECENTER}">
<h1>${%HTTP Proxy Configuration}</h1>
<f:form method="post" action="proxyConfigure" name="proxyConfigure">
<j:scope>
<j:set var="instance" value="${app.proxy}"/>
<j:set var="descriptor" value="${it.proxyDescriptor}"/>
<st:include from="${descriptor}" page="${descriptor.configPage}" />
</j:scope>
<f:block>
<f:submit value="${%Submit}" />
</f:block>
</f:form>
</l:hasPermission>

<l:hasPermission permission="${app.pluginManager.UPLOAD_PLUGINS}">
<h1>${%Upload Plugin}</h1>
<f:form method="post" action="uploadPlugin" name="uploadPlugin" enctype="multipart/form-data">
<f:block>
<div style="margin-bottom: 1em;">
${%uploadtext}
</div>
</f:block>
<f:block>
<!-- @size is for other browsers, @style is for IE -->
${%File}: <input type="file" name="name" class="setting-input" style="width:80%" size='40' />
</f:block>
<f:block>
<f:submit value="${%Upload}" />
</f:block>
</f:form>
</l:hasPermission>
<l:hasPermission permission="${app.pluginManager.CONFIGURE_UPDATECENTER}">
<h1>${%Update Site}</h1>
<f:form method="post" action="siteConfigure" name="siteConfigure">
<f:entry title="${%URL}" >
<f:textbox name="site" value="${app.updateCenter.getSite(app.updateCenter.ID_DEFAULT).url}" />
</f:entry>
<f:block>
<f:submit value="${%Submit}" />
</f:block>
</f:form>
<j:set var="hasNonDefault" value="${false}"/>
<j:forEach var="site" items="${app.updateCenter.sites}">
<j:if test="${site.id != app.updateCenter.ID_DEFAULT}">
<j:set var="hasNonDefault" value="${true}"/>
</j:if>
</j:forEach>
<j:if test="${hasNonDefault}">
<h2>${%Other Sites}</h2>
<ul>
<l:hasPermission permission="${app.pluginManager.UPLOAD_PLUGINS}">
<h1>${%Upload Plugin}</h1>
<f:form method="post" action="uploadPlugin" name="uploadPlugin" enctype="multipart/form-data">
<f:block>
<div style="margin-bottom: 1em;">
${%uploadtext}
</div>
</f:block>
<f:block>
<!-- @size is for other browsers, @style is for IE -->
${%File}: <input type="file" name="name" class="setting-input" style="width:80%" size='40' />
</f:block>
<f:block>
<f:submit value="${%Upload}" />
</f:block>
</f:form>
</l:hasPermission>
<l:hasPermission permission="${app.pluginManager.CONFIGURE_UPDATECENTER}">
<h1>${%Update Site}</h1>
<f:form method="post" action="siteConfigure" name="siteConfigure">
<f:entry title="${%URL}" >
<f:textbox name="site" value="${app.updateCenter.getSite(app.updateCenter.ID_DEFAULT).url}" />
</f:entry>
<f:block>
<f:submit value="${%Submit}" />
</f:block>
</f:form>
<j:set var="hasNonDefault" value="${false}"/>
<j:forEach var="site" items="${app.updateCenter.sites}">
<j:if test="${site.id != app.updateCenter.ID_DEFAULT}">
<li>${site.url}</li>
<j:set var="hasNonDefault" value="${true}"/>
</j:if>
</j:forEach>
</ul>
</j:if>
</l:hasPermission>
</td>
</tr>
</table>
<j:if test="${hasNonDefault}">
<h2>${%Other Sites}</h2>
<ul>
<j:forEach var="site" items="${app.updateCenter.sites}">
<j:if test="${site.id != app.updateCenter.ID_DEFAULT}">
<li>${site.url}</li>
</j:if>
</j:forEach>
</ul>
</j:if>
</l:hasPermission>
</td>
</tr>
</table>
</div>
<div align="right" style="margin-top:1em">
<j:invokeStatic var="ds" className="jenkins.model.DownloadSettings" method="get"/>
<form method="post" action="${ds.useBrowser ? 'checkUpdates' : 'checkUpdatesServer'}">
Expand Down
189 changes: 96 additions & 93 deletions core/src/main/resources/hudson/PluginManager/installed.jelly
Expand Up @@ -36,104 +36,107 @@ THE SOFTWARE.
<input type="text" id="filter-box"/>
</div>
<local:tabBar page="installed" xmlns:local="/hudson/PluginManager" />
<table id="plugins" class="sortable pane bigtable">
<j:choose>
<j:when test="${empty(app.pluginManager.plugins) and empty(app.pluginManager.failedPlugins)}">
<tr><td>
${%No plugins installed.}
</td></tr>
</j:when>
<j:otherwise>
<tr style="border-top: 0px;">
<th width="32" tooltip="${%Uncheck to disable the plugin}">${%Enabled}</th>
<th initialSortDir="down">${%Name}</th>
<th width="1">${%Version}</th>
<th width="1">${%Previously installed version}</th>
<th width="1">${%Pinned}</th>
<th width="1">${%Uninstall}</th>
</tr>
<j:forEach var="p" items="${app.pluginManager.plugins}">
<tr class="plugin">
<j:set var="state" value="${p.enabled?'true':null}"/>
<td class="center pane" data="${state}">
<input type="checkbox" checked="${state}" onclick="flip(event)"
url="plugin/${p.shortName}"
original="${p.active?'true':'false'}"/>
</td>
<td class="pane">
<div>
<a href="${p.url}">
${p.updateInfo.displayName?:p.displayName}

<div class="pane-frame">
<table id="plugins" class="sortable pane bigtable stripped-odd">
<j:choose>
<j:when test="${empty(app.pluginManager.plugins) and empty(app.pluginManager.failedPlugins)}">
<tr><td>
${%No plugins installed.}
</td></tr>
</j:when>
<j:otherwise>
<tr>
<th width="32" tooltip="${%Uncheck to disable the plugin}">${%Enabled}</th>
<th initialSortDir="down">${%Name}</th>
<th width="1">${%Version}</th>
<th width="1">${%Previously installed version}</th>
<th width="1">${%Pinned}</th>
<th width="1">${%Uninstall}</th>
</tr>
<j:forEach var="p" items="${app.pluginManager.plugins}">
<tr class="plugin">
<j:set var="state" value="${p.enabled?'true':null}"/>
<td class="center pane" data="${state}">
<input type="checkbox" checked="${state}" onclick="flip(event)"
url="plugin/${p.shortName}"
original="${p.active?'true':'false'}"/>
</td>
<td class="pane">
<div>
<a href="${p.url}">
${p.updateInfo.displayName?:p.displayName}
</a>
</div>
<div class="excerpt">
<j:set var="indexPage" value="${p.indexPage.toString()}" />
<j:set var="excerpt" value="${app.updateCenter.getPlugin(p.shortName).excerpt}"/>
<j:set var="description" value="${p.manifest.mainAttributes.getValue('Specification-Title')}"/>
<j:choose>
<j:when test="${!empty(indexPage)}"> <!-- src/main/resources/index.jelly, preferred -->
<j:include uri="${indexPage}"/>
</j:when>
<j:when test="${excerpt != null}"> <!-- HTML from {excerpt} in wiki page -->
<j:out value="${excerpt}"/>
</j:when>
<j:when test="${description != null}"> <!-- last resort, from POM -->
${description}
</j:when>
<j:otherwise>
${%No description available.}
</j:otherwise>
</j:choose>
</div>
</td>
<td class="center pane" style="white-space:normal">
<a href="plugin/${p.shortName}/thirdPartyLicenses">
${p.version}
</a>
</div>
<div class="excerpt">
<j:set var="indexPage" value="${p.indexPage.toString()}" />
<j:set var="excerpt" value="${app.updateCenter.getPlugin(p.shortName).excerpt}"/>
<j:set var="description" value="${p.manifest.mainAttributes.getValue('Specification-Title')}"/>
</td>
<td class="pane">
<j:if test="${p.downgradable}">
<form method="post" action="${rootURL}/updateCenter/plugin/${p.shortName}/downgrade">
<s:submit value="${%downgradeTo(p.backupVersion)}"/>
</form>
</j:if>
</td>
<td class="center pane" id='unpin-${p.shortName}'>
<j:if test="${p.isPinned()}">
<input type="button" onclick="unpin(this,'${p.shortName}')" value="${%Unpin}" class="yui-button" />
<a href="${%wiki.url}" target="_blank"><l:icon class="icon-help icon-sm" style="vertical-align:top"/></a>
</j:if>
</td>
<td class="center pane">
<j:choose>
<j:when test="${!empty(indexPage)}"> <!-- src/main/resources/index.jelly, preferred -->
<j:include uri="${indexPage}"/>
</j:when>
<j:when test="${excerpt != null}"> <!-- HTML from {excerpt} in wiki page -->
<j:out value="${excerpt}"/>
<j:when test="${p.isDeleted()}">
<p>${%Uninstallation pending}</p>
</j:when>
<j:when test="${description != null}"> <!-- last resort, from POM -->
${description}
<j:when test="${!p.isBundled()}">
<form method="post" action="plugin/${p.shortName}/uninstall">
<input type="submit" value="${%Uninstall}"/>
</form>
</j:when>
<j:otherwise>
${%No description available.}
</j:otherwise>
</j:choose>
</div>
</td>
<td class="center pane" style="white-space:normal">
<a href="plugin/${p.shortName}/thirdPartyLicenses">
${p.version}
</a>
</td>
<td class="pane">
<j:if test="${p.downgradable}">
<form method="post" action="${rootURL}/updateCenter/plugin/${p.shortName}/downgrade">
<s:submit value="${%downgradeTo(p.backupVersion)}"/>
</form>
</j:if>
</td>
<td class="center pane" id='unpin-${p.shortName}'>
<j:if test="${p.isPinned()}">
<input type="button" onclick="unpin(this,'${p.shortName}')" value="${%Unpin}" class="yui-button" />
<a href="${%wiki.url}" target="_blank"><l:icon class="icon-help icon-sm" style="vertical-align:top"/></a>
</j:if>
</td>
<td class="center pane">
<j:choose>
<j:when test="${p.isDeleted()}">
<p>${%Uninstallation pending}</p>
</j:when>
<j:when test="${!p.isBundled()}">
<form method="post" action="plugin/${p.shortName}/uninstall">
<input type="submit" value="${%Uninstall}"/>
</form>
</j:when>
</j:choose>
</td>
</tr>
</j:forEach>
<!-- failed ones -->
<j:forEach var="p" items="${it.pluginManager.failedPlugins}">
<tr class="hoverback">
<td class="pane" />
<td class="pane">
<h4 class="error">Failed : ${p.name}</h4>
<div stlyle="padding-left: 1em">
<pre>${p.exceptionString}</pre>
</div>
</td>
<td class="pane" />
</tr>
</j:forEach>
</j:otherwise>
</j:choose>
</table>
</td>
</tr>
</j:forEach>
<!-- failed ones -->
<j:forEach var="p" items="${it.pluginManager.failedPlugins}">
<tr class="hoverback">
<td class="pane" />
<td class="pane">
<h4 class="error">Failed : ${p.name}</h4>
<div stlyle="padding-left: 1em">
<pre>${p.exceptionString}</pre>
</div>
</td>
<td class="pane" />
</tr>
</j:forEach>
</j:otherwise>
</j:choose>
</table>
</div>

<div class="warning" id="needRestart" style="display:none; margin: 1em; height: 1em">
<form method="post" action="${rootURL}/safeRestart">
Expand Down

4 comments on commit 7cdb85d

@Memphiz
Copy link

Choose a reason for hiding this comment

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

With 1.576 i get this nice (not ;) ) stacktraces whenever i view certain jobs:

http://pastebin.com/AFx9aiaZ

doesn't happen with 1.575 and i only assume that it has something to do with this commit maybe?

@daniel-beck
Copy link
Member

Choose a reason for hiding this comment

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

@Memphiz There's a good chance it's actually JENKINS-24317 and the element in question retrieves the user (e.g. the "Started by user Memphiz" cause info). See the issue for details on the likely cause and workaround. Please comment there for any further discussion.

@Memphiz
Copy link

Choose a reason for hiding this comment

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

Sorry for posting here again - but this ticket seems totally unrelated to my problem.

  1. I have no login/logout problems, nor am i using ldap
  2. the field in question in my stacktraces is displayname and tooltip (booth are somehow touched in this commit
  3. It only happens by clicking on a job

If you still think i should go to JENKINS-24317 i shut up here - but just wanted to clear it up a bit more ;)

@daniel-beck
Copy link
Member

Choose a reason for hiding this comment

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

File a new issue against core and label it user-experience. I'll follow up in comments to it to determine the cause of your problem.

Please sign in to comment.