From 85c94cb261a16c3126ee856325bc038afd1ef405 Mon Sep 17 00:00:00 2001 From: Jeremy Davis Date: Mon, 2 Mar 2020 16:00:29 +0100 Subject: [PATCH] SONAR-13147 lazyloading --- .../src/main/js/app/components/App.tsx | 4 +- .../components/SimpleSessionsContainer.tsx | 4 +- .../main/js/app/components/StartupModal.tsx | 8 +- .../embed-docs-modal/EmbedDocsPopupHelper.tsx | 4 +- .../nav/component/ComponentNavWarnings.tsx | 7 +- .../ComponentNavWarnings-test.tsx.snap | 2 +- .../app/components/nav/global/GlobalNav.tsx | 8 +- .../components/nav/global/GlobalNavPlus.tsx | 2 +- .../main/js/app/components/search/Search.tsx | 6 +- .../src/main/js/app/utils/startReactApp.tsx | 55 +++-- .../src/main/js/apps/about/routes.ts | 6 +- .../src/main/js/apps/account/routes.ts | 14 +- .../components/TaskActions.tsx | 4 +- .../main/js/apps/background-tasks/routes.ts | 4 +- .../sonar-web/src/main/js/apps/code/routes.ts | 4 +- .../src/main/js/apps/coding-rules/routes.ts | 4 +- .../main/js/apps/component-measures/routes.ts | 4 +- .../main/js/apps/custom-measures/routes.ts | 4 +- .../src/main/js/apps/custom-metrics/routes.ts | 4 +- .../src/main/js/apps/documentation/routes.ts | 4 +- .../src/main/js/apps/groups/routes.ts | 4 +- .../js/apps/issues/IssuesPageSelector.tsx | 37 ---- .../__tests__/IssuesPageSelector-test.tsx | 56 ----- .../IssuesPageSelector-test.tsx.snap | 17 -- .../main/js/apps/issues/components/App.tsx | 23 +- .../apps/issues/components/AppContainer.tsx | 20 +- .../issues/components/IssuesSourceViewer.tsx | 3 - .../issues/components/__tests__/App-test.tsx | 6 +- .../IssuesSourceViewer-test.tsx.snap | 5 - .../CrossComponentSourceViewer.tsx | 4 +- .../src/main/js/apps/maintenance/routes.tsx | 6 +- .../marketplace/components/EditionBox.tsx | 7 +- .../__snapshots__/EditionBox-test.tsx.snap | 2 +- .../src/main/js/apps/marketplace/routes.ts | 4 +- .../components/OrganizationProjects.tsx | 6 +- .../src/main/js/apps/organizations/routes.ts | 42 ++-- .../main/js/apps/overview/components/App.tsx | 6 +- .../pullRequests/PullRequestOverview.tsx | 21 +- .../src/main/js/apps/overview/routes.ts | 4 +- .../js/apps/permission-templates/routes.ts | 4 +- .../src/main/js/apps/permissions/routes.ts | 6 +- .../src/main/js/apps/portfolio/routes.ts | 4 +- .../main/js/apps/projectActivity/routes.ts | 4 +- .../main/js/apps/projectBaseline/routes.ts | 4 +- .../main/js/apps/projectBranches/routes.ts | 4 +- .../main/js/apps/projectQualityGate/routes.ts | 4 +- .../js/apps/projectQualityProfiles/routes.ts | 4 +- .../components/AllProjectsContainer.tsx | 4 +- .../components/DefaultPageSelector.tsx | 16 +- .../src/main/js/apps/projects/routes.ts | 4 +- .../main/js/apps/projectsManagement/routes.ts | 4 +- .../src/main/js/apps/quality-gates/routes.ts | 4 +- .../compare/ComparisonResultActivation.tsx | 4 +- .../main/js/apps/quality-profiles/routes.ts | 14 +- .../src/main/js/apps/sessions/routes.ts | 10 +- .../src/main/js/apps/settings/routes.ts | 6 +- .../src/main/js/apps/system/routes.ts | 4 +- .../src/main/js/apps/tutorials/routes.ts | 7 +- .../src/main/js/apps/users/routes.ts | 4 +- .../src/main/js/apps/web-api/routes.ts | 6 +- .../src/main/js/apps/webhooks/routes.ts | 4 +- .../components/SourceViewer/SourceViewer.tsx | 4 +- .../SourceViewer/SourceViewerBase.tsx | 202 +++++++++--------- .../__tests__/SourceViewerBase-test.tsx | 131 +++++++++++- .../SourceViewerBase-test.tsx.snap | 173 +++++++++++++-- .../main/js/components/controls/DateInput.tsx | 4 +- .../main/js/components/docs/DocTooltip.tsx | 4 +- .../__snapshots__/DocTooltip-test.tsx.snap | 2 +- .../js/components/workspace/Workspace.tsx | 14 +- 69 files changed, 630 insertions(+), 454 deletions(-) delete mode 100644 server/sonar-web/src/main/js/apps/issues/IssuesPageSelector.tsx delete mode 100644 server/sonar-web/src/main/js/apps/issues/__tests__/IssuesPageSelector-test.tsx delete mode 100644 server/sonar-web/src/main/js/apps/issues/__tests__/__snapshots__/IssuesPageSelector-test.tsx.snap diff --git a/server/sonar-web/src/main/js/app/components/App.tsx b/server/sonar-web/src/main/js/app/components/App.tsx index 0c06dbe39a6..3e0fe5e63a5 100644 --- a/server/sonar-web/src/main/js/app/components/App.tsx +++ b/server/sonar-web/src/main/js/app/components/App.tsx @@ -19,14 +19,14 @@ */ import * as React from 'react'; import { connect } from 'react-redux'; -import { lazyLoad } from 'sonar-ui-common/components/lazyLoad'; +import { lazyLoadComponent } from 'sonar-ui-common/components/lazyLoadComponent'; import { fetchMyOrganizations } from '../../apps/account/organizations/actions'; import { isSonarCloud } from '../../helpers/system'; import { isLoggedIn } from '../../helpers/users'; import { fetchLanguages } from '../../store/rootActions'; import { getAppState, getCurrentUser, getGlobalSettingValue, Store } from '../../store/rootReducer'; -const PageTracker = lazyLoad(() => import('./PageTracker')); +const PageTracker = lazyLoadComponent(() => import('./PageTracker')); interface StateProps { appState: T.AppState | undefined; diff --git a/server/sonar-web/src/main/js/app/components/SimpleSessionsContainer.tsx b/server/sonar-web/src/main/js/app/components/SimpleSessionsContainer.tsx index 4d7081762c5..e860884adce 100644 --- a/server/sonar-web/src/main/js/app/components/SimpleSessionsContainer.tsx +++ b/server/sonar-web/src/main/js/app/components/SimpleSessionsContainer.tsx @@ -18,10 +18,10 @@ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ import * as React from 'react'; -import { lazyLoad } from 'sonar-ui-common/components/lazyLoad'; +import { lazyLoadComponent } from 'sonar-ui-common/components/lazyLoadComponent'; import GlobalFooterContainer from './GlobalFooterContainer'; -const PageTracker = lazyLoad(() => import('./PageTracker')); +const PageTracker = lazyLoadComponent(() => import('./PageTracker')); interface Props { children?: React.ReactNode; diff --git a/server/sonar-web/src/main/js/app/components/StartupModal.tsx b/server/sonar-web/src/main/js/app/components/StartupModal.tsx index 196b6282934..c5bb1efa37a 100644 --- a/server/sonar-web/src/main/js/app/components/StartupModal.tsx +++ b/server/sonar-web/src/main/js/app/components/StartupModal.tsx @@ -20,7 +20,7 @@ import * as differenceInDays from 'date-fns/difference_in_days'; import * as React from 'react'; import { connect } from 'react-redux'; -import { lazyLoad } from 'sonar-ui-common/components/lazyLoad'; +import { lazyLoadComponent } from 'sonar-ui-common/components/lazyLoadComponent'; import { parseDate, toShortNotSoISOString } from 'sonar-ui-common/helpers/dates'; import { hasMessage } from 'sonar-ui-common/helpers/l10n'; import { get, save } from 'sonar-ui-common/helpers/storage'; @@ -33,8 +33,10 @@ import { skipOnboarding } from '../../store/users'; import { EditionKey } from '../../types/editions'; import { OnboardingContext } from './OnboardingContext'; -const OnboardingModal = lazyLoad(() => import('../../apps/tutorials/onboarding/OnboardingModal')); -const LicensePromptModal = lazyLoad( +const OnboardingModal = lazyLoadComponent(() => + import('../../apps/tutorials/onboarding/OnboardingModal') +); +const LicensePromptModal = lazyLoadComponent( () => import('../../apps/marketplace/components/LicensePromptModal'), 'LicensePromptModal' ); diff --git a/server/sonar-web/src/main/js/app/components/embed-docs-modal/EmbedDocsPopupHelper.tsx b/server/sonar-web/src/main/js/app/components/embed-docs-modal/EmbedDocsPopupHelper.tsx index 4e82ef25566..9f8d84e27e3 100644 --- a/server/sonar-web/src/main/js/app/components/embed-docs-modal/EmbedDocsPopupHelper.tsx +++ b/server/sonar-web/src/main/js/app/components/embed-docs-modal/EmbedDocsPopupHelper.tsx @@ -21,10 +21,10 @@ import * as React from 'react'; import { ButtonLink } from 'sonar-ui-common/components/controls/buttons'; import Toggler from 'sonar-ui-common/components/controls/Toggler'; import HelpIcon from 'sonar-ui-common/components/icons/HelpIcon'; -import { lazyLoad } from 'sonar-ui-common/components/lazyLoad'; +import { lazyLoadComponent } from 'sonar-ui-common/components/lazyLoadComponent'; import { translate } from 'sonar-ui-common/helpers/l10n'; -const EmbedDocsPopup = lazyLoad(() => import('./EmbedDocsPopup')); +const EmbedDocsPopup = lazyLoadComponent(() => import('./EmbedDocsPopup')); interface State { helpOpen: boolean; diff --git a/server/sonar-web/src/main/js/app/components/nav/component/ComponentNavWarnings.tsx b/server/sonar-web/src/main/js/app/components/nav/component/ComponentNavWarnings.tsx index 62a25948174..f377731fb6f 100644 --- a/server/sonar-web/src/main/js/app/components/nav/component/ComponentNavWarnings.tsx +++ b/server/sonar-web/src/main/js/app/components/nav/component/ComponentNavWarnings.tsx @@ -19,12 +19,13 @@ */ import * as React from 'react'; import { FormattedMessage } from 'react-intl'; -import { lazyLoad } from 'sonar-ui-common/components/lazyLoad'; +import { lazyLoadComponent } from 'sonar-ui-common/components/lazyLoadComponent'; import { Alert } from 'sonar-ui-common/components/ui/Alert'; import { translate } from 'sonar-ui-common/helpers/l10n'; -const AnalysisWarningsModal = lazyLoad(() => - import('../../../../components/common/AnalysisWarningsModal') +const AnalysisWarningsModal = lazyLoadComponent( + () => import('../../../../components/common/AnalysisWarningsModal'), + 'AnalysisWarningsModal' ); interface Props { diff --git a/server/sonar-web/src/main/js/app/components/nav/component/__tests__/__snapshots__/ComponentNavWarnings-test.tsx.snap b/server/sonar-web/src/main/js/app/components/nav/component/__tests__/__snapshots__/ComponentNavWarnings-test.tsx.snap index 0a72b432624..03033721f88 100644 --- a/server/sonar-web/src/main/js/app/components/nav/component/__tests__/__snapshots__/ComponentNavWarnings-test.tsx.snap +++ b/server/sonar-web/src/main/js/app/components/nav/component/__tests__/__snapshots__/ComponentNavWarnings-test.tsx.snap @@ -30,7 +30,7 @@ exports[`should render 1`] = ` } /> - import('./GlobalNavPlus'), 'GlobalNavPlus'); -const NotificationsSidebar = lazyLoad( +const GlobalNavPlus = lazyLoadComponent(() => import('./GlobalNavPlus'), 'GlobalNavPlus'); +const NotificationsSidebar = lazyLoadComponent( () => import('../../notifications/NotificationsSidebar'), 'NotificationsSidebar' ); -const NavLatestNotification = lazyLoad( +const NavLatestNotification = lazyLoadComponent( () => import('../../notifications/NavLatestNotification'), 'NavLatestNotification' ); diff --git a/server/sonar-web/src/main/js/app/components/nav/global/GlobalNavPlus.tsx b/server/sonar-web/src/main/js/app/components/nav/global/GlobalNavPlus.tsx index 7e0b5d171f9..fc2bb9107ee 100644 --- a/server/sonar-web/src/main/js/app/components/nav/global/GlobalNavPlus.tsx +++ b/server/sonar-web/src/main/js/app/components/nav/global/GlobalNavPlus.tsx @@ -200,4 +200,4 @@ export class GlobalNavPlus extends React.PureComponent(GlobalNavPlus); diff --git a/server/sonar-web/src/main/js/app/components/search/Search.tsx b/server/sonar-web/src/main/js/app/components/search/Search.tsx index 31bf701130f..7db674fef92 100644 --- a/server/sonar-web/src/main/js/app/components/search/Search.tsx +++ b/server/sonar-web/src/main/js/app/components/search/Search.tsx @@ -26,7 +26,7 @@ import { DropdownOverlay } from 'sonar-ui-common/components/controls/Dropdown'; import OutsideClickHandler from 'sonar-ui-common/components/controls/OutsideClickHandler'; import SearchBox from 'sonar-ui-common/components/controls/SearchBox'; import ClockIcon from 'sonar-ui-common/components/icons/ClockIcon'; -import { lazyLoad } from 'sonar-ui-common/components/lazyLoad'; +import { lazyLoadComponent } from 'sonar-ui-common/components/lazyLoadComponent'; import DeferredSpinner from 'sonar-ui-common/components/ui/DeferredSpinner'; import { translate, translateWithParameters } from 'sonar-ui-common/helpers/l10n'; import { scrollToElement } from 'sonar-ui-common/helpers/scrolling'; @@ -36,8 +36,8 @@ import RecentHistory from '../RecentHistory'; import './Search.css'; import { ComponentResult, More, Results, sortQualifiers } from './utils'; -const SearchResults = lazyLoad(() => import('./SearchResults')); -const SearchResult = lazyLoad(() => import('./SearchResult')); +const SearchResults = lazyLoadComponent(() => import('./SearchResults')); +const SearchResult = lazyLoadComponent(() => import('./SearchResult')); interface OwnProps { appState: Pick; diff --git a/server/sonar-web/src/main/js/app/utils/startReactApp.tsx b/server/sonar-web/src/main/js/app/utils/startReactApp.tsx index a901bca0c2a..251018d38e7 100644 --- a/server/sonar-web/src/main/js/app/utils/startReactApp.tsx +++ b/server/sonar-web/src/main/js/app/utils/startReactApp.tsx @@ -26,7 +26,6 @@ import { HelmetProvider } from 'react-helmet-async'; import { IntlProvider } from 'react-intl'; import { Provider } from 'react-redux'; import { IndexRoute, Redirect, Route, RouteConfig, RouteProps, Router } from 'react-router'; -import { lazyLoad } from 'sonar-ui-common/components/lazyLoad'; import { lazyLoadComponent } from 'sonar-ui-common/components/lazyLoadComponent'; import { ThemeProvider } from 'sonar-ui-common/components/theme'; import getHistory from 'sonar-ui-common/helpers/getHistory'; @@ -44,7 +43,6 @@ import ExploreIssues from '../../apps/explore/ExploreIssues'; import ExploreProjects from '../../apps/explore/ExploreProjects'; import groupsRoutes from '../../apps/groups/routes'; import Issues from '../../apps/issues/components/AppContainer'; -import IssuesPageSelector from '../../apps/issues/IssuesPageSelector'; import { maintenanceRoutes, setupRoutes } from '../../apps/maintenance/routes'; import marketplaceRoutes from '../../apps/marketplace/routes'; import organizationsRoutes from '../../apps/organizations/routes'; @@ -151,7 +149,7 @@ function renderRedirects() { function renderComponentRoutes() { return ( - import('../components/ComponentContainer'))}> + import('../components/ComponentContainer'))}> @@ -159,7 +157,7 @@ function renderComponentRoutes() { import('../components/extensions/ProjectPageExtension'))} + component={lazyLoadComponent(() => import('../components/extensions/ProjectPageExtension'))} /> - import('../components/ProjectAdminContainer'))}> + import('../components/ProjectAdminContainer'))}> import('../components/extensions/ProjectAdminPageExtension'))} + component={lazyLoadComponent(() => + import('../components/extensions/ProjectAdminPageExtension') + )} /> @@ -205,13 +205,16 @@ function renderComponentRoutes() { import('../../apps/projectDeletion/App'))} + component={lazyLoadComponent(() => import('../../apps/projectDeletion/App'))} /> import('../../apps/projectLinks/App'))} + component={lazyLoadComponent(() => import('../../apps/projectLinks/App'))} + /> + import('../../apps/projectKey/Key'))} /> - import('../../apps/projectKey/Key'))} /> ); @@ -219,10 +222,12 @@ function renderComponentRoutes() { function renderAdminRoutes() { return ( - import('../components/AdminContainer'))} path="admin"> + import('../components/AdminContainer'))} path="admin"> import('../components/extensions/GlobalAdminPageExtension'))} + component={lazyLoadComponent(() => + import('../components/extensions/GlobalAdminPageExtension') + )} /> @@ -259,21 +264,26 @@ export default function startReactApp( import('../components/MarkdownHelp'))} + component={lazyLoadComponent(() => import('../components/MarkdownHelp'))} /> - import('../components/SimpleContainer'))}> + import('../components/SimpleContainer'))}> {maintenanceRoutes} {setupRoutes} - import('../components/SimpleSessionsContainer'))}> + + import('../components/SimpleSessionsContainer') + )}> - import('../components/Landing'))} /> + import('../components/Landing'))} + /> @@ -286,18 +296,20 @@ export default function startReactApp( + component={lazyLoadComponent(() => import('../components/extensions/GlobalPageExtension') )} /> - + import('../components/extensions/PortfoliosPage'))} + component={lazyLoadComponent(() => + import('../components/extensions/PortfoliosPage') + )} /> @@ -308,9 +320,12 @@ export default function startReactApp( import('../components/NotFound'))} + component={lazyLoadComponent(() => import('../components/NotFound'))} + /> + import('../components/NotFound'))} /> - import('../components/NotFound'))} /> diff --git a/server/sonar-web/src/main/js/apps/about/routes.ts b/server/sonar-web/src/main/js/apps/about/routes.ts index 1f191646d3f..597a857f944 100644 --- a/server/sonar-web/src/main/js/apps/about/routes.ts +++ b/server/sonar-web/src/main/js/apps/about/routes.ts @@ -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 { lazyLoad } from 'sonar-ui-common/components/lazyLoad'; +import { lazyLoadComponent } from 'sonar-ui-common/components/lazyLoadComponent'; -const routes = [{ indexRoute: { component: lazyLoad(() => import('./components/AboutApp')) } }]; +const routes = [ + { indexRoute: { component: lazyLoadComponent(() => import('./components/AboutApp')) } } +]; export default routes; diff --git a/server/sonar-web/src/main/js/apps/account/routes.ts b/server/sonar-web/src/main/js/apps/account/routes.ts index 69866937fdf..8fc8ed5cefd 100644 --- a/server/sonar-web/src/main/js/apps/account/routes.ts +++ b/server/sonar-web/src/main/js/apps/account/routes.ts @@ -17,30 +17,30 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -import { lazyLoad } from 'sonar-ui-common/components/lazyLoad'; +import { lazyLoadComponent } from 'sonar-ui-common/components/lazyLoadComponent'; const routes = [ { - component: lazyLoad(() => import('./components/Account')), + component: lazyLoadComponent(() => import('./components/Account')), childRoutes: [ { - indexRoute: { component: lazyLoad(() => import('./profile/Profile')) } + indexRoute: { component: lazyLoadComponent(() => import('./profile/Profile')) } }, { path: 'security', - component: lazyLoad(() => import('./components/Security')) + component: lazyLoadComponent(() => import('./components/Security')) }, { path: 'projects', - component: lazyLoad(() => import('./projects/ProjectsContainer')) + component: lazyLoadComponent(() => import('./projects/ProjectsContainer')) }, { path: 'notifications', - component: lazyLoad(() => import('./notifications/Notifications')) + component: lazyLoadComponent(() => import('./notifications/Notifications')) }, { path: 'organizations', - component: lazyLoad(() => import('./organizations/UserOrganizations')) + component: lazyLoadComponent(() => import('./organizations/UserOrganizations')) } ] } diff --git a/server/sonar-web/src/main/js/apps/background-tasks/components/TaskActions.tsx b/server/sonar-web/src/main/js/apps/background-tasks/components/TaskActions.tsx index 99e159dc4cb..f9352185a85 100644 --- a/server/sonar-web/src/main/js/apps/background-tasks/components/TaskActions.tsx +++ b/server/sonar-web/src/main/js/apps/background-tasks/components/TaskActions.tsx @@ -22,13 +22,13 @@ import ActionsDropdown, { ActionsDropdownItem } from 'sonar-ui-common/components/controls/ActionsDropdown'; import ConfirmModal from 'sonar-ui-common/components/controls/ConfirmModal'; -import { lazyLoad } from 'sonar-ui-common/components/lazyLoad'; +import { lazyLoadComponent } from 'sonar-ui-common/components/lazyLoadComponent'; import { translate, translateWithParameters } from 'sonar-ui-common/helpers/l10n'; import { STATUSES } from '../constants'; import ScannerContext from './ScannerContext'; import Stacktrace from './Stacktrace'; -const AnalysisWarningsModal = lazyLoad( +const AnalysisWarningsModal = lazyLoadComponent( () => import('../../../components/common/AnalysisWarningsModal'), 'AnalysisWarningsModal' ); diff --git a/server/sonar-web/src/main/js/apps/background-tasks/routes.ts b/server/sonar-web/src/main/js/apps/background-tasks/routes.ts index 32ba890ac8f..7f600552b51 100644 --- a/server/sonar-web/src/main/js/apps/background-tasks/routes.ts +++ b/server/sonar-web/src/main/js/apps/background-tasks/routes.ts @@ -17,11 +17,11 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -import { lazyLoad } from 'sonar-ui-common/components/lazyLoad'; +import { lazyLoadComponent } from 'sonar-ui-common/components/lazyLoadComponent'; const routes = [ { - indexRoute: { component: lazyLoad(() => import('./components/BackgroundTasksApp')) } + indexRoute: { component: lazyLoadComponent(() => import('./components/BackgroundTasksApp')) } } ]; diff --git a/server/sonar-web/src/main/js/apps/code/routes.ts b/server/sonar-web/src/main/js/apps/code/routes.ts index 168c5c58de6..92b03bc5607 100644 --- a/server/sonar-web/src/main/js/apps/code/routes.ts +++ b/server/sonar-web/src/main/js/apps/code/routes.ts @@ -17,11 +17,11 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -import { lazyLoad } from 'sonar-ui-common/components/lazyLoad'; +import { lazyLoadComponent } from 'sonar-ui-common/components/lazyLoadComponent'; const routes = [ { - indexRoute: { component: lazyLoad(() => import('./components/App')) } + indexRoute: { component: lazyLoadComponent(() => import('./components/App')) } } ]; diff --git a/server/sonar-web/src/main/js/apps/coding-rules/routes.ts b/server/sonar-web/src/main/js/apps/coding-rules/routes.ts index c52c905b0f3..c40a5571355 100644 --- a/server/sonar-web/src/main/js/apps/coding-rules/routes.ts +++ b/server/sonar-web/src/main/js/apps/coding-rules/routes.ts @@ -18,7 +18,7 @@ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ import { RedirectFunction, RouterState } from 'react-router'; -import { lazyLoad } from 'sonar-ui-common/components/lazyLoad'; +import { lazyLoadComponent } from 'sonar-ui-common/components/lazyLoadComponent'; import { parseQuery, serializeQuery } from './query'; function parseHash(hash: string): T.RawQuery { @@ -47,7 +47,7 @@ const routes = [ replace({ pathname: nextState.location.pathname, query: normalizedQuery }); } }, - component: lazyLoad(() => import('./components/App')) + component: lazyLoadComponent(() => import('./components/App')) } } ]; diff --git a/server/sonar-web/src/main/js/apps/component-measures/routes.ts b/server/sonar-web/src/main/js/apps/component-measures/routes.ts index 2499b15eb9b..07d80dda92c 100644 --- a/server/sonar-web/src/main/js/apps/component-measures/routes.ts +++ b/server/sonar-web/src/main/js/apps/component-measures/routes.ts @@ -18,11 +18,11 @@ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ import { RedirectFunction, RouterState } from 'react-router'; -import { lazyLoad } from 'sonar-ui-common/components/lazyLoad'; +import { lazyLoadComponent } from 'sonar-ui-common/components/lazyLoadComponent'; const routes = [ { - indexRoute: { component: lazyLoad(() => import('./components/App')) } + indexRoute: { component: lazyLoadComponent(() => import('./components/App')) } }, { path: 'domain/:domainName', diff --git a/server/sonar-web/src/main/js/apps/custom-measures/routes.ts b/server/sonar-web/src/main/js/apps/custom-measures/routes.ts index 168c5c58de6..92b03bc5607 100644 --- a/server/sonar-web/src/main/js/apps/custom-measures/routes.ts +++ b/server/sonar-web/src/main/js/apps/custom-measures/routes.ts @@ -17,11 +17,11 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -import { lazyLoad } from 'sonar-ui-common/components/lazyLoad'; +import { lazyLoadComponent } from 'sonar-ui-common/components/lazyLoadComponent'; const routes = [ { - indexRoute: { component: lazyLoad(() => import('./components/App')) } + indexRoute: { component: lazyLoadComponent(() => import('./components/App')) } } ]; diff --git a/server/sonar-web/src/main/js/apps/custom-metrics/routes.ts b/server/sonar-web/src/main/js/apps/custom-metrics/routes.ts index 168c5c58de6..92b03bc5607 100644 --- a/server/sonar-web/src/main/js/apps/custom-metrics/routes.ts +++ b/server/sonar-web/src/main/js/apps/custom-metrics/routes.ts @@ -17,11 +17,11 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -import { lazyLoad } from 'sonar-ui-common/components/lazyLoad'; +import { lazyLoadComponent } from 'sonar-ui-common/components/lazyLoadComponent'; const routes = [ { - indexRoute: { component: lazyLoad(() => import('./components/App')) } + indexRoute: { component: lazyLoadComponent(() => import('./components/App')) } } ]; diff --git a/server/sonar-web/src/main/js/apps/documentation/routes.ts b/server/sonar-web/src/main/js/apps/documentation/routes.ts index 1e488c6b290..061f011e981 100644 --- a/server/sonar-web/src/main/js/apps/documentation/routes.ts +++ b/server/sonar-web/src/main/js/apps/documentation/routes.ts @@ -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 { lazyLoad } from 'sonar-ui-common/components/lazyLoad'; +import { lazyLoadComponent } from 'sonar-ui-common/components/lazyLoadComponent'; -const App = lazyLoad(() => import(/* webpackChunkName: "docs" */ './components/App')); +const App = lazyLoadComponent(() => import(/* webpackChunkName: "docs" */ './components/App')); const routes = [{ indexRoute: { component: App } }, { path: '**', indexRoute: { component: App } }]; diff --git a/server/sonar-web/src/main/js/apps/groups/routes.ts b/server/sonar-web/src/main/js/apps/groups/routes.ts index 168c5c58de6..92b03bc5607 100644 --- a/server/sonar-web/src/main/js/apps/groups/routes.ts +++ b/server/sonar-web/src/main/js/apps/groups/routes.ts @@ -17,11 +17,11 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -import { lazyLoad } from 'sonar-ui-common/components/lazyLoad'; +import { lazyLoadComponent } from 'sonar-ui-common/components/lazyLoadComponent'; const routes = [ { - indexRoute: { component: lazyLoad(() => import('./components/App')) } + indexRoute: { component: lazyLoadComponent(() => import('./components/App')) } } ]; diff --git a/server/sonar-web/src/main/js/apps/issues/IssuesPageSelector.tsx b/server/sonar-web/src/main/js/apps/issues/IssuesPageSelector.tsx deleted file mode 100644 index 286f065e4fc..00000000000 --- a/server/sonar-web/src/main/js/apps/issues/IssuesPageSelector.tsx +++ /dev/null @@ -1,37 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2020 SonarSource SA - * mailto:info AT sonarsource DOT com - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -import * as React from 'react'; -import { withCurrentUser } from '../../components/hoc/withCurrentUser'; -import { Location } from '../../components/hoc/withRouter'; -import { isSonarCloud } from '../../helpers/system'; -import { isLoggedIn } from '../../helpers/users'; -import AppContainer from './components/AppContainer'; - -export interface Props { - currentUser: T.CurrentUser; - location: Location; -} - -export function IssuesPage({ currentUser, location }: Props) { - const myIssues = (isLoggedIn(currentUser) && isSonarCloud()) || undefined; - return ; -} - -export default withCurrentUser(IssuesPage); diff --git a/server/sonar-web/src/main/js/apps/issues/__tests__/IssuesPageSelector-test.tsx b/server/sonar-web/src/main/js/apps/issues/__tests__/IssuesPageSelector-test.tsx deleted file mode 100644 index e8bcac889f0..00000000000 --- a/server/sonar-web/src/main/js/apps/issues/__tests__/IssuesPageSelector-test.tsx +++ /dev/null @@ -1,56 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2020 SonarSource SA - * mailto:info AT sonarsource DOT com - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -import { shallow } from 'enzyme'; -import * as React from 'react'; -import { isSonarCloud } from '../../../helpers/system'; -import { mockCurrentUser, mockLocation, mockLoggedInUser } from '../../../helpers/testMocks'; -import { IssuesPage, Props } from '../IssuesPageSelector'; - -jest.mock('../../../helpers/system', () => ({ isSonarCloud: jest.fn().mockReturnValue(false) })); - -it('should render normal issues page', () => { - expect(shallowRender()).toMatchSnapshot(); - expect( - shallowRender({ currentUser: mockLoggedInUser() }) - .find('Connect(IssuesAppContainer)') - .prop('myIssues') - ).toBeFalsy(); - (isSonarCloud as jest.Mock).mockReturnValueOnce(true); - expect( - shallowRender() - .find('Connect(IssuesAppContainer)') - .prop('myIssues') - ).toBeFalsy(); -}); - -it('should render my issues page', () => { - (isSonarCloud as jest.Mock).mockReturnValueOnce(true); - expect( - shallowRender({ currentUser: mockLoggedInUser() }) - .find('Connect(IssuesAppContainer)') - .prop('myIssues') - ).toBeTruthy(); -}); - -function shallowRender(props: Partial = {}) { - return shallow( - - ); -} diff --git a/server/sonar-web/src/main/js/apps/issues/__tests__/__snapshots__/IssuesPageSelector-test.tsx.snap b/server/sonar-web/src/main/js/apps/issues/__tests__/__snapshots__/IssuesPageSelector-test.tsx.snap deleted file mode 100644 index cc2de94d3fb..00000000000 --- a/server/sonar-web/src/main/js/apps/issues/__tests__/__snapshots__/IssuesPageSelector-test.tsx.snap +++ /dev/null @@ -1,17 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`should render normal issues page 1`] = ` - -`; diff --git a/server/sonar-web/src/main/js/apps/issues/components/App.tsx b/server/sonar-web/src/main/js/apps/issues/components/App.tsx index cb4c4eac287..cf838a1407a 100644 --- a/server/sonar-web/src/main/js/apps/issues/components/App.tsx +++ b/server/sonar-web/src/main/js/apps/issues/components/App.tsx @@ -22,7 +22,6 @@ import { debounce, keyBy, omit, without } from 'lodash'; import * as React from 'react'; import { Helmet } from 'react-helmet-async'; import { FormattedMessage } from 'react-intl'; -import { connect } from 'react-redux'; import { Button } from 'sonar-ui-common/components/controls/buttons'; import Checkbox from 'sonar-ui-common/components/controls/Checkbox'; import ListFooter from 'sonar-ui-common/components/controls/ListFooter'; @@ -41,7 +40,7 @@ import Suggestions from '../../../app/components/embed-docs-modal/Suggestions'; import EmptySearch from '../../../components/common/EmptySearch'; import FiltersHeader from '../../../components/common/FiltersHeader'; import ScreenPositionHelper from '../../../components/common/ScreenPositionHelper'; -import { Location, Router, withRouter } from '../../../components/hoc/withRouter'; +import { Location, Router } from '../../../components/hoc/withRouter'; import '../../../components/search-navigator.css'; import { fillBranchLike, @@ -50,7 +49,6 @@ import { isSameBranchLike } from '../../../helpers/branch-like'; import { isSonarCloud } from '../../../helpers/system'; -import { fetchBranchStatus } from '../../../store/rootActions'; import { BranchLike } from '../../../types/branch-like'; import * as actions from '../actions'; import ConciseIssuesList from '../conciseIssuesList/ConciseIssuesList'; @@ -104,10 +102,10 @@ interface Props { fetchBranchStatus: (branchLike: BranchLike, projectKey: string) => Promise; fetchIssues: (query: T.RawQuery, requestOrganizations?: boolean) => Promise; hideAuthorFacet?: boolean; - location: Pick; + location: Location; multiOrganizations?: boolean; myIssues?: boolean; - onBranchesChange: () => void; + onBranchesChange?: () => void; organization?: { key: string }; router: Pick; userOrganizations: T.Organization[]; @@ -144,7 +142,7 @@ export interface State { const DEFAULT_QUERY = { resolved: 'false' }; const MAX_INITAL_FETCH = 1000; -export class App extends React.PureComponent { +export default class App extends React.PureComponent { mounted = false; constructor(props: Props) { @@ -539,13 +537,13 @@ export class App extends React.PureComponent { const { paging } = this.state; if (!paging) { - return; + return Promise.reject(); } const p = paging.pageIndex + 1; this.setState({ checkAll: false, loadingMore: true }); - this.fetchIssuesPage(p).then( + return this.fetchIssuesPage(p).then( response => { if (this.mounted) { this.setState(state => ({ @@ -825,8 +823,9 @@ export class App extends React.PureComponent { handleReload = () => { this.fetchFirstIssues(); this.refreshBranchStatus(); - if (isPullRequest(this.props.branchLike)) { - this.props.onBranchesChange(); + const { branchLike, onBranchesChange } = this.props; + if (onBranchesChange && isPullRequest(branchLike)) { + onBranchesChange(); } }; @@ -1180,7 +1179,3 @@ export class App extends React.PureComponent { ); } } - -const mapDispatchToProps = { fetchBranchStatus: fetchBranchStatus as any }; - -export default withRouter(connect(null, mapDispatchToProps)(App)); diff --git a/server/sonar-web/src/main/js/apps/issues/components/AppContainer.tsx b/server/sonar-web/src/main/js/apps/issues/components/AppContainer.tsx index a896d854d77..c964c626911 100644 --- a/server/sonar-web/src/main/js/apps/issues/components/AppContainer.tsx +++ b/server/sonar-web/src/main/js/apps/issues/components/AppContainer.tsx @@ -20,12 +20,14 @@ import { uniq } from 'lodash'; import { connect } from 'react-redux'; import { Dispatch } from 'redux'; -import { lazyLoad } from 'sonar-ui-common/components/lazyLoad'; +import { lazyLoadComponent } from 'sonar-ui-common/components/lazyLoadComponent'; import { searchIssues } from '../../../api/issues'; import { getOrganizations } from '../../../api/organizations'; import throwGlobalError from '../../../app/utils/throwGlobalError'; +import { withRouter } from '../../../components/hoc/withRouter'; import { parseIssueFromResponse } from '../../../helpers/issues'; import { receiveOrganizations } from '../../../store/organizations'; +import { fetchBranchStatus } from '../../../store/rootActions'; import { areThereCustomOrganizations, getCurrentUser, @@ -33,6 +35,8 @@ import { Store } from '../../../store/rootReducer'; +const IssuesAppContainer = lazyLoadComponent(() => import('./App'), 'IssuesAppContainer'); + interface StateProps { currentUser: T.CurrentUser; userOrganizations: T.Organization[]; @@ -79,14 +83,10 @@ const fetchIssues = (query: T.RawQuery, requestOrganizations = true) => ( .catch(throwGlobalError); }; -interface DispatchProps { - fetchIssues: (query: T.RawQuery, requestOrganizations?: boolean) => Promise; -} - // have to type cast this, because of async action -const mapDispatchToProps = { fetchIssues: fetchIssues as any } as DispatchProps; +const mapDispatchToProps = { + fetchBranchStatus: fetchBranchStatus as any, + fetchIssues: fetchIssues as any +}; -export default connect( - mapStateToProps, - mapDispatchToProps -)(lazyLoad(() => import('./App'), 'IssuesAppContainer')); +export default withRouter(connect(mapStateToProps, mapDispatchToProps)(IssuesAppContainer)); diff --git a/server/sonar-web/src/main/js/apps/issues/components/IssuesSourceViewer.tsx b/server/sonar-web/src/main/js/apps/issues/components/IssuesSourceViewer.tsx index 1036a7d0f08..3edd0115439 100644 --- a/server/sonar-web/src/main/js/apps/issues/components/IssuesSourceViewer.tsx +++ b/server/sonar-web/src/main/js/apps/issues/components/IssuesSourceViewer.tsx @@ -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 { uniq } from 'lodash'; import * as React from 'react'; import { scrollToElement } from 'sonar-ui-common/helpers/scrolling'; import SourceViewer from '../../../components/SourceViewer/SourceViewer'; @@ -91,12 +90,10 @@ export default class IssuesSourceViewer extends React.PureComponent { : undefined; if (locations.length > 0) { - const components = uniq(locations.map(l => l.component)); return (
(this.node = node)}> ({ default: jest.fn() @@ -90,7 +90,7 @@ it('should not render for anonymous user', () => { it('should open standard facets for vulnerabilities and hotspots', () => { const wrapper = shallowRender({ - location: { pathname: '/issues', query: { types: 'VULNERABILITY' } } + location: mockLocation({ pathname: '/issues', query: { types: 'VULNERABILITY' } }) }); const instance = wrapper.instance(); const fetchFacet = jest.spyOn(instance, 'fetchFacet'); @@ -420,7 +420,7 @@ function shallowRender(props: Partial = {}) { rules: [], users: [] })} - location={{ pathname: '/issues', query: {} }} + location={mockLocation({ pathname: '/issues', query: {} })} onBranchesChange={() => {}} organization={{ key: 'foo' }} router={mockRouter()} diff --git a/server/sonar-web/src/main/js/apps/issues/components/__tests__/__snapshots__/IssuesSourceViewer-test.tsx.snap b/server/sonar-web/src/main/js/apps/issues/components/__tests__/__snapshots__/IssuesSourceViewer-test.tsx.snap index 090eac8205a..a0bd5ab199c 100644 --- a/server/sonar-web/src/main/js/apps/issues/components/__tests__/__snapshots__/IssuesSourceViewer-test.tsx.snap +++ b/server/sonar-web/src/main/js/apps/issues/components/__tests__/__snapshots__/IssuesSourceViewer-test.tsx.snap @@ -11,11 +11,6 @@ exports[`should render CrossComponentSourceViewer correctly 1`] = ` "name": "master", } } - components={ - Array [ - "main.js", - ] - } issue={ Object { "actions": Array [], diff --git a/server/sonar-web/src/main/js/apps/issues/crossComponentSourceViewer/CrossComponentSourceViewer.tsx b/server/sonar-web/src/main/js/apps/issues/crossComponentSourceViewer/CrossComponentSourceViewer.tsx index 420d0cf659c..84a4e68c4d6 100644 --- a/server/sonar-web/src/main/js/apps/issues/crossComponentSourceViewer/CrossComponentSourceViewer.tsx +++ b/server/sonar-web/src/main/js/apps/issues/crossComponentSourceViewer/CrossComponentSourceViewer.tsx @@ -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 { lazyLoad } from 'sonar-ui-common/components/lazyLoad'; +import { lazyLoadComponent } from 'sonar-ui-common/components/lazyLoadComponent'; -const CrossComponentSourceViewer = lazyLoad( +const CrossComponentSourceViewer = lazyLoadComponent( () => import(/* webpackPrefetch: true */ './CrossComponentSourceViewerWrapper'), 'CrossComponentSourceViewer' ); diff --git a/server/sonar-web/src/main/js/apps/maintenance/routes.tsx b/server/sonar-web/src/main/js/apps/maintenance/routes.tsx index 06690209734..705dfafcd47 100644 --- a/server/sonar-web/src/main/js/apps/maintenance/routes.tsx +++ b/server/sonar-web/src/main/js/apps/maintenance/routes.tsx @@ -19,12 +19,12 @@ */ import * as React from 'react'; import { IndexRoute } from 'react-router'; -import { lazyLoad } from 'sonar-ui-common/components/lazyLoad'; +import { lazyLoadComponent } from 'sonar-ui-common/components/lazyLoadComponent'; export const maintenanceRoutes = ( - import('./components/MaintenanceAppContainer'))} /> + import('./components/MaintenanceAppContainer'))} /> ); export const setupRoutes = ( - import('./components/SetupAppContainer'))} /> + import('./components/SetupAppContainer'))} /> ); diff --git a/server/sonar-web/src/main/js/apps/marketplace/components/EditionBox.tsx b/server/sonar-web/src/main/js/apps/marketplace/components/EditionBox.tsx index 1ee19543cd6..dc80a1870f4 100644 --- a/server/sonar-web/src/main/js/apps/marketplace/components/EditionBox.tsx +++ b/server/sonar-web/src/main/js/apps/marketplace/components/EditionBox.tsx @@ -21,12 +21,15 @@ import tooltipDCE from 'Docs/tooltips/editions/datacenter.md'; import tooltipDE from 'Docs/tooltips/editions/developer.md'; import tooltipEE from 'Docs/tooltips/editions/enterprise.md'; import * as React from 'react'; -import { lazyLoad } from 'sonar-ui-common/components/lazyLoad'; +import { lazyLoadComponent } from 'sonar-ui-common/components/lazyLoadComponent'; import { translate } from 'sonar-ui-common/helpers/l10n'; import { getEditionUrl } from '../../../helpers/editions'; import { Edition, EditionKey } from '../../../types/editions'; -const DocMarkdownBlock = lazyLoad(() => import('../../../components/docs/DocMarkdownBlock')); +const DocMarkdownBlock = lazyLoadComponent( + () => import('../../../components/docs/DocMarkdownBlock'), + 'DocMarkdownBlock' +); interface Props { currentEdition?: EditionKey; diff --git a/server/sonar-web/src/main/js/apps/marketplace/components/__tests__/__snapshots__/EditionBox-test.tsx.snap b/server/sonar-web/src/main/js/apps/marketplace/components/__tests__/__snapshots__/EditionBox-test.tsx.snap index cfd28f4bc35..538a9f2b9ef 100644 --- a/server/sonar-web/src/main/js/apps/marketplace/components/__tests__/__snapshots__/EditionBox-test.tsx.snap +++ b/server/sonar-web/src/main/js/apps/marketplace/components/__tests__/__snapshots__/EditionBox-test.tsx.snap @@ -4,7 +4,7 @@ exports[`should display the edition 1`] = `
- +
diff --git a/server/sonar-web/src/main/js/apps/marketplace/routes.ts b/server/sonar-web/src/main/js/apps/marketplace/routes.ts index 68418a8f274..729a854fd60 100644 --- a/server/sonar-web/src/main/js/apps/marketplace/routes.ts +++ b/server/sonar-web/src/main/js/apps/marketplace/routes.ts @@ -17,11 +17,11 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -import { lazyLoad } from 'sonar-ui-common/components/lazyLoad'; +import { lazyLoadComponent } from 'sonar-ui-common/components/lazyLoadComponent'; const routes = [ { - indexRoute: { component: lazyLoad(() => import('./AppContainer')) } + indexRoute: { component: lazyLoadComponent(() => import('./AppContainer')) } } ]; diff --git a/server/sonar-web/src/main/js/apps/organizations/components/OrganizationProjects.tsx b/server/sonar-web/src/main/js/apps/organizations/components/OrganizationProjects.tsx index 83ba57896b9..c53f19f768d 100644 --- a/server/sonar-web/src/main/js/apps/organizations/components/OrganizationProjects.tsx +++ b/server/sonar-web/src/main/js/apps/organizations/components/OrganizationProjects.tsx @@ -29,11 +29,7 @@ interface Props { export default function OrganizationProjects(props: Props) { return ( <> - + ); diff --git a/server/sonar-web/src/main/js/apps/organizations/routes.ts b/server/sonar-web/src/main/js/apps/organizations/routes.ts index 975ddd60eee..1efff137c9f 100644 --- a/server/sonar-web/src/main/js/apps/organizations/routes.ts +++ b/server/sonar-web/src/main/js/apps/organizations/routes.ts @@ -18,18 +18,18 @@ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ import { RedirectFunction, RouterState } from 'react-router'; -import { lazyLoad } from 'sonar-ui-common/components/lazyLoad'; +import { lazyLoadComponent } from 'sonar-ui-common/components/lazyLoadComponent'; import codingRulesRoutes from '../coding-rules/routes'; import qualityGatesRoutes from '../quality-gates/routes'; import qualityProfilesRoutes from '../quality-profiles/routes'; import webhooksRoutes from '../webhooks/routes'; -const OrganizationContainer = lazyLoad(() => import('./components/OrganizationContainer')); +const OrganizationContainer = lazyLoadComponent(() => import('./components/OrganizationContainer')); const routes = [ { path: ':organizationKey', - component: lazyLoad(() => import('./components/OrganizationPage')), + component: lazyLoadComponent(() => import('./components/OrganizationPage')), childRoutes: [ { indexRoute: { @@ -43,14 +43,22 @@ const routes = [ path: 'projects', component: OrganizationContainer, childRoutes: [ - { indexRoute: { component: lazyLoad(() => import('./components/OrganizationProjects')) } } + { + indexRoute: { + component: lazyLoadComponent(() => import('./components/OrganizationProjects')) + } + } ] }, { path: 'issues', component: OrganizationContainer, childRoutes: [ - { indexRoute: { component: lazyLoad(() => import('../issues/components/AppContainer')) } } + { + indexRoute: { + component: lazyLoadComponent(() => import('../issues/components/AppContainer')) + } + } ] }, { @@ -60,7 +68,9 @@ const routes = [ }, { path: 'members', - component: lazyLoad(() => import('../organizationMembers/OrganizationMembersContainer')) + component: lazyLoadComponent(() => + import('../organizationMembers/OrganizationMembersContainer') + ) }, { path: 'quality_profiles', @@ -72,26 +82,32 @@ const routes = [ childRoutes: qualityGatesRoutes }, { - component: lazyLoad(() => import('./components/OrganizationAccessContainer')), + component: lazyLoadComponent(() => import('./components/OrganizationAccessContainer')), childRoutes: [ - { path: 'edit', component: lazyLoad(() => import('./components/OrganizationEdit')) }, - { path: 'groups', component: lazyLoad(() => import('../groups/components/App')) }, + { + path: 'edit', + component: lazyLoadComponent(() => import('./components/OrganizationEdit')) + }, + { + path: 'groups', + component: lazyLoadComponent(() => import('../groups/components/App')) + }, { path: 'permissions', - component: lazyLoad(() => import('../permissions/global/components/App')) + component: lazyLoadComponent(() => import('../permissions/global/components/App')) }, { path: 'permission_templates', - component: lazyLoad(() => import('../permission-templates/components/App')) + component: lazyLoadComponent(() => import('../permission-templates/components/App')) }, { path: 'projects_management', - component: lazyLoad(() => import('../projectsManagement/AppContainer')) + component: lazyLoadComponent(() => import('../projectsManagement/AppContainer')) }, { path: 'webhooks', childRoutes: webhooksRoutes }, { path: 'extension/:pluginKey/:extensionKey', - component: lazyLoad(() => + component: lazyLoadComponent(() => import('../../app/components/extensions/OrganizationPageExtension') ) } diff --git a/server/sonar-web/src/main/js/apps/overview/components/App.tsx b/server/sonar-web/src/main/js/apps/overview/components/App.tsx index e10115c9780..fbd6ea0c950 100644 --- a/server/sonar-web/src/main/js/apps/overview/components/App.tsx +++ b/server/sonar-web/src/main/js/apps/overview/components/App.tsx @@ -18,7 +18,7 @@ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ import * as React from 'react'; -import { lazyLoad } from 'sonar-ui-common/components/lazyLoad'; +import { lazyLoadComponent } from 'sonar-ui-common/components/lazyLoadComponent'; import Suggestions from '../../../app/components/embed-docs-modal/Suggestions'; import { Router, withRouter } from '../../../components/hoc/withRouter'; import { isPullRequest } from '../../../helpers/branch-like'; @@ -26,8 +26,8 @@ import { BranchLike } from '../../../types/branch-like'; import { ComponentQualifier } from '../../../types/component'; import BranchOverview from '../branches/BranchOverview'; -const EmptyOverview = lazyLoad(() => import('./EmptyOverview')); -const PullRequestOverview = lazyLoad(() => import('../pullRequests/PullRequestOverview')); +const EmptyOverview = lazyLoadComponent(() => import('./EmptyOverview')); +const PullRequestOverview = lazyLoadComponent(() => import('../pullRequests/PullRequestOverview')); interface Props { branchLike?: BranchLike; diff --git a/server/sonar-web/src/main/js/apps/overview/pullRequests/PullRequestOverview.tsx b/server/sonar-web/src/main/js/apps/overview/pullRequests/PullRequestOverview.tsx index eeec9f5ea7d..18862261bce 100644 --- a/server/sonar-web/src/main/js/apps/overview/pullRequests/PullRequestOverview.tsx +++ b/server/sonar-web/src/main/js/apps/overview/pullRequests/PullRequestOverview.tsx @@ -41,15 +41,23 @@ import { IssueType, MeasurementType, PR_METRICS } from '../utils'; import AfterMergeEstimate from './AfterMergeEstimate'; import LargeQualityGateBadge from './LargeQualityGateBadge'; -interface Props { - branchLike: PullRequest; - component: T.Component; +interface StateProps { conditions?: QualityGateStatusCondition[]; - fetchBranchStatus: (branchLike: BranchLike, projectKey: string) => Promise; ignoredConditions?: boolean; status?: T.Status; } +interface DispatchProps { + fetchBranchStatus: (branchLike: BranchLike, projectKey: string) => Promise; +} + +interface OwnProps { + branchLike: PullRequest; + component: T.Component; +} + +type Props = StateProps & DispatchProps & OwnProps; + interface State { loading: boolean; measures: T.MeasureEnhanced[]; @@ -244,4 +252,7 @@ const mapStateToProps = (state: Store, { branchLike, component }: Props) => { const mapDispatchToProps = { fetchBranchStatus: fetchBranchStatus as any }; -export default connect(mapStateToProps, mapDispatchToProps)(PullRequestOverview); +export default connect( + mapStateToProps, + mapDispatchToProps +)(PullRequestOverview); diff --git a/server/sonar-web/src/main/js/apps/overview/routes.ts b/server/sonar-web/src/main/js/apps/overview/routes.ts index 168c5c58de6..92b03bc5607 100644 --- a/server/sonar-web/src/main/js/apps/overview/routes.ts +++ b/server/sonar-web/src/main/js/apps/overview/routes.ts @@ -17,11 +17,11 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -import { lazyLoad } from 'sonar-ui-common/components/lazyLoad'; +import { lazyLoadComponent } from 'sonar-ui-common/components/lazyLoadComponent'; const routes = [ { - indexRoute: { component: lazyLoad(() => import('./components/App')) } + indexRoute: { component: lazyLoadComponent(() => import('./components/App')) } } ]; diff --git a/server/sonar-web/src/main/js/apps/permission-templates/routes.ts b/server/sonar-web/src/main/js/apps/permission-templates/routes.ts index 168c5c58de6..92b03bc5607 100644 --- a/server/sonar-web/src/main/js/apps/permission-templates/routes.ts +++ b/server/sonar-web/src/main/js/apps/permission-templates/routes.ts @@ -17,11 +17,11 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -import { lazyLoad } from 'sonar-ui-common/components/lazyLoad'; +import { lazyLoadComponent } from 'sonar-ui-common/components/lazyLoadComponent'; const routes = [ { - indexRoute: { component: lazyLoad(() => import('./components/App')) } + indexRoute: { component: lazyLoadComponent(() => import('./components/App')) } } ]; diff --git a/server/sonar-web/src/main/js/apps/permissions/routes.ts b/server/sonar-web/src/main/js/apps/permissions/routes.ts index cf478a468be..da2a3b06f11 100644 --- a/server/sonar-web/src/main/js/apps/permissions/routes.ts +++ b/server/sonar-web/src/main/js/apps/permissions/routes.ts @@ -17,16 +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 { lazyLoad } from 'sonar-ui-common/components/lazyLoad'; +import { lazyLoadComponent } from 'sonar-ui-common/components/lazyLoadComponent'; export const globalPermissionsRoutes = [ { - indexRoute: { component: lazyLoad(() => import('./global/components/App')) } + indexRoute: { component: lazyLoadComponent(() => import('./global/components/App')) } } ]; export const projectPermissionsRoutes = [ { - indexRoute: { component: lazyLoad(() => import('./project/components/AppContainer')) } + indexRoute: { component: lazyLoadComponent(() => import('./project/components/AppContainer')) } } ]; diff --git a/server/sonar-web/src/main/js/apps/portfolio/routes.ts b/server/sonar-web/src/main/js/apps/portfolio/routes.ts index 168c5c58de6..92b03bc5607 100644 --- a/server/sonar-web/src/main/js/apps/portfolio/routes.ts +++ b/server/sonar-web/src/main/js/apps/portfolio/routes.ts @@ -17,11 +17,11 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -import { lazyLoad } from 'sonar-ui-common/components/lazyLoad'; +import { lazyLoadComponent } from 'sonar-ui-common/components/lazyLoadComponent'; const routes = [ { - indexRoute: { component: lazyLoad(() => import('./components/App')) } + indexRoute: { component: lazyLoadComponent(() => import('./components/App')) } } ]; diff --git a/server/sonar-web/src/main/js/apps/projectActivity/routes.ts b/server/sonar-web/src/main/js/apps/projectActivity/routes.ts index 575ab1d0e7b..96df47d62da 100644 --- a/server/sonar-web/src/main/js/apps/projectActivity/routes.ts +++ b/server/sonar-web/src/main/js/apps/projectActivity/routes.ts @@ -17,12 +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 { lazyLoad } from 'sonar-ui-common/components/lazyLoad'; +import { lazyLoadComponent } from 'sonar-ui-common/components/lazyLoadComponent'; const routes = [ { indexRoute: { - component: lazyLoad(() => import('./components/ProjectActivityAppContainer')) + component: lazyLoadComponent(() => import('./components/ProjectActivityAppContainer')) } } ]; diff --git a/server/sonar-web/src/main/js/apps/projectBaseline/routes.ts b/server/sonar-web/src/main/js/apps/projectBaseline/routes.ts index 2b83ad2df23..2b08f969444 100644 --- a/server/sonar-web/src/main/js/apps/projectBaseline/routes.ts +++ b/server/sonar-web/src/main/js/apps/projectBaseline/routes.ts @@ -17,11 +17,11 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -import { lazyLoad } from 'sonar-ui-common/components/lazyLoad'; +import { lazyLoadComponent } from 'sonar-ui-common/components/lazyLoadComponent'; const routes = [ { - indexRoute: { component: lazyLoad(() => import('./components/AppContainer')) } + indexRoute: { component: lazyLoadComponent(() => import('./components/AppContainer')) } } ]; diff --git a/server/sonar-web/src/main/js/apps/projectBranches/routes.ts b/server/sonar-web/src/main/js/apps/projectBranches/routes.ts index 168c5c58de6..92b03bc5607 100644 --- a/server/sonar-web/src/main/js/apps/projectBranches/routes.ts +++ b/server/sonar-web/src/main/js/apps/projectBranches/routes.ts @@ -17,11 +17,11 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -import { lazyLoad } from 'sonar-ui-common/components/lazyLoad'; +import { lazyLoadComponent } from 'sonar-ui-common/components/lazyLoadComponent'; const routes = [ { - indexRoute: { component: lazyLoad(() => import('./components/App')) } + indexRoute: { component: lazyLoadComponent(() => import('./components/App')) } } ]; diff --git a/server/sonar-web/src/main/js/apps/projectQualityGate/routes.ts b/server/sonar-web/src/main/js/apps/projectQualityGate/routes.ts index 8f91ec48084..d82abd3b146 100644 --- a/server/sonar-web/src/main/js/apps/projectQualityGate/routes.ts +++ b/server/sonar-web/src/main/js/apps/projectQualityGate/routes.ts @@ -17,11 +17,11 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -import { lazyLoad } from 'sonar-ui-common/components/lazyLoad'; +import { lazyLoadComponent } from 'sonar-ui-common/components/lazyLoadComponent'; const routes = [ { - indexRoute: { component: lazyLoad(() => import('./App')) } + indexRoute: { component: lazyLoadComponent(() => import('./App')) } } ]; diff --git a/server/sonar-web/src/main/js/apps/projectQualityProfiles/routes.ts b/server/sonar-web/src/main/js/apps/projectQualityProfiles/routes.ts index 8f91ec48084..d82abd3b146 100644 --- a/server/sonar-web/src/main/js/apps/projectQualityProfiles/routes.ts +++ b/server/sonar-web/src/main/js/apps/projectQualityProfiles/routes.ts @@ -17,11 +17,11 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -import { lazyLoad } from 'sonar-ui-common/components/lazyLoad'; +import { lazyLoadComponent } from 'sonar-ui-common/components/lazyLoadComponent'; const routes = [ { - indexRoute: { component: lazyLoad(() => import('./App')) } + indexRoute: { component: lazyLoadComponent(() => import('./App')) } } ]; diff --git a/server/sonar-web/src/main/js/apps/projects/components/AllProjectsContainer.tsx b/server/sonar-web/src/main/js/apps/projects/components/AllProjectsContainer.tsx index 7877a05ad3c..09c3f522345 100644 --- a/server/sonar-web/src/main/js/apps/projects/components/AllProjectsContainer.tsx +++ b/server/sonar-web/src/main/js/apps/projects/components/AllProjectsContainer.tsx @@ -18,7 +18,7 @@ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ import { connect } from 'react-redux'; -import { lazyLoad } from 'sonar-ui-common/components/lazyLoad'; +import { lazyLoadComponent } from 'sonar-ui-common/components/lazyLoadComponent'; import { areThereCustomOrganizations, getCurrentUser, Store } from '../../../store/rootReducer'; const stateToProps = (state: Store) => ({ @@ -26,4 +26,4 @@ const stateToProps = (state: Store) => ({ organizationsEnabled: areThereCustomOrganizations(state) }); -export default connect(stateToProps)(lazyLoad(() => import('./AllProjects'))); +export default connect(stateToProps)(lazyLoadComponent(() => import('./AllProjects'))); diff --git a/server/sonar-web/src/main/js/apps/projects/components/DefaultPageSelector.tsx b/server/sonar-web/src/main/js/apps/projects/components/DefaultPageSelector.tsx index 476aa33acda..fc3f6fb794f 100644 --- a/server/sonar-web/src/main/js/apps/projects/components/DefaultPageSelector.tsx +++ b/server/sonar-web/src/main/js/apps/projects/components/DefaultPageSelector.tsx @@ -108,13 +108,7 @@ export class DefaultPageSelector extends React.PureComponent { render() { if (isSonarCloud() && isLoggedIn(this.props.currentUser)) { - return ( - - ); + return ; } const { shouldBeRedirected, shouldForceSorting } = this.state; @@ -124,13 +118,7 @@ export class DefaultPageSelector extends React.PureComponent { shouldBeRedirected !== true && shouldForceSorting === undefined ) { - return ( - - ); + return ; } return null; diff --git a/server/sonar-web/src/main/js/apps/projects/routes.ts b/server/sonar-web/src/main/js/apps/projects/routes.ts index b0920a4b169..7cd069419a1 100644 --- a/server/sonar-web/src/main/js/apps/projects/routes.ts +++ b/server/sonar-web/src/main/js/apps/projects/routes.ts @@ -18,7 +18,7 @@ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ import { RedirectFunction, RouterState } from 'react-router'; -import { lazyLoad } from 'sonar-ui-common/components/lazyLoad'; +import { lazyLoadComponent } from 'sonar-ui-common/components/lazyLoadComponent'; import { save } from 'sonar-ui-common/helpers/storage'; import { isDefined } from 'sonar-ui-common/helpers/types'; import DefaultPageSelectorContainer from './components/DefaultPageSelectorContainer'; @@ -37,7 +37,7 @@ const routes = [ { path: 'favorite', component: FavoriteProjectsContainer }, { path: 'create', - component: lazyLoad(() => import('../create/project/CreateProjectPage')) + component: lazyLoadComponent(() => import('../create/project/CreateProjectPage')) } ].filter(isDefined); diff --git a/server/sonar-web/src/main/js/apps/projectsManagement/routes.ts b/server/sonar-web/src/main/js/apps/projectsManagement/routes.ts index 68418a8f274..729a854fd60 100644 --- a/server/sonar-web/src/main/js/apps/projectsManagement/routes.ts +++ b/server/sonar-web/src/main/js/apps/projectsManagement/routes.ts @@ -17,11 +17,11 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -import { lazyLoad } from 'sonar-ui-common/components/lazyLoad'; +import { lazyLoadComponent } from 'sonar-ui-common/components/lazyLoadComponent'; const routes = [ { - indexRoute: { component: lazyLoad(() => import('./AppContainer')) } + indexRoute: { component: lazyLoadComponent(() => import('./AppContainer')) } } ]; diff --git a/server/sonar-web/src/main/js/apps/quality-gates/routes.ts b/server/sonar-web/src/main/js/apps/quality-gates/routes.ts index f2b31650fbd..0b0da83d63d 100644 --- a/server/sonar-web/src/main/js/apps/quality-gates/routes.ts +++ b/server/sonar-web/src/main/js/apps/quality-gates/routes.ts @@ -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 { lazyLoad } from 'sonar-ui-common/components/lazyLoad'; +import { lazyLoadComponent } from 'sonar-ui-common/components/lazyLoadComponent'; -const App = lazyLoad(() => import('./components/App')); +const App = lazyLoadComponent(() => import('./components/App')); const routes = [{ indexRoute: { component: App } }, { path: 'show/:id', component: App }]; diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/compare/ComparisonResultActivation.tsx b/server/sonar-web/src/main/js/apps/quality-profiles/compare/ComparisonResultActivation.tsx index 471a0a1160a..00eba49aa2c 100644 --- a/server/sonar-web/src/main/js/apps/quality-profiles/compare/ComparisonResultActivation.tsx +++ b/server/sonar-web/src/main/js/apps/quality-profiles/compare/ComparisonResultActivation.tsx @@ -19,13 +19,13 @@ */ import * as React from 'react'; import { Button } from 'sonar-ui-common/components/controls/buttons'; -import { lazyLoad } from 'sonar-ui-common/components/lazyLoad'; +import { lazyLoadComponent } from 'sonar-ui-common/components/lazyLoadComponent'; import DeferredSpinner from 'sonar-ui-common/components/ui/DeferredSpinner'; import { translate } from 'sonar-ui-common/helpers/l10n'; import { Profile } from '../../../api/quality-profiles'; import { getRuleDetails } from '../../../api/rules'; -const ActivationFormModal = lazyLoad( +const ActivationFormModal = lazyLoadComponent( () => import('../../coding-rules/components/ActivationFormModal'), 'ActivationFormModal' ); diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/routes.ts b/server/sonar-web/src/main/js/apps/quality-profiles/routes.ts index 85588a40ce6..7d1b18bb50b 100644 --- a/server/sonar-web/src/main/js/apps/quality-profiles/routes.ts +++ b/server/sonar-web/src/main/js/apps/quality-profiles/routes.ts @@ -17,27 +17,27 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -import { lazyLoad } from 'sonar-ui-common/components/lazyLoad'; +import { lazyLoadComponent } from 'sonar-ui-common/components/lazyLoadComponent'; const routes = [ { - component: lazyLoad(() => import('./components/AppContainer')), - indexRoute: { component: lazyLoad(() => import('./home/HomeContainer')) }, + component: lazyLoadComponent(() => import('./components/AppContainer')), + indexRoute: { component: lazyLoadComponent(() => import('./home/HomeContainer')) }, childRoutes: [ { - component: lazyLoad(() => import('./components/ProfileContainer')), + component: lazyLoadComponent(() => import('./components/ProfileContainer')), childRoutes: [ { path: 'show', - component: lazyLoad(() => import('./details/ProfileDetails')) + component: lazyLoadComponent(() => import('./details/ProfileDetails')) }, { path: 'changelog', - component: lazyLoad(() => import('./changelog/ChangelogContainer')) + component: lazyLoadComponent(() => import('./changelog/ChangelogContainer')) }, { path: 'compare', - component: lazyLoad(() => import('./compare/ComparisonContainer')) + component: lazyLoadComponent(() => import('./compare/ComparisonContainer')) } ] } diff --git a/server/sonar-web/src/main/js/apps/sessions/routes.ts b/server/sonar-web/src/main/js/apps/sessions/routes.ts index c1293bf3ee1..6b7c1d13145 100644 --- a/server/sonar-web/src/main/js/apps/sessions/routes.ts +++ b/server/sonar-web/src/main/js/apps/sessions/routes.ts @@ -17,24 +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 { lazyLoad } from 'sonar-ui-common/components/lazyLoad'; +import { lazyLoadComponent } from 'sonar-ui-common/components/lazyLoadComponent'; const routes = [ { path: 'new', - component: lazyLoad(() => import('./components/LoginContainer')) + component: lazyLoadComponent(() => import('./components/LoginContainer')) }, { path: 'logout', - component: lazyLoad(() => import('./components/Logout')) + component: lazyLoadComponent(() => import('./components/Logout')) }, { path: 'unauthorized', - component: lazyLoad(() => import('./components/Unauthorized')) + component: lazyLoadComponent(() => import('./components/Unauthorized')) }, { path: 'email_already_exists', - component: lazyLoad(() => import('./components/EmailAlreadyExists')) + component: lazyLoadComponent(() => import('./components/EmailAlreadyExists')) } ]; diff --git a/server/sonar-web/src/main/js/apps/settings/routes.ts b/server/sonar-web/src/main/js/apps/settings/routes.ts index d36ab7cc4ad..a7ac736f78f 100644 --- a/server/sonar-web/src/main/js/apps/settings/routes.ts +++ b/server/sonar-web/src/main/js/apps/settings/routes.ts @@ -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 { lazyLoad } from 'sonar-ui-common/components/lazyLoad'; +import { lazyLoadComponent } from 'sonar-ui-common/components/lazyLoadComponent'; const routes = [ { - indexRoute: { component: lazyLoad(() => import('./components/AppContainer')) } + indexRoute: { component: lazyLoadComponent(() => import('./components/AppContainer')) } }, { path: 'encryption', - component: lazyLoad(() => import('./encryption/EncryptionApp')) + component: lazyLoadComponent(() => import('./encryption/EncryptionApp')) } ]; diff --git a/server/sonar-web/src/main/js/apps/system/routes.ts b/server/sonar-web/src/main/js/apps/system/routes.ts index 168c5c58de6..92b03bc5607 100644 --- a/server/sonar-web/src/main/js/apps/system/routes.ts +++ b/server/sonar-web/src/main/js/apps/system/routes.ts @@ -17,11 +17,11 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -import { lazyLoad } from 'sonar-ui-common/components/lazyLoad'; +import { lazyLoadComponent } from 'sonar-ui-common/components/lazyLoadComponent'; const routes = [ { - indexRoute: { component: lazyLoad(() => import('./components/App')) } + indexRoute: { component: lazyLoadComponent(() => import('./components/App')) } } ]; diff --git a/server/sonar-web/src/main/js/apps/tutorials/routes.ts b/server/sonar-web/src/main/js/apps/tutorials/routes.ts index adb92439919..4436986b49d 100644 --- a/server/sonar-web/src/main/js/apps/tutorials/routes.ts +++ b/server/sonar-web/src/main/js/apps/tutorials/routes.ts @@ -17,15 +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 { lazyLoad } from 'sonar-ui-common/components/lazyLoad'; -import { isSonarCloud } from '../../helpers/system'; +import { lazyLoadComponent } from 'sonar-ui-common/components/lazyLoadComponent'; const routes = [ { indexRoute: { - component: lazyLoad(() => - isSonarCloud() ? import('./onboarding/OnboardingPage') : import('./ProjectOnboardingPage') - ) + component: lazyLoadComponent(() => import('./ProjectOnboardingPage')) } } ]; diff --git a/server/sonar-web/src/main/js/apps/users/routes.ts b/server/sonar-web/src/main/js/apps/users/routes.ts index 3e75189e325..4df2cd1dab3 100644 --- a/server/sonar-web/src/main/js/apps/users/routes.ts +++ b/server/sonar-web/src/main/js/apps/users/routes.ts @@ -17,11 +17,11 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -import { lazyLoad } from 'sonar-ui-common/components/lazyLoad'; +import { lazyLoadComponent } from 'sonar-ui-common/components/lazyLoadComponent'; const routes = [ { - indexRoute: { component: lazyLoad(() => import('./UsersAppContainer')) } + indexRoute: { component: lazyLoadComponent(() => import('./UsersAppContainer')) } } ]; diff --git a/server/sonar-web/src/main/js/apps/web-api/routes.ts b/server/sonar-web/src/main/js/apps/web-api/routes.ts index fcebe06dc0f..56f159d6cc6 100644 --- a/server/sonar-web/src/main/js/apps/web-api/routes.ts +++ b/server/sonar-web/src/main/js/apps/web-api/routes.ts @@ -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 { lazyLoad } from 'sonar-ui-common/components/lazyLoad'; +import { lazyLoadComponent } from 'sonar-ui-common/components/lazyLoadComponent'; const routes = [ { - indexRoute: { component: lazyLoad(() => import('./components/WebApiApp')) } + indexRoute: { component: lazyLoadComponent(() => import('./components/WebApiApp')) } }, { path: '**', - component: lazyLoad(() => import('./components/WebApiApp')) + component: lazyLoadComponent(() => import('./components/WebApiApp')) } ]; diff --git a/server/sonar-web/src/main/js/apps/webhooks/routes.ts b/server/sonar-web/src/main/js/apps/webhooks/routes.ts index 168c5c58de6..92b03bc5607 100644 --- a/server/sonar-web/src/main/js/apps/webhooks/routes.ts +++ b/server/sonar-web/src/main/js/apps/webhooks/routes.ts @@ -17,11 +17,11 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -import { lazyLoad } from 'sonar-ui-common/components/lazyLoad'; +import { lazyLoadComponent } from 'sonar-ui-common/components/lazyLoadComponent'; const routes = [ { - indexRoute: { component: lazyLoad(() => import('./components/App')) } + indexRoute: { component: lazyLoadComponent(() => import('./components/App')) } } ]; diff --git a/server/sonar-web/src/main/js/components/SourceViewer/SourceViewer.tsx b/server/sonar-web/src/main/js/components/SourceViewer/SourceViewer.tsx index 366e4003b96..0f157ddb6ef 100644 --- a/server/sonar-web/src/main/js/components/SourceViewer/SourceViewer.tsx +++ b/server/sonar-web/src/main/js/components/SourceViewer/SourceViewer.tsx @@ -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 { lazyLoad } from 'sonar-ui-common/components/lazyLoad'; +import { lazyLoadComponent } from 'sonar-ui-common/components/lazyLoadComponent'; -const SourceViewer = lazyLoad( +const SourceViewer = lazyLoadComponent( () => import(/* webpackPrefetch: true */ './SourceViewerBase'), 'SourceViewer' ); diff --git a/server/sonar-web/src/main/js/components/SourceViewer/SourceViewerBase.tsx b/server/sonar-web/src/main/js/components/SourceViewer/SourceViewerBase.tsx index 1872532b9aa..e4588216300 100644 --- a/server/sonar-web/src/main/js/components/SourceViewer/SourceViewerBase.tsx +++ b/server/sonar-web/src/main/js/components/SourceViewer/SourceViewerBase.tsx @@ -67,17 +67,17 @@ export interface Props { // but kept to maintaint the location indexes highlightedLocations?: (T.FlowLocation | undefined)[]; highlightedLocationMessage?: { index: number; text: string | undefined }; - loadComponent: ( + loadComponent?: ( component: string, branchLike: BranchLike | undefined ) => Promise; - loadIssues: ( + loadIssues?: ( component: string, from: number, to: number, branchLike: BranchLike | undefined ) => Promise; - loadSources: ( + loadSources?: ( component: string, from: number, to: number, @@ -129,10 +129,7 @@ export default class SourceViewerBase extends React.PureComponent displayAllIssues: false, displayIssueLocationsCount: true, displayIssueLocationsLink: true, - displayLocationMarkers: true, - loadComponent: defaultLoadComponent, - loadIssues: defaultLoadIssues, - loadSources: defaultLoadSources + displayLocationMarkers: true }; constructor(props: Props) { @@ -208,6 +205,18 @@ export default class SourceViewerBase extends React.PureComponent this.mounted = false; } + get loadComponent() { + return this.props.loadComponent || defaultLoadComponent; + } + + get loadIssues() { + return this.props.loadIssues || defaultLoadIssues; + } + + get propsLoadSources() { + return this.props.loadSources || defaultLoadSources; + } + computeCoverageStatus(lines: T.SourceLine[]) { return lines.map(line => ({ ...line, coverageStatus: getCoverageStatus(line) })); } @@ -228,7 +237,7 @@ export default class SourceViewerBase extends React.PureComponent const to = (this.props.aroundLine || 0) + LINES; const loadIssues = (component: T.SourceViewerFile, sources: T.SourceLine[]) => { - this.props.loadIssues(this.props.component, 1, to, this.props.branchLike).then( + this.loadIssues(this.props.component, 1, to, this.props.branchLike).then( issues => { if (this.mounted) { const finalSources = sources.slice(0, LINES); @@ -300,9 +309,10 @@ export default class SourceViewerBase extends React.PureComponent ); }; - this.props - .loadComponent(this.props.component, this.props.branchLike) - .then(onResolve, onFailLoadComponent); + this.loadComponent(this.props.component, this.props.branchLike).then( + onResolve, + onFailLoadComponent + ); } fetchSources() { @@ -335,27 +345,25 @@ export default class SourceViewerBase extends React.PureComponent } const firstSourceLine = this.state.sources[0]; const lastSourceLine = this.state.sources[this.state.sources.length - 1]; - this.props - .loadIssues( - this.props.component, - firstSourceLine && firstSourceLine.line, - lastSourceLine && lastSourceLine.line, - this.props.branchLike - ) - .then( - issues => { - if (this.mounted) { - this.setState({ - issues, - issuesByLine: issuesByLine(issues), - issueLocationsByLine: locationsByLine(issues) - }); - } - }, - () => { - // TODO + this.loadIssues( + this.props.component, + firstSourceLine && firstSourceLine.line, + lastSourceLine && lastSourceLine.line, + this.props.branchLike + ).then( + issues => { + if (this.mounted) { + this.setState({ + issues, + issuesByLine: issuesByLine(issues), + issueLocationsByLine: locationsByLine(issues) + }); } - ); + }, + () => { + // TODO + } + ); } loadSources = (): Promise => { @@ -381,9 +389,10 @@ export default class SourceViewerBase extends React.PureComponent // request one additional line to define `hasSourcesAfter` to++; - return this.props - .loadSources(this.props.component, from, to, this.props.branchLike) - .then(sources => resolve(sources), onFailLoadSources); + return this.propsLoadSources(this.props.component, from, to, this.props.branchLike).then( + sources => resolve(sources), + onFailLoadSources + ); }); }; @@ -394,43 +403,34 @@ export default class SourceViewerBase extends React.PureComponent const firstSourceLine = this.state.sources[0]; this.setState({ loadingSourcesBefore: true }); const from = Math.max(1, firstSourceLine.line - LINES); - this.props - .loadSources(this.props.component, from, firstSourceLine.line - 1, this.props.branchLike) - .then( - sources => { - this.props - .loadIssues(this.props.component, from, firstSourceLine.line - 1, this.props.branchLike) - .then( - issues => { - if (this.mounted) { - this.setState(prevState => { - const nextIssues = uniqBy( - [...issues, ...(prevState.issues || [])], - issue => issue.key - ); - return { - issues: nextIssues, - issuesByLine: issuesByLine(nextIssues), - issueLocationsByLine: locationsByLine(nextIssues), - loadingSourcesBefore: false, - sources: [ - ...this.computeCoverageStatus(sources), - ...(prevState.sources || []) - ], - symbolsByLine: { ...prevState.symbolsByLine, ...symbolsByLine(sources) } - }; - }); - } - }, - () => { - // TODO - } - ); - }, - () => { - // TODO + Promise.all([ + this.propsLoadSources( + this.props.component, + from, + firstSourceLine.line - 1, + this.props.branchLike + ), + this.loadIssues(this.props.component, from, firstSourceLine.line - 1, this.props.branchLike) + ]).then( + ([sources, issues]) => { + if (this.mounted) { + this.setState(prevState => { + const nextIssues = uniqBy([...issues, ...(prevState.issues || [])], issue => issue.key); + return { + issues: nextIssues, + issuesByLine: issuesByLine(nextIssues), + issueLocationsByLine: locationsByLine(nextIssues), + loadingSourcesBefore: false, + sources: [...this.computeCoverageStatus(sources), ...(prevState.sources || [])], + symbolsByLine: { ...prevState.symbolsByLine, ...symbolsByLine(sources) } + }; + }); } - ); + }, + () => { + // TODO + } + ); }; loadSourcesAfter = () => { @@ -442,38 +442,31 @@ export default class SourceViewerBase extends React.PureComponent const fromLine = lastSourceLine.line + 1; // request one additional line to define `hasSourcesAfter` const toLine = lastSourceLine.line + LINES + 1; - this.props.loadSources(this.props.component, fromLine, toLine, this.props.branchLike).then( - sources => { - this.props.loadIssues(this.props.component, fromLine, toLine, this.props.branchLike).then( - issues => { - if (this.mounted) { - this.setState(prevState => { - const nextIssues = uniqBy( - [...(prevState.issues || []), ...issues], - issue => issue.key - ); - return { - issues: nextIssues, - issuesByLine: issuesByLine(nextIssues), - issueLocationsByLine: locationsByLine(nextIssues), - hasSourcesAfter: sources.length > LINES, - loadingSourcesAfter: false, - sources: [ - ...(prevState.sources || []), - ...this.computeCoverageStatus(sources.slice(0, LINES)) - ], - symbolsByLine: { - ...prevState.symbolsByLine, - ...symbolsByLine(sources.slice(0, LINES)) - } - }; - }); - } - }, - () => { - // TODO - } - ); + Promise.all([ + this.propsLoadSources(this.props.component, fromLine, toLine, this.props.branchLike), + this.loadIssues(this.props.component, fromLine, toLine, this.props.branchLike) + ]).then( + ([sources, issues]) => { + if (this.mounted) { + this.setState(prevState => { + const nextIssues = uniqBy([...(prevState.issues || []), ...issues], issue => issue.key); + return { + issues: nextIssues, + issuesByLine: issuesByLine(nextIssues), + issueLocationsByLine: locationsByLine(nextIssues), + hasSourcesAfter: sources.length > LINES, + loadingSourcesAfter: false, + sources: [ + ...(prevState.sources || []), + ...this.computeCoverageStatus(sources.slice(0, LINES)) + ], + symbolsByLine: { + ...prevState.symbolsByLine, + ...symbolsByLine(sources.slice(0, LINES)) + } + }; + }); + } }, () => { // TODO @@ -723,7 +716,10 @@ export default class SourceViewerBase extends React.PureComponent } } -function defaultLoadComponent(component: string, branchLike: BranchLike | undefined) { +function defaultLoadComponent( + component: string, + branchLike: BranchLike | undefined +): Promise { return Promise.all([ getComponentForSourceViewer({ component, ...getBranchLikeQuery(branchLike) }), getComponentData({ component, ...getBranchLikeQuery(branchLike) }) diff --git a/server/sonar-web/src/main/js/components/SourceViewer/__tests__/SourceViewerBase-test.tsx b/server/sonar-web/src/main/js/components/SourceViewer/__tests__/SourceViewerBase-test.tsx index e7ae07b774b..6bcce8bb4d3 100644 --- a/server/sonar-web/src/main/js/components/SourceViewer/__tests__/SourceViewerBase-test.tsx +++ b/server/sonar-web/src/main/js/components/SourceViewer/__tests__/SourceViewerBase-test.tsx @@ -17,14 +17,137 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ +import { shallow } from 'enzyme'; import * as React from 'react'; +import { waitAndUpdate } from 'sonar-ui-common/helpers/testUtils'; +import { getComponentData, getComponentForSourceViewer, getSources } from '../../../api/components'; import { mockMainBranch } from '../../../helpers/mocks/branch-like'; +import { mockIssue, mockSourceLine, mockSourceViewerFile } from '../../../helpers/testMocks'; +import defaultLoadIssues from '../helpers/loadIssues'; import SourceViewerBase from '../SourceViewerBase'; -it('should render correctly', () => { - expect(shallowRender()).toMatchSnapshot(); +jest.mock('../helpers/loadIssues', () => ({ + default: jest.fn().mockRejectedValue({}) +})); + +jest.mock('../../../api/components', () => ({ + getComponentForSourceViewer: jest.fn().mockRejectedValue(''), + getComponentData: jest.fn().mockRejectedValue(''), + getSources: jest.fn().mockRejectedValue('') +})); + +beforeEach(() => { + jest.resetAllMocks(); +}); + +it('should render nothing from the start', () => { + expect(shallowRender().type()).toBeNull(); +}); + +it('should render correctly', async () => { + (defaultLoadIssues as jest.Mock).mockResolvedValueOnce([mockIssue()]); + (getComponentForSourceViewer as jest.Mock).mockResolvedValueOnce(mockSourceViewerFile()); + (getComponentData as jest.Mock).mockResolvedValueOnce({ + component: { leakPeriodDate: '2018-06-20T17:12:19+0200' } + }); + (getSources as jest.Mock).mockResolvedValueOnce([]); + + const wrapper = shallowRender(); + await waitAndUpdate(wrapper); + + expect(wrapper).toMatchSnapshot(); +}); + +it('should use load props if provided', () => { + const loadComponent = jest.fn().mockResolvedValue({}); + const loadIssues = jest.fn().mockResolvedValue([]); + const loadSources = jest.fn().mockResolvedValue([]); + const wrapper = shallowRender({ + loadComponent, + loadIssues, + loadSources + }); + + expect(wrapper.instance().loadComponent).toBe(loadComponent); +}); + +it('should reload', async () => { + (defaultLoadIssues as jest.Mock) + .mockResolvedValueOnce([mockIssue()]) + .mockResolvedValueOnce([mockIssue()]); + (getComponentForSourceViewer as jest.Mock).mockResolvedValueOnce(mockSourceViewerFile()); + (getComponentData as jest.Mock).mockResolvedValueOnce({ + component: { leakPeriodDate: '2018-06-20T17:12:19+0200' } + }); + (getSources as jest.Mock).mockResolvedValueOnce([mockSourceLine()]); + + const wrapper = shallowRender(); + await waitAndUpdate(wrapper); + + wrapper.instance().reloadIssues(); + + expect(defaultLoadIssues).toBeCalledTimes(2); + + await waitAndUpdate(wrapper); + + expect(wrapper.state().issues).toHaveLength(1); +}); + +it('should load sources before', async () => { + (defaultLoadIssues as jest.Mock) + .mockResolvedValueOnce([mockIssue(false, { key: 'issue1' })]) + .mockResolvedValueOnce([mockIssue(false, { key: 'issue2' })]); + (getComponentForSourceViewer as jest.Mock).mockResolvedValueOnce(mockSourceViewerFile()); + (getComponentData as jest.Mock).mockResolvedValueOnce({ + component: { leakPeriodDate: '2018-06-20T17:12:19+0200' } + }); + (getSources as jest.Mock) + .mockResolvedValueOnce([mockSourceLine()]) + .mockResolvedValueOnce([mockSourceLine()]); + + const wrapper = shallowRender(); + await waitAndUpdate(wrapper); + + wrapper.instance().loadSourcesBefore(); + expect(wrapper.state().loadingSourcesBefore).toBe(true); + + expect(defaultLoadIssues).toBeCalledTimes(2); + expect(getSources).toBeCalledTimes(2); + + await waitAndUpdate(wrapper); + expect(wrapper.state().loadingSourcesBefore).toBe(false); + expect(wrapper.state().issues).toHaveLength(2); +}); + +it('should load sources after', async () => { + (defaultLoadIssues as jest.Mock) + .mockResolvedValueOnce([mockIssue(false, { key: 'issue1' })]) + .mockResolvedValueOnce([mockIssue(false, { key: 'issue2' })]); + (getComponentForSourceViewer as jest.Mock).mockResolvedValueOnce(mockSourceViewerFile()); + (getComponentData as jest.Mock).mockResolvedValueOnce({ + component: { leakPeriodDate: '2018-06-20T17:12:19+0200' } + }); + (getSources as jest.Mock) + .mockResolvedValueOnce([mockSourceLine()]) + .mockResolvedValueOnce([mockSourceLine()]); + + const wrapper = shallowRender(); + await waitAndUpdate(wrapper); + + wrapper.instance().loadSourcesAfter(); + expect(wrapper.state().loadingSourcesAfter).toBe(true); + + expect(defaultLoadIssues).toBeCalledTimes(2); + expect(getSources).toBeCalledTimes(2); + + await waitAndUpdate(wrapper); + + expect(wrapper.state().loadingSourcesAfter).toBe(false); + expect(wrapper.state().issues).toHaveLength(2); }); -function shallowRender() { - return ; +function shallowRender(overrides: Partial = {}) { + return shallow( + + ); } diff --git a/server/sonar-web/src/main/js/components/SourceViewer/__tests__/__snapshots__/SourceViewerBase-test.tsx.snap b/server/sonar-web/src/main/js/components/SourceViewer/__tests__/__snapshots__/SourceViewerBase-test.tsx.snap index 8b0b0958b9f..1c54b627598 100644 --- a/server/sonar-web/src/main/js/components/SourceViewer/__tests__/__snapshots__/SourceViewerBase-test.tsx.snap +++ b/server/sonar-web/src/main/js/components/SourceViewer/__tests__/__snapshots__/SourceViewerBase-test.tsx.snap @@ -1,22 +1,165 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[`should render correctly 1`] = ` - +> +
+ + + + +
+ `; diff --git a/server/sonar-web/src/main/js/components/controls/DateInput.tsx b/server/sonar-web/src/main/js/components/controls/DateInput.tsx index ca84132317b..0a85275bd02 100644 --- a/server/sonar-web/src/main/js/components/controls/DateInput.tsx +++ b/server/sonar-web/src/main/js/components/controls/DateInput.tsx @@ -32,7 +32,7 @@ import Select from 'sonar-ui-common/components/controls/Select'; import CalendarIcon from 'sonar-ui-common/components/icons/CalendarIcon'; import ChevronLeftIcon from 'sonar-ui-common/components/icons/ChevronLeftIcon'; import ChevronRightIcon from 'sonar-ui-common/components/icons/ChevronRightIcon'; -import { lazyLoad } from 'sonar-ui-common/components/lazyLoad'; +import { lazyLoadComponent } from 'sonar-ui-common/components/lazyLoadComponent'; import { getShortMonthName, getShortWeekDayName, @@ -41,7 +41,7 @@ import { import './DayPicker.css'; import './styles.css'; -const DayPicker = lazyLoad(() => import('react-day-picker')); +const DayPicker = lazyLoadComponent(() => import('react-day-picker'), 'DayPicker'); interface Props { className?: string; diff --git a/server/sonar-web/src/main/js/components/docs/DocTooltip.tsx b/server/sonar-web/src/main/js/components/docs/DocTooltip.tsx index decde97522b..a1cfb5d2150 100644 --- a/server/sonar-web/src/main/js/components/docs/DocTooltip.tsx +++ b/server/sonar-web/src/main/js/components/docs/DocTooltip.tsx @@ -19,10 +19,10 @@ */ import * as React from 'react'; import HelpTooltip from 'sonar-ui-common/components/controls/HelpTooltip'; -import { lazyLoad } from 'sonar-ui-common/components/lazyLoad'; +import { lazyLoadComponent } from 'sonar-ui-common/components/lazyLoadComponent'; import { filterContent } from '../../helpers/markdown'; -const DocMarkdownBlock = lazyLoad(() => import('./DocMarkdownBlock')); +const DocMarkdownBlock = lazyLoadComponent(() => import('./DocMarkdownBlock'), 'DocMarkdownBlock'); interface Props { className?: string; diff --git a/server/sonar-web/src/main/js/components/docs/__tests__/__snapshots__/DocTooltip-test.tsx.snap b/server/sonar-web/src/main/js/components/docs/__tests__/__snapshots__/DocTooltip-test.tsx.snap index 2c996886133..cb2fe21b9d9 100644 --- a/server/sonar-web/src/main/js/components/docs/__tests__/__snapshots__/DocTooltip-test.tsx.snap +++ b/server/sonar-web/src/main/js/components/docs/__tests__/__snapshots__/DocTooltip-test.tsx.snap @@ -8,7 +8,7 @@ exports[`should render 2`] = `
- import('./WorkspaceNav')); -const WorkspaceRuleViewer = lazyLoad(() => import('./WorkspaceRuleViewer')); -const WorkspaceComponentViewer = lazyLoad(() => import('./WorkspaceComponentViewer')); +const WorkspaceNav = lazyLoadComponent(() => import('./WorkspaceNav'), 'WorkspaceNav'); +const WorkspaceRuleViewer = lazyLoadComponent( + () => import('./WorkspaceRuleViewer'), + 'WorkspaceRuleViewer' +); +const WorkspaceComponentViewer = lazyLoadComponent( + () => import('./WorkspaceComponentViewer'), + 'WorkspaceComponentViewer' +); interface State { components: ComponentDescriptor[]; -- 2.39.5