ui: Switch to eslint

- Update ui/.eslintrc.js to match with clang-format.
- Add the ui/eslint-all script which runs eslint over everything in
  ui/src
- Fix an enum definition that was causing eslint to crash
- Apply eslint to ui/src/common/actions.ts

Change-Id: Id3be30c7e09b059cff8d5a9a7f894ffe9336d407
diff --git a/ui/.eslintrc.js b/ui/.eslintrc.js
index 4305174..cb6b47c 100644
--- a/ui/.eslintrc.js
+++ b/ui/.eslintrc.js
@@ -16,6 +16,43 @@
     '@typescript-eslint',
   ],
   'rules': {
+    // We don't want to enforce jsdoc everywhere:
     'require-jsdoc': 'off',
+
+    // Max line length is 80 with 2 space tabs. This must match the
+    // ui/.clang-format definition:
+    'max-len': [
+      'error',
+      {
+        'code': 80,
+        'tabWidth': 2,
+        'ignoreUrls': true,
+        'ignoreTemplateLiterals': true,
+        'ignoreStrings': true,
+      }
+    ],
+
+    // Indentation handled by clang-format --js:
+    'indent': 'off',
+
+    // clang-format --js formats EOL comments after (e.g.) an if like:
+    // if (foo) {  // insightful comment
+    // with two spaces between the slash and the brace. Turn
+    // ignoreEOLComments on to allow that. We still want
+    // no-multi-spaces turned on in general as it fixes issues like:
+    // if (a ===   b)
+    'no-multi-spaces': ['error', {ignoreEOLComments: true}],
+
+    // Default no-unused-vars doesn't understand TypeScript enums. See:
+    // https://github.com/typescript-eslint/typescript-eslint/issues/2621
+    'no-unused-vars': 'off',
+    '@typescript-eslint/no-unused-vars':
+        ['error', {'argsIgnorePattern': '^_.*'}],
+
+    // new Array() is banned (use [] instead) but new Array<Foo>() is
+    // allowed since it can be clearer to put the type by the
+    // construtor.
+    'no-array-constructor': 'off',
+    '@typescript-eslint/no-array-constructor': ['error'],
   },
 };