import RecentHistory from '../../RecentHistory';
import './ComponentNav.css';
import ComponentNavBgTaskNotif from './ComponentNavBgTaskNotif';
-import ComponentNavHeader from './ComponentNavHeader';
import ComponentNavMenu from './ComponentNavMenu';
import ComponentNavMeta from './ComponentNavMeta';
+import Header from './Header';
interface Props {
branchLikes: BranchLike[];
id="context-navigation"
notif={notifComponent}>
<div className="navbar-context-justified">
- <ComponentNavHeader
+ <Header
branchLikes={this.props.branchLikes}
component={component}
currentBranchLike={currentBranchLike}
+++ /dev/null
-/*
- * 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 { Helmet } from 'react-helmet-async';
-import { BranchLike } from '../../../../types/branch-like';
-import BranchLikeNavigation from './branch-like/BranchLikeNavigation';
-import CurrentBranchLikeMergeInformation from './branch-like/CurrentBranchLikeMergeInformation';
-import { ComponentBreadcrumb } from './ComponentBreadcrumb';
-
-export interface ComponentNavHeaderProps {
- branchLikes: BranchLike[];
- component: T.Component;
- currentBranchLike: BranchLike | undefined;
-}
-
-export function ComponentNavHeader(props: ComponentNavHeaderProps) {
- const { branchLikes, component, currentBranchLike } = props;
-
- return (
- <>
- <Helmet title={component.name} />
- <header className="display-flex-center flex-shrink">
- <ComponentBreadcrumb component={component} currentBranchLike={currentBranchLike} />
- {currentBranchLike && (
- <>
- <BranchLikeNavigation
- branchLikes={branchLikes}
- component={component}
- currentBranchLike={currentBranchLike}
- />
- <CurrentBranchLikeMergeInformation currentBranchLike={currentBranchLike} />
- </>
- )}
- </header>
- </>
- );
-}
-
-export default React.memo(ComponentNavHeader);
import DetachIcon from 'sonar-ui-common/components/icons/DetachIcon';
import { translate } from 'sonar-ui-common/helpers/l10n';
import BranchStatus from '../../../../components/common/BranchStatus';
-import Favorite from '../../../../components/controls/Favorite';
import HomePageSelect from '../../../../components/controls/HomePageSelect';
import DateTimeFormatter from '../../../../components/intl/DateTimeFormatter';
import { isBranch, isMainBranch, isPullRequest } from '../../../../helpers/branch-like';
)}
{isLoggedIn(currentUser) && (
<div className="navbar-context-meta-secondary">
- {mainBranch && (
- <Favorite
- component={component.key}
- favorite={Boolean(component.isFavorite)}
- qualifier={component.qualifier}
- />
- )}
- {isABranch && currentPage !== undefined && (
+ {mainBranch && currentPage !== undefined && (
<HomePageSelect className="spacer-left" currentPage={currentPage} />
)}
</div>
--- /dev/null
+/*
+ * 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 { 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 { BranchLike } from '../../../../types/branch-like';
+import BranchLikeNavigation from './branch-like/BranchLikeNavigation';
+import CurrentBranchLikeMergeInformation from './branch-like/CurrentBranchLikeMergeInformation';
+import { ComponentBreadcrumb } from './ComponentBreadcrumb';
+
+export interface HeaderProps {
+ branchLikes: BranchLike[];
+ component: T.Component;
+ currentBranchLike: BranchLike | undefined;
+ currentUser: T.CurrentUser;
+}
+
+export function Header(props: HeaderProps) {
+ const { branchLikes, component, currentBranchLike, currentUser } = props;
+
+ return (
+ <>
+ <Helmet title={component.name} />
+ <header className="display-flex-center flex-shrink">
+ <ComponentBreadcrumb component={component} currentBranchLike={currentBranchLike} />
+ {isLoggedIn(currentUser) && (
+ <Favorite
+ className="spacer-left"
+ component={component.key}
+ favorite={Boolean(component.isFavorite)}
+ qualifier={component.qualifier}
+ />
+ )}
+ {currentBranchLike && (
+ <>
+ <BranchLikeNavigation
+ branchLikes={branchLikes}
+ component={component}
+ currentBranchLike={currentBranchLike}
+ />
+ <CurrentBranchLikeMergeInformation currentBranchLike={currentBranchLike} />
+ </>
+ )}
+ </header>
+ </>
+ );
+}
+
+const mapStateToProps = (state: Store) => ({
+ currentUser: getCurrentUser(state)
+});
+
+export default connect(mapStateToProps)(React.memo(Header));
+++ /dev/null
-/*
- * 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 { mockSetOfBranchAndPullRequest } from '../../../../../helpers/mocks/branch-like';
-import { mockComponent } from '../../../../../helpers/testMocks';
-import { ComponentNavHeader, ComponentNavHeaderProps } from '../ComponentNavHeader';
-
-it('should render correctly', () => {
- const wrapper = shallowRender();
- expect(wrapper).toMatchSnapshot();
-});
-
-function shallowRender(props?: Partial<ComponentNavHeaderProps>) {
- const branchLikes = mockSetOfBranchAndPullRequest();
-
- return shallow(
- <ComponentNavHeader
- branchLikes={branchLikes}
- component={mockComponent()}
- currentBranchLike={branchLikes[0]}
- {...props}
- />
- );
-}
--- /dev/null
+/*
+ * 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 Favorite from '../../../../../components/controls/Favorite';
+import { mockSetOfBranchAndPullRequest } from '../../../../../helpers/mocks/branch-like';
+import { mockComponent, mockCurrentUser } from '../../../../../helpers/testMocks';
+import { Header, HeaderProps } from '../Header';
+
+it('should render correctly', () => {
+ const wrapper = shallowRender({ currentUser: mockCurrentUser({ isLoggedIn: true }) });
+ expect(wrapper).toMatchSnapshot();
+});
+
+it('should not render favorite button if the user is not logged in', () => {
+ const wrapper = shallowRender();
+ expect(wrapper.find(Favorite).exists()).toBeFalsy();
+});
+
+function shallowRender(props?: Partial<HeaderProps>) {
+ const branchLikes = mockSetOfBranchAndPullRequest();
+
+ return shallow(
+ <Header
+ branchLikes={branchLikes}
+ component={mockComponent()}
+ currentBranchLike={branchLikes[0]}
+ currentUser={mockCurrentUser()}
+ {...props}
+ />
+ );
+}
<div
className="navbar-context-justified"
>
- <Memo(ComponentNavHeader)
+ <Connect(Component)
branchLikes={Array []}
component={
Object {
+++ /dev/null
-// Jest Snapshot v1, https://goo.gl/fbAQLP
-
-exports[`should render correctly 1`] = `
-<Fragment>
- <Helmet
- defer={true}
- encodeSpecialCharacters={true}
- title="MyProject"
- />
- <header
- className="display-flex-center flex-shrink"
- >
- <ComponentBreadcrumb
- component={
- Object {
- "breadcrumbs": Array [],
- "key": "my-project",
- "name": "MyProject",
- "organization": "foo",
- "qualifier": "TRK",
- "qualityGate": Object {
- "isDefault": true,
- "key": "30",
- "name": "Sonar way",
- },
- "qualityProfiles": Array [
- Object {
- "deleted": false,
- "key": "my-qp",
- "language": "ts",
- "name": "Sonar way",
- },
- ],
- "tags": Array [],
- }
- }
- currentBranchLike={
- Object {
- "analysisDate": "2018-01-01",
- "excludedFromPurge": true,
- "isMain": false,
- "name": "branch-11",
- }
- }
- />
- <Connect(withAppState(Component))
- branchLikes={
- Array [
- Object {
- "analysisDate": "2018-01-01",
- "excludedFromPurge": true,
- "isMain": false,
- "name": "branch-11",
- },
- Object {
- "analysisDate": "2018-01-01",
- "excludedFromPurge": true,
- "isMain": false,
- "name": "branch-1",
- },
- Object {
- "analysisDate": "2018-01-01",
- "excludedFromPurge": true,
- "isMain": true,
- "name": "master",
- },
- Object {
- "analysisDate": "2018-01-01",
- "base": "master",
- "branch": "feature/foo/bar",
- "key": "1",
- "target": "master",
- "title": "PR-1",
- },
- Object {
- "analysisDate": "2018-01-01",
- "excludedFromPurge": true,
- "isMain": false,
- "name": "branch-12",
- },
- Object {
- "analysisDate": "2018-01-01",
- "base": "master",
- "branch": "feature/foo/bar",
- "key": "2",
- "target": "master",
- "title": "PR-2",
- },
- Object {
- "analysisDate": "2018-01-01",
- "excludedFromPurge": true,
- "isMain": false,
- "name": "branch-3",
- },
- Object {
- "analysisDate": "2018-01-01",
- "excludedFromPurge": true,
- "isMain": false,
- "name": "branch-2",
- },
- Object {
- "analysisDate": "2018-01-01",
- "base": "master",
- "branch": "feature/foo/bar",
- "isOrphan": true,
- "key": "2",
- "target": "llb-100",
- "title": "PR-2",
- },
- ]
- }
- component={
- Object {
- "breadcrumbs": Array [],
- "key": "my-project",
- "name": "MyProject",
- "organization": "foo",
- "qualifier": "TRK",
- "qualityGate": Object {
- "isDefault": true,
- "key": "30",
- "name": "Sonar way",
- },
- "qualityProfiles": Array [
- Object {
- "deleted": false,
- "key": "my-qp",
- "language": "ts",
- "name": "Sonar way",
- },
- ],
- "tags": Array [],
- }
- }
- currentBranchLike={
- Object {
- "analysisDate": "2018-01-01",
- "excludedFromPurge": true,
- "isMain": false,
- "name": "branch-11",
- }
- }
- />
- <Memo(CurrentBranchLikeMergeInformation)
- currentBranchLike={
- Object {
- "analysisDate": "2018-01-01",
- "excludedFromPurge": true,
- "isMain": false,
- "name": "branch-11",
- }
- }
- />
- </header>
-</Fragment>
-`;
--- /dev/null
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`should render correctly 1`] = `
+<Fragment>
+ <Helmet
+ defer={true}
+ encodeSpecialCharacters={true}
+ title="MyProject"
+ />
+ <header
+ className="display-flex-center flex-shrink"
+ >
+ <ComponentBreadcrumb
+ component={
+ Object {
+ "breadcrumbs": Array [],
+ "key": "my-project",
+ "name": "MyProject",
+ "organization": "foo",
+ "qualifier": "TRK",
+ "qualityGate": Object {
+ "isDefault": true,
+ "key": "30",
+ "name": "Sonar way",
+ },
+ "qualityProfiles": Array [
+ Object {
+ "deleted": false,
+ "key": "my-qp",
+ "language": "ts",
+ "name": "Sonar way",
+ },
+ ],
+ "tags": Array [],
+ }
+ }
+ currentBranchLike={
+ Object {
+ "analysisDate": "2018-01-01",
+ "excludedFromPurge": true,
+ "isMain": false,
+ "name": "branch-11",
+ }
+ }
+ />
+ <Favorite
+ className="spacer-left"
+ component="my-project"
+ favorite={false}
+ qualifier="TRK"
+ />
+ <Connect(withAppState(Component))
+ branchLikes={
+ Array [
+ Object {
+ "analysisDate": "2018-01-01",
+ "excludedFromPurge": true,
+ "isMain": false,
+ "name": "branch-11",
+ },
+ Object {
+ "analysisDate": "2018-01-01",
+ "excludedFromPurge": true,
+ "isMain": false,
+ "name": "branch-1",
+ },
+ Object {
+ "analysisDate": "2018-01-01",
+ "excludedFromPurge": true,
+ "isMain": true,
+ "name": "master",
+ },
+ Object {
+ "analysisDate": "2018-01-01",
+ "base": "master",
+ "branch": "feature/foo/bar",
+ "key": "1",
+ "target": "master",
+ "title": "PR-1",
+ },
+ Object {
+ "analysisDate": "2018-01-01",
+ "excludedFromPurge": true,
+ "isMain": false,
+ "name": "branch-12",
+ },
+ Object {
+ "analysisDate": "2018-01-01",
+ "base": "master",
+ "branch": "feature/foo/bar",
+ "key": "2",
+ "target": "master",
+ "title": "PR-2",
+ },
+ Object {
+ "analysisDate": "2018-01-01",
+ "excludedFromPurge": true,
+ "isMain": false,
+ "name": "branch-3",
+ },
+ Object {
+ "analysisDate": "2018-01-01",
+ "excludedFromPurge": true,
+ "isMain": false,
+ "name": "branch-2",
+ },
+ Object {
+ "analysisDate": "2018-01-01",
+ "base": "master",
+ "branch": "feature/foo/bar",
+ "isOrphan": true,
+ "key": "2",
+ "target": "llb-100",
+ "title": "PR-2",
+ },
+ ]
+ }
+ component={
+ Object {
+ "breadcrumbs": Array [],
+ "key": "my-project",
+ "name": "MyProject",
+ "organization": "foo",
+ "qualifier": "TRK",
+ "qualityGate": Object {
+ "isDefault": true,
+ "key": "30",
+ "name": "Sonar way",
+ },
+ "qualityProfiles": Array [
+ Object {
+ "deleted": false,
+ "key": "my-qp",
+ "language": "ts",
+ "name": "Sonar way",
+ },
+ ],
+ "tags": Array [],
+ }
+ }
+ currentBranchLike={
+ Object {
+ "analysisDate": "2018-01-01",
+ "excludedFromPurge": true,
+ "isMain": false,
+ "name": "branch-11",
+ }
+ }
+ />
+ <Memo(CurrentBranchLikeMergeInformation)
+ currentBranchLike={
+ Object {
+ "analysisDate": "2018-01-01",
+ "excludedFromPurge": true,
+ "isMain": false,
+ "name": "branch-11",
+ }
+ }
+ />
+ </header>
+</Fragment>
+`;