Merge "Add checker description and checker message to the checks table"
diff --git a/gr-checks/gr-checks-item.html b/gr-checks/gr-checks-item.html
index 64a061b..602cffb 100644
--- a/gr-checks/gr-checks-item.html
+++ b/gr-checks/gr-checks-item.html
@@ -18,8 +18,17 @@
         margin-right: 16px;
         display: inline-block;
       }
+      .nav-icon {
+        cursor: pointer;
+      }
     </style>
-
+    <td>
+      <template is="dom-if" if="[[check.message]]">
+          <iron-icon class="nav-icon" on-tap="_toggleMessageShown"
+            icon="[[_computeExpandIcon(showCheckMessage)]]">
+          </iron-icon>
+      </template>
+    </td>
     <td>[[check.checker_name]]</td>
     <td>[[_requiredForMerge]]</td>
     <td>
@@ -42,6 +51,7 @@
 <!--          Re-run-->
 <!--        </gr-button>-->
       </td>
+      <td>[[check.checker_description]]</td>
   </template>
   <script src="gr-checks-item.js"></script>
 </dom-module>
diff --git a/gr-checks/gr-checks-item.js b/gr-checks/gr-checks-item.js
index 199fc92..2c0d98b 100644
--- a/gr-checks/gr-checks-item.js
+++ b/gr-checks/gr-checks-item.js
@@ -41,6 +41,10 @@
       _requiredForMerge: {
         type: String,
         computed: '_computeRequiredForMerge(check)'
+      },
+      showCheckMessage: {
+        type: Boolean,
+        value: false,
       }
     },
 
@@ -53,6 +57,15 @@
       return moment(check.started).format('LTS');
     },
 
+    _toggleMessageShown() {
+      this.showCheckMessage = !this.showCheckMessage;
+      this.fire('toggle-check-message', {uuid: this.check.checker_uuid})
+    },
+
+    _computeExpandIcon(showCheckMessage) {
+      return showCheckMessage ? "gr-icons:expand-less": "gr-icons:expand-more";
+    },
+
     /**
      * @param {!Defs.Check} check
      * @return {string}
diff --git a/gr-checks/gr-checks-view.html b/gr-checks/gr-checks-view.html
index 67129ee..8a771c3 100644
--- a/gr-checks/gr-checks-view.html
+++ b/gr-checks/gr-checks-view.html
@@ -61,6 +61,29 @@
         padding: 24px 0;
         text-align: center;
       }
+
+      /* Add max-width 1px to check-message make sure content doesn't
+         expand beyond the table width */
+      .check-message {
+        padding-left: 1rem;
+        background: var(--table-subheader-background-color);
+        max-width: 1px;
+      }
+
+      .message {
+        white-space: pre-wrap;
+        word-wrap: break-word;
+      }
+
+      .message-heading {
+        font-weight: bold;
+        margin-top: 1em;
+      }
+
+      .check-message-heading {
+        padding-left: 1em;
+      }
+
     </style>
 
     <template is="dom-if" if="[[_isLoading(_status)]]">
@@ -91,6 +114,7 @@
       <table>
         <thead>
           <tr class="headerRow">
+            <th class="topHeader"></th>
             <th class="topHeader">Name</th>
             <th class="topHeader">For submit</th>
             <th class="topHeader">Status</th>
@@ -98,11 +122,30 @@
             <th class="topHeader">Started</th>
             <th class="topHeader">Duration</th>
             <th class="topHeader"><!-- actions --></th>
+            <th class="topHeader">Description</th>
           </tr>
         </thead>
         <tbody>
           <template is="dom-repeat" items="[[_checks]]" as="check">
-            <gr-checks-item check="[[check]]" retry-check="[[retryCheck]]"></gr-checks-item>
+            <tr>
+              <gr-checks-item on-toggle-check-message="_toggleCheckMessage"
+                check="[[check]]" retry-check="[[retryCheck]]">
+              </gr-checks-item>
+            </tr>
+            <template is="dom-if" if="[[check.showCheckMessage]]">
+              <tr>
+                <td colspan="9" class="check-message-heading">
+                  <span class="message-heading">
+                    Message
+                  </span>
+                </td>
+              </tr>
+              <tr>
+                <td colspan="9" class="check-message">
+                  <span class="message"> [[check.message]] </span>
+                </td>
+              </tr>
+            </template>
           </template>
         </tbody>
       </table>
diff --git a/gr-checks/gr-checks-view.js b/gr-checks/gr-checks-view.js
index f5d083f..bf28841 100644
--- a/gr-checks/gr-checks-view.js
+++ b/gr-checks/gr-checks-view.js
@@ -95,7 +95,20 @@
       getChecks(change._number, revision._number).then(checks => {
         if (checks && checks.length) {
           checks.sort(this._orderChecks);
-          this.set('_checks', checks);
+          if (!this._checks) {
+            this._checks = checks;
+          } else {
+            // Merge checks & this_checks to keep showCheckMessage property
+            this._checks = checks.map(
+              (check) => {
+                const prevCheck = this._checks.find(
+                  (c) => { return c.checker_uuid === check.checker_uuid }
+                )
+                if (!prevCheck) return check;
+                return Object.assign({}, check, prevCheck)
+              }
+            )
+          }
           this.set('_status', LoadingStatus.RESULTS);
         } else {
           this._checkConfigured();
@@ -111,6 +124,22 @@
       this._pollChecksRegularly(this.change, this.revision, this.getChecks);
     },
 
+    _toggleCheckMessage(e) {
+      const uuid = e.detail.uuid;
+      if (!uuid) {
+        console.warn("uuid not found");
+        return;
+      }
+      const idx = this._checks.findIndex(check => check.checker_uuid === uuid);
+      if (idx == -1) {
+        console.warn("check not found");
+        return;
+      }
+      // Update subproperty of _checks[idx] so that it reflects to polymer
+      this.set(`_checks.${idx}.showCheckMessage`,
+        !this._checks[idx].showCheckMessage)
+    },
+
     _pollChecksRegularly(change, revision, getChecks) {
       if (this.pollChecksInterval) {
         clearInterval(this.pollChecksInterval);