Skip to content

Commit

Permalink
Move settings to config page as default jenkinsci#119
Browse files Browse the repository at this point in the history
This commit allows Jenkins users to specify defaults for build monitor
views when creating the views from the Jenkins UI. End users can still
modify these settings using the widget within build monitor.

This is useful because the defaults do not scale to large numbers of builds
so if a user is creating a build monitor view that they anticipate will
contain a large number of builds they can increase the number of columns
and prevent each end user from having to do that individually.

This is essentially a rebase of @tcolligon's changes in pr jenkinsci#189
and is related to issue jenkinsci#119.
  • Loading branch information
hughsaunders committed Jul 18, 2019
1 parent c9395c9 commit 908e466
Show file tree
Hide file tree
Showing 11 changed files with 224 additions and 22 deletions.
9 changes: 7 additions & 2 deletions build-monitor-plugin/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@
<dependency>
<groupId>org.jenkins-ci.modules</groupId>
<artifactId>instance-identity</artifactId>
<version>2.1</version>
<version>2.2</version>
<scope>provided</scope>
</dependency>
<dependency>
Expand Down Expand Up @@ -236,7 +236,12 @@
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.4</version>
<version>2.6</version>
</dependency>
<dependency>
<groupId>commons-beanutils</groupId>
<artifactId>commons-beanutils</artifactId>
<version>1.9.3</version>
</dependency>
<dependency>
<groupId>com.github.detro.ghostdriver</groupId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,34 @@ public FormValidation doCheckIncludeRegex(@QueryParameter String value) {
return FormValidation.ok();
}

@SuppressWarnings("unused") // used in the configure-entries.jelly form
public FormValidation doCheckFontSize(@QueryParameter String value) {
try {
float val = Float.parseFloat(value);
if (val >= 0.3 && val <= 2) {
return FormValidation.ok();
} else {
return FormValidation.error("Must be >= 0.3 and <= 2");
}
} catch (NumberFormatException e) {
return FormValidation.error("Must be float");
}
}

@SuppressWarnings("unused") // used in the configure-entries.jelly form
public FormValidation doCheckNumberOfColumns(@QueryParameter String value) {
try {
int val = Integer.parseInt(value);
if (val >= 1 && val <= 8) {
return FormValidation.ok();
} else {
return FormValidation.error("Must be >= 1 and <= 8");
}
} catch (NumberFormatException e) {
return FormValidation.error("Must be integer");
}
}

@Override
public boolean configure(StaplerRequest req, JSONObject json) throws FormException {
req.bindJSON(this, json.getJSONObject("build-monitor"));
Expand All @@ -53,4 +81,4 @@ public boolean getPermissionToCollectAnonymousUsageStatistics() {
public void setPermissionToCollectAnonymousUsageStatistics(boolean collect) {
this.permissionToCollectAnonymousUsageStatistics = collect;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ public String getCsrfCrumbFieldName() {
public String currentOrder() {
return currentConfig().getOrder().getClass().getSimpleName();
}

@SuppressWarnings("unused") // used in the configure-entries.jelly form
public String currentbuildFailureAnalyzerDisplayedField() {
return currentConfig().getBuildFailureAnalyzerDisplayedField().getValue();
Expand All @@ -96,6 +96,26 @@ public boolean isDisplayCommitters() {
return currentConfig().shouldDisplayCommitters();
}

@SuppressWarnings("unused") // used in the configure-entries.jelly form
public String currentFontSize() {
return String.valueOf(currentConfig().getFontSize());
}

@SuppressWarnings("unused") // used in the configure-entries.jelly form
public String currentNumberOfColumns() {
return String.valueOf(currentConfig().getNumberOfColumns());
}

@SuppressWarnings("unused") // used in the configure-entries.jelly form
public boolean isColourBlindMode() {
return currentConfig().isColourBlindMode();
}

@SuppressWarnings("unused") // used in the configure-entries.jelly form
public String getColourBlindModeValue() {
return isColourBlindMode() ? "1" : "0";
}

private static final BuildMonitorInstallation installation = new BuildMonitorInstallation();

@SuppressWarnings("unused") // used in index.jelly
Expand All @@ -121,7 +141,9 @@ protected void submit(StaplerRequest req) throws ServletException, IOException,

currentConfig().setDisplayCommitters(json.optBoolean("displayCommitters", true));
currentConfig().setBuildFailureAnalyzerDisplayedField(req.getParameter("buildFailureAnalyzerDisplayedField"));

submitFontSize(req);
submitNumberOfColumns(req);
submitColourBlindMode(req);
try {
currentConfig().setOrder(orderIn(requestedOrdering));
} catch (Exception e) {
Expand All @@ -130,12 +152,42 @@ protected void submit(StaplerRequest req) throws ServletException, IOException,
}
}

private void submitFontSize(StaplerRequest req) throws FormException {
String fontSize = req.getParameter("fontSize");
try {
float val = Float.parseFloat(fontSize);
if (val >= 0.3 && val <= 2) {
currentConfig().setFontSize(val);
}
} catch (NumberFormatException e) {
throw new FormException("Font size must be float and not null", fontSize);
}
}


private void submitNumberOfColumns(StaplerRequest req) throws FormException {
String numberOfColumns = req.getParameter("numberOfColumns");
try {
int val = Integer.parseInt(numberOfColumns);
if (val >= 1 && val <= 8) {
currentConfig().setNumberOfColumns(val);
}
} catch (NumberFormatException e) {
throw new FormException("Number of columns must be integer and not null", numberOfColumns);
}
}

private void submitColourBlindMode(StaplerRequest req) throws FormException {
String colourBlindMode = req.getParameter("colourBlindMode");
currentConfig().setColourBlindMode(isGiven(colourBlindMode));
}

/**
* Because of how org.kohsuke.stapler.HttpResponseRenderer is implemented
* it can only work with net.sf.JSONObject in order to produce correct application/json output
*
* @return Json representation of JobViews
* @throws Exception
* @throws Exception description
*/
@JavaScriptMethod
public JSONObject fetchJobViews() throws Exception {
Expand Down Expand Up @@ -196,7 +248,7 @@ private boolean deserailisingFromAnOlderFormat() {

// If an older version of config.xml is loaded, "config" field is missing, but "order" is present
private void migrateFromOldToNewConfigFormat() {
Config c = new Config();
Config c = Config.defaultConfig();
c.setOrder(order);

config = c;
Expand All @@ -214,4 +266,4 @@ private void migrateFromOldToNewConfigFormat() {

@Deprecated // use Config instead
private Comparator<Job<?, ?>> order; // note: this field can be removed when people stop using versions prior to 1.6+build.150
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,11 @@ public class Config {
private BuildFailureAnalyzerDisplayedField buildFailureAnalyzerDisplayedField;

public static Config defaultConfig() {
return new Config();
Config config = new Config();
config.setFontSize(1);
config.setNumberOfColumns(2);
config.setColourBlindMode(false);
return config;
}

public Comparator<Job<?, ?>> getOrder() {
Expand All @@ -32,7 +36,31 @@ public static Config defaultConfig() {
public void setOrder(Comparator<Job<?, ?>> order) {
this.order = order;
}


public float getFontSize() {
return fontSize;
}

public void setFontSize(float fontSize) {
this.fontSize = fontSize;
}

public int getNumberOfColumns() {
return numberOfColumns;
}

public void setNumberOfColumns(int numberOfColumns) {
this.numberOfColumns = numberOfColumns;
}

public boolean isColourBlindMode() {
return colourBlindMode;
}

public void setColourBlindMode(boolean colourBlindMode) {
this.colourBlindMode = colourBlindMode;
}

public BuildFailureAnalyzerDisplayedField getBuildFailureAnalyzerDisplayedField() {
return getOrElse(buildFailureAnalyzerDisplayedField, BuildFailureAnalyzerDisplayedField.Name);
}
Expand Down Expand Up @@ -75,4 +103,11 @@ public enum BuildFailureAnalyzerDisplayedField {
}

private Comparator<Job<?, ?>> order;
}

private float fontSize;

private int numberOfColumns;

private boolean colourBlindMode;

}
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ public class NullSafety {
/**
* @param value a value that can be a potential null
* @param defaultValue a default to be returned if the value is null
* @param <T> a type
*
* @return either value or defaultValue
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ public BuildMonitorInstallation(StaticJenkinsAPIs jenkinsAPIs) {
/**
* Used to make sure that the anonymous Build Monitor stats are not double-counted,
* as in a typical setup there's one Jenkins, but multiple Build Monitors.
* @return anonymous Correlation Id
*/
public String anonymousCorrelationId() {
// we only need to calculate this once
Expand All @@ -48,4 +49,4 @@ public Audience audience() {
public String buildMonitorVersion() {
return buildProperties.get("version");
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,18 @@
</select>
</f:entry>

<f:entry title="${%Font size}">
<f:textbox name="fontSize" field="fontSize" value="${it.currentFontSize()}" />
</f:entry>

<f:entry title="${%Number of columns}">
<f:textbox name="numberOfColumns" field="numberOfColumns" value="${it.currentNumberOfColumns()}" />
</f:entry>

<f:entry title="${%Colour blind mode ?}">
<f:checkbox name="colourBlindMode" checked="${it.isColourBlindMode()}"/>
</f:entry>

</f:section>

<f:section title="${%Build Monitor - Widget Settings}">
Expand Down Expand Up @@ -98,4 +110,4 @@
}());
</script>

</j:jelly>
</j:jelly>
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,9 @@

constant('BUILD_MONITOR_VERSION', '${it.installation.buildMonitorVersion()}').
constant('CSRF_CRUMB_FIELD_NAME', '${it.csrfCrumbFieldName}').
constant('DEFAULT_SETTINGS_FONTSIZE', '${it.currentFontSize()}').
constant('DEFAULT_SETTINGS_NUMBEROFCOLUMNS', '${it.currentNumberOfColumns()}').
constant('DEFAULT_SETTINGS_COLOURBLINDMODE', '${it.getColourBlindModeValue()}').

config(function(proxyProvider, cookieJarProvider, hashCodeProvider) {
var hashCodeOf = hashCodeProvider.hashCodeOf;
Expand Down
13 changes: 8 additions & 5 deletions build-monitor-plugin/src/main/webapp/scripts/settings.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,15 @@ angular.
module('buildMonitor.settings', [ 'buildMonitor.services', 'rzModule']).

controller('controlPanel', ['$scope', 'cookieJar', 'townCrier',
function ($scope, cookieJar, townCrier) {
'DEFAULT_SETTINGS_FONTSIZE', 'DEFAULT_SETTINGS_NUMBEROFCOLUMNS',
'DEFAULT_SETTINGS_COLOURBLINDMODE',
function ($scope, cookieJar, townCrier, DEFAULT_SETTINGS_FONTSIZE,
DEFAULT_SETTINGS_NUMBEROFCOLUMNS, DEFAULT_SETTINGS_COLOURBLINDMODE) {
'use strict';

$scope.settings.fontSize = cookieJar.get('fontSize', 1);
$scope.settings.numberOfColumns = cookieJar.get('numberOfColumns', 2);
$scope.settings.colourBlind = cookieJar.get('colourBlind', 0);
$scope.settings.fontSize = cookieJar.get('fontSize', DEFAULT_SETTINGS_FONTSIZE);
$scope.settings.numberOfColumns = cookieJar.get('numberOfColumns', DEFAULT_SETTINGS_NUMBEROFCOLUMNS);
$scope.settings.colourBlind = cookieJar.get('colourBlind', DEFAULT_SETTINGS_COLOURBLINDMODE);
$scope.settings.reduceMotion = cookieJar.get('reduceMotion', 0);
$scope.settings.showBadges = cookieJar.get('showBadges', 0);

Expand All @@ -21,4 +24,4 @@ angular.
townCrier.uponNewVersion(function() {
$scope.newVersionAvailable = true;
});
}]);
}]);
Original file line number Diff line number Diff line change
Expand Up @@ -40,11 +40,73 @@ public void form_validator_should_advise_how_a_regex_could_be_improved() throws
assertThat(htmlDecoded(result.getMessage()), containsString("Unmatched closing ')'"));
}

@Test
public void form_validator_should_allow_fontsize_in_good_range() throws Exception {
FormValidation result = validator.doCheckFontSize("1.0");

assertThat(result.kind, is(OK));
}

@Test
public void form_validator_should_refuse_fontsize_under_0_3() throws Exception {
FormValidation result = validator.doCheckFontSize("0");

assertThat(result.kind, is(ERROR));
assertThat(htmlDecoded(result.getMessage()), containsString("Must be >= 0.3 and <= 2"));
}

@Test
public void form_validator_should_refuse_fontsize_over_2() throws Exception {
FormValidation result = validator.doCheckFontSize("2.1");

assertThat(result.kind, is(ERROR));
assertThat(htmlDecoded(result.getMessage()), containsString("Must be >= 0.3 and <= 2"));
}

@Test
public void form_validator_should_refuse_fontsize_not_float() throws Exception {
FormValidation result = validator.doCheckFontSize("a");

assertThat(result.kind, is(ERROR));
assertThat(htmlDecoded(result.getMessage()), containsString("Must be float"));
}

@Test
public void form_validator_should_allow_numberofcolumns_in_good_range() throws Exception {
FormValidation result = validator.doCheckNumberOfColumns("1");

assertThat(result.kind, is(OK));
}

@Test
public void form_validator_should_refuse_numberofcolumns_under_1() throws Exception {
FormValidation result = validator.doCheckNumberOfColumns("0");

assertThat(result.kind, is(ERROR));
assertThat(htmlDecoded(result.getMessage()), containsString("Must be >= 1 and <= 8"));
}

@Test
public void form_validator_should_refuse_numberofcolumns_over_8() throws Exception {
FormValidation result = validator.doCheckNumberOfColumns("10");

assertThat(result.kind, is(ERROR));
assertThat(htmlDecoded(result.getMessage()), containsString("Must be >= 1 and <= 8"));
}

@Test
public void form_validator_should_refuse_numberofcolumns_not_integer() throws Exception {
FormValidation result = validator.doCheckNumberOfColumns("a");

assertThat(result.kind, is(ERROR));
assertThat(htmlDecoded(result.getMessage()), containsString("Must be integer"));
}

private String htmlDecoded(String message) {
return StringEscapeUtils.unescapeHtml(message);
}

private String itShouldAllow(String regex) {
return "should allow " + regex;
}
}
}
Loading

0 comments on commit 908e466

Please sign in to comment.