Merge "Add message-id to emails sent by the checks plugin"
diff --git a/.eslintrc.json b/.eslintrc.json
index a43acc6..affb7c4 100644
--- a/.eslintrc.json
+++ b/.eslintrc.json
@@ -152,7 +152,7 @@
   },
   "overrides": [
     {
-      "files": ["*_html.js", "*-styles.js", "externs.js"],
+      "files": ["*_html.js", "*-styles.js"],
       "rules": {
         "max-len": "off"
       }
diff --git a/README.md b/README.md
index 06bed50..638a6a9 100644
--- a/README.md
+++ b/README.md
@@ -20,7 +20,7 @@
 ## Test plugin on Gerrit
 
 1. Build the bundle locally with: `bazel build gr-checks:gr-checks`
-2. Serve your generated 'checks.js' somewhere, you can put it under `gerrit/plugins/checks/` folder and it will automatically served at `http://localhost:8081/plugins_/checks/`
+2. Serve your generated 'checks.js' somewhere, you can put it under `gerrit/plugins/checks/` folder and it will automatically served at `http://localhost:8081/plugins_/checks/` (no need to pass it to --plugins flag)
 3. Use FE dev helper, https://gerrit.googlesource.com/gerrit-fe-dev-helper/, inject the local served 'checks.js' to the page
 
 If your plugin is already enabled, then you can block it and then inject the compiled local verison.
diff --git a/gr-checks/BUILD b/gr-checks/BUILD
index eaab31d..3889aae 100644
--- a/gr-checks/BUILD
+++ b/gr-checks/BUILD
@@ -21,6 +21,7 @@
     entry_point = "gr-checks.js",
     rollup_bin = "//tools/node_tools:rollup-bin",
     sourcemap = "hidden",
+    format = 'iife',
     deps = [
         "@tools_npm//rollup-plugin-node-resolve",
     ],
diff --git a/gr-checks/externs.js b/gr-checks/externs.js
deleted file mode 100644
index 73709b5..0000000
--- a/gr-checks/externs.js
+++ /dev/null
@@ -1,25 +0,0 @@
-/**
- * @license
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-/**
- * @fileoverview externs for global variables provided by Gerrit.
- * @externs
- * @suppress {duplicate,checkTypes}
- */
-
-/* eslint no-unused-vars: 0 */
-
-function moment() {}
\ No newline at end of file
diff --git a/gr-checks/gr-checks-chip-view.js b/gr-checks/gr-checks-chip-view.js
index 3ac4921..3415844 100644
--- a/gr-checks/gr-checks-chip-view.js
+++ b/gr-checks/gr-checks-chip-view.js
@@ -114,7 +114,11 @@
     </style>
     <template is="dom-if" if="[[_hasChecks]]">
       Checks:
-      <span class$="[[_chipClasses]]">
+      <span
+        class$="[[_chipClasses]]"
+        role="button"
+        aria-label="Open checks tab"
+      >
         <gr-checks-status
           status="[[_status]]"
           downgrade-failure-to-warning="[[_downgradeFailureToWarning]]">
@@ -186,6 +190,7 @@
               composed: true,
               detail: {
                 tab: 'change-view-tab-header-checks',
+                scrollIntoView: true,
               },
             })
     );
diff --git a/gr-checks/gr-checks-item.js b/gr-checks/gr-checks-item.js
index 4c7fbfd..494a330 100644
--- a/gr-checks/gr-checks-item.js
+++ b/gr-checks/gr-checks-item.js
@@ -181,10 +181,9 @@
     if (!check.started || !check.finished) {
       return '-';
     }
-    const startTime = moment(check.started);
-    const finishTime = check.finished ? moment(check.finished) : moment();
-    return generateDurationString(
-        moment.duration(finishTime.diff(startTime)));
+    const startTime = new Date(check.started);
+    const finishTime = check.finished ? new Date(check.finished) : new Date();
+    return generateDurationString(startTime, finishTime);
   }
 
   /**
@@ -211,34 +210,41 @@
 const ZERO_SECONDS = '0 sec';
 
 /**
- * @param {!Moment.Duration} duration a moment object
+ * @param {Date} startTime
+ * @param {Date} endTime
  * @return {string}
  */
-function generateDurationString(duration) {
-  if (duration.asSeconds() === 0) {
+function generateDurationString(startTime, endTime) {
+  const secondsAgo = Math.round((endTime - startTime) / 1000);
+
+  if (secondsAgo === 0) {
     return ZERO_SECONDS;
   }
 
   const durationSegments = [];
-  if (duration.months()) {
-    const months = pluralize(duration.months(), 'month', 'months');
-    durationSegments.push(`${duration.months()} ${months}`);
+  if (secondsAgo % 60 !== 0) {
+    durationSegments.push(`${secondsAgo % 60} sec`);
   }
-  if (duration.days()) {
-    const days = pluralize(duration.days(), 'day', 'days');
-    durationSegments.push(`${duration.days()} ${days}`);
+  const minutesAgo = Math.round(secondsAgo / 60);
+  if (minutesAgo % 60 !== 0) {
+    durationSegments.push(`${minutesAgo % 60} min`);
   }
-  if (duration.hours()) {
-    const hours = pluralize(duration.hours(), 'hour', 'hours');
-    durationSegments.push(`${duration.hours()} ${hours}`);
+  const hoursAgo = Math.round(minutesAgo / 60);
+  if (hoursAgo % 24 !== 0) {
+    const hours = pluralize(hoursAgo % 24, 'hour', 'hours');
+    durationSegments.push(`${hoursAgo % 24} ${hours}`);
   }
-  if (duration.minutes()) {
-    durationSegments.push(`${duration.minutes()} min`);
+  const daysAgo = Math.round(hoursAgo / 24);
+  if (daysAgo % 30 !== 0) {
+    const days = pluralize(daysAgo % 30, 'day', 'days');
+    durationSegments.push(`${daysAgo % 30} ${days}`);
   }
-  if (duration.seconds()) {
-    durationSegments.push(`${duration.seconds()} sec`);
+  const monthsAgo = Math.round(daysAgo / 30);
+  if (monthsAgo > 0) {
+    const months = pluralize(monthsAgo, 'month', 'months');
+    durationSegments.push(`${monthsAgo} ${months}`);
   }
-  return durationSegments.slice(0, 2).join(' ');
+  return durationSegments.reverse().slice(0, 2).join(' ');
 }
 
 /**
diff --git a/package-lock.json b/package-lock.json
index 7c6b698..aad9f46 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1146,12 +1146,6 @@
         "minimist": "^1.2.5"
       }
     },
-    "moment": {
-      "version": "2.24.0",
-      "resolved": "https://registry.npmjs.org/moment/-/moment-2.24.0.tgz",
-      "integrity": "sha512-bV7f+6l2QigeBBZSM/6yTNq4P2fNpSWj/0e7jQcy87A8e7o2nAfP/34/2ky5Vw4B9S446EtIhodAzkFCcR4dQg==",
-      "dev": true
-    },
     "ms": {
       "version": "2.1.2",
       "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
diff --git a/package.json b/package.json
index 10c6e25..3f544a6 100644
--- a/package.json
+++ b/package.json
@@ -20,7 +20,6 @@
     "eslint-plugin-html": "^6.0.0",
     "eslint-plugin-import": "^2.20.1",
     "eslint-plugin-jsdoc": "^19.2.0",
-    "moment": "^2.24.0",
     "polymer-bridges": "file:../../polymer-bridges/",
     "polymer-cli": "^1.9.11"
   },
diff --git a/test/common-test-setup.js b/test/common-test-setup.js
index 380a7f3..d2b9953 100644
--- a/test/common-test-setup.js
+++ b/test/common-test-setup.js
@@ -55,7 +55,4 @@
 import 'polymer-bridges/polymer/lib/elements/custom-style_bridge.js';
 import 'polymer-bridges/polymer/lib/legacy/mutable-data-behavior_bridge.js';
 import 'polymer-bridges/polymer/polymer-legacy_bridge.js';
-
-import '@polymer/iron-test-helpers/iron-test-helpers.js';
-import moment from 'moment/src/moment.js';
-self.moment = moment;
\ No newline at end of file
+import '@polymer/iron-test-helpers/iron-test-helpers.js';
\ No newline at end of file