Add configurable support for in-progress status

With long CI pipelines it's hard to detect the current pipeline
status with only passed,failed and unstable statuses. For instance if
jobs are re-triggered within the same patchset there is no easy way to
show this as we are still limited to only current three statuses but
they are not relevant if task is still in progress.
This change introduces config option enableInProgressStatus to enable
visualization of new 'in-progress' status. It has its own gif icon
shown in the same place as other statuses. If option is set to 'true'
in-progress status will be shown for all jobs reported with value=2.
By default the option is set to 'false' and nothing is changed then
comparing to current behavior.
Usage example:
  [plugin "verify-status"]
     enableInProgressStatus = true

loading.gif icon has been generated using http://ajaxload.info/
  type: snake
  background: transparent
  foreground: #666666

Change-Id: I34cebc03c33ab0c55ff4079031b734d48f25765e
Signed-off-by: Sergii Kipot <kipot.sergey@gmail.com>
diff --git a/src/main/java/com/googlesource/gerrit/plugins/verifystatus/client/ConfigInfo.java b/src/main/java/com/googlesource/gerrit/plugins/verifystatus/client/ConfigInfo.java
index 593506f..731da60 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/verifystatus/client/ConfigInfo.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/verifystatus/client/ConfigInfo.java
@@ -21,6 +21,7 @@
   final native boolean showJobsPanel() /*-{ return this.show_jobs_panel ? true : false; }-*/;
   final native boolean showJobsDropDownPanel() /*-{ return this.show_jobs_drop_down_panel ? true : false; }-*/;
   final native boolean showJobsBelowRelatedInfoBlock() /*-{ return this.show_jobs_below_related_info_block ? true : false; }-*/;
+  final native boolean enableInProgressStatus() /*-{ return this.enable_in_progress_status ? true : false; }-*/;
   final native String sortJobsPanel() /*-{ return this.sort_jobs_panel }-*/;
   final native String sortJobsDropDownPanel() /*-{ return this.sort_jobs_drop_down_panel }-*/;
 
@@ -28,6 +29,7 @@
   final native void setShowJobsPanel(boolean s) /*-{ this.show_jobs_panel = s; }-*/;
   final native void setShowJobsDropDownPanel(boolean s) /*-{ this.show_jobs_drop_down_panel = s; }-*/;
   final native void setShowJobsBelowRelatedInfoBlock(boolean s) /*-{ this.show_jobs_below_related_info_block = s; }-*/;
+  final native void setEnableInProgressStatus() /*-{ this.enable_in_progress_status = s; }-*/;
   final native void setSortJobsPanel(String s) /*-{ this.sort_jobs_panel = s; }-*/;
   final native void setSortJobsDropDownPanel(String s) /*-{ this.sort_jobs_drop_down_panel = s; }-*/;
 
diff --git a/src/main/java/com/googlesource/gerrit/plugins/verifystatus/client/JobsPanel.java b/src/main/java/com/googlesource/gerrit/plugins/verifystatus/client/JobsPanel.java
index 1902487..a2d7724 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/verifystatus/client/JobsPanel.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/verifystatus/client/JobsPanel.java
@@ -35,6 +35,7 @@
  * Extension for change screen that displays a status below the label info.
  */
 public class JobsPanel extends FlowPanel {
+  private final ConfigInfo info;
   static class Factory implements Panel.EntryPoint {
     private final ConfigInfo info;
 
@@ -55,6 +56,7 @@
   }
 
   JobsPanel(Panel panel, ConfigInfo info) {
+    this.info = info;
     final ChangeInfo change =
         panel.getObject(GerritUiExtensionPoint.Key.CHANGE_INFO).cast();
     String decodedChangeId = URL.decodePathSegment(change.id());
@@ -88,7 +90,11 @@
       HorizontalPanel p = new HorizontalPanel();
       short vote = jobs.get(key).value();
       if (vote > 0) {
-        p.add(new Image(VerifyStatusPlugin.RESOURCES.greenCheck()));
+        p.add(new Image(
+                ((vote == 2) && info.enableInProgressStatus())
+                    ? VerifyStatusPlugin.RESOURCES.progress()
+                    : VerifyStatusPlugin.RESOURCES.greenCheck()
+                ));
       } else if (vote < 0) {
         p.add(new Image(VerifyStatusPlugin.RESOURCES.redNot()));
       } else if (vote == 0) {
diff --git a/src/main/java/com/googlesource/gerrit/plugins/verifystatus/client/Resources.java b/src/main/java/com/googlesource/gerrit/plugins/verifystatus/client/Resources.java
index 2ac8b97..358c033 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/verifystatus/client/Resources.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/verifystatus/client/Resources.java
@@ -37,4 +37,7 @@
   @Source("donut.png")
   public ImageResource rerun();
 
+  @Source("loader.gif")
+  public ImageResource progress();
+
 }
diff --git a/src/main/java/com/googlesource/gerrit/plugins/verifystatus/client/loader.gif b/src/main/java/com/googlesource/gerrit/plugins/verifystatus/client/loader.gif
new file mode 100644
index 0000000..e40f19a
--- /dev/null
+++ b/src/main/java/com/googlesource/gerrit/plugins/verifystatus/client/loader.gif
Binary files differ
diff --git a/src/main/java/com/googlesource/gerrit/plugins/verifystatus/server/GetConfig.java b/src/main/java/com/googlesource/gerrit/plugins/verifystatus/server/GetConfig.java
index 8d9368c..d1e5cf2 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/verifystatus/server/GetConfig.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/verifystatus/server/GetConfig.java
@@ -39,6 +39,8 @@
     info.showJobsSummaryPanel = cfg.getBoolean("showJobsSummaryPanel", true);
     info.showJobsBelowRelatedInfoBlock = cfg.getBoolean(
         "showJobsBelowRelatedInfoBlock", false);
+    info.enableInProgressStatus = cfg.getBoolean(
+        "enableInProgressStatus", false);
     info.sortJobsPanel = cfg.getEnum(JobsSorting.values(),
         "sortJobsPanel", JobsSorting.REPORTER);
     info.sortJobsDropDownPanel = cfg.getEnum(JobsSorting.values(),
@@ -51,6 +53,7 @@
     Boolean showJobsDropDownPanel;
     Boolean showJobsSummaryPanel;
     Boolean showJobsBelowRelatedInfoBlock;
+    Boolean enableInProgressStatus;
     JobsSorting sortJobsPanel;
     JobsSorting sortJobsDropDownPanel;
   }
diff --git a/src/main/java/com/googlesource/gerrit/plugins/verifystatus/server/PutConfig.java b/src/main/java/com/googlesource/gerrit/plugins/verifystatus/server/PutConfig.java
index 3748b3b..d7304d3 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/verifystatus/server/PutConfig.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/verifystatus/server/PutConfig.java
@@ -42,6 +42,7 @@
     public Boolean showJobsDropDownPanel;
     public Boolean showJobsSummaryPanel;
     public Boolean showJobsBelowRelatedInfoBlock;
+    public Boolean enableInProgressStatus;
     public String sortJobsPanel;
     public String sortJobsDropDownPanel;
   }
@@ -93,6 +94,12 @@
     } else {
       cfg.unset("plugin", pluginName, "showJobsBelowRelatedInfoBlock");
     }
+    if (input.enableInProgressStatus != null) {
+      cfg.setBoolean("plugin", pluginName, "enableInProgressStatus",
+          input.enableInProgressStatus);
+    } else {
+      cfg.unset("plugin", pluginName, "enableInProgressStatus");
+    }
     if (input.sortJobsPanel != null) {
       cfg.setEnum("plugin", pluginName, "sortJobsPanel",
           JobsSorting.valueOf(input.sortJobsPanel));
diff --git a/src/main/resources/Documentation/about.md b/src/main/resources/Documentation/about.md
index e569344..d037730 100644
--- a/src/main/resources/Documentation/about.md
+++ b/src/main/resources/Documentation/about.md
@@ -72,13 +72,25 @@
 |:------------- |:-------|
 |less than 0    |Failed  |
 |0              |Unstable|
-|greater than 0 |Passed  |
+|1              |Passed  |
+|2              |In-progress if enableInProgressStatus=true, otherwise Passed|
+|greater than 2 |Passed  |
 
 
 The information icon is an indicator that a job has abstained from voting
 (or is a non-voting job).  Abstaining typically indicates that a job's
 score may not factor into determining the combined vote.
 
+If enableInProgressStatus is true then the loading icon is an indicator that a job
+has been set with value 2 and identified as 'in progress'.
+_NOTE_: The Jenkins [Gerrit verify status reporter plugin] currently doesn't
+support in-progress or any equivalent status so enabling progress status makes
+sense only if one uses own postbuild/prebuild custom pipeline logic for setting
+statuses via API. For instance:
+1. In-progress status with value=2 is sent via API as the first step of the build.
+2. From postbuild section actual finish status is calculated in groovy script and
+is send via API.
+
 
 ### <a id="configure-panels"> @PLUGIN@ configure-panels
 
@@ -97,6 +109,7 @@
 |showJobsDropDownPanel         | Whether jobs drop down panel should be displayed (default to true)|
 |showJobsSummaryPanel          | Whether jobs summary panel should be displayed (default to true)|
 |showJobsBelowRelatedInfoBlock | Whether jobs panel should be positioned below related info block (default to false)|
+|enableInProgressStatus        | Whether value=2 should be treated as 'in progress' status (default to false)|
 |sortJobsPanel                 | The order of jobs sorting on jobs panel (REPORTER,NAME,DATE default to REPORTER). Both upper and lower cases are allowed.|
 |sortJobsDropDownPanel         | The order of jobs sorting on jobs drop down panel (REPORTER,NAME,DATE default to REPORTER). Both upper and lower cases are allowed.|
 
diff --git a/src/main/resources/Documentation/rest-api-config.md b/src/main/resources/Documentation/rest-api-config.md
index a897276..de16a62 100644
--- a/src/main/resources/Documentation/rest-api-config.md
+++ b/src/main/resources/Documentation/rest-api-config.md
@@ -73,6 +73,7 @@
 |show_jobs_drop_down_panel          | Whether jobs drop down panel should be displayed|
 |show_jobs_summary_panel            | Whether jobs summary panel should be displayed|
 |show_jobs_below_related_info_block | Whether jobs panel should be positioned below related info block|
+|enable_in_progress_status          | Whether value=2 should be treated as 'in progress' status|
 |sort_jobs_panel                    | The order of jobs sorting on jobs panel (REPORTER,NAME,DATE)|
 |sort_jobs_drop_down_panel          | The order of jobs sorting on jobs drop down panel (REPORTER,NAME,DATE)|