Allow users to disable zuul-status with a button

Change-Id: Ibcf369849eedc8799cd1e61416f97848344e5d3e
diff --git a/src/main/resources/static/zuul-status-view.html b/src/main/resources/static/zuul-status-view.html
index f6f972b..a6063b9 100644
--- a/src/main/resources/static/zuul-status-view.html
+++ b/src/main/resources/static/zuul-status-view.html
@@ -139,50 +139,60 @@
           <div class="container">
             <h3 class="labelName">[[_computeTitle(_response)]]</h3>
           </div>
+          <div class="container">
+            <template is="dom-if" if="[[!zuulDisable]]" restamp="true">
+              <gr-button link on-tap="_handleDisableZuulStatus">Disable Zuul Status</gr-button>
+            </template>
+            <template is="dom-if" if="[[zuulDisable]]" restamp="true">
+              <gr-button link on-tap="_handleEnableZuulStatus">Enable Zuul Status</gr-button>
+            </template>
+          </div>
         </div>
-        <div class="bottom container">
-          <table id="list" class="genericList">
-            <tr class="headerRow">
-              <th class="pipeline topHeader">Pipeline</th>
-              <th class="jobName topHeader">Job Name</th>
-              <th class="progressName topHeader">Progress</th>
-            </tr>
-            <tbody>
-              <template is="dom-repeat" items=[[_response]] as="response">
-                <template is="dom-repeat" items=[[response.jobs]] as="jobs">
-                  <tr class="table">
-                    <td class="pipeline">
-                      [[jobs.pipeline]]
-                    </td>
-                    <td class="jobName">
-                      <a href="[[_computeReportURL(jobs)]]" target="_blank"
-                         hidden$="[[!jobs.name]]">
-                        [[jobs.name]]
-                      </a>
-                    </td>
-                    <td class="progressName">
-                      <template is="dom-if" if="[[_getResults(jobs, 'true', 'in progress')]]">
-                        <div class="progress zuul-job-result">
-                          <div class="progress-bar"
-                            id="progressBar"
-                            role="progressbar"
-                            aria-valuenow$="[[_progressPercent(jobs)]]"
-                            aria-valuemin="0"
-                            aria-valuemax="100"></div>
-                        </div>
-                      </template>
-                      <template is="dom-if" if="[[!_getResults(jobs, 'true', 'in progress')]]">
-                        <span class$="zuul-job-result label [[_renderJobStatusLabel(jobs)]]">
-                          [[_getResults(jobs)]]
-                        </span>
-                      </template>
-                    </td>
-                  </tr>
+        <template is="dom-if" if="[[!zuulDisable]]" restamp="true">
+          <div class="bottom container">
+            <table id="list" class="genericList">
+              <tr class="headerRow">
+                <th class="pipeline topHeader">Pipeline</th>
+                <th class="jobName topHeader">Job Name</th>
+                <th class="progressName topHeader">Progress</th>
+              </tr>
+              <tbody>
+                <template is="dom-repeat" items=[[_response]] as="response">
+                  <template is="dom-repeat" items=[[response.jobs]] as="jobs">
+                    <tr class="table">
+                      <td class="pipeline">
+                        [[jobs.pipeline]]
+                      </td>
+                      <td class="jobName">
+                        <a href="[[_computeReportURL(jobs)]]" target="_blank"
+                           hidden$="[[!jobs.name]]">
+                          [[jobs.name]]
+                        </a>
+                      </td>
+                      <td class="progressName">
+                        <template is="dom-if" if="[[_getResults(jobs, 'true', 'in progress')]]">
+                          <div class="progress zuul-job-result">
+                            <div class="progress-bar"
+                              id="progressBar"
+                              role="progressbar"
+                              aria-valuenow$="[[_progressPercent(jobs)]]"
+                              aria-valuemin="0"
+                              aria-valuemax="100"></div>
+                          </div>
+                        </template>
+                        <template is="dom-if" if="[[!_getResults(jobs, 'true', 'in progress')]]">
+                          <span class$="zuul-job-result label [[_renderJobStatusLabel(jobs)]]">
+                            [[_getResults(jobs)]]
+                          </span>
+                        </template>
+                      </td>
+                    </tr>
+                  </template>
                 </template>
-              </template>
-            </tbody>
-          </table>
-        </div>
+              </tbody>
+            </table>
+          </div>
+        </template>
       </div>
     </template>
   </template>
diff --git a/src/main/resources/static/zuul-status-view.js b/src/main/resources/static/zuul-status-view.js
index 10c079a..de873ae 100644
--- a/src/main/resources/static/zuul-status-view.js
+++ b/src/main/resources/static/zuul-status-view.js
@@ -17,6 +17,44 @@
  (function() {
   'use strict';
 
+  /**
+   * Wrapper around localStorage to prevent using it if you have it disabled.
+   *
+   * Temporary until https://gerrit-review.googlesource.com/c/gerrit/+/211472 is merged.
+   *
+   */
+  class ZuulSiteBasedStorage {
+    // Returns the local storage.
+    _storage() {
+      try {
+        return window.localStorage;
+      } catch (err) {
+        console.error('localStorage is disabled with this error ' + err);
+        return null;
+      }
+    }
+
+    getItem(key) {
+      if (this._storage() === null) { return null; }
+      return this._storage().getItem(key);
+    }
+
+    setItem(key, value) {
+      if (this._storage() === null) { return null; }
+      return this._storage().setItem(key, value);
+    }
+
+    removeItem(key) {
+      if (this._storage() === null) { return null; }
+      return this._storage().removeItem(key);
+    }
+
+    clear() {
+      if (this._storage() === null) { return null; }
+      return this._storage().clear();
+    }
+  }
+
   const DEFAULT_UPDATE_INTERVAL_MS = 1000 * 2;
   const MAX_UPDATE_INTERVAL_MS = 1000 * 30 * 2;
 
@@ -43,6 +81,14 @@
       // used to determine how long we've been trying to update.
       _startTime: Date,
       _updateTimeoutID: Number,
+      _storage: {
+        type: Object,
+        value: new ZuulSiteBasedStorage(),
+      },
+      zuulDisable: {
+        type: Boolean,
+        value: false,
+      }
     },
 
     attached() {
@@ -66,6 +112,12 @@
       this._response = null;
       this._startTime = new Date();
 
+      if (this._storage.getItem('disable_zuul_status')) {
+        this.set('zuulDisable', true);
+      } else {
+        this.set('zuulDisable', false);
+      }
+
       const config = await this.getConfig();
       if (config && config.zuul_url) {
         this.zuulUrl = config.zuul_url;
@@ -265,5 +317,17 @@
 
       return className;
     },
+
+    _handleDisableZuulStatus(e) {
+      this._storage.setItem('disable_zuul_status', 'yes');
+
+      this.reload();
+    },
+
+    _handleEnableZuulStatus(e) {
+      this._storage.removeItem('disable_zuul_status');
+
+      this.reload();
+    },
   });
 })();