Add a popup for configuring checks as a top-level action

Bug: Issue 14336
Change-Id: I09ac406277f1f78c76b6263c9f4f86bb68445c4f
diff --git a/gr-checks/gr-checkers-list.js b/gr-checks/gr-checkers-list.js
index da61b22..1cceb61 100644
--- a/gr-checks/gr-checkers-list.js
+++ b/gr-checks/gr-checkers-list.js
@@ -26,7 +26,7 @@
 class GrCheckersList extends Polymer.GestureEventListeners(
     Polymer.LegacyElementMixin(
         Polymer.Element)) {
-/** @returns {?} template for this component */
+  /** @returns {?} template for this component */
   static get template() { return htmlTemplate; }
 
   /** @returns {string} name of the component */
@@ -39,12 +39,12 @@
    */
   static get properties() {
     return {
-      /**
-       * Add observer on pluginRestApi to call getCheckers when it's defined
-       * as initially getCheckers was being called before pluginRestApi was
-       * initialised by gr-checks-view
-       */
+      // This is set by the PopupPluginApi.
+      plugin: {
+        type: Object,
+      },
       pluginRestApi: {
+        computed: '_computePluginRestApi(plugin)',
         type: Object,
       },
       // Checker that will be passed to the editOverlay modal
@@ -89,47 +89,18 @@
   static get observers() {
     return [
       '_showCheckers(_checkers, _filter)',
+      '_getCheckers(plugin)',
     ];
   }
 
-  attached() {
-    super.attached();
-    /**
-     * Adding an observer to listBody element as gr-overlay does not
-     * automatically resize itself once the getCheckers response comes.
-     * Polymer 2 will deprecate use of obserNodes so replacing it
-     * with FlattenedNodesObserver
-     */
-    if (Polymer.FlattenedNodesObserver) {
-      this._checkersListObserver = new Polymer.FlattenedNodesObserver(
-          this.$.listBody, () => {
-            this.$.listOverlay.refit();
-          });
-    } else {
-      this._checkersListObserver = Polymer.dom(this.$.listBody).observeNodes(
-          () => {
-            this.$.listOverlay.refit();
-          });
-    }
-  }
-
-  detached() {
-    super.detached();
-    Polymer.dom(this.$.listBody).unobserveNodes(this._checkersListObserver);
+  _computePluginRestApi(plugin) {
+    return plugin ? plugin.restApi() : undefined;
   }
 
   _contains(target, keyword) {
     return target.toLowerCase().includes(keyword.toLowerCase().trim());
   }
 
-  _showConfigureOverlay() {
-    this.$.listOverlay.open().then(
-        () => {
-          this._getCheckers();
-        }
-    );
-  }
-
   _showCheckers(_checkers, _filter) {
     if (!_checkers) return;
     if (!_filter) _filter = '';
@@ -179,9 +150,9 @@
     }
   }
 
-  _getCheckers() {
-    if (!this.pluginRestApi) return;
-    this.pluginRestApi.get(GET_CHECKERS_URL).then(checkers => {
+  _getCheckers(plugin) {
+    if (!plugin) return;
+    plugin.restApi().get(GET_CHECKERS_URL).then(checkers => {
       if (!checkers) { return; }
       this._checkers = checkers;
       this._startingIndex = 0;
@@ -231,4 +202,4 @@
   }
 }
 
-customElements.define(GrCheckersList.is, GrCheckersList);
\ No newline at end of file
+customElements.define(GrCheckersList.is, GrCheckersList);
diff --git a/gr-checks/gr-checkers-list_html.js b/gr-checks/gr-checkers-list_html.js
index 19f224f..1e12723 100644
--- a/gr-checks/gr-checkers-list_html.js
+++ b/gr-checks/gr-checkers-list_html.js
@@ -19,6 +19,11 @@
     <style include="shared-styles"></style>
     <style include="gr-table-styles"></style>
     <style>
+      #container {
+        width: 80vw;
+        height: 80vh;
+        overflow: auto;
+      }
       iron-icon {
         cursor: pointer;
       }
@@ -63,14 +68,9 @@
         text-decoration: underline;
         cursor: pointer;
       }
-      #listOverlay {
-        max-width: 90%;
-        max-height: 90%;
-        overflow: auto;
-      }
     </style>
 
-    <gr-overlay on-fullscreen-overlay-closed="_handleOverlayClosed" id="listOverlay" with-backdrop>
+    <div id="container">
       <div id="topContainer">
         <div>
           <label>Filter:</label>
@@ -133,43 +133,41 @@
           </a>
         </template>
       </nav>
-
-      <gr-overlay id="createOverlay">
-        <gr-dialog
-            id="createDialog"
-            confirm-label="Create"
-            on-confirm="_handleCreateConfirm"
-            on-cancel="_handleCreateCancel">
-          <div class="header" slot="header">
-            Create Checkers
-          </div>
-          <div slot="main">
-            <gr-create-checkers-dialog
-              id="createNewModal"
-              plugin-rest-api="[[pluginRestApi]]">
-            </gr-create-checkers-dialog>
-          </div>
-        </gr-dialog>
-      </gr-overlay>
-      <gr-overlay id="editOverlay">
-        <gr-dialog
-            id="editDialog"
-            confirm-label="Save"
-            on-confirm="_handleEditConfirm"
-            on-cancel="_handleEditCancel">
-          <div class="header" slot="header">
-            Edit Checker
-          </div>
-          <div slot="main">
-            <gr-create-checkers-dialog
-                checker="[[checker]]"
-                plugin-rest-api="[[pluginRestApi]]"
-                on-cancel="_handleEditCancel"
-                id="editModal">
-            </gr-create-checkers-dialog>
-          </div>
-        </gr-dialog>
-      </gr-overlay>
+    </div>
+    <gr-overlay id="createOverlay">
+      <gr-dialog
+          id="createDialog"
+          confirm-label="Create"
+          on-confirm="_handleCreateConfirm"
+          on-cancel="_handleCreateCancel">
+        <div class="header" slot="header">
+          Create Checkers
+        </div>
+        <div slot="main">
+          <gr-create-checkers-dialog
+            id="createNewModal"
+            plugin-rest-api="[[pluginRestApi]]">
+          </gr-create-checkers-dialog>
+        </div>
+      </gr-dialog>
     </gr-overlay>
-    <gr-rest-api-interface id="restAPI"></gr-rest-api-interface>
-`;
\ No newline at end of file
+    <gr-overlay id="editOverlay">
+      <gr-dialog
+          id="editDialog"
+          confirm-label="Save"
+          on-confirm="_handleEditConfirm"
+          on-cancel="_handleEditCancel">
+        <div class="header" slot="header">
+          Edit Checker
+        </div>
+        <div slot="main">
+          <gr-create-checkers-dialog
+              checker="[[checker]]"
+              plugin-rest-api="[[pluginRestApi]]"
+              on-cancel="_handleEditCancel"
+              id="editModal">
+          </gr-create-checkers-dialog>
+        </div>
+      </gr-dialog>
+    </gr-overlay>
+`;
diff --git a/gr-checks/gr-create-checkers-dialog_html.js b/gr-checks/gr-create-checkers-dialog_html.js
index ac75927..dcfd86f 100644
--- a/gr-checks/gr-create-checkers-dialog_html.js
+++ b/gr-checks/gr-create-checkers-dialog_html.js
@@ -170,5 +170,4 @@
 
       </div>
     </div>
-    <gr-rest-api-interface id="restAPI"></gr-rest-api-interface>
-`;
\ No newline at end of file
+`;
diff --git a/gr-checks/plugin.js b/gr-checks/plugin.js
index f8a0a35..dbf3d5a 100644
--- a/gr-checks/plugin.js
+++ b/gr-checks/plugin.js
@@ -14,11 +14,13 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+import './gr-checkers-list.js';
 import {computeDuration} from './util.js';
 
 class ChecksFetcher {
-  constructor(restApi) {
-    this.restApi = restApi;
+  constructor(plugin) {
+    this.plugin = plugin;
+    this.restApi = plugin.restApi();
   }
 
   async fetchCurrent() {
@@ -32,6 +34,10 @@
     const checks = await this.apiGet('?o=CHECKER');
     return {
       responseCode: 'OK',
+      actions: [{
+        name: 'Configure Checkers',
+        callback: () => this.plugin.popup('gr-checkers-list'),
+      }],
       runs: checks.map(check => this.convert(check)),
     };
   }
@@ -110,7 +116,7 @@
 
 Gerrit.install(plugin => {
   const checksApi = plugin.checks();
-  const fetcher = new ChecksFetcher(plugin.restApi());
+  const fetcher = new ChecksFetcher(plugin);
   checksApi.register({
     fetch: data => fetcher.fetch(data),
   });