Previously all templates were being included on every page, regardless
of whether they were being used, bloating the bundles. In addition,
`templateUrl` has a number of issues compared to `template`:
https://medium.com/@frosty/angularjs-template-vs-templateurl-cdde055b7907
There are now no more instances of non-global `require()`s (or any
require()s for that matter), so we can enable that eslint rule:
https://eslint.org/docs/rules/global-require
Improves the bundle sizes as follows:
* index: -60KB
* logviewer: -138KB
* perf: -84KB
And whilst we're there, use explicit imports instead of relying on
the webpack `ProvidePlugin` to import it for us - which lets us also
remove the eslint global exemption plus unit test workaround.
This adds some new components and removes the AngularJS ng-repeat for
pushes. In the course of this work, some of the AngularJS providers were
converted to helper functions.
In a couple cases, I had to add new code to the AngularJS areas so that it
would continue to interact well between Angular and React.
Also:
* Rename some functions and CSS classes from resultset to push
* Add unlistening for events during unmount of components
Since it's not being used. This will save us having to convert it to
React for now, and also means one less thing slowing down our builds.
Should it be needed in the future, it can be resurrected using the
Git log.
With ES6, the `'use strict'` directives are unnecessary:
https://eslint.org/docs/rules/strict
The directives have been left in the Neutrino configs, since they
are used by node directly, which doesn't yet support ES6 modules.
## Rough summary of the changes
### Front end
The auth callback is written in React and lives under the /login.html endpoint. It communicates with Treeherder using the localStorage.
### Credential expiration
The Django user session expiration is set to expire when the client access token or the id token expires (whichever one expires first). These values are controlled by the IAM team. Presently, the access token expires after 1 day and the id token expires after a week. That being said, the session will therefore expire after 1 day. If you want this value change, we simply need to send a request to the IAM team.
### Credential renewal
Renewals are set to happen every 15 minutes or so. The renewal is skewed slightly so that different open tabs don't renew at the same time. Once renewal happens, both tokens are renewed and the Django session is updated.
### Migration
If the userSession localStorage key is not set, then the user will be logged out including logging out from the Django session. In other words, all users will be automatically logged out when the merge to production happens.
In `configureStore.js` the same object was being exported twice, once
as the default export and once as a named export. Since default exports
are preferred if there is only one export in a file, I've removed the
named import and left the default one.
In `Groups.jsx` the `Groups` class was exported but unused, so has
been adjusted to no longer be exported, so the `App.jsx` import
doesn't trigger the warning:
`import Groups from './Groups';`
See:
https://github.com/benmosher/eslint-plugin-import/blob/master/docs/rules/no-named-as-default.md
Previously only 65 rules were enabled, since the `eslint:recommended`
and `plugin:react/recommended` entries in `extends` had no effect,
since when using ESLint's API rather than CLI, the options must be
passed inside the `baseConfig` property instead.
This commit corrects the usage of `extends` and switches us to AirBnb's
React ESLint preset rather than manually opting into rules:
https://github.com/airbnb/javascript
Even with the temporarily disabled rules (which can be gradually fixed
in the future), there are now over 200 ESLint rules enabled, giving
a significant increase in coverage.
Note: We're having to use v15 of `eslint-config-airbnb` rather than v16
until we update to newer Neutrino, since the latest preset has dropped
support for the ESLint v3 that comes with Neutrino 4.
With the changes in previous commits, all of the assets that were
originally manually copied to `dist/img/` are now correctly handled
by webpack as dependencies (and so emitted to `dist/` automatically).
As such, this leaves only three files that need copying from `src/`,
so they are now listed explicitly to avoid having to continually
update `ignore` to prevent extra files from sneaking in:
https://webpack.js.org/plugins/copy-webpack-plugin/
As a result of this change, the following assets are no longer
needlessly created under `dist/` as part of `yarn build`:
```
img/dancing_cat.gif
img/line_chart.png
img/logviewerIcon.png
img/logviewerIcon.svg
img/logviewerIconHelp.svg
img/tip.png
img/tip-locked.png
img/tree.xcf
img/tree_closed.png
img/tree_open.png
img/treeherder-logo.png
```
To confirm that this would not break anything, the JS and HTML files
under `dist/` were grepped for the string `img/`, and there are no
references remaining.
Previously `html-loader` only parsed `<img src="...">` tags when
looking for assets/dependencies. Now the `<link href="...">` tags
for favicons are processed too, which means `img/tree_open.png`
and friends will be included in the webpack build and not need to
be manually copied into `dist/img/`:
https://webpack.js.org/loaders/html-loader/
This does not visible change the number of hashed images output to
`dist/`, since the favicons are small enough that `url-loader` inlines
them in the HTML as base64 encoded data URIs (this is adjustable if
not desired later):
https://webpack.js.org/loaders/url-loader/
Neutrino 4 configures `file-loader` as the loader for HTML (rather than
the more usual `html-loader`), which means the HTML is not parsed to
look for further dependencies such as `<img src="...">` tags. Our
custom Neutrino config overrode that to `raw-loader` (presumably to
work around bugs caused by the use of `file-loader`), which doesn't
parse HTML either.
Instead, these assets were being manually copied to `dist/img/` by
`neutrino-custom/production.js`'s `CopyPlugin` rule, effectively
circumventing the webpack build process.
Newer Neutrino correctly uses `html-loader`, causing our HTML to be
parsed during the webpack build for the first time. However now that
the images are being resolved at build time rather than runtime, the
relative paths need to be updated to account for the directory layout
differences between `src/` and `dist/`, to prevent build errors.
A significant benefit of this change is that images referenced from
HTML will now be output with hashed filenames, meaning they get given
long-lived `Cache-Control` headers by WhiteNoise.
See:
https://webpack.js.org/loaders/file-loader/https://webpack.js.org/loaders/raw-loader/https://webpack.js.org/loaders/html-loader/
Neutrino 4 configured the SVG mimetype as `application/svg+xml`, which
Firefox doesn't appear to like. Neutrino 8 instead doesn't specify a
mimetype directly, allowing `url-loader` to autodetect via the NPM
`mime` package (which returns `image/svg+xml` for SVGs).
This switches to the Neutrino 8 approach, to prevent the job detail
panel's log viewer icon breaking in later commits when we start
parsing HTML properly (which causes url-loader to embed the icon as
a base64 encoded data URI rather than a URL to a file).
Neutrino 4 only configured `url-loader` for use with `.png` and `.jpg`.
This means that once we start parsing HTML properly in later commits,
we would otherwise get the following error:
```
ERROR in ./ui/img/dancing_cat.gif
Module parse failed: C:\Users\Ed\src\treeherder\ui\img\dancing_cat.gif Unexpected character '�' (1:6)
You may need an appropriate loader to handle this file type.
(Source code omitted for this binary file)
@ ./ui/partials/perf/comparectrl.html 1:214-250
@ ./ui/partials \.html$
@ ./ui/js/cache-templates.js
@ ./ui/js/perfapp.js
@ ./ui/entry-perf.js
@ multi ./ui/entry-perf.js
```
Modify the code to:
* share assets and global settings wherever possible
* update links going both directions
* other small UI tweaks for uniformity with Treeherder
* Fixed a few routing dead-ends on the react side
* Removed the dead TestDetail file we weren't using anyway
* fix production domain urls
Also upgrade Enzyme from 2.7.1 to 3.1.1
Most notable change here is that React.PropTypes is now
moved to a separate package and referenced just by
PropTypes. So this needed some import and linting changes.
This adds the upgrade to Bootstrap 4, and some basic changes and
some CSS tweaks we needed to keep out UI consistent.
The simpler changes are things like:
* Classes that were renamed
* Adding classes that are now needed (dropdown-item, etc)
* Change an item from a button to a span
* Changing order of items (modal header close button, etc)
* CSS class syntax changes
The other changes are lots of CSS padding, margin, font and
other spacing tweaks.