diff options
Diffstat (limited to 'server/sonar-web/src/main/js')
166 files changed, 925 insertions, 667 deletions
diff --git a/server/sonar-web/src/main/js/api/settings.js b/server/sonar-web/src/main/js/api/settings.js index a5212c18453..40e4efc6c74 100644 --- a/server/sonar-web/src/main/js/api/settings.js +++ b/server/sonar-web/src/main/js/api/settings.js @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -import omitBy from 'lodash/omitBy'; +import { omitBy } from 'lodash'; import { getJSON, post, postJSON } from '../helpers/request'; import { TYPE_PROPERTY_SET } from '../apps/settings/constants'; diff --git a/server/sonar-web/src/main/js/app/components/nav/global/SearchView.js b/server/sonar-web/src/main/js/app/components/nav/global/SearchView.js index fad3fad1704..163ec964e26 100644 --- a/server/sonar-web/src/main/js/app/components/nav/global/SearchView.js +++ b/server/sonar-web/src/main/js/app/components/nav/global/SearchView.js @@ -20,8 +20,7 @@ // @flow import Backbone from 'backbone'; import Marionette from 'backbone.marionette'; -import debounce from 'lodash/debounce'; -import sortBy from 'lodash/sortBy'; +import { debounce, sortBy } from 'lodash'; import SelectableCollectionView from '../../../../components/common/selectable-collection-view'; import SearchItemTemplate from '../templates/nav-search-item.hbs'; import EmptySearchTemplate from '../templates/nav-search-empty.hbs'; diff --git a/server/sonar-web/src/main/js/app/index.js b/server/sonar-web/src/main/js/app/index.js index 7f5140de816..0ece6b84f95 100644 --- a/server/sonar-web/src/main/js/app/index.js +++ b/server/sonar-web/src/main/js/app/index.js @@ -25,11 +25,6 @@ import installExtensionsHandler from './utils/installExtensionsHandler'; import { installGlobal } from '../helpers/l10n'; import './styles/index'; -require('script!../libs/third-party/jquery-ui.js'); -require('script!../libs/third-party/select2.js'); -require('script!../libs/third-party/keymaster.js'); -require('script!../libs/third-party/bootstrap/tooltip.js'); -require('script!../libs/third-party/bootstrap/dropdown.js'); require('script!../libs/select2-jquery-ui-fix.js'); require('script!../libs/inputs.js'); require('script!../libs/jquery-isolated-scroll.js'); diff --git a/server/sonar-web/src/main/js/app/utils/startAjaxMonitoring.js b/server/sonar-web/src/main/js/app/utils/startAjaxMonitoring.js index c60f3bca742..f468cab3149 100644 --- a/server/sonar-web/src/main/js/app/utils/startAjaxMonitoring.js +++ b/server/sonar-web/src/main/js/app/utils/startAjaxMonitoring.js @@ -21,7 +21,7 @@ import $ from 'jquery'; import Backbone from 'backbone'; import Marionette from 'backbone.marionette'; import escapeHtml from 'escape-html'; -import uniqueId from 'lodash/uniqueId'; +import { uniqueId } from 'lodash'; import { translate } from '../../helpers/l10n'; import { getCSRFTokenName, getCSRFTokenValue } from '../../helpers/request'; diff --git a/server/sonar-web/src/main/js/app/utils/startReactApp.js b/server/sonar-web/src/main/js/app/utils/startReactApp.js index 5f92bfa3697..34f86b21085 100644 --- a/server/sonar-web/src/main/js/app/utils/startReactApp.js +++ b/server/sonar-web/src/main/js/app/utils/startReactApp.js @@ -51,7 +51,7 @@ import groupsRoutes from '../../apps/groups/routes'; import issuesRoutes from '../../apps/issues/routes'; import metricsRoutes from '../../apps/metrics/routes'; import overviewRoutes from '../../apps/overview/routes'; -import organizationsRouters from '../../apps/organizations/routes'; +import organizationsRoutes from '../../apps/organizations/routes'; import permissionTemplatesRoutes from '../../apps/permission-templates/routes'; import projectActivityRoutes from '../../apps/projectActivity/routes'; import projectAdminRoutes from '../../apps/project-admin/routes'; @@ -88,13 +88,42 @@ const startReactApp = () => { <Provider store={store}> <Router history={history} onUpdate={handleUpdate}> <Route + path="/account/issues" + onEnter={() => { + const defaultFilter = window.location.hash || '#resolve=false'; + window.location = `${window.baseUrl}/issues${defaultFilter}|assigned_to_me=true`; + }} + /> + + <Route + path="/codingrules" + onEnter={(nextState, replace) => { + replace('/coding_rules' + window.location.hash); + }} + /> + + <Route path="/dashboard/index/:key" onEnter={(nextState, replace) => { replace({ pathname: '/dashboard', query: { id: nextState.params.key } }); }} /> + <Route + path="/issues/search" + onEnter={(nextState, replace) => { + replace('/issues' + window.location.hash); + }} + /> + + <Redirect from="/component/index" to="/component" /> + <Redirect from="/dashboard/index" to="/dashboard" /> + <Redirect from="/governance" to="/view" /> <Redirect from="/extension/governance/portfolios" to="/portfolios" /> + <Redirect from="/profiles/index" to="/profiles" /> + <Redirect from="/quality_gates/index" to="/quality_gates" /> + <Redirect from="/settings/index" to="/settings" /> + <Redirect from="/system/index" to="/system" /> <Route path="markdown/help" component={MarkdownHelp} /> @@ -114,34 +143,27 @@ const startReactApp = () => { <IndexRoute component={Landing} /> <Route component={GlobalContainer}> - <Route path="about">{aboutRoutes}</Route> - <Route path="account">{accountRoutes}</Route> - <Route - path="codingrules" - onEnter={(nextState, replace) => { - replace('/coding_rules' + window.location.hash); - }} - /> - <Route path="coding_rules">{codingRulesRoutes}</Route> - <Route path="component">{componentRoutes}</Route> + <Route path="about" childRoutes={aboutRoutes} /> + <Route path="account" childRoutes={accountRoutes} /> + <Route path="coding_rules" childRoutes={codingRulesRoutes} /> + <Route path="component" childRoutes={componentRoutes} /> <Route path="extension/:pluginKey/:extensionKey" component={GlobalPageExtension} /> - <Route path="issues">{issuesRoutes}</Route> - <Route path="organizations">{organizationsRouters}</Route> - <Route path="projects">{projectsRoutes}</Route> - <Route path="quality_gates">{qualityGatesRoutes}</Route> + <Route path="issues" childRoutes={issuesRoutes} /> + <Route path="organizations" childRoutes={organizationsRoutes} /> + <Route path="projects" childRoutes={projectsRoutes} /> + <Route path="quality_gates" childRoutes={qualityGatesRoutes} /> <Route path="portfolios" component={PortfoliosPage} /> - <Route path="profiles">{qualityProfilesRoutes}</Route> - <Route path="web_api">{webAPIRoutes}</Route> + <Route path="profiles" childRoutes={qualityProfilesRoutes} /> + <Route path="web_api" childRoutes={webAPIRoutes} /> <Route component={ProjectContainer}> - <Route path="code">{codeRoutes}</Route> - <Route path="component_issues">{componentIssuesRoutes}</Route> - <Route path="component_measures">{componentMeasuresRoutes}</Route> - <Route path="custom_measures">{customMeasuresRoutes}</Route> - <Route path="dashboard">{overviewRoutes}</Route> - <Redirect from="governance" to="/view" /> + <Route path="code" childRoutes={codeRoutes} /> + <Route path="component_issues" childRoutes={componentIssuesRoutes} /> + <Route path="component_measures" childRoutes={componentMeasuresRoutes} /> + <Route path="custom_measures" childRoutes={customMeasuresRoutes} /> + <Route path="dashboard" childRoutes={overviewRoutes} /> <Route path="project"> - <Route path="activity">{projectActivityRoutes}</Route> + <Route path="activity" childRoutes={projectActivityRoutes} /> <Route path="admin" component={ProjectAdminContainer}> <Route path="extension/:pluginKey/:extensionKey" @@ -153,11 +175,11 @@ const startReactApp = () => { path="extension/:pluginKey/:extensionKey" component={ProjectPageExtension} /> - <Route path="background_tasks">{backgroundTasksRoutes}</Route> - <Route path="settings">{settingsRoutes}</Route> + <Route path="background_tasks" childRoutes={backgroundTasksRoutes} /> + <Route path="settings" childRoutes={settingsRoutes} /> {projectAdminRoutes} </Route> - <Route path="project_roles">{projectPermissionsRoutes}</Route> + <Route path="project_roles" childRoutes={projectPermissionsRoutes} /> <Route path="view" component={ViewDashboard} /> </Route> @@ -166,16 +188,16 @@ const startReactApp = () => { path="admin/extension/:pluginKey/:extensionKey" component={GlobalAdminPageExtension} /> - <Route path="background_tasks">{backgroundTasksRoutes}</Route> - <Route path="groups">{groupsRoutes}</Route> - <Route path="metrics">{metricsRoutes}</Route> - <Route path="permission_templates">{permissionTemplatesRoutes}</Route> - <Route path="projects_admin">{projectsAdminRoutes}</Route> - <Route path="roles/global">{globalPermissionsRoutes}</Route> - <Route path="settings">{settingsRoutes}</Route> - <Route path="system">{systemRoutes}</Route> - <Route path="updatecenter">{updateCenterRoutes}</Route> - <Route path="users">{usersRoutes}</Route> + <Route path="background_tasks" childRoutes={backgroundTasksRoutes} /> + <Route path="groups" childRoutes={groupsRoutes} /> + <Route path="metrics" childRoutes={metricsRoutes} /> + <Route path="permission_templates" childRoutes={permissionTemplatesRoutes} /> + <Route path="projects_admin" childRoutes={projectsAdminRoutes} /> + <Route path="roles/global" childRoutes={globalPermissionsRoutes} /> + <Route path="settings" childRoutes={settingsRoutes} /> + <Route path="system" childRoutes={systemRoutes} /> + <Route path="updatecenter" childRoutes={updateCenterRoutes} /> + <Route path="users" childRoutes={usersRoutes} /> </Route> </Route> diff --git a/server/sonar-web/src/main/js/apps/about/components/AboutApp.js b/server/sonar-web/src/main/js/apps/about/components/AboutApp.js index 6efe4c891d0..a0f80af5dca 100644 --- a/server/sonar-web/src/main/js/apps/about/components/AboutApp.js +++ b/server/sonar-web/src/main/js/apps/about/components/AboutApp.js @@ -20,7 +20,7 @@ // @flow import React from 'react'; import { connect } from 'react-redux'; -import keyBy from 'lodash/keyBy'; +import { keyBy } from 'lodash'; import { Link } from 'react-router'; import AboutProjects from './AboutProjects'; import EntryIssueTypes from './EntryIssueTypes'; @@ -43,7 +43,7 @@ type State = { loading: boolean, projectsCount?: number, issueTypes?: { - [key: string]: { + [key: string]: ?{ count: number } } @@ -140,8 +140,7 @@ class AboutApp extends React.Component { <a className="button" href="https://redirect.sonarsource.com/doc/home.html" - target="_blank" - > + target="_blank"> {translate('about_page.read_documentation')} </a> </div> diff --git a/server/sonar-web/src/main/js/apps/about/routes.js b/server/sonar-web/src/main/js/apps/about/routes.js index a8d72cc6e72..13940436e30 100644 --- a/server/sonar-web/src/main/js/apps/about/routes.js +++ b/server/sonar-web/src/main/js/apps/about/routes.js @@ -17,8 +17,13 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -import React from 'react'; -import { IndexRoute } from 'react-router'; -import AboutApp from './components/AboutApp'; +const routes = [ + { + getIndexRoute(_, callback) { + require.ensure([], require => + callback(null, { component: require('./components/AboutApp').default })); + } + } +]; -export default <IndexRoute component={AboutApp} />; +export default routes; diff --git a/server/sonar-web/src/main/js/apps/account/notifications/Projects.js b/server/sonar-web/src/main/js/apps/account/notifications/Projects.js index ccc704ab397..41de2832fdb 100644 --- a/server/sonar-web/src/main/js/apps/account/notifications/Projects.js +++ b/server/sonar-web/src/main/js/apps/account/notifications/Projects.js @@ -20,7 +20,7 @@ import React from 'react'; import Select from 'react-select'; import { connect } from 'react-redux'; -import differenceBy from 'lodash/differenceBy'; +import { differenceBy } from 'lodash'; import ProjectNotifications from './ProjectNotifications'; import Organization from '../../../components/shared/Organization'; import { translate } from '../../../helpers/l10n'; diff --git a/server/sonar-web/src/main/js/apps/account/organizations/CreateOrganizationForm.js b/server/sonar-web/src/main/js/apps/account/organizations/CreateOrganizationForm.js index 34baf4aa21f..26d0f515e48 100644 --- a/server/sonar-web/src/main/js/apps/account/organizations/CreateOrganizationForm.js +++ b/server/sonar-web/src/main/js/apps/account/organizations/CreateOrganizationForm.js @@ -20,7 +20,7 @@ // @flow import React from 'react'; import Modal from 'react-modal'; -import debounce from 'lodash/debounce'; +import { debounce } from 'lodash'; import { connect } from 'react-redux'; import { withRouter } from 'react-router'; import { translate } from '../../../helpers/l10n'; diff --git a/server/sonar-web/src/main/js/apps/account/projects/ProjectCard.js b/server/sonar-web/src/main/js/apps/account/projects/ProjectCard.js index 6464f3edeeb..b6130a538c7 100644 --- a/server/sonar-web/src/main/js/apps/account/projects/ProjectCard.js +++ b/server/sonar-web/src/main/js/apps/account/projects/ProjectCard.js @@ -19,7 +19,7 @@ */ import React from 'react'; import moment from 'moment'; -import sortBy from 'lodash/sortBy'; +import { sortBy } from 'lodash'; import { Link } from 'react-router'; import Level from '../../../components/ui/Level'; import { projectType } from './propTypes'; diff --git a/server/sonar-web/src/main/js/apps/account/routes.js b/server/sonar-web/src/main/js/apps/account/routes.js index daeea0fbb33..0fc03242eaa 100644 --- a/server/sonar-web/src/main/js/apps/account/routes.js +++ b/server/sonar-web/src/main/js/apps/account/routes.js @@ -17,34 +17,56 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -import React from 'react'; -import { Route, IndexRoute } from 'react-router'; -import Account from './components/Account'; -import ProjectsContainer from './projects/ProjectsContainer'; -import Security from './components/Security'; -import Profile from './profile/Profile'; -import Notifications from './notifications/Notifications'; -import UserOrganizations from './organizations/UserOrganizations'; -import CreateOrganizationForm from './organizations/CreateOrganizationForm'; +const routes = [ + { + getComponent(_, callback) { + require.ensure([], require => callback(null, require('./components/Account').default)); + }, + childRoutes: [ + { + getIndexRoute(_, callback) { + require.ensure([], require => + callback(null, { component: require('./profile/Profile').default })); + } + }, + { + path: 'security', + getComponent(_, callback) { + require.ensure([], require => callback(null, require('./components/Security').default)); + } + }, + { + path: 'projects', + getComponent(_, callback) { + require.ensure([], require => + callback(null, require('./projects/ProjectsContainer').default)); + } + }, + { + path: 'notifications', + getComponent(_, callback) { + require.ensure([], require => + callback(null, require('./notifications/Notifications').default)); + } + }, + { + path: 'organizations', + getComponent(_, callback) { + require.ensure([], require => + callback(null, require('./organizations/UserOrganizations').default)); + }, + childRoutes: [ + { + path: 'create', + getComponent(_, callback) { + require.ensure([], require => + callback(null, require('./organizations/CreateOrganizationForm').default)); + } + } + ] + } + ] + } +]; -export default ( - <Route component={Account}> - <IndexRoute component={Profile} /> - <Route path="security" component={Security} /> - <Route path="projects" component={ProjectsContainer} /> - <Route path="notifications" component={Notifications} /> - <Route path="organizations" component={UserOrganizations}> - <Route path="create" component={CreateOrganizationForm} /> - </Route> - - <Route - path="issues" - onEnter={() => { - window.location = window.baseUrl + - '/issues' + - window.location.hash + - '|assigned_to_me=true'; - }} - /> - </Route> -); +export default routes; diff --git a/server/sonar-web/src/main/js/apps/background-tasks/components/BackgroundTasksApp.js b/server/sonar-web/src/main/js/apps/background-tasks/components/BackgroundTasksApp.js index ed7d23a657d..a0994d4bef8 100644 --- a/server/sonar-web/src/main/js/apps/background-tasks/components/BackgroundTasksApp.js +++ b/server/sonar-web/src/main/js/apps/background-tasks/components/BackgroundTasksApp.js @@ -20,8 +20,7 @@ // @flow import React from 'react'; import shallowCompare from 'react-addons-shallow-compare'; -import debounce from 'lodash/debounce'; -import uniq from 'lodash/uniq'; +import { debounce, uniq } from 'lodash'; import { connect } from 'react-redux'; import { DEFAULT_FILTERS, DEBOUNCE_DELAY, STATUSES, CURRENTS } from './../constants'; import Header from './Header'; diff --git a/server/sonar-web/src/main/js/apps/background-tasks/routes.js b/server/sonar-web/src/main/js/apps/background-tasks/routes.js index 895734d05ef..b67c86a2771 100644 --- a/server/sonar-web/src/main/js/apps/background-tasks/routes.js +++ b/server/sonar-web/src/main/js/apps/background-tasks/routes.js @@ -17,8 +17,13 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -import React from 'react'; -import { IndexRoute } from 'react-router'; -import BackgroundTasksApp from './components/BackgroundTasksApp'; +const routes = [ + { + getIndexRoute(_, callback) { + require.ensure([], require => + callback(null, { component: require('./components/BackgroundTasksApp').default })); + } + } +]; -export default <IndexRoute component={BackgroundTasksApp} />; +export default routes; diff --git a/server/sonar-web/src/main/js/apps/code/components/Search.js b/server/sonar-web/src/main/js/apps/code/components/Search.js index 93315434b45..0c2d95a7209 100644 --- a/server/sonar-web/src/main/js/apps/code/components/Search.js +++ b/server/sonar-web/src/main/js/apps/code/components/Search.js @@ -20,7 +20,7 @@ import React from 'react'; import shallowCompare from 'react-addons-shallow-compare'; import classNames from 'classnames'; -import debounce from 'lodash/debounce'; +import { debounce } from 'lodash'; import Components from './Components'; import { getTree } from '../../../api/components'; import { translate, translateWithParameters } from '../../../helpers/l10n'; diff --git a/server/sonar-web/src/main/js/apps/code/routes.js b/server/sonar-web/src/main/js/apps/code/routes.js index 07bb9e8a918..c2e9fd242f4 100644 --- a/server/sonar-web/src/main/js/apps/code/routes.js +++ b/server/sonar-web/src/main/js/apps/code/routes.js @@ -17,8 +17,13 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -import React from 'react'; -import { IndexRoute } from 'react-router'; -import App from './components/App'; +const routes = [ + { + getIndexRoute(_, callback) { + require.ensure([], require => + callback(null, { component: require('./components/App').default })); + } + } +]; -export default <IndexRoute component={App} />; +export default routes; diff --git a/server/sonar-web/src/main/js/apps/code/utils.js b/server/sonar-web/src/main/js/apps/code/utils.js index c5451d4a89e..44d539a2122 100644 --- a/server/sonar-web/src/main/js/apps/code/utils.js +++ b/server/sonar-web/src/main/js/apps/code/utils.js @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -import without from 'lodash/without'; +import { without } from 'lodash'; import { addComponent, getComponent as getComponentFromBucket, diff --git a/server/sonar-web/src/main/js/apps/coding-rules/facets/active-severity-facet.js b/server/sonar-web/src/main/js/apps/coding-rules/facets/active-severity-facet.js index 0bda9b9fada..11eaa506d3a 100644 --- a/server/sonar-web/src/main/js/apps/coding-rules/facets/active-severity-facet.js +++ b/server/sonar-web/src/main/js/apps/coding-rules/facets/active-severity-facet.js @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -import sortBy from 'lodash/sortBy'; +import { sortBy } from 'lodash'; import BaseFacet from './base-facet'; import Template from '../templates/facets/coding-rules-severity-facet.hbs'; import { translate } from '../../../helpers/l10n'; diff --git a/server/sonar-web/src/main/js/apps/coding-rules/facets/quality-profile-facet.js b/server/sonar-web/src/main/js/apps/coding-rules/facets/quality-profile-facet.js index f2568f2109c..1fd1c67ead6 100644 --- a/server/sonar-web/src/main/js/apps/coding-rules/facets/quality-profile-facet.js +++ b/server/sonar-web/src/main/js/apps/coding-rules/facets/quality-profile-facet.js @@ -18,7 +18,7 @@ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ import $ from 'jquery'; -import sortBy from 'lodash/sortBy'; +import { sortBy } from 'lodash'; import BaseFacet from './base-facet'; import Template from '../templates/facets/coding-rules-quality-profile-facet.hbs'; diff --git a/server/sonar-web/src/main/js/apps/coding-rules/facets/repository-facet.js b/server/sonar-web/src/main/js/apps/coding-rules/facets/repository-facet.js index 379c9b8fbdc..2e6a00b28d2 100644 --- a/server/sonar-web/src/main/js/apps/coding-rules/facets/repository-facet.js +++ b/server/sonar-web/src/main/js/apps/coding-rules/facets/repository-facet.js @@ -17,7 +17,6 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -import 'lodash/object'; import CustomValuesFacet from './custom-values-facet'; export default CustomValuesFacet.extend({ diff --git a/server/sonar-web/src/main/js/apps/coding-rules/facets/severity-facet.js b/server/sonar-web/src/main/js/apps/coding-rules/facets/severity-facet.js index cc0afc62ce3..f3b21711f7f 100644 --- a/server/sonar-web/src/main/js/apps/coding-rules/facets/severity-facet.js +++ b/server/sonar-web/src/main/js/apps/coding-rules/facets/severity-facet.js @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -import sortBy from 'lodash/sortBy'; +import { sortBy } from 'lodash'; import BaseFacet from './base-facet'; import Template from '../templates/facets/coding-rules-severity-facet.hbs'; diff --git a/server/sonar-web/src/main/js/apps/coding-rules/facets/status-facet.js b/server/sonar-web/src/main/js/apps/coding-rules/facets/status-facet.js index 49645fe82bb..9468aff68e7 100644 --- a/server/sonar-web/src/main/js/apps/coding-rules/facets/status-facet.js +++ b/server/sonar-web/src/main/js/apps/coding-rules/facets/status-facet.js @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -import sortBy from 'lodash/sortBy'; +import { sortBy } from 'lodash'; import BaseFacet from './base-facet'; import { translate } from '../../../helpers/l10n'; diff --git a/server/sonar-web/src/main/js/apps/coding-rules/facets/type-facet.js b/server/sonar-web/src/main/js/apps/coding-rules/facets/type-facet.js index 7e940f0ff7b..8dfbaf61eaf 100644 --- a/server/sonar-web/src/main/js/apps/coding-rules/facets/type-facet.js +++ b/server/sonar-web/src/main/js/apps/coding-rules/facets/type-facet.js @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -import sortBy from 'lodash/sortBy'; +import { sortBy } from 'lodash'; import BaseFacet from './base-facet'; import Template from '../templates/facets/coding-rules-type-facet.hbs'; diff --git a/server/sonar-web/src/main/js/apps/coding-rules/init.js b/server/sonar-web/src/main/js/apps/coding-rules/init.js index bd3eeebda96..f25d2ad0c10 100644 --- a/server/sonar-web/src/main/js/apps/coding-rules/init.js +++ b/server/sonar-web/src/main/js/apps/coding-rules/init.js @@ -18,7 +18,7 @@ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ import $ from 'jquery'; -import sortBy from 'lodash/sortBy'; +import { sortBy } from 'lodash'; import Backbone from 'backbone'; import Marionette from 'backbone.marionette'; import State from './models/state'; diff --git a/server/sonar-web/src/main/js/apps/coding-rules/routes.js b/server/sonar-web/src/main/js/apps/coding-rules/routes.js index 651cc6aeaec..a1bba34c6b6 100644 --- a/server/sonar-web/src/main/js/apps/coding-rules/routes.js +++ b/server/sonar-web/src/main/js/apps/coding-rules/routes.js @@ -17,8 +17,16 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -import React from 'react'; -import { IndexRoute } from 'react-router'; -import CodingRulesAppContainer from './components/CodingRulesAppContainer'; +const routes = [ + { + indexRoute: { + getComponent(_, callback) { + require.ensure([], require => { + callback(null, require('./components/CodingRulesAppContainer').default); + }); + } + } + } +]; -export default <IndexRoute component={CodingRulesAppContainer} />; +export default routes; diff --git a/server/sonar-web/src/main/js/apps/coding-rules/rule-details-view.js b/server/sonar-web/src/main/js/apps/coding-rules/rule-details-view.js index c83af70b66b..2fa5eb3f2f4 100644 --- a/server/sonar-web/src/main/js/apps/coding-rules/rule-details-view.js +++ b/server/sonar-web/src/main/js/apps/coding-rules/rule-details-view.js @@ -18,7 +18,7 @@ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ import $ from 'jquery'; -import union from 'lodash/union'; +import { union } from 'lodash'; import Backbone from 'backbone'; import Marionette from 'backbone.marionette'; import Rules from './models/rules'; diff --git a/server/sonar-web/src/main/js/apps/coding-rules/rule-filter-view.js b/server/sonar-web/src/main/js/apps/coding-rules/rule-filter-view.js index 98e7529af5c..e3cb43a256f 100644 --- a/server/sonar-web/src/main/js/apps/coding-rules/rule-filter-view.js +++ b/server/sonar-web/src/main/js/apps/coding-rules/rule-filter-view.js @@ -18,7 +18,7 @@ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ import $ from 'jquery'; -import union from 'lodash/union'; +import { union } from 'lodash'; import ActionOptionsView from '../../components/common/action-options-view'; import Template from './templates/coding-rules-rule-filter-form.hbs'; diff --git a/server/sonar-web/src/main/js/apps/coding-rules/rule/rule-meta-view.js b/server/sonar-web/src/main/js/apps/coding-rules/rule/rule-meta-view.js index b7fdf7d3c33..ba8ed5311ba 100644 --- a/server/sonar-web/src/main/js/apps/coding-rules/rule/rule-meta-view.js +++ b/server/sonar-web/src/main/js/apps/coding-rules/rule/rule-meta-view.js @@ -18,8 +18,7 @@ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ import $ from 'jquery'; -import difference from 'lodash/difference'; -import union from 'lodash/union'; +import { difference, union } from 'lodash'; import Marionette from 'backbone.marionette'; import RuleFilterMixin from './rule-filter-mixin'; import Template from '../templates/rule/coding-rules-rule-meta.hbs'; diff --git a/server/sonar-web/src/main/js/apps/coding-rules/rule/rule-profile-view.js b/server/sonar-web/src/main/js/apps/coding-rules/rule/rule-profile-view.js index 7265d718b25..eab8d1be804 100644 --- a/server/sonar-web/src/main/js/apps/coding-rules/rule/rule-profile-view.js +++ b/server/sonar-web/src/main/js/apps/coding-rules/rule/rule-profile-view.js @@ -18,7 +18,7 @@ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ import $ from 'jquery'; -import sortBy from 'lodash/sortBy'; +import { sortBy } from 'lodash'; import Backbone from 'backbone'; import Marionette from 'backbone.marionette'; import ProfileActivationView from './profile-activation-view'; diff --git a/server/sonar-web/src/main/js/apps/coding-rules/workspace-list-item-view.js b/server/sonar-web/src/main/js/apps/coding-rules/workspace-list-item-view.js index 80568ff7d9e..77c0b59d6a5 100644 --- a/server/sonar-web/src/main/js/apps/coding-rules/workspace-list-item-view.js +++ b/server/sonar-web/src/main/js/apps/coding-rules/workspace-list-item-view.js @@ -18,7 +18,7 @@ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ import $ from 'jquery'; -import union from 'lodash/union'; +import { union } from 'lodash'; import Backbone from 'backbone'; import WorkspaceListItemView from '../../components/navigator/workspace-list-item-view'; import ProfileActivationView from './rule/profile-activation-view'; diff --git a/server/sonar-web/src/main/js/apps/component-issues/init.js b/server/sonar-web/src/main/js/apps/component-issues/init.js index 65721263cc7..038c2cdd78d 100644 --- a/server/sonar-web/src/main/js/apps/component-issues/init.js +++ b/server/sonar-web/src/main/js/apps/component-issues/init.js @@ -18,7 +18,7 @@ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ import $ from 'jquery'; -import difference from 'lodash/difference'; +import { difference } from 'lodash'; import Backbone from 'backbone'; import Marionette from 'backbone.marionette'; import State from '../issues/models/state'; diff --git a/server/sonar-web/src/main/js/apps/component-issues/routes.js b/server/sonar-web/src/main/js/apps/component-issues/routes.js index 0b64f94952f..954ba1487bb 100644 --- a/server/sonar-web/src/main/js/apps/component-issues/routes.js +++ b/server/sonar-web/src/main/js/apps/component-issues/routes.js @@ -17,8 +17,15 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -import React from 'react'; -import { IndexRoute } from 'react-router'; -import ComponentIssuesAppContainer from './components/ComponentIssuesAppContainer'; +const routes = [ + { + indexRoute: { + getComponent(_, callback) { + require.ensure([], require => + callback(null, require('./components/ComponentIssuesAppContainer').default)); + } + } + } +]; -export default <IndexRoute component={ComponentIssuesAppContainer} />; +export default routes; diff --git a/server/sonar-web/src/main/js/apps/component-measures/app/App.js b/server/sonar-web/src/main/js/apps/component-measures/app/App.js index 29aa89ae573..b8e50e87846 100644 --- a/server/sonar-web/src/main/js/apps/component-measures/app/App.js +++ b/server/sonar-web/src/main/js/apps/component-measures/app/App.js @@ -19,6 +19,7 @@ */ import React from 'react'; import Spinner from './../components/Spinner'; +import '../styles.css'; export default class App extends React.Component { state = { componentSet: false }; diff --git a/server/sonar-web/src/main/js/apps/component-measures/details/history/MeasureHistory.js b/server/sonar-web/src/main/js/apps/component-measures/details/history/MeasureHistory.js index 833043b8c9e..75f439d3ecc 100644 --- a/server/sonar-web/src/main/js/apps/component-measures/details/history/MeasureHistory.js +++ b/server/sonar-web/src/main/js/apps/component-measures/details/history/MeasureHistory.js @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -import sortBy from 'lodash/sortBy'; +import { sortBy } from 'lodash'; import moment from 'moment'; import React from 'react'; import Spinner from './../../components/Spinner'; diff --git a/server/sonar-web/src/main/js/apps/component-measures/details/treemap/MeasureTreemap.js b/server/sonar-web/src/main/js/apps/component-measures/details/treemap/MeasureTreemap.js index 74f0cc9975d..5287d9f05a6 100644 --- a/server/sonar-web/src/main/js/apps/component-measures/details/treemap/MeasureTreemap.js +++ b/server/sonar-web/src/main/js/apps/component-measures/details/treemap/MeasureTreemap.js @@ -18,6 +18,7 @@ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ import React from 'react'; +import { scaleLinear, scaleOrdinal } from 'd3-scale'; import Spinner from './../../components/Spinner'; import { getLeakValue } from '../../utils'; import { Treemap } from '../../../../components/charts/treemap'; @@ -100,7 +101,7 @@ export default class MeasureTreemap extends React.Component { return `<div class="text-left">${inner}</div>`; } getPercentColorScale(metric) { - const color = d3.scale.linear().domain([0, 25, 50, 75, 100]); + const color = scaleLinear().domain([0, 25, 50, 75, 100]); color.range( metric.direction === 1 ? ['#d4333f', '#ed7d20', '#eabe06', '#b0d513', '#00aa00'] @@ -109,14 +110,12 @@ export default class MeasureTreemap extends React.Component { return color; } getRatingColorScale() { - return d3.scale - .linear() + return scaleLinear() .domain([1, 2, 3, 4, 5]) .range(['#00aa00', '#b0d513', '#eabe06', '#ed7d20', '#d4333f']); } getLevelColorScale() { - return d3.scale - .ordinal() + return scaleOrdinal() .domain(['ERROR', 'WARN', 'OK', 'NONE']) .range(['#d4333f', '#ed7d20', '#00aa00', '#b4b4b4']); } diff --git a/server/sonar-web/src/main/js/apps/component-measures/home/HomeMeasuresList.js b/server/sonar-web/src/main/js/apps/component-measures/home/HomeMeasuresList.js index 187f34739be..d7dbd648955 100644 --- a/server/sonar-web/src/main/js/apps/component-measures/home/HomeMeasuresList.js +++ b/server/sonar-web/src/main/js/apps/component-measures/home/HomeMeasuresList.js @@ -18,8 +18,7 @@ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ import React from 'react'; -import partition from 'lodash/partition'; -import sortBy from 'lodash/sortBy'; +import { partition, sortBy } from 'lodash'; import MeasuresList from './MeasuresList'; import { domains } from '../config/domains'; import { getLocalizedMetricName } from '../../../helpers/l10n'; diff --git a/server/sonar-web/src/main/js/apps/component-measures/home/reducer.js b/server/sonar-web/src/main/js/apps/component-measures/home/reducer.js index f404b7addd1..f529a7ac851 100644 --- a/server/sonar-web/src/main/js/apps/component-measures/home/reducer.js +++ b/server/sonar-web/src/main/js/apps/component-measures/home/reducer.js @@ -17,10 +17,7 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -import groupBy from 'lodash/groupBy'; -import partition from 'lodash/partition'; -import sortBy from 'lodash/sortBy'; -import toPairs from 'lodash/toPairs'; +import { groupBy, partition, sortBy, toPairs } from 'lodash'; import { RECEIVE_MEASURES } from './actions'; import { getLocalizedMetricName } from '../../../helpers/l10n'; diff --git a/server/sonar-web/src/main/js/apps/component-measures/routes.js b/server/sonar-web/src/main/js/apps/component-measures/routes.js index 1fe9d219852..bbf67ad283b 100644 --- a/server/sonar-web/src/main/js/apps/component-measures/routes.js +++ b/server/sonar-web/src/main/js/apps/component-measures/routes.js @@ -17,33 +17,82 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -import React from 'react'; -import { Route, IndexRoute, IndexRedirect } from 'react-router'; -import AppContainer from './app/AppContainer'; -import HomeContainer from './home/HomeContainer'; -import AllMeasuresContainer from './home/AllMeasuresContainer'; -import DomainMeasuresContainer from './home/DomainMeasuresContainer'; -import MeasureDetailsContainer from './details/MeasureDetailsContainer'; -import ListViewContainer from './details/drilldown/ListViewContainer'; -import TreeViewContainer from './details/drilldown/TreeViewContainer'; -import MeasureHistoryContainer from './details/history/MeasureHistoryContainer'; -import MeasureTreemapContainer from './details/treemap/MeasureTreemapContainer'; -import { checkHistoryExistence } from './hooks'; -import './styles.css'; +const routes = [ + { + getComponent(_, callback) { + require.ensure([], require => callback(null, require('./app/AppContainer').default)); + }, + childRoutes: [ + { + getComponent(_, callback) { + require.ensure([], require => callback(null, require('./home/HomeContainer').default)); + }, + childRoutes: [ + { + getIndexRoute(_, callback) { + require.ensure([], require => + callback(null, { component: require('./home/AllMeasuresContainer').default })); + } + }, + { + path: 'domain/:domainName', + getComponent(_, callback) { + require.ensure([], require => + callback(null, require('./home/DomainMeasuresContainer').default)); + } + } + ] + }, + { + path: 'metric/:metricKey', + getComponent(_, callback) { + require.ensure([], require => + callback(null, require('./details/MeasureDetailsContainer').default)); + }, + childRoutes: [ + { + indexRoute: { + onEnter(nextState, replace) { + const { params, location } = nextState; + replace({ + pathname: `/component_measures/metric/${params.metricKey}/list`, + query: location.query + }); + } + } + }, + { + path: 'list', + getComponent(_, callback) { + require.ensure([], require => + callback(null, require('./details/drilldown/ListViewContainer').default)); + } + }, + { + path: 'tree', + getComponent(_, callback) { + require.ensure([], require => + callback(null, require('./details/drilldown/TreeViewContainer').default)); + } + }, + { + path: 'history', + getComponent(_, callback) { + require.ensure([], require => + callback(null, require('./details/history/MeasureHistoryContainer').default)); + } + }, + { + path: 'treemap', + getComponent(_, callback) { + require.ensure([], require => + callback(null, require('./details/treemap/MeasureTreemapContainer').default)); + } + } + ] + } + ] + } +]; -export default ( - <Route component={AppContainer}> - <Route component={HomeContainer}> - <IndexRoute component={AllMeasuresContainer} /> - <Route path="domain/:domainName" component={DomainMeasuresContainer} /> - </Route> - - <Route path="metric/:metricKey" component={MeasureDetailsContainer}> - <IndexRedirect to="list" /> - <Route path="list" component={ListViewContainer} /> - <Route path="tree" component={TreeViewContainer} /> - <Route path="history" component={MeasureHistoryContainer} onEnter={checkHistoryExistence} /> - <Route path="treemap" component={MeasureTreemapContainer} /> - </Route> - </Route> -); +export default routes; diff --git a/server/sonar-web/src/main/js/apps/component-measures/store/treeViewActions.js b/server/sonar-web/src/main/js/apps/component-measures/store/treeViewActions.js index 2d58b671872..34fffe1b8cd 100644 --- a/server/sonar-web/src/main/js/apps/component-measures/store/treeViewActions.js +++ b/server/sonar-web/src/main/js/apps/component-measures/store/treeViewActions.js @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -import initial from 'lodash/initial'; +import { initial } from 'lodash'; import { getComponentTree } from '../../../api/components'; import { enhanceWithMeasure } from '../utils'; import { startFetching, stopFetching } from './statusActions'; diff --git a/server/sonar-web/src/main/js/apps/component-measures/store/treeViewReducer.js b/server/sonar-web/src/main/js/apps/component-measures/store/treeViewReducer.js index 05c6edb9b7f..71050fdad57 100644 --- a/server/sonar-web/src/main/js/apps/component-measures/store/treeViewReducer.js +++ b/server/sonar-web/src/main/js/apps/component-measures/store/treeViewReducer.js @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -import pick from 'lodash/pick'; +import { pick } from 'lodash'; import { DISPLAY_HOME } from './../app/actions'; import { UPDATE_STORE, INIT } from './treeViewActions'; diff --git a/server/sonar-web/src/main/js/apps/component/routes.js b/server/sonar-web/src/main/js/apps/component/routes.js index b8938d81faf..edb7d77a7f2 100644 --- a/server/sonar-web/src/main/js/apps/component/routes.js +++ b/server/sonar-web/src/main/js/apps/component/routes.js @@ -17,12 +17,14 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -// @flow -import React from 'react'; -import { IndexRoute, Redirect } from 'react-router'; -import App from './components/App'; - -export default [ - <Redirect key="1" from="/component/index" to="/component" />, - <IndexRoute key="2" component={App} /> +const routes = [ + { + indexRoute: { + getComponent(_, callback) { + require.ensure([], require => callback(null, require('./components/App').default)); + } + } + } ]; + +export default routes; diff --git a/server/sonar-web/src/main/js/apps/custom-measures/custom-measure.js b/server/sonar-web/src/main/js/apps/custom-measures/custom-measure.js index 1338212736a..b2db378831b 100644 --- a/server/sonar-web/src/main/js/apps/custom-measures/custom-measure.js +++ b/server/sonar-web/src/main/js/apps/custom-measures/custom-measure.js @@ -17,8 +17,7 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -import defaults from 'lodash/defaults'; -import pick from 'lodash/pick'; +import { defaults, pick } from 'lodash'; import Backbone from 'backbone'; export default Backbone.Model.extend({ diff --git a/server/sonar-web/src/main/js/apps/custom-measures/custom-measures.js b/server/sonar-web/src/main/js/apps/custom-measures/custom-measures.js index 512b11d279a..e35c981c784 100644 --- a/server/sonar-web/src/main/js/apps/custom-measures/custom-measures.js +++ b/server/sonar-web/src/main/js/apps/custom-measures/custom-measures.js @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -import uniq from 'lodash/uniq'; +import { uniq } from 'lodash'; import Backbone from 'backbone'; import CustomMeasure from './custom-measure'; diff --git a/server/sonar-web/src/main/js/apps/custom-measures/routes.js b/server/sonar-web/src/main/js/apps/custom-measures/routes.js index cef57a1375d..bae2abe703a 100644 --- a/server/sonar-web/src/main/js/apps/custom-measures/routes.js +++ b/server/sonar-web/src/main/js/apps/custom-measures/routes.js @@ -17,8 +17,13 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -import React from 'react'; -import { IndexRoute } from 'react-router'; -import CustomMeasuresAppContainer from './components/CustomMeasuresAppContainer'; +const routes = [ + { + getIndexRoute(_, callback) { + require.ensure([], require => + callback(null, { component: require('./components/CustomMeasuresAppContainer').default })); + } + } +]; -export default <IndexRoute component={CustomMeasuresAppContainer} />; +export default routes; diff --git a/server/sonar-web/src/main/js/apps/groups/group.js b/server/sonar-web/src/main/js/apps/groups/group.js index a6a0d587a19..4ca0a08d98e 100644 --- a/server/sonar-web/src/main/js/apps/groups/group.js +++ b/server/sonar-web/src/main/js/apps/groups/group.js @@ -17,8 +17,7 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -import defaults from 'lodash/defaults'; -import pick from 'lodash/pick'; +import { defaults, pick } from 'lodash'; import Backbone from 'backbone'; export default Backbone.Model.extend({ diff --git a/server/sonar-web/src/main/js/apps/groups/routes.js b/server/sonar-web/src/main/js/apps/groups/routes.js index 682cb275dab..d161da9d9fe 100644 --- a/server/sonar-web/src/main/js/apps/groups/routes.js +++ b/server/sonar-web/src/main/js/apps/groups/routes.js @@ -17,9 +17,17 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -import React from 'react'; -import { IndexRoute } from 'react-router'; -import GroupsAppContainer from './components/GroupsAppContainer'; -import forSingleOrganization from '../organizations/forSingleOrganization'; +const routes = [ + { + getIndexRoute(_, callback) { + require.ensure([], require => { + const GroupsAppContainer = require('./components/GroupsAppContainer').default; + const forSingleOrganization = require('../organizations/forSingleOrganization').default; + const component = forSingleOrganization(GroupsAppContainer); + callback(null, { component }); + }); + } + } +]; -export default <IndexRoute component={forSingleOrganization(GroupsAppContainer)} />; +export default routes; diff --git a/server/sonar-web/src/main/js/apps/groups/search-view.js b/server/sonar-web/src/main/js/apps/groups/search-view.js index 6c25de952a0..9acd7109e57 100644 --- a/server/sonar-web/src/main/js/apps/groups/search-view.js +++ b/server/sonar-web/src/main/js/apps/groups/search-view.js @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -import debounce from 'lodash/debounce'; +import { debounce } from 'lodash'; import Marionette from 'backbone.marionette'; import Template from './templates/groups-search.hbs'; diff --git a/server/sonar-web/src/main/js/apps/issues/BulkChangeForm.js b/server/sonar-web/src/main/js/apps/issues/BulkChangeForm.js index 40e9eae8ac5..92e51cb2d7c 100644 --- a/server/sonar-web/src/main/js/apps/issues/BulkChangeForm.js +++ b/server/sonar-web/src/main/js/apps/issues/BulkChangeForm.js @@ -18,7 +18,7 @@ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ // @flow -import sortBy from 'lodash/sortBy'; +import { sortBy } from 'lodash'; import ModalForm from '../../components/common/modal-form'; import Template from './templates/BulkChangeForm.hbs'; import getCurrentUserFromStore from '../../app/utils/getCurrentUserFromStore'; diff --git a/server/sonar-web/src/main/js/apps/issues/facets/assignee-facet.js b/server/sonar-web/src/main/js/apps/issues/facets/assignee-facet.js index 471d7c75192..0df30cbced8 100644 --- a/server/sonar-web/src/main/js/apps/issues/facets/assignee-facet.js +++ b/server/sonar-web/src/main/js/apps/issues/facets/assignee-facet.js @@ -18,7 +18,7 @@ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ import $ from 'jquery'; -import sortBy from 'lodash/sortBy'; +import { sortBy } from 'lodash'; import CustomValuesFacet from './custom-values-facet'; import Template from '../templates/facets/issues-assignee-facet.hbs'; diff --git a/server/sonar-web/src/main/js/apps/issues/facets/creation-date-facet.js b/server/sonar-web/src/main/js/apps/issues/facets/creation-date-facet.js index 41110a8a6cd..81c31973b79 100644 --- a/server/sonar-web/src/main/js/apps/issues/facets/creation-date-facet.js +++ b/server/sonar-web/src/main/js/apps/issues/facets/creation-date-facet.js @@ -19,7 +19,7 @@ */ import $ from 'jquery'; import moment from 'moment'; -import times from 'lodash/times'; +import { times } from 'lodash'; import BaseFacet from './base-facet'; import Template from '../templates/facets/issues-creation-date-facet.hbs'; import '../../../components/widgets/barchart'; diff --git a/server/sonar-web/src/main/js/apps/issues/facets/resolution-facet.js b/server/sonar-web/src/main/js/apps/issues/facets/resolution-facet.js index c0289fe5956..d4e01b1c0f4 100644 --- a/server/sonar-web/src/main/js/apps/issues/facets/resolution-facet.js +++ b/server/sonar-web/src/main/js/apps/issues/facets/resolution-facet.js @@ -18,7 +18,7 @@ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ import $ from 'jquery'; -import sortBy from 'lodash/sortBy'; +import { sortBy } from 'lodash'; import BaseFacet from './base-facet'; import Template from '../templates/facets/issues-resolution-facet.hbs'; diff --git a/server/sonar-web/src/main/js/apps/issues/facets/severity-facet.js b/server/sonar-web/src/main/js/apps/issues/facets/severity-facet.js index 6e2a83deb6b..db5cd337838 100644 --- a/server/sonar-web/src/main/js/apps/issues/facets/severity-facet.js +++ b/server/sonar-web/src/main/js/apps/issues/facets/severity-facet.js @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -import sortBy from 'lodash/sortBy'; +import { sortBy } from 'lodash'; import BaseFacet from './base-facet'; import Template from '../templates/facets/issues-severity-facet.hbs'; diff --git a/server/sonar-web/src/main/js/apps/issues/facets/status-facet.js b/server/sonar-web/src/main/js/apps/issues/facets/status-facet.js index 4259ecb1930..cb4e88a5f49 100644 --- a/server/sonar-web/src/main/js/apps/issues/facets/status-facet.js +++ b/server/sonar-web/src/main/js/apps/issues/facets/status-facet.js @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -import sortBy from 'lodash/sortBy'; +import { sortBy } from 'lodash'; import BaseFacet from './base-facet'; import Template from '../templates/facets/issues-status-facet.hbs'; diff --git a/server/sonar-web/src/main/js/apps/issues/facets/type-facet.js b/server/sonar-web/src/main/js/apps/issues/facets/type-facet.js index 6cc723ade7b..efac17ea9f4 100644 --- a/server/sonar-web/src/main/js/apps/issues/facets/type-facet.js +++ b/server/sonar-web/src/main/js/apps/issues/facets/type-facet.js @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -import sortBy from 'lodash/sortBy'; +import { sortBy } from 'lodash'; import BaseFacet from './base-facet'; import Template from '../templates/facets/issues-type-facet.hbs'; diff --git a/server/sonar-web/src/main/js/apps/issues/routes.js b/server/sonar-web/src/main/js/apps/issues/routes.js index 94f564e8728..5f3a27c905c 100644 --- a/server/sonar-web/src/main/js/apps/issues/routes.js +++ b/server/sonar-web/src/main/js/apps/issues/routes.js @@ -17,15 +17,15 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -import React from 'react'; -import { IndexRoute, Route } from 'react-router'; -import IssuesAppContainer from './components/IssuesAppContainer'; - -const onSearchEnter = (nextState, replace) => { - replace('/issues' + window.location.hash); -}; - -export default [ - <IndexRoute key="index" component={IssuesAppContainer} />, - <Route key="search" path="search" onEnter={onSearchEnter} /> +const routes = [ + { + indexRoute: { + getComponent(_, callback) { + require.ensure([], require => + callback(null, require('./components/IssuesAppContainer').default)); + } + } + } ]; + +export default routes; diff --git a/server/sonar-web/src/main/js/apps/metrics/metric.js b/server/sonar-web/src/main/js/apps/metrics/metric.js index 12e186ce6f1..f407122a3ac 100644 --- a/server/sonar-web/src/main/js/apps/metrics/metric.js +++ b/server/sonar-web/src/main/js/apps/metrics/metric.js @@ -17,8 +17,7 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -import defaults from 'lodash/defaults'; -import pick from 'lodash/pick'; +import { defaults, pick } from 'lodash'; import Backbone from 'backbone'; export default Backbone.Model.extend({ diff --git a/server/sonar-web/src/main/js/apps/metrics/routes.js b/server/sonar-web/src/main/js/apps/metrics/routes.js index fe9790a43b1..a7b1354ecf4 100644 --- a/server/sonar-web/src/main/js/apps/metrics/routes.js +++ b/server/sonar-web/src/main/js/apps/metrics/routes.js @@ -17,8 +17,13 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -import React from 'react'; -import { IndexRoute } from 'react-router'; -import MetricsAppContainer from './components/MetricsAppContainer'; +const routes = [ + { + getIndexRoute(_, callback) { + require.ensure([], require => + callback(null, { component: require('./components/MetricsAppContainer').default })); + } + } +]; -export default <IndexRoute component={MetricsAppContainer} />; +export default routes; diff --git a/server/sonar-web/src/main/js/apps/organizations/components/OrganizationEdit.js b/server/sonar-web/src/main/js/apps/organizations/components/OrganizationEdit.js index 63edc23329d..a7052a459ed 100644 --- a/server/sonar-web/src/main/js/apps/organizations/components/OrganizationEdit.js +++ b/server/sonar-web/src/main/js/apps/organizations/components/OrganizationEdit.js @@ -20,7 +20,7 @@ // @flow import React from 'react'; import { connect } from 'react-redux'; -import debounce from 'lodash/debounce'; +import { debounce } from 'lodash'; import { translate } from '../../../helpers/l10n'; import type { Organization } from '../../../store/organizations/duck'; import { getOrganizationByKey } from '../../../store/rootReducer'; diff --git a/server/sonar-web/src/main/js/apps/organizations/routes.js b/server/sonar-web/src/main/js/apps/organizations/routes.js index 6621e19c153..0fdd1061526 100644 --- a/server/sonar-web/src/main/js/apps/organizations/routes.js +++ b/server/sonar-web/src/main/js/apps/organizations/routes.js @@ -17,8 +17,6 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -import React from 'react'; -import { Route, IndexRedirect } from 'react-router'; import OrganizationPage from './components/OrganizationPage'; import OrganizationProjects from './components/OrganizationProjects'; import OrganizationFavoriteProjects from './components/OrganizationFavoriteProjects'; @@ -30,18 +28,40 @@ import OrganizationPermissionTemplates from './components/OrganizationPermission import OrganizationProjectsManagement from './components/OrganizationProjectsManagement'; import OrganizationDelete from './components/OrganizationDelete'; -export default ( - <Route path=":organizationKey" component={OrganizationPage}> - <IndexRedirect to="projects" /> - <Route path="projects" component={OrganizationProjects} /> - <Route path="projects/favorite" component={OrganizationFavoriteProjects} /> - <Route component={OrganizationAdmin}> - <Route path="delete" component={OrganizationDelete} /> - <Route path="edit" component={OrganizationEdit} /> - <Route path="groups" component={OrganizationGroups} /> - <Route path="permissions" component={OrganizationPermissions} /> - <Route path="permission_templates" component={OrganizationPermissionTemplates} /> - <Route path="projects_management" component={OrganizationProjectsManagement} /> - </Route> - </Route> -); +const routes = [ + { + path: ':organizationKey', + component: OrganizationPage, + childRoutes: [ + { + indexRoute: { + onEnter(nextState, replace) { + const { params } = nextState; + replace(`/organizations/${params.organizationKey}/projects`); + } + } + }, + { + path: 'projects', + component: OrganizationProjects + }, + { + path: 'projects/favorite', + component: OrganizationFavoriteProjects + }, + { + component: OrganizationAdmin, + childRoutes: [ + { path: 'delete', component: OrganizationDelete }, + { path: 'edit', component: OrganizationEdit }, + { path: 'groups', component: OrganizationGroups }, + { path: 'permissions', component: OrganizationPermissions }, + { path: 'permission_templates', component: OrganizationPermissionTemplates }, + { path: 'projects_management', component: OrganizationProjectsManagement } + ] + } + ] + } +]; + +export default routes; diff --git a/server/sonar-web/src/main/js/apps/overview/components/Timeline.js b/server/sonar-web/src/main/js/apps/overview/components/Timeline.js index 0c42ba8daff..f2fd61c218a 100644 --- a/server/sonar-web/src/main/js/apps/overview/components/Timeline.js +++ b/server/sonar-web/src/main/js/apps/overview/components/Timeline.js @@ -17,9 +17,9 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -import d3 from 'd3'; import React from 'react'; import shallowCompare from 'react-addons-shallow-compare'; +import { max } from 'd3-array'; import { LineChart } from '../../../components/charts/line-chart'; const HEIGHT = 80; @@ -56,7 +56,7 @@ export default class Timeline extends React.Component { return { x: index, y: snapshot.value }; }); - const domain = [0, d3.max(this.props.history, d => d.value)]; + const domain = [0, max(this.props.history, d => d.value)]; return ( <LineChart diff --git a/server/sonar-web/src/main/js/apps/overview/qualityGate/QualityGateConditions.js b/server/sonar-web/src/main/js/apps/overview/qualityGate/QualityGateConditions.js index 6c036de57de..5e7b533671f 100644 --- a/server/sonar-web/src/main/js/apps/overview/qualityGate/QualityGateConditions.js +++ b/server/sonar-web/src/main/js/apps/overview/qualityGate/QualityGateConditions.js @@ -19,7 +19,7 @@ */ import React from 'react'; import shallowCompare from 'react-addons-shallow-compare'; -import sortBy from 'lodash/sortBy'; +import { sortBy } from 'lodash'; import QualityGateCondition from './QualityGateCondition'; import { ComponentType, ConditionsListType } from '../propTypes'; import { getMeasuresAndMeta } from '../../../api/measures'; diff --git a/server/sonar-web/src/main/js/apps/overview/routes.js b/server/sonar-web/src/main/js/apps/overview/routes.js index a8f9dc5e335..755ec975fd6 100644 --- a/server/sonar-web/src/main/js/apps/overview/routes.js +++ b/server/sonar-web/src/main/js/apps/overview/routes.js @@ -17,11 +17,13 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -import React from 'react'; -import { IndexRoute, Redirect } from 'react-router'; -import AppContainer from './components/AppContainer'; - -export default [ - <Redirect key="redirect" from="/dashboard/index" to="/dashboard" />, - <IndexRoute key="index" component={AppContainer} /> +const routes = [ + { + getIndexRoute(_, callback) { + require.ensure([], require => + callback(null, { component: require('./components/AppContainer').default })); + } + } ]; + +export default routes; diff --git a/server/sonar-web/src/main/js/apps/permission-templates/components/ActionsCell.js b/server/sonar-web/src/main/js/apps/permission-templates/components/ActionsCell.js index 1741a96ca90..f43f135ab7f 100644 --- a/server/sonar-web/src/main/js/apps/permission-templates/components/ActionsCell.js +++ b/server/sonar-web/src/main/js/apps/permission-templates/components/ActionsCell.js @@ -19,7 +19,7 @@ */ import React from 'react'; import { Link } from 'react-router'; -import difference from 'lodash/difference'; +import { difference } from 'lodash'; import Backbone from 'backbone'; import { PermissionTemplateType, CallbackType } from '../propTypes'; import QualifierIcon from '../../../components/shared/qualifier-icon'; diff --git a/server/sonar-web/src/main/js/apps/permission-templates/components/Defaults.js b/server/sonar-web/src/main/js/apps/permission-templates/components/Defaults.js index 2d13657c8a4..a3b3b0675bf 100644 --- a/server/sonar-web/src/main/js/apps/permission-templates/components/Defaults.js +++ b/server/sonar-web/src/main/js/apps/permission-templates/components/Defaults.js @@ -18,7 +18,7 @@ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ import React from 'react'; -import sortBy from 'lodash/sortBy'; +import { sortBy } from 'lodash'; import { translate } from '../../../helpers/l10n'; import { PermissionTemplateType } from '../propTypes'; diff --git a/server/sonar-web/src/main/js/apps/permission-templates/components/Template.js b/server/sonar-web/src/main/js/apps/permission-templates/components/Template.js index 974ef4834f4..c4a0a7d5fdc 100644 --- a/server/sonar-web/src/main/js/apps/permission-templates/components/Template.js +++ b/server/sonar-web/src/main/js/apps/permission-templates/components/Template.js @@ -19,7 +19,7 @@ */ import React from 'react'; import Helmet from 'react-helmet'; -import debounce from 'lodash/debounce'; +import { debounce } from 'lodash'; import TemplateHeader from './TemplateHeader'; import TemplateDetails from './TemplateDetails'; import HoldersList from '../../permissions/shared/components/HoldersList'; diff --git a/server/sonar-web/src/main/js/apps/permission-templates/routes.js b/server/sonar-web/src/main/js/apps/permission-templates/routes.js index 497a7817a42..d44e8735ad3 100644 --- a/server/sonar-web/src/main/js/apps/permission-templates/routes.js +++ b/server/sonar-web/src/main/js/apps/permission-templates/routes.js @@ -17,9 +17,17 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -import React from 'react'; -import { IndexRoute } from 'react-router'; -import AppContainer from './components/AppContainer'; -import forSingleOrganization from '../organizations/forSingleOrganization'; +const routes = [ + { + getIndexRoute(_, callback) { + require.ensure([], require => { + const AppContainer = require('./components/AppContainer').default; + const forSingleOrganization = require('../organizations/forSingleOrganization').default; + const component = forSingleOrganization(AppContainer); + callback(null, { component }); + }); + } + } +]; -export default <IndexRoute component={forSingleOrganization(AppContainer)} />; +export default routes; diff --git a/server/sonar-web/src/main/js/apps/permission-templates/utils.js b/server/sonar-web/src/main/js/apps/permission-templates/utils.js index 3b634820b5b..ec3be9d776c 100644 --- a/server/sonar-web/src/main/js/apps/permission-templates/utils.js +++ b/server/sonar-web/src/main/js/apps/permission-templates/utils.js @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -import sortBy from 'lodash/sortBy'; +import { sortBy } from 'lodash'; export const PERMISSIONS_ORDER = ['user', 'codeviewer', 'issueadmin', 'admin', 'scan']; diff --git a/server/sonar-web/src/main/js/apps/permissions/routes.js b/server/sonar-web/src/main/js/apps/permissions/routes.js index 388fffb75b6..00de5223f65 100644 --- a/server/sonar-web/src/main/js/apps/permissions/routes.js +++ b/server/sonar-web/src/main/js/apps/permissions/routes.js @@ -17,14 +17,24 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -import React from 'react'; -import { IndexRoute } from 'react-router'; -import GlobalPermissionsApp from './global/components/App'; -import ProjectPermissionsApp from './project/components/App'; -import forSingleOrganization from '../organizations/forSingleOrganization'; +export const globalPermissionsRoutes = [ + { + getIndexRoute(_, callback) { + require.ensure([], require => { + const GlobalPermissionsApp = require('./global/components/App').default; + const forSingleOrganization = require('../organizations/forSingleOrganization').default; + const component = forSingleOrganization(GlobalPermissionsApp); + callback(null, { component }); + }); + } + } +]; -export const globalPermissionsRoutes = ( - <IndexRoute component={forSingleOrganization(GlobalPermissionsApp)} /> -); - -export const projectPermissionsRoutes = <IndexRoute component={ProjectPermissionsApp} />; +export const projectPermissionsRoutes = [ + { + getIndexRoute(_, callback) { + require.ensure([], require => + callback(null, { component: require('./project/components/App').default })); + } + } +]; diff --git a/server/sonar-web/src/main/js/apps/permissions/shared/store/groups/byName.js b/server/sonar-web/src/main/js/apps/permissions/shared/store/groups/byName.js index 9708a736397..4b7f9faedb5 100644 --- a/server/sonar-web/src/main/js/apps/permissions/shared/store/groups/byName.js +++ b/server/sonar-web/src/main/js/apps/permissions/shared/store/groups/byName.js @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -import keyBy from 'lodash/keyBy'; +import { keyBy } from 'lodash'; import { RECEIVE_HOLDERS_SUCCESS, GRANT_PERMISSION_TO_GROUP, diff --git a/server/sonar-web/src/main/js/apps/permissions/shared/store/users/byLogin.js b/server/sonar-web/src/main/js/apps/permissions/shared/store/users/byLogin.js index 006a5b932c1..aaebcdcad61 100644 --- a/server/sonar-web/src/main/js/apps/permissions/shared/store/users/byLogin.js +++ b/server/sonar-web/src/main/js/apps/permissions/shared/store/users/byLogin.js @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -import keyBy from 'lodash/keyBy'; +import { keyBy } from 'lodash'; import { RECEIVE_HOLDERS_SUCCESS, GRANT_PERMISSION_TO_USER, diff --git a/server/sonar-web/src/main/js/apps/project-admin/key/BulkUpdateResults.js b/server/sonar-web/src/main/js/apps/project-admin/key/BulkUpdateResults.js index 7b6bbb3550e..a23d6307d7d 100644 --- a/server/sonar-web/src/main/js/apps/project-admin/key/BulkUpdateResults.js +++ b/server/sonar-web/src/main/js/apps/project-admin/key/BulkUpdateResults.js @@ -18,7 +18,7 @@ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ import React from 'react'; -import some from 'lodash/some'; +import { some } from 'lodash'; import { translateWithParameters, translate } from '../../../helpers/l10n'; export default class BulkUpdateResults extends React.Component { diff --git a/server/sonar-web/src/main/js/apps/project-admin/links/utils.js b/server/sonar-web/src/main/js/apps/project-admin/links/utils.js index 7b6486df900..2b6373a63b4 100644 --- a/server/sonar-web/src/main/js/apps/project-admin/links/utils.js +++ b/server/sonar-web/src/main/js/apps/project-admin/links/utils.js @@ -17,8 +17,7 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -import partition from 'lodash/partition'; -import sortBy from 'lodash/sortBy'; +import { partition, sortBy } from 'lodash'; const PROVIDED_TYPES = ['homepage', 'ci', 'issue', 'scm', 'scm_dev']; diff --git a/server/sonar-web/src/main/js/apps/project-admin/quality-gate/Form.js b/server/sonar-web/src/main/js/apps/project-admin/quality-gate/Form.js index a02fead0ffd..154115c58e0 100644 --- a/server/sonar-web/src/main/js/apps/project-admin/quality-gate/Form.js +++ b/server/sonar-web/src/main/js/apps/project-admin/quality-gate/Form.js @@ -20,7 +20,7 @@ import React from 'react'; import Select from 'react-select'; import shallowCompare from 'react-addons-shallow-compare'; -import some from 'lodash/some'; +import { some } from 'lodash'; import { translate } from '../../../helpers/l10n'; export default class Form extends React.Component { diff --git a/server/sonar-web/src/main/js/apps/project-admin/quality-profiles/Table.js b/server/sonar-web/src/main/js/apps/project-admin/quality-profiles/Table.js index 4b3d6bdc3aa..10251c140c2 100644 --- a/server/sonar-web/src/main/js/apps/project-admin/quality-profiles/Table.js +++ b/server/sonar-web/src/main/js/apps/project-admin/quality-profiles/Table.js @@ -19,8 +19,7 @@ */ import React from 'react'; import shallowCompare from 'react-addons-shallow-compare'; -import groupBy from 'lodash/groupBy'; -import orderBy from 'lodash/orderBy'; +import { groupBy, orderBy } from 'lodash'; import ProfileRow from './ProfileRow'; import { translate } from '../../../helpers/l10n'; diff --git a/server/sonar-web/src/main/js/apps/project-admin/store/components.js b/server/sonar-web/src/main/js/apps/project-admin/store/components.js index 59f53b674b0..9745dd347e4 100644 --- a/server/sonar-web/src/main/js/apps/project-admin/store/components.js +++ b/server/sonar-web/src/main/js/apps/project-admin/store/components.js @@ -17,8 +17,7 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -import keyBy from 'lodash/keyBy'; -import omit from 'lodash/omit'; +import { keyBy, omit } from 'lodash'; import { RECEIVE_PROJECT_MODULES, CHANGE_KEY } from './actions'; const components = (state = {}, action = {}) => { diff --git a/server/sonar-web/src/main/js/apps/project-admin/store/gates.js b/server/sonar-web/src/main/js/apps/project-admin/store/gates.js index 319b8ac3f36..d68aae11508 100644 --- a/server/sonar-web/src/main/js/apps/project-admin/store/gates.js +++ b/server/sonar-web/src/main/js/apps/project-admin/store/gates.js @@ -17,8 +17,7 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -import keyBy from 'lodash/keyBy'; -import values from 'lodash/values'; +import { keyBy, values } from 'lodash'; import { RECEIVE_GATES } from './actions'; const gates = (state = {}, action = {}) => { diff --git a/server/sonar-web/src/main/js/apps/project-admin/store/links.js b/server/sonar-web/src/main/js/apps/project-admin/store/links.js index 1f5bc45b153..214c3d94f09 100644 --- a/server/sonar-web/src/main/js/apps/project-admin/store/links.js +++ b/server/sonar-web/src/main/js/apps/project-admin/store/links.js @@ -17,8 +17,7 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -import keyBy from 'lodash/keyBy'; -import omit from 'lodash/omit'; +import { keyBy, omit } from 'lodash'; import { RECEIVE_PROJECT_LINKS, DELETE_PROJECT_LINK, ADD_PROJECT_LINK } from './actions'; const links = (state = {}, action = {}) => { diff --git a/server/sonar-web/src/main/js/apps/project-admin/store/linksByProject.js b/server/sonar-web/src/main/js/apps/project-admin/store/linksByProject.js index 54413eeb56e..8ed793ca1f1 100644 --- a/server/sonar-web/src/main/js/apps/project-admin/store/linksByProject.js +++ b/server/sonar-web/src/main/js/apps/project-admin/store/linksByProject.js @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -import without from 'lodash/without'; +import { without } from 'lodash'; import { RECEIVE_PROJECT_LINKS, DELETE_PROJECT_LINK, ADD_PROJECT_LINK } from './actions'; const linksByProject = (state = {}, action = {}) => { diff --git a/server/sonar-web/src/main/js/apps/project-admin/store/profiles.js b/server/sonar-web/src/main/js/apps/project-admin/store/profiles.js index 01302f946c7..ed6a8345d0e 100644 --- a/server/sonar-web/src/main/js/apps/project-admin/store/profiles.js +++ b/server/sonar-web/src/main/js/apps/project-admin/store/profiles.js @@ -17,8 +17,7 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -import keyBy from 'lodash/keyBy'; -import values from 'lodash/values'; +import { keyBy, values } from 'lodash'; import { RECEIVE_PROFILES } from './actions'; const profiles = (state = {}, action = {}) => { diff --git a/server/sonar-web/src/main/js/apps/project-admin/store/profilesByProject.js b/server/sonar-web/src/main/js/apps/project-admin/store/profilesByProject.js index 3eed6b11561..afc7ea0143b 100644 --- a/server/sonar-web/src/main/js/apps/project-admin/store/profilesByProject.js +++ b/server/sonar-web/src/main/js/apps/project-admin/store/profilesByProject.js @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -import without from 'lodash/without'; +import { without } from 'lodash'; import { RECEIVE_PROJECT_PROFILES, SET_PROJECT_PROFILE } from './actions'; const profilesByProject = (state = {}, action = {}) => { diff --git a/server/sonar-web/src/main/js/apps/projectActivity/components/Events.js b/server/sonar-web/src/main/js/apps/projectActivity/components/Events.js index 18a48fbfc23..87afe5b5e5a 100644 --- a/server/sonar-web/src/main/js/apps/projectActivity/components/Events.js +++ b/server/sonar-web/src/main/js/apps/projectActivity/components/Events.js @@ -19,7 +19,7 @@ */ // @flow import React from 'react'; -import sortBy from 'lodash/sortBy'; +import { sortBy } from 'lodash'; import Event from './Event'; import type { Event as EventType } from '../../../store/projectActivity/duck'; diff --git a/server/sonar-web/src/main/js/apps/projectActivity/components/ProjectActivityAnalysesList.js b/server/sonar-web/src/main/js/apps/projectActivity/components/ProjectActivityAnalysesList.js index 60989c83a47..7acb76cd43b 100644 --- a/server/sonar-web/src/main/js/apps/projectActivity/components/ProjectActivityAnalysesList.js +++ b/server/sonar-web/src/main/js/apps/projectActivity/components/ProjectActivityAnalysesList.js @@ -20,21 +20,19 @@ // @flow import React from 'react'; import { connect } from 'react-redux'; -import groupBy from 'lodash/groupBy'; +import { groupBy } from 'lodash'; import moment from 'moment'; import ProjectActivityAnalysis from './ProjectActivityAnalysis'; import FormattedDate from '../../../components/ui/FormattedDate'; import { getProjectActivity } from '../../../store/rootReducer'; import { getAnalyses } from '../../../store/projectActivity/duck'; import { translate } from '../../../helpers/l10n'; +import type { Analysis } from '../../../store/projectActivity/duck'; class ProjectActivityAnalysesList extends React.Component { props: { project: string, - analyses?: Array<{ - key: string, - date: string - }>, + analyses?: Array<Analysis>, canAdmin: boolean }; @@ -59,22 +57,22 @@ class ProjectActivityAnalysesList extends React.Component { <li key={day} className="project-activity-day" - data-day={moment(Number(day)).format('YYYY-MM-DD')} - > + data-day={moment(Number(day)).format('YYYY-MM-DD')}> <div className="project-activity-date"> <FormattedDate date={Number(day)} format="LL" /> </div> <ul className="project-activity-analyses-list"> - {byDay[day].map(analysis => ( - <ProjectActivityAnalysis - key={analysis.key} - analysis={analysis} - isFirst={analysis === firstAnalysis} - project={this.props.project} - canAdmin={this.props.canAdmin} - /> - ))} + {byDay[day] != null && + byDay[day].map(analysis => ( + <ProjectActivityAnalysis + key={analysis.key} + analysis={analysis} + isFirst={analysis === firstAnalysis} + project={this.props.project} + canAdmin={this.props.canAdmin} + /> + ))} </ul> </li> ))} diff --git a/server/sonar-web/src/main/js/apps/projectActivity/routes.js b/server/sonar-web/src/main/js/apps/projectActivity/routes.js index 5c2042e8395..3b2ed907d49 100644 --- a/server/sonar-web/src/main/js/apps/projectActivity/routes.js +++ b/server/sonar-web/src/main/js/apps/projectActivity/routes.js @@ -17,9 +17,13 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -// @flow -import React from 'react'; -import { IndexRoute } from 'react-router'; -import ProjectActivityApp from './components/ProjectActivityApp'; +const routes = [ + { + getIndexRoute(_, callback) { + require.ensure([], require => + callback(null, { component: require('./components/ProjectActivityApp').default })); + } + } +]; -export default <IndexRoute component={ProjectActivityApp} />; +export default routes; diff --git a/server/sonar-web/src/main/js/apps/projects-admin/main.js b/server/sonar-web/src/main/js/apps/projects-admin/main.js index ad8a243ba60..29278721294 100644 --- a/server/sonar-web/src/main/js/apps/projects-admin/main.js +++ b/server/sonar-web/src/main/js/apps/projects-admin/main.js @@ -18,9 +18,7 @@ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ import React from 'react'; -import debounce from 'lodash/debounce'; -import uniq from 'lodash/uniq'; -import without from 'lodash/without'; +import { debounce, uniq, without } from 'lodash'; import Header from './header'; import Search from './search'; import Projects from './projects'; diff --git a/server/sonar-web/src/main/js/apps/projects-admin/routes.js b/server/sonar-web/src/main/js/apps/projects-admin/routes.js index 476312d444e..6ca2206f863 100644 --- a/server/sonar-web/src/main/js/apps/projects-admin/routes.js +++ b/server/sonar-web/src/main/js/apps/projects-admin/routes.js @@ -17,9 +17,17 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -import React from 'react'; -import { IndexRoute } from 'react-router'; -import AppContainer from './AppContainer'; -import forSingleOrganization from '../organizations/forSingleOrganization'; +const routes = [ + { + getIndexRoute(_, callback) { + require.ensure([], require => { + const AppContainer = require('./AppContainer').default; + const forSingleOrganization = require('../organizations/forSingleOrganization').default; + const component = forSingleOrganization(AppContainer); + callback(null, { component }); + }); + } + } +]; -export default <IndexRoute component={forSingleOrganization(AppContainer)} />; +export default routes; diff --git a/server/sonar-web/src/main/js/apps/projects-admin/search.js b/server/sonar-web/src/main/js/apps/projects-admin/search.js index efd640663db..b4c658ce0d8 100644 --- a/server/sonar-web/src/main/js/apps/projects-admin/search.js +++ b/server/sonar-web/src/main/js/apps/projects-admin/search.js @@ -18,7 +18,7 @@ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ import React from 'react'; -import sortBy from 'lodash/sortBy'; +import { sortBy } from 'lodash'; import { TYPE, QUALIFIERS_ORDER } from './constants'; import DeleteView from './delete-view'; import RadioToggle from '../../components/controls/RadioToggle'; diff --git a/server/sonar-web/src/main/js/apps/projects/components/AllProjects.js b/server/sonar-web/src/main/js/apps/projects/components/AllProjects.js index 96b4b5a4943..8c0a54dca6c 100644 --- a/server/sonar-web/src/main/js/apps/projects/components/AllProjects.js +++ b/server/sonar-web/src/main/js/apps/projects/components/AllProjects.js @@ -25,6 +25,7 @@ import PageSidebar from './PageSidebar'; import VisualizationsContainer from '../visualizations/VisualizationsContainer'; import { parseUrlQuery } from '../store/utils'; import { getProjectUrl } from '../../../helpers/urls'; +import '../styles.css'; export default class AllProjects extends React.Component { static propTypes = { diff --git a/server/sonar-web/src/main/js/apps/projects/components/App.js b/server/sonar-web/src/main/js/apps/projects/components/App.js index bd9e6468d10..c5c3b94bda1 100644 --- a/server/sonar-web/src/main/js/apps/projects/components/App.js +++ b/server/sonar-web/src/main/js/apps/projects/components/App.js @@ -20,7 +20,6 @@ import React from 'react'; import Helmet from 'react-helmet'; import { translate } from '../../../helpers/l10n'; -import '../styles.css'; export default class App extends React.Component { componentDidMount() { diff --git a/server/sonar-web/src/main/js/apps/projects/components/ProjectCardLanguages.js b/server/sonar-web/src/main/js/apps/projects/components/ProjectCardLanguages.js index 3b789e8bd24..172d228f0d8 100644 --- a/server/sonar-web/src/main/js/apps/projects/components/ProjectCardLanguages.js +++ b/server/sonar-web/src/main/js/apps/projects/components/ProjectCardLanguages.js @@ -18,7 +18,7 @@ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ import React from 'react'; -import sortBy from 'lodash/sortBy'; +import { sortBy } from 'lodash'; import { connect } from 'react-redux'; import Tooltip from '../../../components/controls/Tooltip'; import { getLanguages } from '../../../store/rootReducer'; diff --git a/server/sonar-web/src/main/js/apps/projects/components/ProjectTagsSelectorContainer.js b/server/sonar-web/src/main/js/apps/projects/components/ProjectTagsSelectorContainer.js index 537bc3d4a8e..19f2fa34533 100644 --- a/server/sonar-web/src/main/js/apps/projects/components/ProjectTagsSelectorContainer.js +++ b/server/sonar-web/src/main/js/apps/projects/components/ProjectTagsSelectorContainer.js @@ -20,8 +20,7 @@ //@flow import React from 'react'; import { connect } from 'react-redux'; -import debounce from 'lodash/debounce'; -import without from 'lodash/without'; +import { debounce, without } from 'lodash'; import TagsSelector from '../../../components/tags/TagsSelector'; import { searchProjectTags } from '../../../api/components'; import { setProjectTags } from '../store/actions'; diff --git a/server/sonar-web/src/main/js/apps/projects/filters/LanguagesFilter.js b/server/sonar-web/src/main/js/apps/projects/filters/LanguagesFilter.js index 9a7b75988da..9787900bf19 100644 --- a/server/sonar-web/src/main/js/apps/projects/filters/LanguagesFilter.js +++ b/server/sonar-web/src/main/js/apps/projects/filters/LanguagesFilter.js @@ -19,8 +19,7 @@ */ //@flow import React from 'react'; -import difference from 'lodash/difference'; -import sortBy from 'lodash/sortBy'; +import { difference, sortBy } from 'lodash'; import Filter from './Filter'; import FilterHeader from './FilterHeader'; import SearchableFilterFooter from './SearchableFilterFooter'; diff --git a/server/sonar-web/src/main/js/apps/projects/filters/SearchFilterContainer.js b/server/sonar-web/src/main/js/apps/projects/filters/SearchFilterContainer.js index 72b89f46ca8..b70d403a499 100644 --- a/server/sonar-web/src/main/js/apps/projects/filters/SearchFilterContainer.js +++ b/server/sonar-web/src/main/js/apps/projects/filters/SearchFilterContainer.js @@ -20,7 +20,7 @@ //@flow import React from 'react'; import { withRouter } from 'react-router'; -import debounce from 'lodash/debounce'; +import { debounce } from 'lodash'; import { getFilterUrl } from './utils'; import SearchFilter from './SearchFilter'; diff --git a/server/sonar-web/src/main/js/apps/projects/filters/TagsFilter.js b/server/sonar-web/src/main/js/apps/projects/filters/TagsFilter.js index 7344d20ee2d..59d464d6e4d 100644 --- a/server/sonar-web/src/main/js/apps/projects/filters/TagsFilter.js +++ b/server/sonar-web/src/main/js/apps/projects/filters/TagsFilter.js @@ -19,9 +19,7 @@ */ //@flow import React from 'react'; -import debounce from 'lodash/debounce'; -import difference from 'lodash/difference'; -import sortBy from 'lodash/sortBy'; +import { debounce, difference, sortBy } from 'lodash'; import Filter from './Filter'; import FilterHeader from './FilterHeader'; import SearchableFilterFooter from './SearchableFilterFooter'; diff --git a/server/sonar-web/src/main/js/apps/projects/filters/utils.js b/server/sonar-web/src/main/js/apps/projects/filters/utils.js index 4cbd4ed410c..5be12186542 100644 --- a/server/sonar-web/src/main/js/apps/projects/filters/utils.js +++ b/server/sonar-web/src/main/js/apps/projects/filters/utils.js @@ -17,9 +17,7 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -import each from 'lodash/each'; -import omitBy from 'lodash/omitBy'; -import isNil from 'lodash/isNil'; +import { each, isNil, omitBy } from 'lodash'; export const getFilterUrl = (ownProps, part) => { const basePathName = ownProps.organization diff --git a/server/sonar-web/src/main/js/apps/projects/routes.js b/server/sonar-web/src/main/js/apps/projects/routes.js index 371a29f49a9..8eccdcd0ccc 100644 --- a/server/sonar-web/src/main/js/apps/projects/routes.js +++ b/server/sonar-web/src/main/js/apps/projects/routes.js @@ -17,23 +17,36 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -import React from 'react'; -import { Route, IndexRoute } from 'react-router'; -import App from './components/App'; -import DefaultPageSelector from './components/DefaultPageSelector'; -import FavoriteProjectsContainer from './components/FavoriteProjectsContainer'; import { saveAll } from './utils'; -export default ( - <Route component={App}> - <IndexRoute component={DefaultPageSelector} /> - <Route - path="all" - onEnter={(_, replace) => { - saveAll(); - replace('/projects'); - }} - /> - <Route path="favorite" component={FavoriteProjectsContainer} /> - </Route> -); +const routes = [ + { + getComponent(_, callback) { + require.ensure([], require => callback(null, require('./components/App').default)); + }, + childRoutes: [ + { + getIndexRoute(_, callback) { + require.ensure([], require => + callback(null, { component: require('./components/DefaultPageSelector').default })); + } + }, + { + path: 'all', + onEnter(_, replace) { + saveAll(); + replace('/projects'); + } + }, + { + path: 'favorite', + getComponent(_, callback) { + require.ensure([], require => + callback(null, require('./components/FavoriteProjectsContainer').default)); + } + } + ] + } +]; + +export default routes; diff --git a/server/sonar-web/src/main/js/apps/projects/store/actions.js b/server/sonar-web/src/main/js/apps/projects/store/actions.js index ec113c07fab..b57ce5dda28 100644 --- a/server/sonar-web/src/main/js/apps/projects/store/actions.js +++ b/server/sonar-web/src/main/js/apps/projects/store/actions.js @@ -17,8 +17,7 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -import groupBy from 'lodash/groupBy'; -import uniq from 'lodash/uniq'; +import { groupBy, uniq } from 'lodash'; import { searchProjects, setProjectTags as apiSetProjectTags } from '../../../api/components'; import { addGlobalErrorMessage } from '../../../store/globalMessages/duck'; import { parseError } from '../../code/utils'; @@ -206,11 +205,8 @@ export const setProjectTags = (project, tags) => (dispatch, getState) => { const previousTags = getComponent(getState(), project).tags; dispatch(receiveProjectTags(project, tags)); - return apiSetProjectTags({ project, tags: tags.join(',') }).then( - null, - error => { - dispatch(receiveProjectTags(project, previousTags)); - onFail(dispatch)(error); - } - ); + return apiSetProjectTags({ project, tags: tags.join(',') }).then(null, error => { + dispatch(receiveProjectTags(project, previousTags)); + onFail(dispatch)(error); + }); }; diff --git a/server/sonar-web/src/main/js/apps/projects/store/facetsDuck.js b/server/sonar-web/src/main/js/apps/projects/store/facetsDuck.js index cd15ca36fdb..953fcaf4101 100644 --- a/server/sonar-web/src/main/js/apps/projects/store/facetsDuck.js +++ b/server/sonar-web/src/main/js/apps/projects/store/facetsDuck.js @@ -17,8 +17,7 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -import flatMap from 'lodash/flatMap'; -import sumBy from 'lodash/sumBy'; +import { flatMap, sumBy } from 'lodash'; import { createMap } from '../../../store/utils/generalReducers'; import { actions } from './projectsDuck'; import { mapMetricToProperty } from './utils'; diff --git a/server/sonar-web/src/main/js/apps/projects/styles.css b/server/sonar-web/src/main/js/apps/projects/styles.css index 81b7af2c1cd..87101df7544 100644 --- a/server/sonar-web/src/main/js/apps/projects/styles.css +++ b/server/sonar-web/src/main/js/apps/projects/styles.css @@ -202,4 +202,32 @@ color: #777; font-size: 12px; text-align: center; +} + +.measure-details-bubble-chart-axis { + position: absolute; + color: #777; + font-size: 12px; +} + +.measure-details-bubble-chart-axis.x { + left: 50%; + bottom: 10px; + width: 500px; + margin-left: -250px; + text-align: center; +} + +.measure-details-bubble-chart-axis.y { + top: 50%; + left: -20px; + transform: rotate(-90deg); +} + +.measure-details-bubble-chart-axis.size { + left: 50%; + top: 10px; + width: 500px; + margin-left: -250px; + text-align: center; }
\ No newline at end of file diff --git a/server/sonar-web/src/main/js/apps/quality-gates/components/AddConditionForm.js b/server/sonar-web/src/main/js/apps/quality-gates/components/AddConditionForm.js index d21b39d2fc3..eaf8d1ac436 100644 --- a/server/sonar-web/src/main/js/apps/quality-gates/components/AddConditionForm.js +++ b/server/sonar-web/src/main/js/apps/quality-gates/components/AddConditionForm.js @@ -19,7 +19,7 @@ */ import React from 'react'; import Select from 'react-select'; -import sortBy from 'lodash/sortBy'; +import { sortBy } from 'lodash'; import { translate, getLocalizedMetricName, getLocalizedMetricDomain } from '../../../helpers/l10n'; export default function AddConditionForm({ metrics, onSelect }) { diff --git a/server/sonar-web/src/main/js/apps/quality-gates/components/Conditions.js b/server/sonar-web/src/main/js/apps/quality-gates/components/Conditions.js index 48cf7b78752..54830da056a 100644 --- a/server/sonar-web/src/main/js/apps/quality-gates/components/Conditions.js +++ b/server/sonar-web/src/main/js/apps/quality-gates/components/Conditions.js @@ -18,8 +18,7 @@ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ import React from 'react'; -import sortBy from 'lodash/sortBy'; -import uniqBy from 'lodash/uniqBy'; +import { sortBy, uniqBy } from 'lodash'; import ConditionsAlert from './ConditionsAlert'; import AddConditionForm from './AddConditionForm'; import Condition from './Condition'; diff --git a/server/sonar-web/src/main/js/apps/quality-gates/routes.js b/server/sonar-web/src/main/js/apps/quality-gates/routes.js index 7c6b54381b2..7db41853db8 100644 --- a/server/sonar-web/src/main/js/apps/quality-gates/routes.js +++ b/server/sonar-web/src/main/js/apps/quality-gates/routes.js @@ -17,17 +17,28 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -import React from 'react'; -import { Route, IndexRoute, Redirect } from 'react-router'; -import QualityGatesAppContainer from './containers/QualityGatesAppContainer'; -import Intro from './components/Intro'; -import DetailsContainer from './containers/DetailsContainer'; +const routes = [ + { + getComponent(_, callback) { + require.ensure([], require => + callback(null, require('./containers/QualityGatesAppContainer').default)); + }, + childRoutes: [ + { + getIndexRoute(_, callback) { + require.ensure([], require => + callback(null, { component: require('./components/Intro').default })); + } + }, + { + path: 'show/:id', + getComponent(_, callback) { + require.ensure([], require => + callback(null, require('./containers/DetailsContainer').default)); + } + } + ] + } +]; -export default ( - <Route component={QualityGatesAppContainer}> - <Redirect from="/quality_gates/index" to="/quality_gates/" /> - - <IndexRoute component={Intro} /> - <Route path="show/:id" component={DetailsContainer} /> - </Route> -); +export default routes; diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/details/ProfileRules.js b/server/sonar-web/src/main/js/apps/quality-profiles/details/ProfileRules.js index 79bad9a8e38..cf530249158 100644 --- a/server/sonar-web/src/main/js/apps/quality-profiles/details/ProfileRules.js +++ b/server/sonar-web/src/main/js/apps/quality-profiles/details/ProfileRules.js @@ -19,7 +19,7 @@ */ import React from 'react'; import { Link } from 'react-router'; -import keyBy from 'lodash/keyBy'; +import { keyBy } from 'lodash'; import ProfileRulesRow from './ProfileRulesRow'; import { ProfileType } from '../propTypes'; import { searchRules, takeFacet } from '../../../api/rules'; diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/home/EvolutionDeprecated.js b/server/sonar-web/src/main/js/apps/quality-profiles/home/EvolutionDeprecated.js index a198b3197ad..d5f04ac306a 100644 --- a/server/sonar-web/src/main/js/apps/quality-profiles/home/EvolutionDeprecated.js +++ b/server/sonar-web/src/main/js/apps/quality-profiles/home/EvolutionDeprecated.js @@ -19,7 +19,7 @@ */ import React from 'react'; import { Link } from 'react-router'; -import sortBy from 'lodash/sortBy'; +import { sortBy } from 'lodash'; import ProfileLink from '../components/ProfileLink'; import { getDeprecatedActiveRulesUrl } from '../../../helpers/urls'; import { ProfilesListType } from '../propTypes'; diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/home/EvolutionRules.js b/server/sonar-web/src/main/js/apps/quality-profiles/home/EvolutionRules.js index fee0049a0a2..224be2a3b28 100644 --- a/server/sonar-web/src/main/js/apps/quality-profiles/home/EvolutionRules.js +++ b/server/sonar-web/src/main/js/apps/quality-profiles/home/EvolutionRules.js @@ -20,7 +20,7 @@ import React from 'react'; import { Link } from 'react-router'; import moment from 'moment'; -import sortBy from 'lodash/sortBy'; +import { sortBy } from 'lodash'; import { searchRules } from '../../../api/rules'; import { translateWithParameters, translate } from '../../../helpers/l10n'; import { getRulesUrl } from '../../../helpers/urls'; diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/home/ProfilesList.js b/server/sonar-web/src/main/js/apps/quality-profiles/home/ProfilesList.js index 47a80df6252..34d0317107f 100644 --- a/server/sonar-web/src/main/js/apps/quality-profiles/home/ProfilesList.js +++ b/server/sonar-web/src/main/js/apps/quality-profiles/home/ProfilesList.js @@ -18,9 +18,7 @@ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ import React from 'react'; -import groupBy from 'lodash/groupBy'; -import pick from 'lodash/pick'; -import sortBy from 'lodash/sortBy'; +import { groupBy, pick, sortBy } from 'lodash'; import ProfilesListRow from './ProfilesListRow'; import ProfilesListHeader from './ProfilesListHeader'; import { ProfilesListType, LanguagesListType } from '../propTypes'; diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/routes.js b/server/sonar-web/src/main/js/apps/quality-profiles/routes.js index 85c42a87438..ac8f4c22894 100644 --- a/server/sonar-web/src/main/js/apps/quality-profiles/routes.js +++ b/server/sonar-web/src/main/js/apps/quality-profiles/routes.js @@ -17,25 +17,54 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -import React from 'react'; -import { Route, IndexRoute, Redirect } from 'react-router'; -import AppContainer from './components/AppContainer'; -import ProfileContainer from './components/ProfileContainer'; -import HomeContainer from './home/HomeContainer'; -import ProfileDetails from './details/ProfileDetails'; -import ChangelogContainer from './changelog/ChangelogContainer'; -import ComparisonContainer from './compare/ComparisonContainer'; +const routes = [ + { + getComponent(_, callback) { + require.ensure([], require => { + callback(null, require('./components/AppContainer').default); + }); + }, + getIndexRoute(_, callback) { + require.ensure([], require => { + callback(null, { component: require('./home/HomeContainer').default }); + }); + }, + childRoutes: [ + { + getComponent(_, callback) { + require.ensure([], require => { + callback(null, require('./components/ProfileContainer').default); + }); + }, + childRoutes: [ + { + path: 'show', + getComponent(_, callback) { + require.ensure([], require => { + callback(null, require('./details/ProfileDetails').default); + }); + } + }, + { + path: 'changelog', + getComponent(_, callback) { + require.ensure([], require => { + callback(null, require('./changelog/ChangelogContainer').default); + }); + } + }, + { + path: 'compare', + getComponent(_, callback) { + require.ensure([], require => { + callback(null, require('./compare/ComparisonContainer').default); + }); + } + } + ] + } + ] + } +]; -export default ( - <Route component={AppContainer}> - <Redirect from="/profiles/index" to="/profiles" /> - - <IndexRoute component={HomeContainer} /> - - <Route component={ProfileContainer}> - <Route path="show" component={ProfileDetails} /> - <Route path="changelog" component={ChangelogContainer} /> - <Route path="compare" component={ComparisonContainer} /> - </Route> - </Route> -); +export default routes; diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/utils.js b/server/sonar-web/src/main/js/apps/quality-profiles/utils.js index 0ebe30db86f..d5ea476bab8 100644 --- a/server/sonar-web/src/main/js/apps/quality-profiles/utils.js +++ b/server/sonar-web/src/main/js/apps/quality-profiles/utils.js @@ -18,7 +18,7 @@ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ // @flow -import sortBy from 'lodash/sortBy'; +import { sortBy } from 'lodash'; import moment from 'moment'; type Profiles = Array<{ diff --git a/server/sonar-web/src/main/js/apps/settings/components/CategoriesList.js b/server/sonar-web/src/main/js/apps/settings/components/CategoriesList.js index d6c89287b91..873dc94d63d 100644 --- a/server/sonar-web/src/main/js/apps/settings/components/CategoriesList.js +++ b/server/sonar-web/src/main/js/apps/settings/components/CategoriesList.js @@ -20,7 +20,7 @@ // @flow import React from 'react'; import shallowCompare from 'react-addons-shallow-compare'; -import sortBy from 'lodash/sortBy'; +import { sortBy } from 'lodash'; import { IndexLink } from 'react-router'; import { getCategoryName } from '../utils'; diff --git a/server/sonar-web/src/main/js/apps/settings/components/SubCategoryDefinitionsList.js b/server/sonar-web/src/main/js/apps/settings/components/SubCategoryDefinitionsList.js index f6db05ef5fe..eb7b7fb045d 100644 --- a/server/sonar-web/src/main/js/apps/settings/components/SubCategoryDefinitionsList.js +++ b/server/sonar-web/src/main/js/apps/settings/components/SubCategoryDefinitionsList.js @@ -20,8 +20,7 @@ // @flow import React from 'react'; import shallowCompare from 'react-addons-shallow-compare'; -import groupBy from 'lodash/groupBy'; -import sortBy from 'lodash/sortBy'; +import { groupBy, sortBy } from 'lodash'; import DefinitionsList from './DefinitionsList'; import EmailForm from './EmailForm'; import { getSubCategoryName, getSubCategoryDescription } from '../utils'; diff --git a/server/sonar-web/src/main/js/apps/settings/routes.js b/server/sonar-web/src/main/js/apps/settings/routes.js index d7c693a3365..68300e6d2c8 100644 --- a/server/sonar-web/src/main/js/apps/settings/routes.js +++ b/server/sonar-web/src/main/js/apps/settings/routes.js @@ -17,17 +17,38 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -import React from 'react'; -import { IndexRoute, Route, Redirect } from 'react-router'; -import AppContainer from './components/AppContainer'; -import LicensesApp from './licenses/LicensesApp'; -import EncryptionAppContainer from './encryption/EncryptionAppContainer'; -import ServerIdAppContainer from './serverId/ServerIdAppContainer'; - -export default [ - <Redirect key="1" from="/settings/index" to="/settings" />, - <IndexRoute key="2" component={AppContainer} />, - <Route key="3" path="licenses" component={LicensesApp} />, - <Route key="4" path="encryption" component={EncryptionAppContainer} />, - <Route key="5" path="server_id" component={ServerIdAppContainer} /> +const routes = [ + { + getIndexRoute(_, callback) { + require.ensure([], require => { + callback(null, { component: require('./components/AppContainer').default }); + }); + } + }, + { + path: 'licenses', + getComponent(_, callback) { + require.ensure([], require => { + callback(null, require('./licenses/LicensesApp').default); + }); + } + }, + { + path: 'encryption', + getComponent(_, callback) { + require.ensure([], require => { + callback(null, require('./encryption/EncryptionAppContainer').default); + }); + } + }, + { + path: 'server_id', + getComponent(_, callback) { + require.ensure([], require => { + callback(null, require('./serverId/ServerIdAppContainer').default); + }); + } + } ]; + +export default routes; diff --git a/server/sonar-web/src/main/js/apps/settings/store/definitions/reducer.js b/server/sonar-web/src/main/js/apps/settings/store/definitions/reducer.js index 4e96d1018de..6d473517a27 100644 --- a/server/sonar-web/src/main/js/apps/settings/store/definitions/reducer.js +++ b/server/sonar-web/src/main/js/apps/settings/store/definitions/reducer.js @@ -18,9 +18,7 @@ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ // @flow -import keyBy from 'lodash/keyBy'; -import sortBy from 'lodash/sortBy'; -import uniqBy from 'lodash/uniqBy'; +import { keyBy, sortBy, uniqBy } from 'lodash'; import { RECEIVE_DEFINITIONS } from './actions'; import { DEFAULT_CATEGORY, getCategoryName } from '../../utils'; import type { Definition } from '../../types'; diff --git a/server/sonar-web/src/main/js/apps/settings/store/licenses/reducer.js b/server/sonar-web/src/main/js/apps/settings/store/licenses/reducer.js index a8732d8f697..35f68211c16 100644 --- a/server/sonar-web/src/main/js/apps/settings/store/licenses/reducer.js +++ b/server/sonar-web/src/main/js/apps/settings/store/licenses/reducer.js @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -import keyBy from 'lodash/keyBy'; +import { keyBy } from 'lodash'; import { RECEIVE_LICENSES } from './actions'; const reducer = (state = {}, action = {}) => { diff --git a/server/sonar-web/src/main/js/apps/settings/store/settingsPage/changedValues/reducer.js b/server/sonar-web/src/main/js/apps/settings/store/settingsPage/changedValues/reducer.js index dcafa07b34f..a1899f4bd22 100644 --- a/server/sonar-web/src/main/js/apps/settings/store/settingsPage/changedValues/reducer.js +++ b/server/sonar-web/src/main/js/apps/settings/store/settingsPage/changedValues/reducer.js @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -import omit from 'lodash/omit'; +import { omit } from 'lodash'; import { CHANGE_VALUE, CANCEL_CHANGE } from './actions'; const reducer = (state = {}, action = {}) => { diff --git a/server/sonar-web/src/main/js/apps/settings/store/values/reducer.js b/server/sonar-web/src/main/js/apps/settings/store/values/reducer.js index 1e75fe48727..c78b114484c 100644 --- a/server/sonar-web/src/main/js/apps/settings/store/values/reducer.js +++ b/server/sonar-web/src/main/js/apps/settings/store/values/reducer.js @@ -18,7 +18,7 @@ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ // @flow -import keyBy from 'lodash/keyBy'; +import { keyBy } from 'lodash'; import { RECEIVE_VALUES } from './actions'; type State = { [key: string]: {} }; diff --git a/server/sonar-web/src/main/js/apps/system/main.js b/server/sonar-web/src/main/js/apps/system/main.js index 26d5bf24e0e..faafb6057d2 100644 --- a/server/sonar-web/src/main/js/apps/system/main.js +++ b/server/sonar-web/src/main/js/apps/system/main.js @@ -18,7 +18,7 @@ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ import React from 'react'; -import sortBy from 'lodash/sortBy'; +import { sortBy } from 'lodash'; import { getSystemInfo } from '../../api/system'; import Section from './section'; import { translate } from '../../helpers/l10n'; diff --git a/server/sonar-web/src/main/js/apps/system/routes.js b/server/sonar-web/src/main/js/apps/system/routes.js index d75c6810ef7..454ff5127fa 100644 --- a/server/sonar-web/src/main/js/apps/system/routes.js +++ b/server/sonar-web/src/main/js/apps/system/routes.js @@ -17,11 +17,12 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -import React from 'react'; -import { IndexRoute, Redirect } from 'react-router'; -import Main from './main'; - -export default [ - <Redirect key="redirect" from="/system/index" to="/system" />, - <IndexRoute key="index" component={Main} /> +const routes = [ + { + getIndexRoute(_, callback) { + require.ensure([], require => callback(null, { component: require('./main').default })); + } + } ]; + +export default routes; diff --git a/server/sonar-web/src/main/js/apps/update-center/plugins.js b/server/sonar-web/src/main/js/apps/update-center/plugins.js index 2a23578bb81..9062db7da2f 100644 --- a/server/sonar-web/src/main/js/apps/update-center/plugins.js +++ b/server/sonar-web/src/main/js/apps/update-center/plugins.js @@ -18,7 +18,7 @@ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ import $ from 'jquery'; -import findLastIndex from 'lodash/findLastIndex'; +import { findLastIndex } from 'lodash'; import Backbone from 'backbone'; import Plugin from './plugin'; diff --git a/server/sonar-web/src/main/js/apps/update-center/routes.js b/server/sonar-web/src/main/js/apps/update-center/routes.js index 12e493960a1..46327c282d3 100644 --- a/server/sonar-web/src/main/js/apps/update-center/routes.js +++ b/server/sonar-web/src/main/js/apps/update-center/routes.js @@ -17,14 +17,41 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -import React from 'react'; -import { IndexRoute, Route } from 'react-router'; -import UpdateCenterAppContainer from './components/UpdateCenterAppContainer'; - -export default [ - <IndexRoute key="index" component={UpdateCenterAppContainer} />, - <Route key="installed" path="installed" component={UpdateCenterAppContainer} />, - <Route key="updates" path="updates" component={UpdateCenterAppContainer} />, - <Route key="available" path="available" component={UpdateCenterAppContainer} />, - <Route key="system" path="system" component={UpdateCenterAppContainer} /> +const routes = [ + { + getIndexRoute(_, callback) { + require.ensure([], require => + callback(null, { component: require('./components/UpdateCenterAppContainer').default })); + } + }, + { + path: 'installed', + getComponent(_, callback) { + require.ensure([], require => + callback(null, require('./components/UpdateCenterAppContainer').default)); + } + }, + { + path: 'updates', + getComponent(_, callback) { + require.ensure([], require => + callback(null, require('./components/UpdateCenterAppContainer').default)); + } + }, + { + path: 'available', + getComponent(_, callback) { + require.ensure([], require => + callback(null, require('./components/UpdateCenterAppContainer').default)); + } + }, + { + path: 'system', + getComponent(_, callback) { + require.ensure([], require => + callback(null, require('./components/UpdateCenterAppContainer').default)); + } + } ]; + +export default routes; diff --git a/server/sonar-web/src/main/js/apps/update-center/search-view.js b/server/sonar-web/src/main/js/apps/update-center/search-view.js index b8bff2a3573..eb899c7f58c 100644 --- a/server/sonar-web/src/main/js/apps/update-center/search-view.js +++ b/server/sonar-web/src/main/js/apps/update-center/search-view.js @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -import debounce from 'lodash/debounce'; +import { debounce } from 'lodash'; import Marionette from 'backbone.marionette'; import Template from './templates/update-center-search.hbs'; diff --git a/server/sonar-web/src/main/js/apps/users/routes.js b/server/sonar-web/src/main/js/apps/users/routes.js index 8efebd13ba7..0a52028e543 100644 --- a/server/sonar-web/src/main/js/apps/users/routes.js +++ b/server/sonar-web/src/main/js/apps/users/routes.js @@ -17,8 +17,13 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -import React from 'react'; -import { IndexRoute } from 'react-router'; -import UsersAppContainer from './components/UsersAppContainer'; +const routes = [ + { + getIndexRoute(_, callback) { + require.ensure([], require => + callback(null, { component: require('./components/UsersAppContainer').default })); + } + } +]; -export default <IndexRoute component={UsersAppContainer} />; +export default routes; diff --git a/server/sonar-web/src/main/js/apps/users/search-view.js b/server/sonar-web/src/main/js/apps/users/search-view.js index 7f7424381eb..a0f52d20cac 100644 --- a/server/sonar-web/src/main/js/apps/users/search-view.js +++ b/server/sonar-web/src/main/js/apps/users/search-view.js @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -import debounce from 'lodash/debounce'; +import { debounce } from 'lodash'; import Marionette from 'backbone.marionette'; import Template from './templates/users-search.hbs'; diff --git a/server/sonar-web/src/main/js/apps/users/user.js b/server/sonar-web/src/main/js/apps/users/user.js index f37524edb6a..a819925daa8 100644 --- a/server/sonar-web/src/main/js/apps/users/user.js +++ b/server/sonar-web/src/main/js/apps/users/user.js @@ -17,8 +17,7 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -import defaults from 'lodash/defaults'; -import pick from 'lodash/pick'; +import { defaults, pick } from 'lodash'; import Backbone from 'backbone'; export default Backbone.Model.extend({ diff --git a/server/sonar-web/src/main/js/apps/web-api/components/Search.js b/server/sonar-web/src/main/js/apps/web-api/components/Search.js index 6e90c0a6920..342a8dfbd6b 100644 --- a/server/sonar-web/src/main/js/apps/web-api/components/Search.js +++ b/server/sonar-web/src/main/js/apps/web-api/components/Search.js @@ -19,7 +19,7 @@ */ // @flow import React from 'react'; -import debounce from 'lodash/debounce'; +import { debounce } from 'lodash'; import Checkbox from '../../../components/controls/Checkbox'; import { TooltipsContainer } from '../../../components/mixins/tooltips-mixin'; import { translate } from '../../../helpers/l10n'; diff --git a/server/sonar-web/src/main/js/apps/web-api/routes.js b/server/sonar-web/src/main/js/apps/web-api/routes.js index fd647f2e21a..040d8dad6ab 100644 --- a/server/sonar-web/src/main/js/apps/web-api/routes.js +++ b/server/sonar-web/src/main/js/apps/web-api/routes.js @@ -17,11 +17,19 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -import React from 'react'; -import { IndexRoute, Route } from 'react-router'; -import WebApiApp from './components/WebApiApp'; - -export default [ - <IndexRoute key="index" component={WebApiApp} />, - <Route key="splat" path="**" component={WebApiApp} /> +const routes = [ + { + getIndexRoute(_, callback) { + require.ensure([], require => + callback(null, { component: require('./components/WebApiApp').default })); + } + }, + { + path: '**', + getComponent(_, callback) { + require.ensure([], require => callback(null, require('./components/WebApiApp').default)); + } + } ]; + +export default routes; diff --git a/server/sonar-web/src/main/js/components/SelectList/index.js b/server/sonar-web/src/main/js/components/SelectList/index.js index 0855e6106cb..00f59f2855c 100644 --- a/server/sonar-web/src/main/js/components/SelectList/index.js +++ b/server/sonar-web/src/main/js/components/SelectList/index.js @@ -19,8 +19,7 @@ */ import $ from 'jquery'; import Backbone from 'backbone'; -import debounce from 'lodash/debounce'; -import throttle from 'lodash/throttle'; +import { debounce, throttle } from 'lodash'; import { translate } from '../../helpers/l10n'; import ItemTemplate from './templates/item.hbs'; import ListTemplate from './templates/list.hbs'; diff --git a/server/sonar-web/src/main/js/components/SourceViewer/SourceViewerBase.js b/server/sonar-web/src/main/js/components/SourceViewer/SourceViewerBase.js index d902f2c4b7f..ce5ba82b3bb 100644 --- a/server/sonar-web/src/main/js/components/SourceViewer/SourceViewerBase.js +++ b/server/sonar-web/src/main/js/components/SourceViewer/SourceViewerBase.js @@ -20,7 +20,7 @@ // @flow import React from 'react'; import classNames from 'classnames'; -import uniqBy from 'lodash/uniqBy'; +import { uniqBy } from 'lodash'; import SourceViewerHeader from './SourceViewerHeader'; import SourceViewerCode from './SourceViewerCode'; import SourceViewerIssueLocations from './SourceViewerIssueLocations'; diff --git a/server/sonar-web/src/main/js/components/SourceViewer/SourceViewerIssueLocations.js b/server/sonar-web/src/main/js/components/SourceViewer/SourceViewerIssueLocations.js index acd8abb398b..ea68c7fca11 100644 --- a/server/sonar-web/src/main/js/components/SourceViewer/SourceViewerIssueLocations.js +++ b/server/sonar-web/src/main/js/components/SourceViewer/SourceViewerIssueLocations.js @@ -22,7 +22,7 @@ import React from 'react'; import AutoSizer from 'react-virtualized/dist/commonjs/AutoSizer'; import { DraggableCore } from 'react-draggable'; import classNames from 'classnames'; -import throttle from 'lodash/throttle'; +import { throttle } from 'lodash'; import { scrollToElement } from '../../helpers/scrolling'; import { translate } from '../../helpers/l10n'; import type { Issue, FlowLocation } from '../issue/types'; diff --git a/server/sonar-web/src/main/js/components/SourceViewer/components/Line.js b/server/sonar-web/src/main/js/components/SourceViewer/components/Line.js index 9303cfa53c2..bc5e80c2e1f 100644 --- a/server/sonar-web/src/main/js/components/SourceViewer/components/Line.js +++ b/server/sonar-web/src/main/js/components/SourceViewer/components/Line.js @@ -20,7 +20,7 @@ // @flow import React from 'react'; import classNames from 'classnames'; -import times from 'lodash/times'; +import { times } from 'lodash'; import LineNumber from './LineNumber'; import LineSCM from './LineSCM'; import LineCoverage from './LineCoverage'; diff --git a/server/sonar-web/src/main/js/components/SourceViewer/popups/coverage-popup.js b/server/sonar-web/src/main/js/components/SourceViewer/popups/coverage-popup.js index e8dd4f0f23c..3206805adc1 100644 --- a/server/sonar-web/src/main/js/components/SourceViewer/popups/coverage-popup.js +++ b/server/sonar-web/src/main/js/components/SourceViewer/popups/coverage-popup.js @@ -18,7 +18,7 @@ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ import $ from 'jquery'; -import groupBy from 'lodash/groupBy'; +import { groupBy } from 'lodash'; import Popup from '../../common/popup'; import Template from './templates/source-viewer-coverage-popup.hbs'; diff --git a/server/sonar-web/src/main/js/components/SourceViewer/popups/duplication-popup.js b/server/sonar-web/src/main/js/components/SourceViewer/popups/duplication-popup.js index 3ca962bca6c..fec8023fc77 100644 --- a/server/sonar-web/src/main/js/components/SourceViewer/popups/duplication-popup.js +++ b/server/sonar-web/src/main/js/components/SourceViewer/popups/duplication-popup.js @@ -18,8 +18,7 @@ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ import $ from 'jquery'; -import groupBy from 'lodash/groupBy'; -import sortBy from 'lodash/sortBy'; +import { groupBy, sortBy } from 'lodash'; import Popup from '../../common/popup'; import Template from './templates/source-viewer-duplication-popup.hbs'; diff --git a/server/sonar-web/src/main/js/components/SourceViewer/views/measures-overlay.js b/server/sonar-web/src/main/js/components/SourceViewer/views/measures-overlay.js index 0ceca9b9952..4be08ed6802 100644 --- a/server/sonar-web/src/main/js/components/SourceViewer/views/measures-overlay.js +++ b/server/sonar-web/src/main/js/components/SourceViewer/views/measures-overlay.js @@ -18,9 +18,9 @@ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ import $ from 'jquery'; -import groupBy from 'lodash/groupBy'; -import sortBy from 'lodash/sortBy'; -import toPairs from 'lodash/toPairs'; +import { select } from 'd3-selection'; +import { arc as d3Arc, pie as d3Pie } from 'd3-shape'; +import { groupBy, sortBy, toPairs } from 'lodash'; import ModalView from '../../common/modals'; import Template from './templates/source-viewer-measures.hbs'; import { getMeasures } from '../../../api/measures'; @@ -68,11 +68,11 @@ export default ModalView.extend({ const options = { ...defaults, ...$(this).data() }; const radius = options.size / 2; - const container = d3.select(this); + const container = select(this); const svg = container.append('svg').attr('width', options.size).attr('height', options.size); const plot = svg.append('g').attr('transform', trans(radius, radius)); - const arc = d3.svg.arc().innerRadius(radius - options.thickness).outerRadius(radius); - const pie = d3.layout.pie().sort(null).value(d => d); + const arc = d3Arc().innerRadius(radius - options.thickness).outerRadius(radius); + const pie = d3Pie().sort(null).value(d => d); const colors = function(i) { return i === 0 ? options.color : options.baseColor; }; diff --git a/server/sonar-web/src/main/js/components/charts/BubbleChart.js b/server/sonar-web/src/main/js/components/charts/BubbleChart.js index 5ab12ae709b..4916fa7e9d4 100644 --- a/server/sonar-web/src/main/js/components/charts/BubbleChart.js +++ b/server/sonar-web/src/main/js/components/charts/BubbleChart.js @@ -19,10 +19,10 @@ */ // @flow import React from 'react'; -import d3 from 'd3'; -import sortBy from 'lodash/sortBy'; -import uniq from 'lodash/uniq'; -import { AutoSizer } from 'react-virtualized'; +import { min, max } from 'd3-array'; +import { scaleLinear } from 'd3-scale'; +import { sortBy, uniq } from 'lodash'; +import AutoSizer from 'react-virtualized/dist/commonjs/AutoSizer'; import { TooltipsContainer } from '../mixins/tooltips-mixin'; type Scale = { @@ -115,16 +115,16 @@ export default class BubbleChart extends React.PureComponent { }; getXRange(xScale: Scale, sizeScale: Scale, availableWidth: number) { - const minX = d3.min(this.props.items, d => xScale(d.x) - sizeScale(d.size)); - const maxX = d3.max(this.props.items, d => xScale(d.x) + sizeScale(d.size)); + const minX = min(this.props.items, d => xScale(d.x) - sizeScale(d.size)); + const maxX = max(this.props.items, d => xScale(d.x) + sizeScale(d.size)); const dMinX = minX < 0 ? xScale.range()[0] - minX : xScale.range()[0]; const dMaxX = maxX > xScale.range()[1] ? maxX - xScale.range()[1] : 0; return [dMinX, availableWidth - dMaxX]; } getYRange(yScale: Scale, sizeScale: Scale, availableHeight: number) { - const minY = d3.min(this.props.items, d => yScale(d.y) - sizeScale(d.size)); - const maxY = d3.max(this.props.items, d => yScale(d.y) + sizeScale(d.size)); + const minY = min(this.props.items, d => yScale(d.y) - sizeScale(d.size)); + const maxY = max(this.props.items, d => yScale(d.y) + sizeScale(d.size)); const dMinY = minY < 0 ? yScale.range()[1] - minY : yScale.range()[1]; const dMaxY = maxY > yScale.range()[0] ? maxY - yScale.range()[0] : 0; return [availableHeight - dMaxY, dMinY]; @@ -215,19 +215,16 @@ export default class BubbleChart extends React.PureComponent { const availableWidth = width - this.props.padding[1] - this.props.padding[3]; const availableHeight = this.props.height - this.props.padding[0] - this.props.padding[2]; - const xScale = d3.scale - .linear() - .domain(this.props.xDomain || [0, d3.max(this.props.items, d => d.x)]) + const xScale = scaleLinear() + .domain(this.props.xDomain || [0, max(this.props.items, d => d.x)]) .range([0, availableWidth]) .nice(); - const yScale = d3.scale - .linear() - .domain(this.props.yDomain || [0, d3.max(this.props.items, d => d.y)]) + const yScale = scaleLinear() + .domain(this.props.yDomain || [0, max(this.props.items, d => d.y)]) .range([availableHeight, 0]) .nice(); - const sizeScale = d3.scale - .linear() - .domain(this.props.sizeDomain || [0, d3.max(this.props.items, d => d.size)]) + const sizeScale = scaleLinear() + .domain(this.props.sizeDomain || [0, max(this.props.items, d => d.size)]) .range(this.props.sizeRange); const xScaleOriginal = xScale.copy(); diff --git a/server/sonar-web/src/main/js/components/charts/LanguageDistribution.js b/server/sonar-web/src/main/js/components/charts/LanguageDistribution.js index 6713668693a..aa76423e19c 100644 --- a/server/sonar-web/src/main/js/components/charts/LanguageDistribution.js +++ b/server/sonar-web/src/main/js/components/charts/LanguageDistribution.js @@ -17,8 +17,7 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -import find from 'lodash/find'; -import sortBy from 'lodash/sortBy'; +import { find, sortBy } from 'lodash'; import React from 'react'; import shallowCompare from 'react-addons-shallow-compare'; import { Histogram } from './histogram'; diff --git a/server/sonar-web/src/main/js/components/charts/Timeline.js b/server/sonar-web/src/main/js/components/charts/Timeline.js index 26b8db6ce45..a64525b960c 100644 --- a/server/sonar-web/src/main/js/components/charts/Timeline.js +++ b/server/sonar-web/src/main/js/components/charts/Timeline.js @@ -18,9 +18,11 @@ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ import $ from 'jquery'; -import d3 from 'd3'; import moment from 'moment'; import React from 'react'; +import { extent, max } from 'd3-array'; +import { scaleLinear, scaleOrdinal, scaleTime } from 'd3-scale'; +import { line as d3Line } from 'd3-shape'; import { ResizeMixin } from '../mixins/resize-mixin'; import { TooltipsMixin } from '../mixins/tooltips-mixin'; @@ -49,11 +51,11 @@ const Timeline = React.createClass({ }, getRatingScale(availableHeight) { - return d3.scale.ordinal().domain([5, 4, 3, 2, 1]).rangePoints([availableHeight, 0]); + return scaleOrdinal().domain([5, 4, 3, 2, 1]).rangePoints([availableHeight, 0]); }, getLevelScale(availableHeight) { - return d3.scale.ordinal().domain(['ERROR', 'WARN', 'OK']).rangePoints([availableHeight, 0]); + return scaleOrdinal().domain(['ERROR', 'WARN', 'OK']).rangePoints([availableHeight, 0]); }, getYScale(availableHeight) { @@ -62,10 +64,9 @@ const Timeline = React.createClass({ } else if (this.props.metricType === 'LEVEL') { return this.getLevelScale(availableHeight); } else { - return d3.scale - .linear() + return scaleLinear() .range([availableHeight, 0]) - .domain([0, d3.max(this.props.data, d => d.y || 0)]) + .domain([0, max(this.props.data, d => d.y || 0)]) .nice(); } }, @@ -99,8 +100,7 @@ const Timeline = React.createClass({ dx="-1em" dy="0.3em" textAnchor="end" - {...opts} - > + {...opts}> {this.props.formatYTick(tick)} </text> <line @@ -154,12 +154,7 @@ const Timeline = React.createClass({ }, renderLine(xScale, yScale) { - const p = d3.svg - .line() - .x(d => xScale(d.x)) - .y(d => yScale(d.y)) - .interpolate(this.props.interpolate); - + const p = d3Line().x(d => xScale(d.x)).y(d => yScale(d.y)).interpolate(this.props.interpolate); return <path className="line-chart-path" d={p(this.props.data)} />; }, @@ -200,9 +195,8 @@ const Timeline = React.createClass({ } const availableWidth = this.state.width - this.props.padding[1] - this.props.padding[3]; const availableHeight = this.state.height - this.props.padding[0] - this.props.padding[2]; - const xScale = d3.time - .scale() - .domain(d3.extent(this.props.data, d => d.x || 0)) + const xScale = scaleTime() + .domain(extent(this.props.data, d => d.x || 0)) .range([0, availableWidth]) .clamp(true); const yScale = this.getYScale(availableHeight); diff --git a/server/sonar-web/src/main/js/components/charts/__tests__/__snapshots__/BubbleChart-test.js.snap b/server/sonar-web/src/main/js/components/charts/__tests__/__snapshots__/BubbleChart-test.js.snap index d8510705564..7a8e95f13ab 100644 --- a/server/sonar-web/src/main/js/components/charts/__tests__/__snapshots__/BubbleChart-test.js.snap +++ b/server/sonar-web/src/main/js/components/charts/__tests__/__snapshots__/BubbleChart-test.js.snap @@ -62,43 +62,43 @@ exports[`test should display bubbles 1`] = ` x1={51.666666666666664} x2={51.666666666666664} y1={61.66666666666666} - y2={33.57142857142858} /> + y2={33.57142857142857} /> <line className="bubble-chart-grid" x1={30} x2={30} y1={61.66666666666666} - y2={33.57142857142858} /> + y2={33.57142857142857} /> <line className="bubble-chart-grid" x1={8.333333333333336} x2={8.333333333333336} y1={61.66666666666666} - y2={33.57142857142858} /> + y2={33.57142857142857} /> <line className="bubble-chart-grid" - x1={-13.33333333333334} - x2={-13.33333333333334} + x1={-13.333333333333336} + x2={-13.333333333333336} y1={61.66666666666666} - y2={33.57142857142858} /> + y2={33.57142857142857} /> <line className="bubble-chart-grid" - x1={-35} - x2={-35} + x1={-34.99999999999999} + x2={-34.99999999999999} y1={61.66666666666666} - y2={33.57142857142858} /> + y2={33.57142857142857} /> <line className="bubble-chart-grid" x1={-56.66666666666668} x2={-56.66666666666668} y1={61.66666666666666} - y2={33.57142857142858} /> + y2={33.57142857142857} /> <line className="bubble-chart-grid" x1={-78.33333333333334} x2={-78.33333333333334} y1={61.66666666666666} - y2={33.57142857142858} /> + y2={33.57142857142857} /> </g> <g> <text @@ -123,14 +123,14 @@ exports[`test should display bubbles 1`] = ` <text className="bubble-chart-tick" dy="1.5em" - x={-13.33333333333334} + x={-13.333333333333336} y={80}> 1.5 </text> <text className="bubble-chart-tick" dy="1.5em" - x={-35} + x={-34.99999999999999} y={80}> 2 </text> @@ -160,8 +160,8 @@ exports[`test should display bubbles 1`] = ` className="bubble-chart-grid" x1={51.666666666666664} x2={-78.33333333333334} - y1={56.98412698412698} - y2={56.98412698412698} /> + y1={56.98412698412697} + y2={56.98412698412697} /> <line className="bubble-chart-grid" x1={51.666666666666664} @@ -172,8 +172,8 @@ exports[`test should display bubbles 1`] = ` className="bubble-chart-grid" x1={51.666666666666664} x2={-78.33333333333334} - y1={47.61904761904762} - y2={47.61904761904762} /> + y1={47.61904761904761} + y2={47.61904761904761} /> <line className="bubble-chart-grid" x1={51.666666666666664} @@ -190,8 +190,8 @@ exports[`test should display bubbles 1`] = ` className="bubble-chart-grid" x1={51.666666666666664} x2={-78.33333333333334} - y1={33.57142857142858} - y2={33.57142857142858} /> + y1={33.57142857142857} + y2={33.57142857142857} /> </g> <g> <text @@ -205,7 +205,7 @@ exports[`test should display bubbles 1`] = ` dx="-0.5em" dy="0.3em" x={0} - y={56.98412698412698}> + y={56.98412698412697}> 5 </text> <text @@ -221,7 +221,7 @@ exports[`test should display bubbles 1`] = ` dx="-0.5em" dy="0.3em" x={0} - y={47.61904761904762}> + y={47.61904761904761}> 15 </text> <text @@ -245,7 +245,7 @@ exports[`test should display bubbles 1`] = ` dx="-0.5em" dy="0.3em" x={0} - y={33.57142857142858}> + y={33.57142857142857}> 30 </text> </g> @@ -268,21 +268,21 @@ exports[`test should display bubbles 1`] = ` </g> </Bubble> <Bubble - r={33.57142857142858} - x={-35} - y={33.57142857142858}> + r={33.57142857142857} + x={-34.99999999999999} + y={33.57142857142857}> <g> <circle className="bubble-chart-bubble" onClick={[Function]} - r={33.57142857142858} + r={33.57142857142857} style={ Object { "fill": undefined, "stroke": undefined, } } - transform="translate(-35, 33.57142857142858)" /> + transform="translate(-34.99999999999999, 33.57142857142857)" /> </g> </Bubble> <Bubble diff --git a/server/sonar-web/src/main/js/components/charts/bar-chart.js b/server/sonar-web/src/main/js/components/charts/bar-chart.js index af5b42cf108..dc4f0082f27 100644 --- a/server/sonar-web/src/main/js/components/charts/bar-chart.js +++ b/server/sonar-web/src/main/js/components/charts/bar-chart.js @@ -17,8 +17,9 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -import d3 from 'd3'; import React from 'react'; +import { max } from 'd3-array'; +import { scaleLinear, scaleBand } from 'd3-scale'; import { ResizeMixin } from './../mixins/resize-mixin'; import { TooltipsMixin } from './../mixins/tooltips-mixin'; @@ -57,7 +58,7 @@ export const BarChart = React.createClass({ } const ticks = this.props.xTicks.map((tick, index) => { const point = this.props.data[index]; - const x = Math.round(xScale(point.x) + xScale.rangeBand() / 2); + const x = Math.round(xScale(point.x) + xScale.bandwidth() / 2); const y = yScale.range()[0]; const d = this.props.data[index]; const tooltipAtts = {}; @@ -67,15 +68,14 @@ export const BarChart = React.createClass({ } return ( <text + {...tooltipAtts} key={index} className="bar-chart-tick" x={x} y={y} dy="1.5em" onClick={this.props.onBarClick && this.handleClick.bind(this, point)} - style={{ cursor: this.props.onBarClick ? 'pointer' : 'default' }} - {...tooltipAtts} - > + style={{ cursor: this.props.onBarClick ? 'pointer' : 'default' }}> {tick} </text> ); @@ -89,7 +89,7 @@ export const BarChart = React.createClass({ } const ticks = this.props.xValues.map((value, index) => { const point = this.props.data[index]; - const x = Math.round(xScale(point.x) + xScale.rangeBand() / 2); + const x = Math.round(xScale(point.x) + xScale.bandwidth() / 2); const y = yScale(point.y); const d = this.props.data[index]; const tooltipAtts = {}; @@ -106,8 +106,7 @@ export const BarChart = React.createClass({ dy="-1em" onClick={this.props.onBarClick && this.handleClick.bind(this, point)} style={{ cursor: this.props.onBarClick ? 'pointer' : 'default' }} - {...tooltipAtts} - > + {...tooltipAtts}> {value} </text> ); @@ -155,12 +154,12 @@ export const BarChart = React.createClass({ (this.props.data.length - 1); const relativeInnerPadding = innerPadding / (innerPadding + this.props.barsWidth); - const maxY = d3.max(this.props.data, d => d.y); - const xScale = d3.scale - .ordinal() + const maxY = max(this.props.data, d => d.y); + const xScale = scaleBand() .domain(this.props.data.map(d => d.x)) - .rangeBands([0, availableWidth], relativeInnerPadding, 0); - const yScale = d3.scale.linear().domain([0, maxY]).range([availableHeight, 0]); + .range([0, availableWidth]) + .paddingInner(relativeInnerPadding); + const yScale = scaleLinear().domain([0, maxY]).range([availableHeight, 0]); return ( <svg className="bar-chart" width={this.state.width} height={this.state.height}> diff --git a/server/sonar-web/src/main/js/components/charts/donut-chart.js b/server/sonar-web/src/main/js/components/charts/donut-chart.js index f4217c72d40..a55a243a72f 100644 --- a/server/sonar-web/src/main/js/components/charts/donut-chart.js +++ b/server/sonar-web/src/main/js/components/charts/donut-chart.js @@ -17,15 +17,14 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -import d3 from 'd3'; import React from 'react'; +import { arc as d3Arc, pie as d3Pie } from 'd3-shape'; import { ResizeMixin } from './../mixins/resize-mixin'; import { TooltipsMixin } from './../mixins/tooltips-mixin'; const Sector = React.createClass({ render() { - const arc = d3.svg - .arc() + const arc = d3Arc() .outerRadius(this.props.radius) .innerRadius(this.props.radius - this.props.thickness); return <path d={arc(this.props.data)} style={{ fill: this.props.fill }} />; @@ -58,7 +57,7 @@ export const DonutChart = React.createClass({ const size = Math.min(availableWidth, availableHeight); const radius = Math.floor(size / 2); - const pie = d3.layout.pie().sort(null).value(d => d.value); + const pie = d3Pie().sort(null).value(d => d.value); const sectors = pie(this.props.data).map((d, i) => { return ( <Sector diff --git a/server/sonar-web/src/main/js/components/charts/histogram.js b/server/sonar-web/src/main/js/components/charts/histogram.js index a06dee0abb4..de0d72efa04 100644 --- a/server/sonar-web/src/main/js/components/charts/histogram.js +++ b/server/sonar-web/src/main/js/components/charts/histogram.js @@ -17,8 +17,9 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -import d3 from 'd3'; import React from 'react'; +import { max } from 'd3-array'; +import { scaleLinear, scaleBand } from 'd3-scale'; import { ResizeMixin } from './../mixins/resize-mixin'; import { TooltipsMixin } from './../mixins/tooltips-mixin'; @@ -60,7 +61,7 @@ export const Histogram = React.createClass({ const ticks = this.props.yTicks.map((tick, index) => { const point = this.props.data[index]; const x = xScale.range()[0]; - const y = Math.round(yScale(point.y) + yScale.rangeBand() / 2 + this.props.barsHeight / 2); + const y = Math.round(yScale(point.y) + yScale.bandwidth() / 2 + this.props.barsHeight / 2); const label = tick.label ? tick.label : tick; const tooltip = tick.tooltip ? tick.tooltip : null; return ( @@ -74,8 +75,7 @@ export const Histogram = React.createClass({ x={x} y={y} dx="-1em" - dy="0.3em" - > + dy="0.3em"> {label} </text> ); @@ -90,7 +90,7 @@ export const Histogram = React.createClass({ const ticks = this.props.yValues.map((value, index) => { const point = this.props.data[index]; const x = xScale(point.x); - const y = Math.round(yScale(point.y) + yScale.rangeBand() / 2 + this.props.barsHeight / 2); + const y = Math.round(yScale(point.y) + yScale.bandwidth() / 2 + this.props.barsHeight / 2); return ( <text key={index} @@ -100,8 +100,7 @@ export const Histogram = React.createClass({ x={x} y={y} dx="1em" - dy="0.3em" - > + dy="0.3em"> {value} </text> ); @@ -112,7 +111,7 @@ export const Histogram = React.createClass({ renderBars(xScale, yScale) { const bars = this.props.data.map((d, index) => { const x = Math.round(xScale(d.x)) + /* minimum bar width */ 1; - const y = Math.round(yScale(d.y) + yScale.rangeBand() / 2); + const y = Math.round(yScale(d.y) + yScale.bandwidth() / 2); return ( <rect key={index} @@ -137,12 +136,11 @@ export const Histogram = React.createClass({ const availableWidth = this.state.width - this.props.padding[1] - this.props.padding[3]; const availableHeight = this.state.height - this.props.padding[0] - this.props.padding[2]; - const maxX = d3.max(this.props.data, d => d.x); - const xScale = d3.scale.linear().domain([0, maxX]).range([0, availableWidth]); - const yScale = d3.scale - .ordinal() + const maxX = max(this.props.data, d => d.x); + const xScale = scaleLinear().domain([0, maxX]).range([0, availableWidth]); + const yScale = scaleBand() .domain(this.props.data.map(d => d.y)) - .rangeRoundBands([0, availableHeight]); + .rangeRound([0, availableHeight]); return ( <svg className="bar-chart" width={this.state.width} height={this.state.height}> diff --git a/server/sonar-web/src/main/js/components/charts/line-chart.js b/server/sonar-web/src/main/js/components/charts/line-chart.js index 804debc86ef..e2941cf2ce0 100644 --- a/server/sonar-web/src/main/js/components/charts/line-chart.js +++ b/server/sonar-web/src/main/js/components/charts/line-chart.js @@ -17,8 +17,10 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -import d3 from 'd3'; import React from 'react'; +import { extent, max } from 'd3-array'; +import { scaleLinear } from 'd3-scale'; +import { area as d3Area, line as d3Line, curveBasis } from 'd3-shape'; import { ResizeMixin } from './../mixins/resize-mixin'; import { TooltipsMixin } from './../mixins/tooltips-mixin'; @@ -32,8 +34,7 @@ export const LineChart = React.createClass({ displayBackdrop: React.PropTypes.bool, displayPoints: React.PropTypes.bool, displayVerticalGrid: React.PropTypes.bool, - height: React.PropTypes.number, - interpolate: React.PropTypes.string + height: React.PropTypes.number }, mixins: [ResizeMixin, TooltipsMixin], @@ -45,8 +46,7 @@ export const LineChart = React.createClass({ displayVerticalGrid: true, xTicks: [], xValues: [], - padding: [10, 10, 10, 10], - interpolate: 'basis' + padding: [10, 10, 10, 10] }; }, @@ -59,12 +59,11 @@ export const LineChart = React.createClass({ return null; } - const area = d3.svg - .area() + const area = d3Area() .x(d => xScale(d.x)) .y0(yScale.range()[0]) .y1(d => yScale(d.y)) - .interpolate(this.props.interpolate); + .curve(curveBasis); let data = this.props.data; if (this.props.backdropConstraints) { @@ -126,12 +125,7 @@ export const LineChart = React.createClass({ }, renderLine(xScale, yScale) { - const p = d3.svg - .line() - .x(d => xScale(d.x)) - .y(d => yScale(d.y)) - .interpolate(this.props.interpolate); - + const p = d3Line().x(d => xScale(d.x)).y(d => yScale(d.y)).curve(curveBasis); return <path className="line-chart-path" d={p(this.props.data)} />; }, @@ -144,17 +138,16 @@ export const LineChart = React.createClass({ const availableHeight = this.state.height - this.props.padding[0] - this.props.padding[2]; let maxY; - const xScale = d3.scale - .linear() - .domain(d3.extent(this.props.data, d => d.x)) + const xScale = scaleLinear() + .domain(extent(this.props.data, d => d.x)) .range([0, availableWidth]); - const yScale = d3.scale.linear().range([availableHeight, 0]); + const yScale = scaleLinear().range([availableHeight, 0]); if (this.props.domain) { maxY = this.props.domain[1]; yScale.domain(this.props.domain); } else { - maxY = d3.max(this.props.data, d => d.y); + maxY = max(this.props.data, d => d.y); yScale.domain([0, maxY]); } diff --git a/server/sonar-web/src/main/js/components/charts/treemap.js b/server/sonar-web/src/main/js/components/charts/treemap.js index 2efbc0c29bb..77316c7c78f 100644 --- a/server/sonar-web/src/main/js/components/charts/treemap.js +++ b/server/sonar-web/src/main/js/components/charts/treemap.js @@ -17,14 +17,15 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -import d3 from 'd3'; import React from 'react'; +import { scaleLinear } from 'd3-scale'; +import { treemap as d3Treemap, hierarchy as d3Hierarchy } from 'd3-hierarchy'; import { TreemapBreadcrumbs } from './treemap-breadcrumbs'; import { ResizeMixin } from './../mixins/resize-mixin'; import { TooltipsMixin } from './../mixins/tooltips-mixin'; import { translate } from '../../helpers/l10n'; -const SIZE_SCALE = d3.scale.linear().domain([3, 15]).range([11, 18]).clamp(true); +const SIZE_SCALE = scaleLinear().domain([3, 15]).range([11, 18]).clamp(true); function mostCommitPrefix(strings) { const sortedStrings = strings.slice(0).sort(); @@ -66,8 +67,7 @@ export const TreemapRect = React.createClass({ onClick={e => e.stopPropagation()} className="treemap-link" href={this.props.link} - style={{ fontSize: 12 }} - > + style={{ fontSize: 12 }}> <span className="icon-link" /> </a> ); @@ -98,8 +98,7 @@ export const TreemapRect = React.createClass({ className="treemap-cell" {...tooltipAttrs} style={cellStyles} - onClick={this.props.onClick} - > + onClick={this.props.onClick}> <div className="treemap-inner" dangerouslySetInnerHTML={{ __html: this.props.label }} @@ -129,8 +128,7 @@ export const Treemap = React.createClass({ <div className="sonar-d3"> <div className="treemap-container" - style={{ width: this.state.width, height: this.state.height }} - > + style={{ width: this.state.width, height: this.state.height }}> {translate('no_data')} </div> <TreemapBreadcrumbs {...this.props} /> @@ -147,38 +145,37 @@ export const Treemap = React.createClass({ return this.renderWhenNoData(); } - const treemap = d3.layout - .treemap() - .round(true) - .value(d => d.size) - .sort((a, b) => a.value - b.value) - .size([this.state.width, this.state.height]); - const nodes = treemap - .nodes({ children: this.props.items }) - .filter(d => !d.children) - .filter(d => !!d.dx && !!d.dy); + const hierarchy = d3Hierarchy({ children: this.props.items }) + .sum(d => d.size) + .sort((a, b) => b.value - a.value); + + const treemap = d3Treemap().round(true).size([this.state.width, this.state.height]); + + const nodes = treemap(hierarchy).leaves(); const prefix = mostCommitPrefix(this.props.items.map(item => item.label)); const prefixLength = prefix.length; const rectangles = nodes.map(node => { - const key = node.label; - const label = prefixLength ? `${prefix}<br>${node.label.substr(prefixLength)}` : node.label; - const onClick = this.props.canBeClicked(node) - ? () => this.props.onRectangleClick(node) + const key = node.data.label; + const label = prefixLength + ? `${prefix}<br>${node.data.label.substr(prefixLength)}` + : node.data.label; + const onClick = this.props.canBeClicked(node.data) + ? () => this.props.onRectangleClick(node.data) : null; return ( <TreemapRect key={key} - x={node.x} - y={node.y} - width={node.dx} - height={node.dy} - fill={node.color} + x={node.x0} + y={node.y0} + width={node.x1 - node.x0} + height={node.y1 - node.y0} + fill={node.data.color} label={label} prefix={prefix} - tooltip={node.tooltip} - link={node.link} + tooltip={node.data.tooltip} + link={node.data.link} onClick={onClick} /> ); @@ -188,8 +185,7 @@ export const Treemap = React.createClass({ <div className="sonar-d3"> <div className="treemap-container" - style={{ width: this.state.width, height: this.state.height }} - > + style={{ width: this.state.width, height: this.state.height }}> {rectangles} </div> <TreemapBreadcrumbs {...this.props} /> diff --git a/server/sonar-web/src/main/js/components/charts/word-cloud.js b/server/sonar-web/src/main/js/components/charts/word-cloud.js index f29ae2da943..b3ea398c8cc 100644 --- a/server/sonar-web/src/main/js/components/charts/word-cloud.js +++ b/server/sonar-web/src/main/js/components/charts/word-cloud.js @@ -17,9 +17,10 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -import d3 from 'd3'; import React from 'react'; -import sortBy from 'lodash/sortBy'; +import { max } from 'd3-array'; +import { scaleLinear } from 'd3-scale'; +import { sortBy } from 'lodash'; import { TooltipsMixin } from './../mixins/tooltips-mixin'; export const Word = React.createClass({ @@ -67,9 +68,8 @@ export const WordCloud = React.createClass({ return index % 2 * (len - index) + index / 2; }); - const sizeScale = d3.scale - .linear() - .domain([0, d3.max(this.props.items, d => d.size)]) + const sizeScale = scaleLinear() + .domain([0, max(this.props.items, d => d.size)]) .range(this.props.sizeRange); const words = sortedItems.map((item, index) => ( <Word diff --git a/server/sonar-web/src/main/js/components/common/MultiSelect.js b/server/sonar-web/src/main/js/components/common/MultiSelect.js index ec8adb3ced9..842695b0732 100644 --- a/server/sonar-web/src/main/js/components/common/MultiSelect.js +++ b/server/sonar-web/src/main/js/components/common/MultiSelect.js @@ -19,7 +19,7 @@ */ // @flow import React from 'react'; -import difference from 'lodash/difference'; +import { difference } from 'lodash'; import MultiSelectOption from './MultiSelectOption'; import { translate } from '../../helpers/l10n'; diff --git a/server/sonar-web/src/main/js/components/common/file-upload.js b/server/sonar-web/src/main/js/components/common/file-upload.js index 8c5a2729101..40cf7f8cff2 100644 --- a/server/sonar-web/src/main/js/components/common/file-upload.js +++ b/server/sonar-web/src/main/js/components/common/file-upload.js @@ -18,7 +18,7 @@ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ import $ from 'jquery'; -import uniqueId from 'lodash/uniqueId'; +import { uniqueId } from 'lodash'; function createFrame() { const uuid = uniqueId('upload-form-'); diff --git a/server/sonar-web/src/main/js/components/controls/DateInput.js b/server/sonar-web/src/main/js/components/controls/DateInput.js index 7ceb11373e5..a339a44bc08 100644 --- a/server/sonar-web/src/main/js/components/controls/DateInput.js +++ b/server/sonar-web/src/main/js/components/controls/DateInput.js @@ -19,7 +19,7 @@ */ import $ from 'jquery'; import React from 'react'; -import pick from 'lodash/pick'; +import { pick } from 'lodash'; import './styles.css'; export default class DateInput extends React.Component { diff --git a/server/sonar-web/src/main/js/components/issue/views/assign-form-view.js b/server/sonar-web/src/main/js/components/issue/views/assign-form-view.js index c0a738e4f01..c567b9edb92 100644 --- a/server/sonar-web/src/main/js/components/issue/views/assign-form-view.js +++ b/server/sonar-web/src/main/js/components/issue/views/assign-form-view.js @@ -18,8 +18,7 @@ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ import $ from 'jquery'; -import debounce from 'lodash/debounce'; -import uniqBy from 'lodash/uniqBy'; +import { debounce, uniqBy } from 'lodash'; import ActionOptionsView from '../../common/action-options-view'; import Template from '../templates/issue-assign-form.hbs'; import OptionTemplate from '../templates/issue-assign-form-option.hbs'; diff --git a/server/sonar-web/src/main/js/components/issue/views/tags-form-view.js b/server/sonar-web/src/main/js/components/issue/views/tags-form-view.js index db9360a9782..87b1287bee9 100644 --- a/server/sonar-web/src/main/js/components/issue/views/tags-form-view.js +++ b/server/sonar-web/src/main/js/components/issue/views/tags-form-view.js @@ -18,9 +18,7 @@ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ import $ from 'jquery'; -import debounce from 'lodash/debounce'; -import difference from 'lodash/difference'; -import without from 'lodash/without'; +import { debounce, difference, without } from 'lodash'; import ActionOptionsView from '../../common/action-options-view'; import Template from '../templates/issue-tags-form.hbs'; import OptionTemplate from '../templates/issue-tags-form-option.hbs'; diff --git a/server/sonar-web/src/main/js/components/navigator/controller.js b/server/sonar-web/src/main/js/components/navigator/controller.js index 27769a53b78..9f60ff97d9b 100644 --- a/server/sonar-web/src/main/js/components/navigator/controller.js +++ b/server/sonar-web/src/main/js/components/navigator/controller.js @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -import uniq from 'lodash/uniq'; +import { uniq } from 'lodash'; import Marionette from 'backbone.marionette'; export default Marionette.Controller.extend({ diff --git a/server/sonar-web/src/main/js/components/navigator/workspace-list-view.js b/server/sonar-web/src/main/js/components/navigator/workspace-list-view.js index 78b7732a92b..d47b6e82ba4 100644 --- a/server/sonar-web/src/main/js/components/navigator/workspace-list-view.js +++ b/server/sonar-web/src/main/js/components/navigator/workspace-list-view.js @@ -18,7 +18,7 @@ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ import $ from 'jquery'; -import throttle from 'lodash/throttle'; +import { throttle } from 'lodash'; import Marionette from 'backbone.marionette'; const BOTTOM_OFFSET = 60; diff --git a/server/sonar-web/src/main/js/components/select-list/controls.js b/server/sonar-web/src/main/js/components/select-list/controls.js index bc0c0d7c57d..9ed3851a393 100644 --- a/server/sonar-web/src/main/js/components/select-list/controls.js +++ b/server/sonar-web/src/main/js/components/select-list/controls.js @@ -18,7 +18,7 @@ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ import React from 'react'; -import debounce from 'lodash/debounce'; +import { debounce } from 'lodash'; import RadioToggle from '../controls/RadioToggle'; import { translate } from '../../helpers/l10n'; diff --git a/server/sonar-web/src/main/js/components/ui/DuplicationsRating.js b/server/sonar-web/src/main/js/components/ui/DuplicationsRating.js index ddb058109c4..7132052d4b6 100644 --- a/server/sonar-web/src/main/js/components/ui/DuplicationsRating.js +++ b/server/sonar-web/src/main/js/components/ui/DuplicationsRating.js @@ -20,7 +20,7 @@ // @flow import React from 'react'; import classNames from 'classnames'; -import inRange from 'lodash/inRange'; +import { inRange } from 'lodash'; import './DuplicationsRating.css'; export default class DuplicationsRating extends React.Component { @@ -41,7 +41,7 @@ export default class DuplicationsRating extends React.Component { 'duplications-rating-small': size === 'small', 'duplications-rating-big': size === 'big', 'duplications-rating-muted': muted, - 'duplications-rating-A': inRange(value, 3), + 'duplications-rating-A': inRange(value, 0, 3), 'duplications-rating-B': inRange(value, 3, 5), 'duplications-rating-C': inRange(value, 5, 10), 'duplications-rating-D': inRange(value, 10, 20), diff --git a/server/sonar-web/src/main/js/components/ui/SizeRating.js b/server/sonar-web/src/main/js/components/ui/SizeRating.js index f1b2f919d55..0e0c8098c2b 100644 --- a/server/sonar-web/src/main/js/components/ui/SizeRating.js +++ b/server/sonar-web/src/main/js/components/ui/SizeRating.js @@ -20,7 +20,7 @@ // @flow import React from 'react'; import classNames from 'classnames'; -import inRange from 'lodash/inRange'; +import { inRange } from 'lodash'; import './SizeRating.css'; export default class SizeRating extends React.Component { @@ -43,7 +43,7 @@ export default class SizeRating extends React.Component { } let letter; - if (inRange(value, 1000)) { + if (inRange(value, 0, 1000)) { letter = 'XS'; } else if (inRange(value, 1000, 10000)) { letter = 'S'; diff --git a/server/sonar-web/src/main/js/components/widgets/barchart.js b/server/sonar-web/src/main/js/components/widgets/barchart.js index 26635fcaa20..b84aa71d2e7 100644 --- a/server/sonar-web/src/main/js/components/widgets/barchart.js +++ b/server/sonar-web/src/main/js/components/widgets/barchart.js @@ -19,7 +19,9 @@ */ import $ from 'jquery'; import moment from 'moment'; -import d3 from 'd3'; +import { max } from 'd3-array'; +import { select } from 'd3-selection'; +import { scaleLinear, scaleBand } from 'd3-scale'; function trans(left, top) { return `translate(${left}, ${top})`; @@ -31,7 +33,6 @@ const defaults = function() { return { height: 140, color: '#1f77b4', - interpolate: 'basis', marginLeft: 1, marginRight: 1, @@ -55,16 +56,16 @@ $.fn.barchart = function(data) { endDate: options.endDate ? moment(options.endDate) : null }); - const container = d3.select(this); + const container = select(this); const svg = container .append('svg') .attr('width', options.width + 2) .attr('height', options.height + 2) .classed('sonar-d3', true); const plot = svg.append('g').classed('plot', true); - const xScale = d3.scale.ordinal().domain(data.map((d, i) => i)); - const yScaleMax = d3.max(data, d => d.count); - const yScale = d3.scale.linear().domain([0, yScaleMax]); + const xScale = scaleBand().domain(data.map((d, i) => i)); + const yScaleMax = max(data, d => d.count); + const yScale = scaleLinear().domain([0, yScaleMax]); Object.assign(options, { availableWidth: options.width - options.marginLeft - options.marginRight, @@ -72,10 +73,10 @@ $.fn.barchart = function(data) { }); plot.attr('transform', trans(options.marginLeft, options.marginTop)); - xScale.rangeRoundBands([0, options.availableWidth], 0.05, 0); + xScale.rangeRound([0, options.availableWidth]).paddingInner(0.05); yScale.range([3, options.availableHeight]); - const barWidth = xScale.rangeBand(); + const barWidth = xScale.bandwidth(); const bars = plot.selectAll('g').data(data); if (barWidth > 0) { @@ -117,7 +118,7 @@ $.fn.barchart = function(data) { }) .attr('data-placement', 'bottom') .attr('data-toggle', 'tooltip'); - const maxValue = d3.max(data, d => d.count); + const maxValue = max(data, d => d.count); let isValueShown = false; barsEnter .append('text') diff --git a/server/sonar-web/src/main/js/components/workspace/views/rule-view.js b/server/sonar-web/src/main/js/components/workspace/views/rule-view.js index f32a3908aaf..1fe6440d64c 100644 --- a/server/sonar-web/src/main/js/components/workspace/views/rule-view.js +++ b/server/sonar-web/src/main/js/components/workspace/views/rule-view.js @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -import union from 'lodash/union'; +import { union } from 'lodash'; import Marionette from 'backbone.marionette'; import BaseView from './base-viewer-view'; import Template from '../templates/workspace-rule.hbs'; diff --git a/server/sonar-web/src/main/js/helpers/issues.js b/server/sonar-web/src/main/js/helpers/issues.js index 906ee766099..e8ce3a697ec 100644 --- a/server/sonar-web/src/main/js/helpers/issues.js +++ b/server/sonar-web/src/main/js/helpers/issues.js @@ -18,7 +18,7 @@ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ // @flow -import sortBy from 'lodash/sortBy'; +import { sortBy } from 'lodash'; import { SEVERITIES } from './constants'; type TextRange = { diff --git a/server/sonar-web/src/main/js/helpers/scrolling.js b/server/sonar-web/src/main/js/helpers/scrolling.js index fb747932015..e0ee20ab024 100644 --- a/server/sonar-web/src/main/js/helpers/scrolling.js +++ b/server/sonar-web/src/main/js/helpers/scrolling.js @@ -18,7 +18,7 @@ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ // @flow -import debounce from 'lodash/debounce'; +import { debounce } from 'lodash'; const SCROLLING_DURATION = 100; const SCROLLING_INTERVAL = 10; diff --git a/server/sonar-web/src/main/js/libs/third-party/keymaster.js b/server/sonar-web/src/main/js/libs/third-party/keymaster.js index 4a1caa41888..8ba7aad8487 100644 --- a/server/sonar-web/src/main/js/libs/third-party/keymaster.js +++ b/server/sonar-web/src/main/js/libs/third-party/keymaster.js @@ -311,6 +311,4 @@ global.key.noConflict = noConflict; global.key.unbind = unbindKey; - if(typeof module !== 'undefined') module.exports = key; - -})(this); +})(window); diff --git a/server/sonar-web/src/main/js/store/components/reducer.js b/server/sonar-web/src/main/js/store/components/reducer.js index 0f90ce90862..e8a96a36685 100644 --- a/server/sonar-web/src/main/js/store/components/reducer.js +++ b/server/sonar-web/src/main/js/store/components/reducer.js @@ -18,8 +18,7 @@ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ import { combineReducers } from 'redux'; -import keyBy from 'lodash/keyBy'; -import uniq from 'lodash/uniq'; +import { keyBy, uniq } from 'lodash'; import { RECEIVE_COMPONENTS, RECEIVE_PROJECT_TAGS } from './actions'; const byKey = (state = {}, action = {}) => { diff --git a/server/sonar-web/src/main/js/store/favorites/duck.js b/server/sonar-web/src/main/js/store/favorites/duck.js index 27d3864c86f..73abccaeef1 100644 --- a/server/sonar-web/src/main/js/store/favorites/duck.js +++ b/server/sonar-web/src/main/js/store/favorites/duck.js @@ -18,8 +18,7 @@ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ // @flow -import uniq from 'lodash/uniq'; -import without from 'lodash/without'; +import { uniq, without } from 'lodash'; type Favorite = { key: string }; diff --git a/server/sonar-web/src/main/js/store/globalMessages/duck.js b/server/sonar-web/src/main/js/store/globalMessages/duck.js index f0cc29ba053..367c8a61e36 100644 --- a/server/sonar-web/src/main/js/store/globalMessages/duck.js +++ b/server/sonar-web/src/main/js/store/globalMessages/duck.js @@ -18,7 +18,7 @@ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ // @flow -import uniqueId from 'lodash/uniqueId'; +import { uniqueId } from 'lodash'; type Level = 'ERROR' | 'SUCCESS'; diff --git a/server/sonar-web/src/main/js/store/issues/duck.js b/server/sonar-web/src/main/js/store/issues/duck.js index 7b5cb240404..b559d8103c7 100644 --- a/server/sonar-web/src/main/js/store/issues/duck.js +++ b/server/sonar-web/src/main/js/store/issues/duck.js @@ -18,7 +18,7 @@ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ // @flow -import keyBy from 'lodash/keyBy'; +import { keyBy } from 'lodash'; type Issue = { key: string }; diff --git a/server/sonar-web/src/main/js/store/languages/reducer.js b/server/sonar-web/src/main/js/store/languages/reducer.js index 4e4dbfef3b8..52177241e61 100644 --- a/server/sonar-web/src/main/js/store/languages/reducer.js +++ b/server/sonar-web/src/main/js/store/languages/reducer.js @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -import keyBy from 'lodash/keyBy'; +import { keyBy } from 'lodash'; import { RECEIVE_LANGUAGES } from './actions'; const reducer = (state = {}, action = {}) => { diff --git a/server/sonar-web/src/main/js/store/notifications/duck.js b/server/sonar-web/src/main/js/store/notifications/duck.js index cd4f7a7ab05..1a3f554fbd5 100644 --- a/server/sonar-web/src/main/js/store/notifications/duck.js +++ b/server/sonar-web/src/main/js/store/notifications/duck.js @@ -19,8 +19,7 @@ */ // @flow import { combineReducers } from 'redux'; -import uniqBy from 'lodash/uniqBy'; -import uniqWith from 'lodash/uniqWith'; +import { uniqBy, uniqWith } from 'lodash'; export type Notification = { channel: string, @@ -145,15 +144,16 @@ export default combineReducers({ notifications, channels, globalTypes, perProjec export const getGlobal = (state: State): NotificationsState => state.notifications.filter(n => !n.project); -export const getProjects = (state: State): Array<string> => - uniqBy( - state.notifications.filter(n => n.project).map(n => ({ - key: n.project, - name: n.projectName, - organization: n.organization - })), - project => project.key - ); +export const getProjects = (state: State): Array<{ key: string, name: string }> => { + // $FlowFixMe + const allProjects = state.notifications.filter(n => n.project != null).map(n => ({ + key: n.project, + name: n.projectName, + organization: n.organization + })); + + return uniqBy(allProjects, project => project.key); +}; export const getForProject = (state: State, project: string): NotificationsState => state.notifications.filter(n => n.project === project); diff --git a/server/sonar-web/src/main/js/store/organizations/duck.js b/server/sonar-web/src/main/js/store/organizations/duck.js index f04782a8541..40d815ce856 100644 --- a/server/sonar-web/src/main/js/store/organizations/duck.js +++ b/server/sonar-web/src/main/js/store/organizations/duck.js @@ -19,9 +19,7 @@ */ // @flow import { combineReducers } from 'redux'; -import omit from 'lodash/omit'; -import uniq from 'lodash/uniq'; -import without from 'lodash/without'; +import { omit, uniq, without } from 'lodash'; export type Organization = { avatar?: string, diff --git a/server/sonar-web/src/main/js/store/projectActivity/analyses.js b/server/sonar-web/src/main/js/store/projectActivity/analyses.js index 90e02537484..1bed62ad651 100644 --- a/server/sonar-web/src/main/js/store/projectActivity/analyses.js +++ b/server/sonar-web/src/main/js/store/projectActivity/analyses.js @@ -18,7 +18,7 @@ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ // @flow -import keyBy from 'lodash/keyBy'; +import { keyBy } from 'lodash'; import type { Action, ReceiveProjectActivityAction, diff --git a/server/sonar-web/src/main/js/store/projectActivity/events.js b/server/sonar-web/src/main/js/store/projectActivity/events.js index 41446540e8d..d4024b2e068 100644 --- a/server/sonar-web/src/main/js/store/projectActivity/events.js +++ b/server/sonar-web/src/main/js/store/projectActivity/events.js @@ -18,7 +18,7 @@ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ // @flow -import keyBy from 'lodash/keyBy'; +import { keyBy } from 'lodash'; import type { Action, ReceiveProjectActivityAction, diff --git a/server/sonar-web/src/main/js/store/users/reducer.js b/server/sonar-web/src/main/js/store/users/reducer.js index 71b313077ed..f0ec0163898 100644 --- a/server/sonar-web/src/main/js/store/users/reducer.js +++ b/server/sonar-web/src/main/js/store/users/reducer.js @@ -18,7 +18,7 @@ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ import { combineReducers } from 'redux'; -import uniq from 'lodash/uniq'; +import { uniq } from 'lodash'; import { RECEIVE_CURRENT_USER } from './actions'; const usersByLogin = (state = {}, action = {}) => { diff --git a/server/sonar-web/src/main/js/store/utils/generalReducers.js b/server/sonar-web/src/main/js/store/utils/generalReducers.js index 21342cb4bde..a95b2bfa5bb 100644 --- a/server/sonar-web/src/main/js/store/utils/generalReducers.js +++ b/server/sonar-web/src/main/js/store/utils/generalReducers.js @@ -19,7 +19,7 @@ */ // Author: Christoffer Niska <christofferniska@gmail.com> // https://gist.github.com/crisu83/42ecffccad9d04c74605fbc75c9dc9d1 -import uniq from 'lodash/uniq'; +import { uniq } from 'lodash'; /** * Creates a reducer that manages a single value. |