diff --git a/.eslintrc.js b/.eslintrc.js index ce8520118..af3503e27 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -47,5 +47,13 @@ module.exports = { 'react/jsx-one-expression-per-line': 'off', 'react/jsx-wrap-multilines': 'off', 'react/no-access-state-in-setstate': 'off', + // Override AirBnB's config for this rule to make it more strict. + // https://github.com/benmosher/eslint-plugin-import/blob/master/docs/rules/order.md + 'import/order': [ + 'error', + { + 'newlines-between': 'always', + }, + ], }, }; diff --git a/docs/code_style.md b/docs/code_style.md index b024ef94e..430a3f55d 100644 --- a/docs/code_style.md +++ b/docs/code_style.md @@ -35,3 +35,8 @@ UI -- We use the [Airbnb](https://github.com/airbnb/javascript) style guide for Javascript and validate it with ESlint (see Validating Javascript in the [Installation section](installation.html#validating-javascript)). For CSS, we use [reactstrap](https://reactstrap.github.io/) and Bootstrap's utility classes as much as possible before adding custom CSS to a style sheet. Any custom style that can be made reusable should be named generically and stored in the ``ui/css/treeherder-global.css`` file. + +Imports in JS/JSX must be ordered like so (with newlines between each group): +1. external modules (eg `'react'`) +2. modules from a parent directory (eg `'../foo'`) +3. "sibling" modules from the same or a sibling's directory (eg `'./bar'` or './bar/baz') diff --git a/ui/helpers/taskcluster.js b/ui/helpers/taskcluster.js index 48533d2c1..8a58558d0 100644 --- a/ui/helpers/taskcluster.js +++ b/ui/helpers/taskcluster.js @@ -1,4 +1,5 @@ import { OIDCCredentialAgent, Queue } from 'taskcluster-client-web'; + import { tcRootUrl, getUserSessionUrl } from './url'; const taskcluster = (() => { diff --git a/ui/intermittent-failures/BugDetailsView.jsx b/ui/intermittent-failures/BugDetailsView.jsx index eb7b6ff24..fa2129c51 100644 --- a/ui/intermittent-failures/BugDetailsView.jsx +++ b/ui/intermittent-failures/BugDetailsView.jsx @@ -4,8 +4,9 @@ import { Link } from 'react-router-dom'; import Icon from 'react-fontawesome'; import ReactTable from 'react-table'; -import { calculateMetrics, prettyDate, tableRowStyling } from './helpers'; import { bugDetailsEndpoint, getJobsUrl } from '../helpers/url'; + +import { calculateMetrics, prettyDate, tableRowStyling } from './helpers'; import BugLogColumn from './BugLogColumn'; import Layout from './Layout'; import withView from './View'; diff --git a/ui/intermittent-failures/BugLogColumn.jsx b/ui/intermittent-failures/BugLogColumn.jsx index 0de2cd027..d04444c94 100644 --- a/ui/intermittent-failures/BugLogColumn.jsx +++ b/ui/intermittent-failures/BugLogColumn.jsx @@ -1,6 +1,7 @@ import React from 'react'; import PropTypes from 'prop-types'; import { Tooltip } from 'reactstrap'; + import { getLogViewerUrl } from '../helpers/url'; diff --git a/ui/intermittent-failures/DateRangePicker.jsx b/ui/intermittent-failures/DateRangePicker.jsx index 36636d869..36de69c1c 100644 --- a/ui/intermittent-failures/DateRangePicker.jsx +++ b/ui/intermittent-failures/DateRangePicker.jsx @@ -3,9 +3,9 @@ import 'react-day-picker/lib/style.css'; import DayPickerInput from 'react-day-picker/DayPickerInput'; import moment from 'moment'; import PropTypes from 'prop-types'; - import { parseDate, formatDate } from 'react-day-picker/moment'; import { Button } from 'reactstrap'; + import { ISODate } from './helpers'; export default class DateRangePicker extends React.Component { diff --git a/ui/intermittent-failures/ErrorMessages.jsx b/ui/intermittent-failures/ErrorMessages.jsx index 29584731c..679efc577 100644 --- a/ui/intermittent-failures/ErrorMessages.jsx +++ b/ui/intermittent-failures/ErrorMessages.jsx @@ -1,6 +1,7 @@ import React from 'react'; import PropTypes from 'prop-types'; import { Alert } from 'reactstrap'; + import { processErrorMessage } from './helpers'; const ErrorMessages = ({ failureMessage, failureStatus, errorMessages }) => { diff --git a/ui/intermittent-failures/Layout.jsx b/ui/intermittent-failures/Layout.jsx index 149053894..90e71cfe5 100644 --- a/ui/intermittent-failures/Layout.jsx +++ b/ui/intermittent-failures/Layout.jsx @@ -3,11 +3,12 @@ import { Container } from 'reactstrap'; import PropTypes from 'prop-types'; import Icon from 'react-fontawesome'; +import ErrorBoundary from '../shared/ErrorBoundary'; + import Navigation from './Navigation'; import GraphsContainer from './GraphsContainer'; import ErrorMessages from './ErrorMessages'; import { prettyErrorMessages, errorMessageClass } from './constants'; -import ErrorBoundary from '../shared/ErrorBoundary'; const Layout = (props) => { diff --git a/ui/intermittent-failures/MainView.jsx b/ui/intermittent-failures/MainView.jsx index 3ab794172..1db459fa8 100644 --- a/ui/intermittent-failures/MainView.jsx +++ b/ui/intermittent-failures/MainView.jsx @@ -4,9 +4,10 @@ import PropTypes from 'prop-types'; import moment from 'moment'; import ReactTable from 'react-table'; +import { bugsEndpoint } from '../helpers/url'; + import BugColumn from './BugColumn'; import { calculateMetrics, prettyDate, ISODate, tableRowStyling } from './helpers'; -import { bugsEndpoint } from '../helpers/url'; import withView from './View'; import Layout from './Layout'; import DateRangePicker from './DateRangePicker'; diff --git a/ui/intermittent-failures/View.jsx b/ui/intermittent-failures/View.jsx index 2fa97bbf6..ede4a299a 100644 --- a/ui/intermittent-failures/View.jsx +++ b/ui/intermittent-failures/View.jsx @@ -1,11 +1,12 @@ import React from 'react'; import PropTypes from 'prop-types'; -import { updateQueryParams, validateQueryParams, mergeData, formatBugs } from './helpers'; import { graphsEndpoint, parseQueryParams, createQueryParams, createApiUrl, bugzillaBugsApi } from '../helpers/url'; import { getData } from '../helpers/http'; +import { updateQueryParams, validateQueryParams, mergeData, formatBugs } from './helpers'; + const withView = defaultState => WrappedComponent => class View extends React.Component { constructor(props) { diff --git a/ui/intermittent-failures/helpers.js b/ui/intermittent-failures/helpers.js index efc22245e..3a0709e51 100644 --- a/ui/intermittent-failures/helpers.js +++ b/ui/intermittent-failures/helpers.js @@ -1,4 +1,5 @@ import moment from 'moment'; + import { prettyErrorMessages } from './constants'; // be sure to wrap date arg in a moment() diff --git a/ui/job-view/App.jsx b/ui/job-view/App.jsx index ddd15a65b..cbe7cd486 100644 --- a/ui/job-view/App.jsx +++ b/ui/job-view/App.jsx @@ -3,24 +3,25 @@ import { hot } from 'react-hot-loader'; import SplitPane from 'react-split-pane'; import { thFavicons } from '../helpers/constants'; -import { Pushes } from './context/Pushes'; -import { SelectedJob } from './context/SelectedJob'; -import { PinnedJobs } from './context/PinnedJobs'; import { Notifications } from '../shared/context/Notifications'; +import NotificationList from '../shared/NotificationList'; +import ShortcutTable from '../shared/ShortcutTable'; import { matchesDefaults } from '../helpers/filter'; import { getAllUrlParams, getRepo } from '../helpers/location'; import { deployedRevisionUrl } from '../helpers/url'; import ClassificationTypeModel from '../models/classificationType'; import FilterModel from '../models/filter'; import RepositoryModel from '../models/repository'; + +import { Pushes } from './context/Pushes'; +import { SelectedJob } from './context/SelectedJob'; +import { PinnedJobs } from './context/PinnedJobs'; import PrimaryNavBar from './headerbars/PrimaryNavBar'; import ActiveFilters from './headerbars/ActiveFilters'; import UpdateAvailable from './headerbars/UpdateAvailable'; import DetailsPanel from './details/DetailsPanel'; import PushList from './pushes/PushList'; import KeyboardShortcuts from './KeyboardShortcuts'; -import NotificationList from '../shared/NotificationList'; -import ShortcutTable from '../shared/ShortcutTable'; const DEFAULT_DETAILS_PCT = 40; const REVISION_POLL_INTERVAL = 1000 * 60 * 5; diff --git a/ui/job-view/CustomJobActions.jsx b/ui/job-view/CustomJobActions.jsx index c40868b34..24caf362c 100644 --- a/ui/job-view/CustomJobActions.jsx +++ b/ui/job-view/CustomJobActions.jsx @@ -11,9 +11,10 @@ import { import { formatTaskclusterError } from '../helpers/errorMessage'; import TaskclusterModel from '../models/taskcluster'; -import { withPushes } from './context/Pushes'; import { withNotifications } from '../shared/context/Notifications'; +import { withPushes } from './context/Pushes'; + class CustomJobActions extends React.PureComponent { constructor(props) { super(props); diff --git a/ui/job-view/KeyboardShortcuts.jsx b/ui/job-view/KeyboardShortcuts.jsx index 465332e57..b655ad6b9 100644 --- a/ui/job-view/KeyboardShortcuts.jsx +++ b/ui/job-view/KeyboardShortcuts.jsx @@ -3,9 +3,10 @@ import PropTypes from 'prop-types'; import { HotKeys } from 'react-hotkeys'; import { thEvents } from '../helpers/constants'; +import { withNotifications } from '../shared/context/Notifications'; + import { withPinnedJobs } from './context/PinnedJobs'; import { withSelectedJob } from './context/SelectedJob'; -import { withNotifications } from '../shared/context/Notifications'; const keyMap = { addRelatedBug: 'b', diff --git a/ui/job-view/context/PinnedJobs.jsx b/ui/job-view/context/PinnedJobs.jsx index 1a3e50768..1b6a4d0e6 100644 --- a/ui/job-view/context/PinnedJobs.jsx +++ b/ui/job-view/context/PinnedJobs.jsx @@ -1,5 +1,6 @@ import React from 'react'; import PropTypes from 'prop-types'; + import { withNotifications } from '../../shared/context/Notifications'; const COUNT_ERROR = 'Max pinboard size of 500 reached.'; diff --git a/ui/job-view/context/SelectedJob.jsx b/ui/job-view/context/SelectedJob.jsx index 8fa3183ff..be173fb2d 100644 --- a/ui/job-view/context/SelectedJob.jsx +++ b/ui/job-view/context/SelectedJob.jsx @@ -15,9 +15,10 @@ import { getUrlParam, setUrlParam } from '../../helpers/location'; import { getJobsUrl } from '../../helpers/url'; import JobModel from '../../models/job'; import PushModel from '../../models/push'; +import { withNotifications } from '../../shared/context/Notifications'; + import { withPinnedJobs } from './PinnedJobs'; import { withPushes } from './Pushes'; -import { withNotifications } from '../../shared/context/Notifications'; const SelectedJobContext = React.createContext({}); diff --git a/ui/job-view/details/DetailsPanel.jsx b/ui/job-view/details/DetailsPanel.jsx index 77f6b8c8d..a28eff306 100644 --- a/ui/job-view/details/DetailsPanel.jsx +++ b/ui/job-view/details/DetailsPanel.jsx @@ -5,6 +5,7 @@ import chunk from 'lodash/chunk'; import { thEvents, thBugSuggestionLimit } from '../../helpers/constants'; import { withPinnedJobs } from '../context/PinnedJobs'; import { withSelectedJob } from '../context/SelectedJob'; +import { withPushes } from '../context/Pushes'; import { getLogViewerUrl, getReftestUrl } from '../../helpers/url'; import BugJobMapModel from '../../models/bugJobMap'; import BugSuggestionsModel from '../../models/bugSuggestions'; @@ -14,10 +15,10 @@ import JobDetailModel from '../../models/jobDetail'; import JobLogUrlModel from '../../models/jobLogUrl'; import TextLogStepModel from '../../models/textLogStep'; import PerfSeriesModel from '../../models/perfSeries'; + import PinBoard from './PinBoard'; import SummaryPanel from './summary/SummaryPanel'; import TabsPanel from './tabs/TabsPanel'; -import { withPushes } from '../context/Pushes'; export const pinboardHeight = 100; diff --git a/ui/job-view/details/summary/ActionBar.jsx b/ui/job-view/details/summary/ActionBar.jsx index 9d0da6c5a..54653f109 100644 --- a/ui/job-view/details/summary/ActionBar.jsx +++ b/ui/job-view/details/summary/ActionBar.jsx @@ -9,12 +9,13 @@ import { getInspectTaskUrl, getReftestUrl } from '../../../helpers/url'; import JobModel from '../../../models/job'; import TaskclusterModel from '../../../models/taskcluster'; import CustomJobActions from '../../CustomJobActions'; -import LogUrls from './LogUrls'; import { withSelectedJob } from '../../context/SelectedJob'; import { withPinnedJobs } from '../../context/PinnedJobs'; import { withPushes } from '../../context/Pushes'; import { withNotifications } from '../../../shared/context/Notifications'; +import LogUrls from './LogUrls'; + class ActionBar extends React.PureComponent { constructor(props) { super(props); diff --git a/ui/job-view/details/summary/SummaryPanel.jsx b/ui/job-view/details/summary/SummaryPanel.jsx index a2ccdb50a..440068123 100644 --- a/ui/job-view/details/summary/SummaryPanel.jsx +++ b/ui/job-view/details/summary/SummaryPanel.jsx @@ -3,6 +3,7 @@ import PropTypes from 'prop-types'; import { withSelectedJob } from '../../context/SelectedJob'; import JobInfo from '../../../shared/JobInfo'; + import ActionBar from './ActionBar'; import ClassificationsPanel from './ClassificationsPanel'; import StatusPanel from './StatusPanel'; diff --git a/ui/job-view/details/tabs/TabsPanel.jsx b/ui/job-view/details/tabs/TabsPanel.jsx index 47460b083..22a06e4f5 100644 --- a/ui/job-view/details/tabs/TabsPanel.jsx +++ b/ui/job-view/details/tabs/TabsPanel.jsx @@ -5,15 +5,15 @@ import { Tab, Tabs, TabList, TabPanel } from 'react-tabs'; import { thEvents } from '../../../helpers/constants'; import { getAllUrlParams } from '../../../helpers/location'; import { getStatus } from '../../../helpers/job'; - import JobDetails from '../../../shared/JobDetails'; +import { withPinnedJobs } from '../../context/PinnedJobs'; +import { withSelectedJob } from '../../context/SelectedJob'; + import FailureSummaryTab from './failureSummary/FailureSummaryTab'; import PerformanceTab from './PerformanceTab'; import AutoclassifyTab from './autoclassify/AutoclassifyTab'; import AnnotationsTab from './AnnotationsTab'; import SimilarJobsTab from './SimilarJobsTab'; -import { withPinnedJobs } from '../../context/PinnedJobs'; -import { withSelectedJob } from '../../context/SelectedJob'; class TabsPanel extends React.Component { constructor(props) { diff --git a/ui/job-view/details/tabs/autoclassify/AutoclassifyTab.jsx b/ui/job-view/details/tabs/autoclassify/AutoclassifyTab.jsx index 77b074907..0449fbaa9 100644 --- a/ui/job-view/details/tabs/autoclassify/AutoclassifyTab.jsx +++ b/ui/job-view/details/tabs/autoclassify/AutoclassifyTab.jsx @@ -5,13 +5,13 @@ import React from 'react'; import { thEvents } from '../../../../helpers/constants'; import { getProjectJobUrl } from '../../../../helpers/url'; import TextLogErrorsModel from '../../../../models/textLogErrors'; +import { withSelectedJob } from '../../../context/SelectedJob'; +import { withPinnedJobs } from '../../../context/PinnedJobs'; +import { withNotifications } from '../../../../shared/context/Notifications'; import AutoclassifyToolbar from './AutoclassifyToolbar'; import ErrorLine from './ErrorLine'; import ErrorLineData from './ErrorLineModel'; -import { withSelectedJob } from '../../../context/SelectedJob'; -import { withPinnedJobs } from '../../../context/PinnedJobs'; -import { withNotifications } from '../../../../shared/context/Notifications'; class AutoclassifyTab extends React.Component { constructor(props) { diff --git a/ui/job-view/details/tabs/autoclassify/ErrorLine.jsx b/ui/job-view/details/tabs/autoclassify/ErrorLine.jsx index dac334232..2308c05ba 100644 --- a/ui/job-view/details/tabs/autoclassify/ErrorLine.jsx +++ b/ui/job-view/details/tabs/autoclassify/ErrorLine.jsx @@ -5,11 +5,11 @@ import { FormGroup } from 'reactstrap'; import { thEvents } from '../../../../helpers/constants'; import { stringOverlap, highlightLogLine } from '../../../../helpers/autoclassify'; import { getBugUrl, getLogViewerUrl } from '../../../../helpers/url'; +import { withSelectedJob } from '../../../context/SelectedJob'; import LineOption from './LineOption'; import LineOptionModel from './LineOptionModel'; import StaticLineOption from './StaticLineOption'; -import { withSelectedJob } from '../../../context/SelectedJob'; const GOOD_MATCH_SCORE = 0.75; const BAD_MATCH_SCORE = 0.25; diff --git a/ui/job-view/details/tabs/failureSummary/FailureSummaryTab.jsx b/ui/job-view/details/tabs/failureSummary/FailureSummaryTab.jsx index 17e9769f7..0d6810255 100644 --- a/ui/job-view/details/tabs/failureSummary/FailureSummaryTab.jsx +++ b/ui/job-view/details/tabs/failureSummary/FailureSummaryTab.jsx @@ -4,13 +4,13 @@ import PropTypes from 'prop-types'; import { thEvents } from '../../../../helpers/constants'; import { isReftest } from '../../../../helpers/job'; import { getBugUrl } from '../../../../helpers/url'; +import { withSelectedJob } from '../../../context/SelectedJob'; +import { withPinnedJobs } from '../../../context/PinnedJobs'; +import BugFiler from '../../BugFiler'; import ErrorsList from './ErrorsList'; import ListItem from './ListItem'; import SuggestionsListItem from './SuggestionsListItem'; -import BugFiler from '../../BugFiler'; -import { withSelectedJob } from '../../../context/SelectedJob'; -import { withPinnedJobs } from '../../../context/PinnedJobs'; class FailureSummaryTab extends React.Component { constructor(props) { diff --git a/ui/job-view/details/tabs/failureSummary/SuggestionsListItem.jsx b/ui/job-view/details/tabs/failureSummary/SuggestionsListItem.jsx index 0f0afc6fb..91393013e 100644 --- a/ui/job-view/details/tabs/failureSummary/SuggestionsListItem.jsx +++ b/ui/job-view/details/tabs/failureSummary/SuggestionsListItem.jsx @@ -2,6 +2,7 @@ import React from 'react'; import PropTypes from 'prop-types'; import { thBugSuggestionLimit } from '../../../../helpers/constants'; + import BugListItem from './BugListItem'; export default class SuggestionsListItem extends React.Component { diff --git a/ui/job-view/headerbars/PrimaryNavBar.jsx b/ui/job-view/headerbars/PrimaryNavBar.jsx index 3f5ce2ea3..dba88006f 100644 --- a/ui/job-view/headerbars/PrimaryNavBar.jsx +++ b/ui/job-view/headerbars/PrimaryNavBar.jsx @@ -4,6 +4,7 @@ import PropTypes from 'prop-types'; import Logo from '../../img/treeherder-logo.png'; import Login from '../../shared/auth/Login'; import LogoMenu from '../../shared/LogoMenu'; + import NotificationsMenu from './NotificationsMenu'; import InfraMenu from './InfraMenu'; import ReposMenu from './ReposMenu'; diff --git a/ui/job-view/headerbars/SecondaryNavBar.jsx b/ui/job-view/headerbars/SecondaryNavBar.jsx index aaf7b49bf..82328435d 100644 --- a/ui/job-view/headerbars/SecondaryNavBar.jsx +++ b/ui/job-view/headerbars/SecondaryNavBar.jsx @@ -10,9 +10,10 @@ import { } from '../../helpers/location'; import RepositoryModel from '../../models/repository'; import ErrorBoundary from '../../shared/ErrorBoundary'; -import WatchedRepo from './WatchedRepo'; import { withPushes } from '../context/Pushes'; +import WatchedRepo from './WatchedRepo'; + const MAX_WATCHED_REPOS = 3; const WATCHED_REPOS_STORAGE_KEY = 'thWatchedRepos'; diff --git a/ui/job-view/pushes/JobButton.jsx b/ui/job-view/pushes/JobButton.jsx index 68474d1eb..a386aae74 100644 --- a/ui/job-view/pushes/JobButton.jsx +++ b/ui/job-view/pushes/JobButton.jsx @@ -1,5 +1,6 @@ import React from 'react'; import PropTypes from 'prop-types'; + import { getBtnClass, findJobInstance } from '../../helpers/job'; import { getUrlParam } from '../../helpers/location'; diff --git a/ui/job-view/pushes/JobGroup.jsx b/ui/job-view/pushes/JobGroup.jsx index dd824c22a..66377594b 100644 --- a/ui/job-view/pushes/JobGroup.jsx +++ b/ui/job-view/pushes/JobGroup.jsx @@ -6,6 +6,7 @@ import { withSelectedJob } from '../context/SelectedJob'; import { thFailureResults } from '../../helpers/constants'; import { getBtnClass, getStatus } from '../../helpers/job'; import { getUrlParam } from '../../helpers/location'; + import JobButton from './JobButton'; import JobCount from './JobCount'; diff --git a/ui/job-view/pushes/JobsAndGroups.jsx b/ui/job-view/pushes/JobsAndGroups.jsx index 4c5e4808a..61873a885 100644 --- a/ui/job-view/pushes/JobsAndGroups.jsx +++ b/ui/job-view/pushes/JobsAndGroups.jsx @@ -1,8 +1,10 @@ import PropTypes from 'prop-types'; import React from 'react'; + +import { getStatus } from '../../helpers/job'; + import JobButton from './JobButton'; import JobGroup from './JobGroup'; -import { getStatus } from '../../helpers/job'; export default class JobsAndGroups extends React.Component { render() { diff --git a/ui/job-view/pushes/Platform.jsx b/ui/job-view/pushes/Platform.jsx index 7be5d2bbc..ad3021561 100644 --- a/ui/job-view/pushes/Platform.jsx +++ b/ui/job-view/pushes/Platform.jsx @@ -1,5 +1,6 @@ import PropTypes from 'prop-types'; import React from 'react'; + import JobsAndGroups from './JobsAndGroups'; function PlatformName(props) { diff --git a/ui/job-view/pushes/Push.jsx b/ui/job-view/pushes/Push.jsx index fc845566a..8f0dd9b21 100644 --- a/ui/job-view/pushes/Push.jsx +++ b/ui/job-view/pushes/Push.jsx @@ -2,9 +2,6 @@ import React from 'react'; import PropTypes from 'prop-types'; import sortBy from 'lodash/sortBy'; -import PushJobs from './PushJobs'; -import PushHeader from './PushHeader'; -import { RevisionList } from './RevisionList'; import { thEvents, thOptionOrder, thPlatformMap } from '../../helpers/constants'; import { withPushes } from '../context/Pushes'; import { escapeId, getGroupMapKey } from '../../helpers/aggregateId'; @@ -15,6 +12,10 @@ import { withNotifications } from '../../shared/context/Notifications'; import { getRevisionTitle } from '../../helpers/revision'; import { getPercentComplete } from '../../helpers/display'; +import PushHeader from './PushHeader'; +import PushJobs from './PushJobs'; +import { RevisionList } from './RevisionList'; + const watchCycleStates = ['none', 'push', 'job', 'none']; const platformArray = Object.values(thPlatformMap); diff --git a/ui/job-view/pushes/PushActionMenu.jsx b/ui/job-view/pushes/PushActionMenu.jsx index 2953738aa..08f4596e9 100644 --- a/ui/job-view/pushes/PushActionMenu.jsx +++ b/ui/job-view/pushes/PushActionMenu.jsx @@ -1,5 +1,6 @@ import React from 'react'; import PropTypes from 'prop-types'; + import { getUrlParam } from '../../helpers/location'; import { formatTaskclusterError } from '../../helpers/errorMessage'; import CustomJobActions from '../CustomJobActions'; diff --git a/ui/job-view/pushes/PushHeader.jsx b/ui/job-view/pushes/PushHeader.jsx index 29bf67ced..3f01a8dc6 100644 --- a/ui/job-view/pushes/PushHeader.jsx +++ b/ui/job-view/pushes/PushHeader.jsx @@ -1,6 +1,6 @@ import React from 'react'; import PropTypes from 'prop-types'; -import PushActionMenu from './PushActionMenu'; + import { getPercentComplete, toDateStr } from '../../helpers/display'; import { formatTaskclusterError } from '../../helpers/errorMessage'; import { getJobsUrl } from '../../helpers/url'; @@ -11,6 +11,8 @@ import { withSelectedJob } from '../context/SelectedJob'; import { withPushes } from '../context/Pushes'; import { withNotifications } from '../../shared/context/Notifications'; +import PushActionMenu from './PushActionMenu'; + // url params we don't want added from the current querystring to the revision // and author links. const SKIPPED_LINK_PARAMS = [ diff --git a/ui/job-view/pushes/PushJobs.jsx b/ui/job-view/pushes/PushJobs.jsx index 3fd48222a..9f3327f57 100644 --- a/ui/job-view/pushes/PushJobs.jsx +++ b/ui/job-view/pushes/PushJobs.jsx @@ -9,9 +9,10 @@ import { findInstance, findSelectedInstance } from '../../helpers/job'; import { getUrlParam } from '../../helpers/location'; import { getLogViewerUrl } from '../../helpers/url'; import JobModel from '../../models/job'; -import Platform from './Platform'; import { withPushes } from '../context/Pushes'; +import Platform from './Platform'; + class PushJobs extends React.Component { static getDerivedStateFromProps(nextProps) { const { filterModel, push, platforms, runnableVisible } = nextProps; diff --git a/ui/job-view/pushes/PushList.jsx b/ui/job-view/pushes/PushList.jsx index 6fc352468..ac1313d93 100644 --- a/ui/job-view/pushes/PushList.jsx +++ b/ui/job-view/pushes/PushList.jsx @@ -2,9 +2,10 @@ import React from 'react'; import PropTypes from 'prop-types'; import ErrorBoundary from '../../shared/ErrorBoundary'; +import { withPushes } from '../context/Pushes'; + import Push from './Push'; import PushLoadErrors from './PushLoadErrors'; -import { withPushes } from '../context/Pushes'; class PushList extends React.Component { constructor(props) { diff --git a/ui/js/filters.js b/ui/js/filters.js index 96c9c2b54..1fcf79c02 100755 --- a/ui/js/filters.js +++ b/ui/js/filters.js @@ -2,9 +2,10 @@ /* eslint-disable func-names, prefer-arrow-callback */ import numeral from 'numeral'; -import treeherder from './treeherder'; import { getJobsUrl } from '../helpers/url'; +import treeherder from './treeherder'; + treeherder.filter('getRevisionUrl', function () { return function (revision, projectName) { if (revision) { diff --git a/ui/js/perf.js b/ui/js/perf.js index ea6d8d58b..cef047ae2 100644 --- a/ui/js/perf.js +++ b/ui/js/perf.js @@ -7,6 +7,7 @@ import LocalStorageModule from 'angular-local-storage'; import { react2angular } from 'react2angular/index.es2015'; import Login from '../shared/auth/Login'; + import treeherderModule from './treeherder'; const perf = angular.module('perf', [ diff --git a/ui/js/perfapp.js b/ui/js/perfapp.js index dcc066ada..ec39c2dc0 100644 --- a/ui/js/perfapp.js +++ b/ui/js/perfapp.js @@ -1,6 +1,5 @@ // Remove the eslint-disable when rewriting this file during the React conversion. /* eslint-disable func-names, prefer-arrow-callback */ -import perf from './perf'; import alertsCtrlTemplate from '../partials/perf/alertsctrl.html'; import graphsCtrlTemplate from '../partials/perf/graphsctrl.html'; import compareCtrlTemplate from '../partials/perf/comparectrl.html'; @@ -10,6 +9,8 @@ import compareSubtestDistributionTemplate from '../partials/perf/comparesubtestd import helpMenuTemplate from '../partials/perf/helpMenu.html'; import tooltipGraphsTemplate from '../partials/perf/tooltipgraphs.html'; +import perf from './perf'; + // configure the router here, after we have defined all the controllers etc perf.config(['$compileProvider', '$locationProvider', '$httpProvider', '$stateProvider', '$urlRouterProvider', function ($compileProvider, $locationProvider, $httpProvider, $stateProvider, $urlRouterProvider) { diff --git a/ui/logviewer/App.jsx b/ui/logviewer/App.jsx index 5bacdb983..cf7073ae0 100644 --- a/ui/logviewer/App.jsx +++ b/ui/logviewer/App.jsx @@ -12,6 +12,7 @@ import PushModel from '../models/push'; import TextLogStepModel from '../models/textLogStep'; import JobDetails from '../shared/JobDetails'; import JobInfo from '../shared/JobInfo'; + import Navigation from './Navigation'; import ErrorLines from './ErrorLines'; diff --git a/ui/models/job.js b/ui/models/job.js index b33b3e33f..014065af0 100644 --- a/ui/models/job.js +++ b/ui/models/job.js @@ -1,6 +1,7 @@ import { thPlatformMap } from '../helpers/constants'; import { createQueryParams, getProjectUrl } from '../helpers/url'; import { formatTaskclusterError } from '../helpers/errorMessage'; + import TaskclusterModel from './taskcluster'; const uri = getProjectUrl('/jobs/'); diff --git a/ui/models/perfSeries.js b/ui/models/perfSeries.js index d0c3b2b7a..edeadef8d 100644 --- a/ui/models/perfSeries.js +++ b/ui/models/perfSeries.js @@ -1,6 +1,7 @@ import queryString from 'query-string'; import { getApiUrl, getProjectUrl } from '../helpers/url'; + import OptionCollectionModel from './optionCollection'; export const getTestName = function getTestName(signatureProps) { diff --git a/ui/models/push.js b/ui/models/push.js index 38a3525e5..b9a30be78 100644 --- a/ui/models/push.js +++ b/ui/models/push.js @@ -4,6 +4,7 @@ import { thMaxPushFetchSize } from '../helpers/constants'; import { getUrlParam } from '../helpers/location'; import taskcluster from '../helpers/taskcluster'; import { createQueryParams, getProjectUrl } from '../helpers/url'; + import JobModel from './job'; import TaskclusterModel from './taskcluster'; diff --git a/ui/models/runnableJob.js b/ui/models/runnableJob.js index 907e790d6..a7ced457a 100644 --- a/ui/models/runnableJob.js +++ b/ui/models/runnableJob.js @@ -1,4 +1,5 @@ import { getProjectUrl } from '../helpers/url'; + import JobModel from './job'; const uri = getProjectUrl('/runnable_jobs/'); diff --git a/ui/perfherder/helpers.js b/ui/perfherder/helpers.js index 72074ab3c..9c37b94dd 100644 --- a/ui/perfherder/helpers.js +++ b/ui/perfherder/helpers.js @@ -1,11 +1,12 @@ import chunk from 'lodash/chunk'; -import { tValueCareMin, tValueConfidence } from './constants'; import { getApiUrl, createQueryParams } from '../helpers/url'; import { getData } from '../helpers/http'; import PerfSeriesModel from '../models/perfSeries'; import { phTimeRanges } from '../helpers/constants'; +import { tValueCareMin, tValueConfidence } from './constants'; + export const calcPercentOf = function calcPercentOf(a, b) { return b ? 100 * a / b : 0; }; diff --git a/ui/shared/auth/Login.jsx b/ui/shared/auth/Login.jsx index 8686aa708..da8b1bdae 100644 --- a/ui/shared/auth/Login.jsx +++ b/ui/shared/auth/Login.jsx @@ -2,13 +2,14 @@ import React from 'react'; import PropTypes from 'prop-types'; import isEqual from 'lodash/isEqual'; -import AuthService from './AuthService'; import { loggedOutUser } from '../../helpers/auth'; import taskcluster from '../../helpers/taskcluster'; import { getApiUrl, loginCallbackUrl } from '../../helpers/url'; import UserModel from '../../models/user'; import { withNotifications } from '../context/Notifications'; +import AuthService from './AuthService'; + /** * This component handles logging in to Taskcluster Authentication * diff --git a/ui/test-view/redux/configureStore.js b/ui/test-view/redux/configureStore.js index a844ed4d9..f298c6f36 100644 --- a/ui/test-view/redux/configureStore.js +++ b/ui/test-view/redux/configureStore.js @@ -6,10 +6,12 @@ import { } from 'redux'; import createHistory from 'history/createBrowserHistory'; import createDebounce from 'redux-debounce'; -import * as groupsStore from './modules/groups'; + import { thPlatformMap } from '../../helpers/constants'; import { getServiceUrl, getProjectUrl } from '../../helpers/url'; +import * as groupsStore from './modules/groups'; + function getGroupText(group) { const symbol = group.symbol.startsWith('tc-') ? group.symbol.substring(3) : group.symbol; diff --git a/ui/test-view/ui/Groups.jsx b/ui/test-view/ui/Groups.jsx index 8f338489d..3c6bf3873 100644 --- a/ui/test-view/ui/Groups.jsx +++ b/ui/test-view/ui/Groups.jsx @@ -4,10 +4,11 @@ import { Form, FormGroup, Input, Label, Row, Col, Table, Container } from 'react import Icon from 'react-fontawesome'; import { connect } from 'react-redux'; +import { store, actions } from '../redux/store'; + import { Test, BugCount } from './Test'; import StatusProgress from './StatusProgress'; import StatusNavbar from './StatusNavbar'; -import { store, actions } from '../redux/store'; const mapStateToProps = ({ groups }) => groups; diff --git a/ui/test-view/ui/Navigation.jsx b/ui/test-view/ui/Navigation.jsx index 6c7bc99d5..fe56d72db 100644 --- a/ui/test-view/ui/Navigation.jsx +++ b/ui/test-view/ui/Navigation.jsx @@ -1,5 +1,6 @@ import React from 'react'; import { Nav, Navbar, Collapse } from 'reactstrap'; + import logoUrl from '../../img/treeherder-logo.png'; export default class Navigation extends React.Component { diff --git a/ui/test-view/ui/Test.jsx b/ui/test-view/ui/Test.jsx index db50153d3..4516cfa90 100644 --- a/ui/test-view/ui/Test.jsx +++ b/ui/test-view/ui/Test.jsx @@ -7,9 +7,9 @@ import { Badge } from 'reactstrap'; import { store, actions } from '../redux/store'; import { thPlatformMap } from '../../helpers/constants'; -import LogViewer from './LogViewer'; import { getBugUrl } from '../../helpers/url'; +import LogViewer from './LogViewer'; const mapStateToProps = ({ groups }) => ({ expanded: groups.expanded,