aboutsummaryrefslogtreecommitdiffstats
path: root/server/sonar-web/src/main/js/app
diff options
context:
space:
mode:
Diffstat (limited to 'server/sonar-web/src/main/js/app')
-rw-r--r--server/sonar-web/src/main/js/app/components/Landing.tsx7
-rw-r--r--server/sonar-web/src/main/js/app/components/PluginRiskConsent.tsx2
-rw-r--r--server/sonar-web/src/main/js/app/components/ResetPassword.tsx2
-rw-r--r--server/sonar-web/src/main/js/app/components/StartupModal.tsx12
-rw-r--r--server/sonar-web/src/main/js/app/components/__tests__/Landing-test.tsx2
-rw-r--r--server/sonar-web/src/main/js/app/components/__tests__/StartupModal-test.tsx2
-rw-r--r--server/sonar-web/src/main/js/app/components/__tests__/__snapshots__/GlobalContainer-test.tsx.snap12
-rw-r--r--server/sonar-web/src/main/js/app/components/current-user/CurrentUserContext.ts31
-rw-r--r--server/sonar-web/src/main/js/app/components/current-user/CurrentUserContextProvider.tsx62
-rw-r--r--server/sonar-web/src/main/js/app/components/current-user/withCurrentUserContext.tsx42
-rw-r--r--server/sonar-web/src/main/js/app/components/extensions/Extension.tsx14
-rw-r--r--server/sonar-web/src/main/js/app/components/extensions/__tests__/__snapshots__/ProjectAdminPageExtension-test.tsx.snap2
-rw-r--r--server/sonar-web/src/main/js/app/components/extensions/__tests__/__snapshots__/ProjectPageExtension-test.tsx.snap2
-rw-r--r--server/sonar-web/src/main/js/app/components/indexation/IndexationNotification.tsx8
-rw-r--r--server/sonar-web/src/main/js/app/components/nav/component/Header.tsx13
-rw-r--r--server/sonar-web/src/main/js/app/components/nav/component/HeaderMeta.tsx13
-rw-r--r--server/sonar-web/src/main/js/app/components/nav/component/__tests__/__snapshots__/ComponentNav-test.tsx.snap36
-rw-r--r--server/sonar-web/src/main/js/app/components/nav/component/__tests__/__snapshots__/HeaderMeta-test.tsx.snap6
-rw-r--r--server/sonar-web/src/main/js/app/components/nav/component/projectInformation/ProjectInformation.tsx13
-rw-r--r--server/sonar-web/src/main/js/app/components/nav/global/GlobalNav.tsx13
-rw-r--r--server/sonar-web/src/main/js/app/components/nav/global/GlobalNavMenu.tsx3
-rw-r--r--server/sonar-web/src/main/js/app/components/nav/global/GlobalNavUser.tsx3
-rw-r--r--server/sonar-web/src/main/js/app/components/promotion-notification/PromotionNotification.tsx20
-rw-r--r--server/sonar-web/src/main/js/app/components/promotion-notification/__tests__/PromotionNotification-test.tsx18
-rw-r--r--server/sonar-web/src/main/js/app/components/search/Search.tsx3
-rw-r--r--server/sonar-web/src/main/js/app/components/update-notification/UpdateNotification.tsx19
-rw-r--r--server/sonar-web/src/main/js/app/components/update-notification/__tests__/UpdateNotification-test.tsx9
-rw-r--r--server/sonar-web/src/main/js/app/components/update-notification/__tests__/__snapshots__/UpdateNotification-test.tsx.snap2
-rw-r--r--server/sonar-web/src/main/js/app/utils/getStore.ts9
-rw-r--r--server/sonar-web/src/main/js/app/utils/startReactApp.tsx158
30 files changed, 321 insertions, 217 deletions
diff --git a/server/sonar-web/src/main/js/app/components/Landing.tsx b/server/sonar-web/src/main/js/app/components/Landing.tsx
index ede739b43fe..13109175290 100644
--- a/server/sonar-web/src/main/js/app/components/Landing.tsx
+++ b/server/sonar-web/src/main/js/app/components/Landing.tsx
@@ -18,11 +18,10 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
import * as React from 'react';
-import { withCurrentUser } from '../../components/hoc/withCurrentUser';
import { Router, withRouter } from '../../components/hoc/withRouter';
import { getHomePageUrl } from '../../helpers/urls';
-import { isLoggedIn } from '../../helpers/users';
-import { CurrentUser } from '../../types/types';
+import { CurrentUser, isLoggedIn } from '../../types/users';
+import withCurrentUserContext from './current-user/withCurrentUserContext';
export interface LandingProps {
currentUser: CurrentUser;
@@ -45,4 +44,4 @@ export class Landing extends React.PureComponent<LandingProps> {
}
}
-export default withRouter(withCurrentUser(Landing));
+export default withRouter(withCurrentUserContext(Landing));
diff --git a/server/sonar-web/src/main/js/app/components/PluginRiskConsent.tsx b/server/sonar-web/src/main/js/app/components/PluginRiskConsent.tsx
index ab85767d669..6b560a90ca2 100644
--- a/server/sonar-web/src/main/js/app/components/PluginRiskConsent.tsx
+++ b/server/sonar-web/src/main/js/app/components/PluginRiskConsent.tsx
@@ -27,7 +27,7 @@ import { hasGlobalPermission } from '../../helpers/users';
import { Permissions } from '../../types/permissions';
import { RiskConsent } from '../../types/plugins';
import { SettingsKey } from '../../types/settings';
-import { LoggedInUser } from '../../types/types';
+import { LoggedInUser } from '../../types/users';
import GlobalMessagesContainer from './GlobalMessagesContainer';
import './PluginRiskConsent.css';
diff --git a/server/sonar-web/src/main/js/app/components/ResetPassword.tsx b/server/sonar-web/src/main/js/app/components/ResetPassword.tsx
index 800b9e05c3b..183cd2accb8 100644
--- a/server/sonar-web/src/main/js/app/components/ResetPassword.tsx
+++ b/server/sonar-web/src/main/js/app/components/ResetPassword.tsx
@@ -22,7 +22,7 @@ import ResetPasswordForm from '../../components/common/ResetPasswordForm';
import { whenLoggedIn } from '../../components/hoc/whenLoggedIn';
import { translate } from '../../helpers/l10n';
import { getBaseUrl } from '../../helpers/system';
-import { LoggedInUser } from '../../types/types';
+import { LoggedInUser } from '../../types/users';
import GlobalMessagesContainer from './GlobalMessagesContainer';
export interface ResetPasswordProps {
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 5b7c3915672..ebbdebed587 100644
--- a/server/sonar-web/src/main/js/app/components/StartupModal.tsx
+++ b/server/sonar-web/src/main/js/app/components/StartupModal.tsx
@@ -19,19 +19,17 @@
*/
import { differenceInDays } from 'date-fns';
import * as React from 'react';
-import { connect } from 'react-redux';
import { showLicense } from '../../api/marketplace';
import { Location, Router, withRouter } from '../../components/hoc/withRouter';
import { lazyLoadComponent } from '../../components/lazyLoadComponent';
import { parseDate, toShortNotSoISOString } from '../../helpers/dates';
import { hasMessage } from '../../helpers/l10n';
import { get, save } from '../../helpers/storage';
-import { isLoggedIn } from '../../helpers/users';
-import { getCurrentUser, Store } from '../../store/rootReducer';
import { AppState } from '../../types/appstate';
import { EditionKey } from '../../types/editions';
-import { CurrentUser } from '../../types/types';
+import { CurrentUser, isLoggedIn } from '../../types/users';
import withAppStateContext from './app-state/withAppStateContext';
+import withCurrentUserContext from './current-user/withCurrentUserContext';
const LicensePromptModal = lazyLoadComponent(
() => import('../../apps/marketplace/components/LicensePromptModal'),
@@ -98,8 +96,4 @@ export class StartupModal extends React.PureComponent<Props & StateProps, State>
}
}
-const mapStateToProps = (state: Store): StateProps => ({
- currentUser: getCurrentUser(state)
-});
-
-export default connect(mapStateToProps)(withRouter(withAppStateContext(StartupModal)));
+export default withCurrentUserContext(withRouter(withAppStateContext(StartupModal)));
diff --git a/server/sonar-web/src/main/js/app/components/__tests__/Landing-test.tsx b/server/sonar-web/src/main/js/app/components/__tests__/Landing-test.tsx
index 102f5f819fa..437ef87cf29 100644
--- a/server/sonar-web/src/main/js/app/components/__tests__/Landing-test.tsx
+++ b/server/sonar-web/src/main/js/app/components/__tests__/Landing-test.tsx
@@ -20,7 +20,7 @@
import { shallow } from 'enzyme';
import * as React from 'react';
import { mockCurrentUser, mockLoggedInUser, mockRouter } from '../../../helpers/testMocks';
-import { CurrentUser } from '../../../types/types';
+import { CurrentUser } from '../../../types/users';
import { Landing } from '../Landing';
it.each([
diff --git a/server/sonar-web/src/main/js/app/components/__tests__/StartupModal-test.tsx b/server/sonar-web/src/main/js/app/components/__tests__/StartupModal-test.tsx
index 4a07e47012b..0813389c9ba 100644
--- a/server/sonar-web/src/main/js/app/components/__tests__/StartupModal-test.tsx
+++ b/server/sonar-web/src/main/js/app/components/__tests__/StartupModal-test.tsx
@@ -27,7 +27,7 @@ import { get, save } from '../../../helpers/storage';
import { mockAppState } from '../../../helpers/testMocks';
import { waitAndUpdate } from '../../../helpers/testUtils';
import { EditionKey } from '../../../types/editions';
-import { LoggedInUser } from '../../../types/types';
+import { LoggedInUser } from '../../../types/users';
import { StartupModal } from '../StartupModal';
jest.mock('../../../api/marketplace', () => ({
diff --git a/server/sonar-web/src/main/js/app/components/__tests__/__snapshots__/GlobalContainer-test.tsx.snap b/server/sonar-web/src/main/js/app/components/__tests__/__snapshots__/GlobalContainer-test.tsx.snap
index cf997f458f2..ab5e5905229 100644
--- a/server/sonar-web/src/main/js/app/components/__tests__/__snapshots__/GlobalContainer-test.tsx.snap
+++ b/server/sonar-web/src/main/js/app/components/__tests__/__snapshots__/GlobalContainer-test.tsx.snap
@@ -3,7 +3,7 @@
exports[`should render correctly 1`] = `
<SuggestionsProvider>
<A11yProvider>
- <Connect(withRouter(withAppStateContext(StartupModal)))>
+ <withCurrentUserContext(withRouter(withAppStateContext(StartupModal)))>
<A11ySkipLinks />
<div
className="global-container"
@@ -19,7 +19,7 @@ exports[`should render correctly 1`] = `
<withAppStateContext(IndexationContextProvider)>
<LanguagesContextProvider>
<MetricsContextProvider>
- <Connect(GlobalNav)
+ <withCurrentUserContext(GlobalNav)
location={
Object {
"action": "PUSH",
@@ -33,8 +33,8 @@ exports[`should render correctly 1`] = `
}
/>
<Connect(GlobalMessages) />
- <Connect(withCurrentUser(withIndexationContext(IndexationNotification))) />
- <Connect(withCurrentUser(withAppStateContext(UpdateNotification)))
+ <withCurrentUserContext(withIndexationContext(IndexationNotification)) />
+ <withCurrentUserContext(withAppStateContext(UpdateNotification))
dismissable={true}
/>
<ChildComponent />
@@ -43,11 +43,11 @@ exports[`should render correctly 1`] = `
</withAppStateContext(IndexationContextProvider)>
</Workspace>
</div>
- <Connect(Connect(withCurrentUser(PromotionNotification))) />
+ <withCurrentUserContext(PromotionNotification) />
</div>
<withAppStateContext(GlobalFooter) />
</div>
- </Connect(withRouter(withAppStateContext(StartupModal)))>
+ </withCurrentUserContext(withRouter(withAppStateContext(StartupModal)))>
</A11yProvider>
</SuggestionsProvider>
`;
diff --git a/server/sonar-web/src/main/js/app/components/current-user/CurrentUserContext.ts b/server/sonar-web/src/main/js/app/components/current-user/CurrentUserContext.ts
new file mode 100644
index 00000000000..efb10534705
--- /dev/null
+++ b/server/sonar-web/src/main/js/app/components/current-user/CurrentUserContext.ts
@@ -0,0 +1,31 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2022 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 { CurrentUser, HomePage } from '../../../types/users';
+
+export interface CurrentUserContextInterface {
+ currentUser: CurrentUser;
+ updateCurrentUserHomepage: (homepage: HomePage) => void;
+ updateCurrentUserSonarLintAdSeen: () => void;
+}
+
+export const CurrentUserContext = React.createContext<CurrentUserContextInterface | undefined>(
+ undefined
+);
diff --git a/server/sonar-web/src/main/js/app/components/current-user/CurrentUserContextProvider.tsx b/server/sonar-web/src/main/js/app/components/current-user/CurrentUserContextProvider.tsx
new file mode 100644
index 00000000000..9ffe3d1ec59
--- /dev/null
+++ b/server/sonar-web/src/main/js/app/components/current-user/CurrentUserContextProvider.tsx
@@ -0,0 +1,62 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2022 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 { CurrentUser, HomePage } from '../../../types/users';
+import { CurrentUserContext } from './CurrentUserContext';
+
+interface Props {
+ currentUser?: CurrentUser;
+}
+
+interface State {
+ currentUser: CurrentUser;
+}
+
+export default class CurrentUserContextProvider extends React.PureComponent<Props, State> {
+ constructor(props: Props) {
+ super(props);
+ this.state = { currentUser: props.currentUser ?? { isLoggedIn: false } };
+ }
+
+ updateCurrentUserHomepage = (homepage: HomePage) => {
+ this.setState(prevState => ({
+ currentUser: { ...prevState.currentUser, homepage }
+ }));
+ };
+
+ updateCurrentUserSonarLintAdSeen = () => {
+ this.setState(prevState => ({
+ currentUser: { ...prevState.currentUser, sonarLintAdSeen: true }
+ }));
+ };
+
+ render() {
+ return (
+ <CurrentUserContext.Provider
+ value={{
+ currentUser: this.state.currentUser,
+ updateCurrentUserHomepage: this.updateCurrentUserHomepage,
+ updateCurrentUserSonarLintAdSeen: this.updateCurrentUserSonarLintAdSeen
+ }}>
+ {this.props.children}
+ </CurrentUserContext.Provider>
+ );
+ }
+}
diff --git a/server/sonar-web/src/main/js/app/components/current-user/withCurrentUserContext.tsx b/server/sonar-web/src/main/js/app/components/current-user/withCurrentUserContext.tsx
new file mode 100644
index 00000000000..e2621f072ac
--- /dev/null
+++ b/server/sonar-web/src/main/js/app/components/current-user/withCurrentUserContext.tsx
@@ -0,0 +1,42 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2022 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 { getWrappedDisplayName } from '../../../components/hoc/utils';
+import { CurrentUserContext, CurrentUserContextInterface } from './CurrentUserContext';
+
+export default function withCurrentUserContext<P>(
+ WrappedComponent: React.ComponentType<P & Pick<CurrentUserContextInterface, 'currentUser'>>
+) {
+ return class WithCurrentUserContext extends React.PureComponent<
+ Omit<P, keyof CurrentUserContextInterface>
+ > {
+ static displayName = getWrappedDisplayName(WrappedComponent, 'withCurrentUserContext');
+
+ render() {
+ return (
+ <CurrentUserContext.Consumer>
+ {(currentUserContext: CurrentUserContextInterface) => (
+ <WrappedComponent {...currentUserContext} {...(this.props as P)} />
+ )}
+ </CurrentUserContext.Consumer>
+ );
+ }
+ };
+}
diff --git a/server/sonar-web/src/main/js/app/components/extensions/Extension.tsx b/server/sonar-web/src/main/js/app/components/extensions/Extension.tsx
index db90d3e0342..695cd5f3efc 100644
--- a/server/sonar-web/src/main/js/app/components/extensions/Extension.tsx
+++ b/server/sonar-web/src/main/js/app/components/extensions/Extension.tsx
@@ -26,13 +26,14 @@ import { getExtensionStart } from '../../../helpers/extensions';
import { getCurrentL10nBundle, translate } from '../../../helpers/l10n';
import { getBaseUrl } from '../../../helpers/system';
import { addGlobalErrorMessage } from '../../../store/globalMessages';
-import { getCurrentUser, Store } from '../../../store/rootReducer';
import { AppState } from '../../../types/appstate';
import { ExtensionStartMethod } from '../../../types/extension';
-import { CurrentUser, Dict, Extension as TypeExtension } from '../../../types/types';
+import { Dict, Extension as TypeExtension } from '../../../types/types';
+import { CurrentUser } from '../../../types/users';
import * as theme from '../../theme';
import getStore from '../../utils/getStore';
import withAppStateContext from '../app-state/withAppStateContext';
+import withCurrentUserContext from '../current-user/withCurrentUserContext';
interface Props extends WrappedComponentProps {
appState: AppState;
@@ -126,9 +127,10 @@ export class Extension extends React.PureComponent<Props, State> {
}
}
-const mapStateToProps = (state: Store) => ({ currentUser: getCurrentUser(state) });
-const mapDispatchToProps = { onFail: addGlobalErrorMessage };
-
export default injectIntl(
- withRouter(withAppStateContext(connect(mapStateToProps, mapDispatchToProps)(Extension)))
+ withRouter(
+ withAppStateContext(
+ withCurrentUserContext(connect(null, { onFail: addGlobalErrorMessage })(Extension))
+ )
+ )
);
diff --git a/server/sonar-web/src/main/js/app/components/extensions/__tests__/__snapshots__/ProjectAdminPageExtension-test.tsx.snap b/server/sonar-web/src/main/js/app/components/extensions/__tests__/__snapshots__/ProjectAdminPageExtension-test.tsx.snap
index bb720539c93..41c11c85e36 100644
--- a/server/sonar-web/src/main/js/app/components/extensions/__tests__/__snapshots__/ProjectAdminPageExtension-test.tsx.snap
+++ b/server/sonar-web/src/main/js/app/components/extensions/__tests__/__snapshots__/ProjectAdminPageExtension-test.tsx.snap
@@ -1,7 +1,7 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`should render correctly: extension exists 1`] = `
-<injectIntl(withRouter(withAppStateContext(Connect(Extension))))
+<injectIntl(withRouter(withAppStateContext(withCurrentUserContext(Connect(Extension)))))
extension={
Object {
"key": "foo/bar",
diff --git a/server/sonar-web/src/main/js/app/components/extensions/__tests__/__snapshots__/ProjectPageExtension-test.tsx.snap b/server/sonar-web/src/main/js/app/components/extensions/__tests__/__snapshots__/ProjectPageExtension-test.tsx.snap
index 53b7d0d8243..bb710428d4c 100644
--- a/server/sonar-web/src/main/js/app/components/extensions/__tests__/__snapshots__/ProjectPageExtension-test.tsx.snap
+++ b/server/sonar-web/src/main/js/app/components/extensions/__tests__/__snapshots__/ProjectPageExtension-test.tsx.snap
@@ -1,7 +1,7 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`should render correctly 1`] = `
-<injectIntl(withRouter(withAppStateContext(Connect(Extension))))
+<injectIntl(withRouter(withAppStateContext(withCurrentUserContext(Connect(Extension)))))
extension={
Object {
"key": "plugin-key/extension-key",
diff --git a/server/sonar-web/src/main/js/app/components/indexation/IndexationNotification.tsx b/server/sonar-web/src/main/js/app/components/indexation/IndexationNotification.tsx
index 391bb0a7c52..52bb015e917 100644
--- a/server/sonar-web/src/main/js/app/components/indexation/IndexationNotification.tsx
+++ b/server/sonar-web/src/main/js/app/components/indexation/IndexationNotification.tsx
@@ -18,14 +18,14 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
import * as React from 'react';
-import { withCurrentUser } from '../../../components/hoc/withCurrentUser';
import withIndexationContext, {
WithIndexationContextProps
} from '../../../components/hoc/withIndexationContext';
-import { hasGlobalPermission, isLoggedIn } from '../../../helpers/users';
+import { hasGlobalPermission } from '../../../helpers/users';
import { IndexationNotificationType } from '../../../types/indexation';
import { Permissions } from '../../../types/permissions';
-import { CurrentUser } from '../../../types/types';
+import { CurrentUser, isLoggedIn } from '../../../types/users';
+import withCurrentUserContext from '../current-user/withCurrentUserContext';
import './IndexationNotification.css';
import IndexationNotificationHelper from './IndexationNotificationHelper';
import IndexationNotificationRenderer from './IndexationNotificationRenderer';
@@ -104,4 +104,4 @@ export class IndexationNotification extends React.PureComponent<Props, State> {
}
}
-export default withCurrentUser(withIndexationContext(IndexationNotification));
+export default withCurrentUserContext(withIndexationContext(IndexationNotification));
diff --git a/server/sonar-web/src/main/js/app/components/nav/component/Header.tsx b/server/sonar-web/src/main/js/app/components/nav/component/Header.tsx
index 7cc1e130c0c..f17925c709b 100644
--- a/server/sonar-web/src/main/js/app/components/nav/component/Header.tsx
+++ b/server/sonar-web/src/main/js/app/components/nav/component/Header.tsx
@@ -19,13 +19,12 @@
*/
import * as React from 'react';
import { Helmet } from 'react-helmet-async';
-import { connect } from 'react-redux';
import Favorite from '../../../../components/controls/Favorite';
-import { isLoggedIn } from '../../../../helpers/users';
-import { getCurrentUser, Store } from '../../../../store/rootReducer';
import { ProjectAlmBindingResponse } from '../../../../types/alm-settings';
import { BranchLike } from '../../../../types/branch-like';
-import { Component, CurrentUser } from '../../../../types/types';
+import { Component } from '../../../../types/types';
+import { CurrentUser, isLoggedIn } from '../../../../types/users';
+import withCurrentUserContext from '../../current-user/withCurrentUserContext';
import BranchLikeNavigation from './branch-like/BranchLikeNavigation';
import CurrentBranchLikeMergeInformation from './branch-like/CurrentBranchLikeMergeInformation';
import { Breadcrumb } from './Breadcrumb';
@@ -70,8 +69,4 @@ export function Header(props: HeaderProps) {
);
}
-const mapStateToProps = (state: Store) => ({
- currentUser: getCurrentUser(state)
-});
-
-export default connect(mapStateToProps)(React.memo(Header));
+export default withCurrentUserContext(React.memo(Header));
diff --git a/server/sonar-web/src/main/js/app/components/nav/component/HeaderMeta.tsx b/server/sonar-web/src/main/js/app/components/nav/component/HeaderMeta.tsx
index cf2f755debb..f77c4429974 100644
--- a/server/sonar-web/src/main/js/app/components/nav/component/HeaderMeta.tsx
+++ b/server/sonar-web/src/main/js/app/components/nav/component/HeaderMeta.tsx
@@ -18,19 +18,18 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
import * as React from 'react';
-import { connect } from 'react-redux';
import BranchStatus from '../../../../components/common/BranchStatus';
import HomePageSelect from '../../../../components/controls/HomePageSelect';
import DetachIcon from '../../../../components/icons/DetachIcon';
import DateTimeFormatter from '../../../../components/intl/DateTimeFormatter';
import { isBranch, isPullRequest } from '../../../../helpers/branch-like';
import { translate } from '../../../../helpers/l10n';
-import { isLoggedIn } from '../../../../helpers/users';
-import { getCurrentUser, Store } from '../../../../store/rootReducer';
import { BranchLike } from '../../../../types/branch-like';
import { ComponentQualifier } from '../../../../types/component';
import { TaskWarning } from '../../../../types/tasks';
-import { Component, CurrentUser, HomePage } from '../../../../types/types';
+import { Component } from '../../../../types/types';
+import { CurrentUser, HomePage, isLoggedIn } from '../../../../types/users';
+import withCurrentUserContext from '../../current-user/withCurrentUserContext';
import ComponentNavWarnings from './ComponentNavWarnings';
import './HeaderMeta.css';
@@ -124,8 +123,4 @@ export function getCurrentPage(component: Component, branchLike: BranchLike | un
return currentPage;
}
-const mapStateToProps = (state: Store) => ({
- currentUser: getCurrentUser(state)
-});
-
-export default connect(mapStateToProps)(HeaderMeta);
+export default withCurrentUserContext(HeaderMeta);
diff --git a/server/sonar-web/src/main/js/app/components/nav/component/__tests__/__snapshots__/ComponentNav-test.tsx.snap b/server/sonar-web/src/main/js/app/components/nav/component/__tests__/__snapshots__/ComponentNav-test.tsx.snap
index 0a372d2d7b8..02a675e164a 100644
--- a/server/sonar-web/src/main/js/app/components/nav/component/__tests__/__snapshots__/ComponentNav-test.tsx.snap
+++ b/server/sonar-web/src/main/js/app/components/nav/component/__tests__/__snapshots__/ComponentNav-test.tsx.snap
@@ -9,7 +9,7 @@ exports[`renders correctly: default 1`] = `
<div
className="display-flex-center display-flex-space-between little-padded-top padded-bottom"
>
- <Connect(Component)
+ <withCurrentUserContext(Component)
branchLikes={Array []}
component={
Object {
@@ -40,7 +40,7 @@ exports[`renders correctly: default 1`] = `
}
}
/>
- <Connect(HeaderMeta)
+ <withCurrentUserContext(HeaderMeta)
component={
Object {
"breadcrumbs": Array [
@@ -112,7 +112,7 @@ exports[`renders correctly: default 1`] = `
onClose={[Function]}
top={120}
>
- <Connect(withMetricsContext(ProjectInformation))
+ <withCurrentUserContext(withMetricsContext(ProjectInformation))
component={
Object {
"breadcrumbs": Array [
@@ -203,7 +203,7 @@ exports[`renders correctly: has failed notification 1`] = `
<div
className="display-flex-center display-flex-space-between little-padded-top padded-bottom"
>
- <Connect(Component)
+ <withCurrentUserContext(Component)
branchLikes={Array []}
component={
Object {
@@ -234,7 +234,7 @@ exports[`renders correctly: has failed notification 1`] = `
}
}
/>
- <Connect(HeaderMeta)
+ <withCurrentUserContext(HeaderMeta)
component={
Object {
"breadcrumbs": Array [
@@ -306,7 +306,7 @@ exports[`renders correctly: has failed notification 1`] = `
onClose={[Function]}
top={120}
>
- <Connect(withMetricsContext(ProjectInformation))
+ <withCurrentUserContext(withMetricsContext(ProjectInformation))
component={
Object {
"breadcrumbs": Array [
@@ -383,7 +383,7 @@ exports[`renders correctly: has failed project binding 1`] = `
<div
className="display-flex-center display-flex-space-between little-padded-top padded-bottom"
>
- <Connect(Component)
+ <withCurrentUserContext(Component)
branchLikes={Array []}
component={
Object {
@@ -414,7 +414,7 @@ exports[`renders correctly: has failed project binding 1`] = `
}
}
/>
- <Connect(HeaderMeta)
+ <withCurrentUserContext(HeaderMeta)
component={
Object {
"breadcrumbs": Array [
@@ -486,7 +486,7 @@ exports[`renders correctly: has failed project binding 1`] = `
onClose={[Function]}
top={120}
>
- <Connect(withMetricsContext(ProjectInformation))
+ <withCurrentUserContext(withMetricsContext(ProjectInformation))
component={
Object {
"breadcrumbs": Array [
@@ -565,7 +565,7 @@ exports[`renders correctly: has in progress notification 1`] = `
<div
className="display-flex-center display-flex-space-between little-padded-top padded-bottom"
>
- <Connect(Component)
+ <withCurrentUserContext(Component)
branchLikes={Array []}
component={
Object {
@@ -596,7 +596,7 @@ exports[`renders correctly: has in progress notification 1`] = `
}
}
/>
- <Connect(HeaderMeta)
+ <withCurrentUserContext(HeaderMeta)
component={
Object {
"breadcrumbs": Array [
@@ -668,7 +668,7 @@ exports[`renders correctly: has in progress notification 1`] = `
onClose={[Function]}
top={120}
>
- <Connect(withMetricsContext(ProjectInformation))
+ <withCurrentUserContext(withMetricsContext(ProjectInformation))
component={
Object {
"breadcrumbs": Array [
@@ -747,7 +747,7 @@ exports[`renders correctly: has pending notification 1`] = `
<div
className="display-flex-center display-flex-space-between little-padded-top padded-bottom"
>
- <Connect(Component)
+ <withCurrentUserContext(Component)
branchLikes={Array []}
component={
Object {
@@ -778,7 +778,7 @@ exports[`renders correctly: has pending notification 1`] = `
}
}
/>
- <Connect(HeaderMeta)
+ <withCurrentUserContext(HeaderMeta)
component={
Object {
"breadcrumbs": Array [
@@ -850,7 +850,7 @@ exports[`renders correctly: has pending notification 1`] = `
onClose={[Function]}
top={120}
>
- <Connect(withMetricsContext(ProjectInformation))
+ <withCurrentUserContext(withMetricsContext(ProjectInformation))
component={
Object {
"breadcrumbs": Array [
@@ -894,7 +894,7 @@ exports[`renders correctly: has warnings 1`] = `
<div
className="display-flex-center display-flex-space-between little-padded-top"
>
- <Connect(Component)
+ <withCurrentUserContext(Component)
branchLikes={Array []}
component={
Object {
@@ -925,7 +925,7 @@ exports[`renders correctly: has warnings 1`] = `
}
}
/>
- <Connect(HeaderMeta)
+ <withCurrentUserContext(HeaderMeta)
component={
Object {
"breadcrumbs": Array [
@@ -1005,7 +1005,7 @@ exports[`renders correctly: has warnings 1`] = `
onClose={[Function]}
top={120}
>
- <Connect(withMetricsContext(ProjectInformation))
+ <withCurrentUserContext(withMetricsContext(ProjectInformation))
component={
Object {
"breadcrumbs": Array [
diff --git a/server/sonar-web/src/main/js/app/components/nav/component/__tests__/__snapshots__/HeaderMeta-test.tsx.snap b/server/sonar-web/src/main/js/app/components/nav/component/__tests__/__snapshots__/HeaderMeta-test.tsx.snap
index fd0e0ab897d..14a257a1b3c 100644
--- a/server/sonar-web/src/main/js/app/components/nav/component/__tests__/__snapshots__/HeaderMeta-test.tsx.snap
+++ b/server/sonar-web/src/main/js/app/components/nav/component/__tests__/__snapshots__/HeaderMeta-test.tsx.snap
@@ -39,7 +39,7 @@ exports[`should render correctly for a branch 1`] = `
>
version 0.0.1
</span>
- <Connect(HomePageSelect)
+ <withCurrentUserContext(HomePageSelect)
className="spacer-left"
currentPage={
Object {
@@ -92,7 +92,7 @@ exports[`should render correctly for a main project branch 1`] = `
>
version 0.0.1
</span>
- <Connect(HomePageSelect)
+ <withCurrentUserContext(HomePageSelect)
className="spacer-left"
currentPage={
Object {
@@ -133,7 +133,7 @@ exports[`should render correctly for a portfolio 1`] = `
}
/>
</span>
- <Connect(HomePageSelect)
+ <withCurrentUserContext(HomePageSelect)
className="spacer-left"
currentPage={
Object {
diff --git a/server/sonar-web/src/main/js/app/components/nav/component/projectInformation/ProjectInformation.tsx b/server/sonar-web/src/main/js/app/components/nav/component/projectInformation/ProjectInformation.tsx
index 6f28bae6697..952b65e7d1e 100644
--- a/server/sonar-web/src/main/js/app/components/nav/component/projectInformation/ProjectInformation.tsx
+++ b/server/sonar-web/src/main/js/app/components/nav/component/projectInformation/ProjectInformation.tsx
@@ -18,14 +18,13 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
import * as React from 'react';
-import { connect } from 'react-redux';
import { getMeasures } from '../../../../../api/measures';
-import { isLoggedIn } from '../../../../../helpers/users';
-import { getCurrentUser, Store } from '../../../../../store/rootReducer';
import { BranchLike } from '../../../../../types/branch-like';
import { ComponentQualifier } from '../../../../../types/component';
import { MetricKey } from '../../../../../types/metrics';
-import { Component, CurrentUser, Dict, Measure, Metric } from '../../../../../types/types';
+import { Component, Dict, Measure, Metric } from '../../../../../types/types';
+import { CurrentUser, isLoggedIn } from '../../../../../types/users';
+import withCurrentUserContext from '../../../current-user/withCurrentUserContext';
import withMetricsContext from '../../../metrics/withMetricsContext';
import ProjectBadges from './badges/ProjectBadges';
import InfoDrawerPage from './InfoDrawerPage';
@@ -121,8 +120,4 @@ export class ProjectInformation extends React.PureComponent<Props, State> {
}
}
-const mapStateToProps = (state: Store) => ({
- currentUser: getCurrentUser(state)
-});
-
-export default connect(mapStateToProps)(withMetricsContext(ProjectInformation));
+export default withCurrentUserContext(withMetricsContext(ProjectInformation));
diff --git a/server/sonar-web/src/main/js/app/components/nav/global/GlobalNav.tsx b/server/sonar-web/src/main/js/app/components/nav/global/GlobalNav.tsx
index 488135ebd8b..45288c9ef07 100644
--- a/server/sonar-web/src/main/js/app/components/nav/global/GlobalNav.tsx
+++ b/server/sonar-web/src/main/js/app/components/nav/global/GlobalNav.tsx
@@ -18,11 +18,10 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
import * as React from 'react';
-import { connect } from 'react-redux';
import NavBar from '../../../../components/ui/NavBar';
-import { getCurrentUser, Store } from '../../../../store/rootReducer';
-import { CurrentUser } from '../../../../types/types';
+import { CurrentUser } from '../../../../types/users';
import { rawSizes } from '../../../theme';
+import withCurrentUserContext from '../../current-user/withCurrentUserContext';
import EmbedDocsPopupHelper from '../../embed-docs-modal/EmbedDocsPopupHelper';
import Search from '../../search/Search';
import './GlobalNav.css';
@@ -52,10 +51,4 @@ export function GlobalNav(props: GlobalNavProps) {
);
}
-const mapStateToProps = (state: Store) => {
- return {
- currentUser: getCurrentUser(state)
- };
-};
-
-export default connect(mapStateToProps)(GlobalNav);
+export default withCurrentUserContext(GlobalNav);
diff --git a/server/sonar-web/src/main/js/app/components/nav/global/GlobalNavMenu.tsx b/server/sonar-web/src/main/js/app/components/nav/global/GlobalNavMenu.tsx
index 230bdffe274..e608efc5955 100644
--- a/server/sonar-web/src/main/js/app/components/nav/global/GlobalNavMenu.tsx
+++ b/server/sonar-web/src/main/js/app/components/nav/global/GlobalNavMenu.tsx
@@ -27,7 +27,8 @@ import { translate } from '../../../../helpers/l10n';
import { getQualityGatesUrl } from '../../../../helpers/urls';
import { AppState } from '../../../../types/appstate';
import { ComponentQualifier } from '../../../../types/component';
-import { CurrentUser, Extension } from '../../../../types/types';
+import { Extension } from '../../../../types/types';
+import { CurrentUser } from '../../../../types/users';
import withAppStateContext from '../../app-state/withAppStateContext';
interface Props {
diff --git a/server/sonar-web/src/main/js/app/components/nav/global/GlobalNavUser.tsx b/server/sonar-web/src/main/js/app/components/nav/global/GlobalNavUser.tsx
index 2e6e24706b4..91079564dbe 100644
--- a/server/sonar-web/src/main/js/app/components/nav/global/GlobalNavUser.tsx
+++ b/server/sonar-web/src/main/js/app/components/nav/global/GlobalNavUser.tsx
@@ -24,8 +24,7 @@ import { Router, withRouter } from '../../../../components/hoc/withRouter';
import Avatar from '../../../../components/ui/Avatar';
import { translate } from '../../../../helpers/l10n';
import { getBaseUrl } from '../../../../helpers/system';
-import { isLoggedIn } from '../../../../helpers/users';
-import { CurrentUser, LoggedInUser } from '../../../../types/types';
+import { CurrentUser, isLoggedIn, LoggedInUser } from '../../../../types/users';
import { rawSizes } from '../../../theme';
interface Props {
diff --git a/server/sonar-web/src/main/js/app/components/promotion-notification/PromotionNotification.tsx b/server/sonar-web/src/main/js/app/components/promotion-notification/PromotionNotification.tsx
index 8f9e68a3b01..924b1da4cae 100644
--- a/server/sonar-web/src/main/js/app/components/promotion-notification/PromotionNotification.tsx
+++ b/server/sonar-web/src/main/js/app/components/promotion-notification/PromotionNotification.tsx
@@ -18,21 +18,17 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
import * as React from 'react';
-import { connect } from 'react-redux';
import { dismissSonarlintAd } from '../../../api/users';
import { ButtonLink } from '../../../components/controls/buttons';
-import { withCurrentUser } from '../../../components/hoc/withCurrentUser';
import { translate } from '../../../helpers/l10n';
import { getBaseUrl } from '../../../helpers/system';
-import { isLoggedIn } from '../../../helpers/users';
-import { setSonarlintAd } from '../../../store/users';
-import { CurrentUser } from '../../../types/types';
+import { isLoggedIn } from '../../../types/users';
+import { CurrentUserContextInterface } from '../current-user/CurrentUserContext';
+import withCurrentUserContext from '../current-user/withCurrentUserContext';
import './PromotionNotification.css';
-export interface PromotionNotificationProps {
- setSonarlintAd: () => void;
- currentUser: CurrentUser;
-}
+export interface PromotionNotificationProps
+ extends Pick<CurrentUserContextInterface, 'currentUser' | 'updateCurrentUserSonarLintAdSeen'> {}
export function PromotionNotification(props: PromotionNotificationProps) {
const { currentUser } = props;
@@ -43,7 +39,7 @@ export function PromotionNotification(props: PromotionNotificationProps) {
const onClick = () => {
dismissSonarlintAd();
- props.setSonarlintAd();
+ props.updateCurrentUserSonarLintAdSeen();
};
return (
@@ -74,6 +70,4 @@ export function PromotionNotification(props: PromotionNotificationProps) {
);
}
-const dispatchToProps = { setSonarlintAd };
-
-export default connect(null, dispatchToProps)(withCurrentUser(PromotionNotification));
+export default withCurrentUserContext(PromotionNotification);
diff --git a/server/sonar-web/src/main/js/app/components/promotion-notification/__tests__/PromotionNotification-test.tsx b/server/sonar-web/src/main/js/app/components/promotion-notification/__tests__/PromotionNotification-test.tsx
index c39dd065ca1..059d0560dbf 100644
--- a/server/sonar-web/src/main/js/app/components/promotion-notification/__tests__/PromotionNotification-test.tsx
+++ b/server/sonar-web/src/main/js/app/components/promotion-notification/__tests__/PromotionNotification-test.tsx
@@ -40,29 +40,33 @@ it('should render correctly', () => {
});
it('should remove the toaster when click on dismiss', () => {
- const setSonarlintAd = jest.fn();
+ const updateCurrentUserSonarLintAdSeen = jest.fn();
const wrapper = shallowRender({
currentUser: mockLoggedInUser({ sonarLintAdSeen: false }),
- setSonarlintAd
+ updateCurrentUserSonarLintAdSeen
});
wrapper.find('.toaster-actions ButtonLink').simulate('click');
expect(dismissSonarlintAd).toBeCalled();
- expect(setSonarlintAd).toBeCalled();
+ expect(updateCurrentUserSonarLintAdSeen).toBeCalled();
});
it('should remove the toaster and navigate to sonarlint when click on learn more', () => {
- const setSonarlintAd = jest.fn();
+ const updateCurrentUserSonarLintAdSeen = jest.fn();
const wrapper = shallowRender({
currentUser: mockLoggedInUser({ sonarLintAdSeen: false }),
- setSonarlintAd
+ updateCurrentUserSonarLintAdSeen
});
wrapper.find('.toaster-actions .button-primary').simulate('click');
expect(dismissSonarlintAd).toBeCalled();
- expect(setSonarlintAd).toBeCalled();
+ expect(updateCurrentUserSonarLintAdSeen).toBeCalled();
});
function shallowRender(props: Partial<PromotionNotificationProps> = {}) {
return shallow(
- <PromotionNotification currentUser={mockCurrentUser()} setSonarlintAd={jest.fn()} {...props} />
+ <PromotionNotification
+ currentUser={mockCurrentUser()}
+ updateCurrentUserSonarLintAdSeen={jest.fn()}
+ {...props}
+ />
);
}
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 0140d17e0b1..9e8664ef0fc 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
@@ -34,7 +34,8 @@ import { translate, translateWithParameters } from '../../../helpers/l10n';
import { scrollToElement } from '../../../helpers/scrolling';
import { getComponentOverviewUrl } from '../../../helpers/urls';
import { ComponentQualifier } from '../../../types/component';
-import { CurrentUser, Dict } from '../../../types/types';
+import { Dict } from '../../../types/types';
+import { CurrentUser } from '../../../types/users';
import RecentHistory from '../RecentHistory';
import './Search.css';
import { ComponentResult, More, Results, sortQualifiers } from './utils';
diff --git a/server/sonar-web/src/main/js/app/components/update-notification/UpdateNotification.tsx b/server/sonar-web/src/main/js/app/components/update-notification/UpdateNotification.tsx
index b399276ddf0..123260509da 100644
--- a/server/sonar-web/src/main/js/app/components/update-notification/UpdateNotification.tsx
+++ b/server/sonar-web/src/main/js/app/components/update-notification/UpdateNotification.tsx
@@ -20,18 +20,19 @@
import { groupBy, isEmpty, mapValues } from 'lodash';
import * as React from 'react';
import { getSystemUpgrades } from '../../../api/system';
-import { withCurrentUser } from '../../../components/hoc/withCurrentUser';
import { Alert, AlertVariant } from '../../../components/ui/Alert';
import DismissableAlert from '../../../components/ui/DismissableAlert';
import SystemUpgradeButton from '../../../components/upgrade/SystemUpgradeButton';
import { sortUpgrades, UpdateUseCase } from '../../../components/upgrade/utils';
import { translate } from '../../../helpers/l10n';
-import { hasGlobalPermission, isLoggedIn } from '../../../helpers/users';
+import { hasGlobalPermission } from '../../../helpers/users';
import { AppState } from '../../../types/appstate';
import { Permissions } from '../../../types/permissions';
import { SystemUpgrade } from '../../../types/system';
-import { CurrentUser, Dict } from '../../../types/types';
+import { Dict } from '../../../types/types';
+import { CurrentUser, isLoggedIn } from '../../../types/users';
import withAppStateContext from '../app-state/withAppStateContext';
+import withCurrentUserContext from '../current-user/withCurrentUserContext';
import './UpdateNotification.css';
const MONTH_BEFOR_PREVIOUS_LTS_NOTIFICATION = 6;
@@ -74,20 +75,12 @@ export class UpdateNotification extends React.PureComponent<Props, State> {
canSeeNotification: false,
useCase: UpdateUseCase.NewMinorVersion
};
- this.fetchSystemUpgradeInformation();
}
componentDidMount() {
this.mounted = true;
- }
- componentDidUpdate(prevProps: Props) {
- if (
- prevProps.currentUser !== this.props.currentUser ||
- this.props.appState.version !== prevProps.appState.version
- ) {
- this.fetchSystemUpgradeInformation();
- }
+ this.fetchSystemUpgradeInformation();
}
componentWillUnmount() {
@@ -250,4 +243,4 @@ export class UpdateNotification extends React.PureComponent<Props, State> {
}
}
-export default withCurrentUser(withAppStateContext(UpdateNotification));
+export default withCurrentUserContext(withAppStateContext(UpdateNotification));
diff --git a/server/sonar-web/src/main/js/app/components/update-notification/__tests__/UpdateNotification-test.tsx b/server/sonar-web/src/main/js/app/components/update-notification/__tests__/UpdateNotification-test.tsx
index b5d9edd0b3b..f63a4aee7f7 100644
--- a/server/sonar-web/src/main/js/app/components/update-notification/__tests__/UpdateNotification-test.tsx
+++ b/server/sonar-web/src/main/js/app/components/update-notification/__tests__/UpdateNotification-test.tsx
@@ -42,13 +42,18 @@ function formatDate(date: Date): string {
}
it('should render correctly', async () => {
- const wrapper = shallowRender({
+ let wrapper = shallowRender({
appState: mockAppState({ version: '9.0' }),
currentUser: mockLoggedInUser({ permissions: { global: [Permissions.Admin] } })
});
await waitAndUpdate(wrapper);
expect(wrapper).toMatchSnapshot('default');
- expect(wrapper.setProps({ currentUser: mockCurrentUser() })).toMatchSnapshot('anonymous user');
+
+ wrapper = shallowRender({
+ appState: mockAppState({ version: '9.0' }),
+ currentUser: mockCurrentUser()
+ });
+ expect(wrapper.type()).toBeNull();
});
it('should not show prompt when not admin', async () => {
diff --git a/server/sonar-web/src/main/js/app/components/update-notification/__tests__/__snapshots__/UpdateNotification-test.tsx.snap b/server/sonar-web/src/main/js/app/components/update-notification/__tests__/__snapshots__/UpdateNotification-test.tsx.snap
index c788a784593..a6d9f0767dd 100644
--- a/server/sonar-web/src/main/js/app/components/update-notification/__tests__/__snapshots__/UpdateNotification-test.tsx.snap
+++ b/server/sonar-web/src/main/js/app/components/update-notification/__tests__/__snapshots__/UpdateNotification-test.tsx.snap
@@ -1,7 +1,5 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
-exports[`should render correctly: anonymous user 1`] = `""`;
-
exports[`should render correctly: default 1`] = `
<DismissableAlert
alertKey="new_minor_version9.1"
diff --git a/server/sonar-web/src/main/js/app/utils/getStore.ts b/server/sonar-web/src/main/js/app/utils/getStore.ts
index 63b5701d0d1..251dd073983 100644
--- a/server/sonar-web/src/main/js/app/utils/getStore.ts
+++ b/server/sonar-web/src/main/js/app/utils/getStore.ts
@@ -19,18 +19,13 @@
*/
import { Store } from 'redux';
import rootReducer, { Store as State } from '../../store/rootReducer';
-import { receiveCurrentUser } from '../../store/users';
import configureStore from '../../store/utils/configureStore';
-import { CurrentUser } from '../../types/types';
let store: Store<State, any>;
-const createStore = (currentUser?: CurrentUser) => {
+const createStore = () => {
store = configureStore(rootReducer);
- if (currentUser) {
- store.dispatch(receiveCurrentUser(currentUser));
- }
return store;
};
-export default (currentUser?: CurrentUser) => (store ? store : createStore(currentUser));
+export default () => (store ? store : createStore());
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 6854fa5fbb7..0c8dc2ab1d5 100644
--- a/server/sonar-web/src/main/js/app/utils/startReactApp.tsx
+++ b/server/sonar-web/src/main/js/app/utils/startReactApp.tsx
@@ -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.
*/
-/* eslint-disable react/jsx-sort-props */
+
import { Location } from 'history';
import { pick } from 'lodash';
import * as React from 'react';
@@ -61,9 +61,10 @@ import withIndexationGuard from '../../components/hoc/withIndexationGuard';
import { lazyLoadComponent } from '../../components/lazyLoadComponent';
import getHistory from '../../helpers/getHistory';
import { AppState } from '../../types/appstate';
-import { CurrentUser } from '../../types/types';
+import { CurrentUser } from '../../types/users';
import App from '../components/App';
import AppStateContextProvider from '../components/app-state/AppStateContextProvider';
+import CurrentUserContextProvider from '../components/current-user/CurrentUserContextProvider';
import GlobalContainer from '../components/GlobalContainer';
import { PageContext } from '../components/indexation/PageUnavailableDueToIndexation';
import MigrationContainer from '../components/MigrationContainer';
@@ -286,100 +287,105 @@ export default function startReactApp(lang: string, appState: AppState, currentU
const el = document.getElementById('content');
const history = getHistory();
- const store = getStore(currentUser);
+ const store = getStore();
render(
<HelmetProvider>
<Provider store={store}>
<AppStateContextProvider appState={appState}>
- <IntlProvider defaultLocale={lang} locale={lang}>
- <Router history={history} onUpdate={handleUpdate}>
- {renderRedirects()}
-
- <Route
- path="formatting/help"
- component={lazyLoadComponent(() => import('../components/FormattingHelp'))}
- />
+ <CurrentUserContextProvider currentUser={currentUser}>
+ <IntlProvider defaultLocale={lang} locale={lang}>
+ <Router history={history} onUpdate={handleUpdate}>
+ {renderRedirects()}
- <Route component={lazyLoadComponent(() => import('../components/SimpleContainer'))}>
- <Route path="maintenance">{maintenanceRoutes}</Route>
- <Route path="setup">{setupRoutes}</Route>
- </Route>
-
- <Route component={MigrationContainer}>
<Route
- component={lazyLoadComponent(() =>
- import('../components/SimpleSessionsContainer')
- )}>
- <RouteWithChildRoutes path="/sessions" childRoutes={sessionsRoutes} />
+ path="formatting/help"
+ component={lazyLoadComponent(() => import('../components/FormattingHelp'))}
+ />
+
+ <Route component={lazyLoadComponent(() => import('../components/SimpleContainer'))}>
+ <Route path="maintenance">{maintenanceRoutes}</Route>
+ <Route path="setup">{setupRoutes}</Route>
</Route>
- <Route path="/" component={App}>
- <IndexRoute
- component={lazyLoadComponent(() => import('../components/Landing'))}
- />
+ <Route component={MigrationContainer}>
+ <Route
+ component={lazyLoadComponent(() =>
+ import('../components/SimpleSessionsContainer')
+ )}>
+ <RouteWithChildRoutes path="/sessions" childRoutes={sessionsRoutes} />
+ </Route>
- <Route component={GlobalContainer}>
- <RouteWithChildRoutes path="account" childRoutes={accountRoutes} />
- <RouteWithChildRoutes path="coding_rules" childRoutes={codingRulesRoutes} />
- <RouteWithChildRoutes path="documentation" childRoutes={documentationRoutes} />
+ <Route path="/" component={App}>
+ <IndexRoute
+ component={lazyLoadComponent(() => import('../components/Landing'))}
+ />
+
+ <Route component={GlobalContainer}>
+ <RouteWithChildRoutes path="account" childRoutes={accountRoutes} />
+ <RouteWithChildRoutes path="coding_rules" childRoutes={codingRulesRoutes} />
+ <RouteWithChildRoutes
+ path="documentation"
+ childRoutes={documentationRoutes}
+ />
+ <Route
+ path="extension/:pluginKey/:extensionKey"
+ component={lazyLoadComponent(() =>
+ import('../components/extensions/GlobalPageExtension')
+ )}
+ />
+ <Route
+ path="issues"
+ component={withIndexationGuard(Issues, PageContext.Issues)}
+ />
+ <RouteWithChildRoutes path="projects" childRoutes={projectsRoutes} />
+ <RouteWithChildRoutes path="quality_gates" childRoutes={qualityGatesRoutes} />
+ <Route
+ path="portfolios"
+ component={lazyLoadComponent(() =>
+ import('../components/extensions/PortfoliosPage')
+ )}
+ />
+ <RouteWithChildRoutes path="profiles" childRoutes={qualityProfilesRoutes} />
+ <RouteWithChildRoutes path="web_api" childRoutes={webAPIRoutes} />
+
+ {renderComponentRoutes()}
+
+ {renderAdminRoutes()}
+ </Route>
+ <Route
+ // We don't want this route to have any menu.
+ // That is why we can not have it under the accountRoutes
+ path="account/reset_password"
+ component={lazyLoadComponent(() => import('../components/ResetPassword'))}
+ />
<Route
- path="extension/:pluginKey/:extensionKey"
+ // We don't want this route to have any menu. This is why we define it here
+ // rather than under the admin routes.
+ path="admin/change_admin_password"
component={lazyLoadComponent(() =>
- import('../components/extensions/GlobalPageExtension')
+ import('../../apps/change-admin-password/ChangeAdminPasswordApp')
)}
/>
<Route
- path="issues"
- component={withIndexationGuard(Issues, PageContext.Issues)}
+ // We don't want this route to have any menu. This is why we define it here
+ // rather than under the admin routes.
+ path="admin/plugin_risk_consent"
+ component={lazyLoadComponent(() => import('../components/PluginRiskConsent'))}
/>
- <RouteWithChildRoutes path="projects" childRoutes={projectsRoutes} />
- <RouteWithChildRoutes path="quality_gates" childRoutes={qualityGatesRoutes} />
<Route
- path="portfolios"
- component={lazyLoadComponent(() =>
- import('../components/extensions/PortfoliosPage')
- )}
+ path="not_found"
+ component={lazyLoadComponent(() => import('../components/NotFound'))}
+ />
+ <Route
+ path="*"
+ component={lazyLoadComponent(() => import('../components/NotFound'))}
/>
- <RouteWithChildRoutes path="profiles" childRoutes={qualityProfilesRoutes} />
- <RouteWithChildRoutes path="web_api" childRoutes={webAPIRoutes} />
-
- {renderComponentRoutes()}
-
- {renderAdminRoutes()}
</Route>
- <Route
- // We don't want this route to have any menu.
- // That is why we can not have it under the accountRoutes
- path="account/reset_password"
- component={lazyLoadComponent(() => import('../components/ResetPassword'))}
- />
- <Route
- // We don't want this route to have any menu. This is why we define it here
- // rather than under the admin routes.
- path="admin/change_admin_password"
- component={lazyLoadComponent(() =>
- import('../../apps/change-admin-password/ChangeAdminPasswordApp')
- )}
- />
- <Route
- // We don't want this route to have any menu. This is why we define it here
- // rather than under the admin routes.
- path="admin/plugin_risk_consent"
- component={lazyLoadComponent(() => import('../components/PluginRiskConsent'))}
- />
- <Route
- path="not_found"
- component={lazyLoadComponent(() => import('../components/NotFound'))}
- />
- <Route
- path="*"
- component={lazyLoadComponent(() => import('../components/NotFound'))}
- />
</Route>
- </Route>
- </Router>
- </IntlProvider>
+ </Router>
+ </IntlProvider>
+ </CurrentUserContextProvider>
</AppStateContextProvider>
</Provider>
</HelmetProvider>,