diff options
author | Wouter Admiraal <wouter.admiraal@sonarsource.com> | 2020-04-20 10:52:46 +0200 |
---|---|---|
committer | sonartech <sonartech@sonarsource.com> | 2020-05-04 20:03:53 +0000 |
commit | f2007c36e01307d34599181e4387d74834257edf (patch) | |
tree | b736c8a1739d0c419197fcdc1bfe5f1dc4556ad6 | |
parent | a39da3564be402a41ba7957d9755646a6172cba6 (diff) | |
download | sonarqube-f2007c36e01307d34599181e4387d74834257edf.tar.gz sonarqube-f2007c36e01307d34599181e4387d74834257edf.zip |
Drop SonarCloud onboarding logic
33 files changed, 150 insertions, 870 deletions
diff --git a/server/sonar-docs/src/tooltips/project/visibility-private.md b/server/sonar-docs/src/tooltips/project/visibility-private.md deleted file mode 100644 index 3b72630b6bd..00000000000 --- a/server/sonar-docs/src/tooltips/project/visibility-private.md +++ /dev/null @@ -1,5 +0,0 @@ -This project is private. Only the members of this organization are able to browse it and its source code. - ---- - -See also: [Organization Visibility](/organizations/organization-visibility/) diff --git a/server/sonar-docs/src/tooltips/project/visibility-public-admin.md b/server/sonar-docs/src/tooltips/project/visibility-public-admin.md deleted file mode 100644 index d2811f6da3d..00000000000 --- a/server/sonar-docs/src/tooltips/project/visibility-public-admin.md +++ /dev/null @@ -1,5 +0,0 @@ -This project is public, which means anyone is able to browse its source code. Subscribe to a paid plan to get unlimited private projects in [Administration > Billing](/#sonarcloud#/organizations/#organization#/extension/billing/billing). - ---- - -See also: [Pricing](/sonarcloud-pricing/) diff --git a/server/sonar-docs/src/tooltips/project/visibility-public-paid-org-admin.md b/server/sonar-docs/src/tooltips/project/visibility-public-paid-org-admin.md deleted file mode 100644 index d824b273d50..00000000000 --- a/server/sonar-docs/src/tooltips/project/visibility-public-paid-org-admin.md +++ /dev/null @@ -1,5 +0,0 @@ -This project is public, which means anyone is able to browse its source code. Go to your project's [Administration > Permissions](/#sonarcloud#/project_roles?id=#projectKey#) to make it private. - ---- - -See also: [Organization Visibility](/organizations/organization-visibility/) diff --git a/server/sonar-docs/src/tooltips/project/visibility-public-paid-org.md b/server/sonar-docs/src/tooltips/project/visibility-public-paid-org.md deleted file mode 100644 index bf7bb43aab1..00000000000 --- a/server/sonar-docs/src/tooltips/project/visibility-public-paid-org.md +++ /dev/null @@ -1,5 +0,0 @@ -This project is public, which means anyone is able to browse its source code. Contact the project administrator to make it private. - ---- - -See also: [Organization Visibility](/organizations/organization-visibility/) diff --git a/server/sonar-docs/src/tooltips/project/visibility-public.md b/server/sonar-docs/src/tooltips/project/visibility-public.md deleted file mode 100644 index 83218708607..00000000000 --- a/server/sonar-docs/src/tooltips/project/visibility-public.md +++ /dev/null @@ -1,5 +0,0 @@ -This project is public, which means anyone is able to browse its source code. Contact the organization administrator if you want to make it private. - ---- - -See also: [Pricing](/sonarcloud-pricing/) diff --git a/server/sonar-web/src/main/js/app/components/OnboardingContext.tsx b/server/sonar-web/src/main/js/app/components/OnboardingContext.tsx deleted file mode 100644 index 6d3814ef437..00000000000 --- a/server/sonar-web/src/main/js/app/components/OnboardingContext.tsx +++ /dev/null @@ -1,24 +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 { createContext } from 'react'; - -export type OnboardingContextShape = (organization?: T.Organization) => void; - -export const OnboardingContext = createContext<OnboardingContextShape>(() => {}); diff --git a/server/sonar-web/src/main/js/app/components/nav/component/projectInformation/ProjectInformationRenderer.tsx b/server/sonar-web/src/main/js/app/components/nav/component/projectInformation/ProjectInformationRenderer.tsx index 25bab1a9d05..df0c03d8a15 100644 --- a/server/sonar-web/src/main/js/app/components/nav/component/projectInformation/ProjectInformationRenderer.tsx +++ b/server/sonar-web/src/main/js/app/components/nav/component/projectInformation/ProjectInformationRenderer.tsx @@ -58,9 +58,7 @@ export function ProjectInformationRenderer(props: ProjectInformationRendererProp <h3 className="spacer-right">{translate('project.info.description')}</h3> {component.visibility && ( <PrivacyBadgeContainer - organization={undefined} qualifier={component.qualifier} - tooltipProps={{ projectKey: component.key }} visibility={component.visibility} /> )} diff --git a/server/sonar-web/src/main/js/app/components/nav/component/projectInformation/__tests__/__snapshots__/ProjectInformationRenderer-test.tsx.snap b/server/sonar-web/src/main/js/app/components/nav/component/projectInformation/__tests__/__snapshots__/ProjectInformationRenderer-test.tsx.snap index 8819cf6af17..2531e3c9133 100644 --- a/server/sonar-web/src/main/js/app/components/nav/component/projectInformation/__tests__/__snapshots__/ProjectInformationRenderer-test.tsx.snap +++ b/server/sonar-web/src/main/js/app/components/nav/component/projectInformation/__tests__/__snapshots__/ProjectInformationRenderer-test.tsx.snap @@ -118,13 +118,8 @@ exports[`should render a private project correctly 1`] = ` > project.info.description </h3> - <Connect(PrivacyBadge) + <PrivacyBadgeContainer qualifier="TRK" - tooltipProps={ - Object { - "projectKey": "my-project", - } - } visibility="private" /> </div> @@ -387,13 +382,8 @@ exports[`should render correctly: default 1`] = ` > project.info.description </h3> - <Connect(PrivacyBadge) + <PrivacyBadgeContainer qualifier="TRK" - tooltipProps={ - Object { - "projectKey": "my-project", - } - } visibility="public" /> </div> @@ -553,13 +543,8 @@ exports[`should render correctly: no badges 1`] = ` > project.info.description </h3> - <Connect(PrivacyBadge) + <PrivacyBadgeContainer qualifier="TRK" - tooltipProps={ - Object { - "projectKey": "my-project", - } - } visibility="public" /> </div> @@ -714,13 +699,8 @@ exports[`should render correctly: no badges, no notifications 1`] = ` > project.info.description </h3> - <Connect(PrivacyBadge) + <PrivacyBadgeContainer qualifier="TRK" - tooltipProps={ - Object { - "projectKey": "my-project", - } - } visibility="public" /> </div> @@ -870,13 +850,8 @@ exports[`should render correctly: with notifications 1`] = ` > project.info.description </h3> - <Connect(PrivacyBadge) + <PrivacyBadgeContainer qualifier="TRK" - tooltipProps={ - Object { - "projectKey": "my-project", - } - } visibility="public" /> </div> 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 27c84ab5f8a..78e44e4536c 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 @@ -39,7 +39,6 @@ import { import { setCurrentUserSetting } from '../../../../store/users'; import { rawSizes } from '../../../theme'; import EmbedDocsPopupHelper from '../../embed-docs-modal/EmbedDocsPopupHelper'; -import { OnboardingContext } from '../../OnboardingContext'; import Search from '../../search/Search'; import './GlobalNav.css'; import GlobalNavBranding, { SonarCloudNavBranding } from './GlobalNavBranding'; @@ -193,15 +192,7 @@ export class GlobalNav extends React.PureComponent<Props, State> { <EmbedDocsPopupHelper /> <Search appState={appState} currentUser={currentUser} /> {isLoggedIn(currentUser) && ( - <OnboardingContext.Consumer data-test="global-nav-plus"> - {openProjectOnboarding => ( - <GlobalNavPlus - appState={appState} - currentUser={currentUser} - openProjectOnboarding={openProjectOnboarding} - /> - )} - </OnboardingContext.Consumer> + <GlobalNavPlus appState={appState} currentUser={currentUser} /> )} <GlobalNavUserContainer appState={appState} currentUser={currentUser} /> </ul> 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 fc2bb9107ee..2d3f41d9629 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 @@ -28,12 +28,10 @@ import { getExtensionStart } from '../../../../helpers/extensions'; import { isSonarCloud } from '../../../../helpers/system'; import { getPortfolioAdminUrl, getPortfolioUrl } from '../../../../helpers/urls'; import { hasGlobalPermission } from '../../../../helpers/users'; -import { OnboardingContextShape } from '../../OnboardingContext'; interface Props { appState: Pick<T.AppState, 'qualifiers'>; currentUser: T.LoggedInUser; - openProjectOnboarding: OnboardingContextShape; } interface State { @@ -65,7 +63,7 @@ export class GlobalNavPlus extends React.PureComponent<Props & WithRouterProps, handleNewProjectClick = (event: React.MouseEvent<HTMLAnchorElement>) => { event.preventDefault(); - this.props.openProjectOnboarding(); + this.props.router.push('/projects/create'); }; openCreatePortfolioForm = () => { diff --git a/server/sonar-web/src/main/js/app/components/nav/global/__tests__/GlobalNav-test.tsx b/server/sonar-web/src/main/js/app/components/nav/global/__tests__/GlobalNav-test.tsx index 187481a36ac..fe1f064d71d 100644 --- a/server/sonar-web/src/main/js/app/components/nav/global/__tests__/GlobalNav-test.tsx +++ b/server/sonar-web/src/main/js/app/components/nav/global/__tests__/GlobalNav-test.tsx @@ -81,25 +81,16 @@ beforeEach(() => { (fetchPrismicFeatureNews as jest.Mock).mockClear(); }); -it('should render for SonarQube', async () => { +it('should render correctly', async () => { (isSonarCloud as jest.Mock).mockImplementation(() => false); const wrapper = shallowRender(); - expect(wrapper).toMatchSnapshot(); + expect(wrapper).toMatchSnapshot('anonymous users'); wrapper.setProps({ currentUser: { isLoggedIn: true } }); - expect(wrapper.find('[data-test="global-nav-plus"]').exists()).toBe(true); + expect(wrapper).toMatchSnapshot('logged in users'); await waitAndUpdate(wrapper); - expect(fetchPrismicRefs).not.toBeCalled(); -}); - -it('should render for SonarCloud', () => { - (isSonarCloud as jest.Mock).mockImplementation(() => true); - const wrapper = shallowRender({ currentUser: { isLoggedIn: true } }); - - expect(wrapper).toMatchSnapshot(); - expect(wrapper.find('[data-test="global-nav-plus"]').exists()).toBe(true); }); it('should render correctly if there are new features', async () => { diff --git a/server/sonar-web/src/main/js/app/components/nav/global/__tests__/GlobalNavPlus-test.tsx b/server/sonar-web/src/main/js/app/components/nav/global/__tests__/GlobalNavPlus-test.tsx index daf44b13f15..4914ea8d02a 100644 --- a/server/sonar-web/src/main/js/app/components/nav/global/__tests__/GlobalNavPlus-test.tsx +++ b/server/sonar-web/src/main/js/app/components/nav/global/__tests__/GlobalNavPlus-test.tsx @@ -38,10 +38,10 @@ it('render', () => { }); it('opens onboarding', () => { - const openProjectOnboarding = jest.fn(); - const wrapper = getOverlayWrapper(getWrapper({ openProjectOnboarding })); + const push = jest.fn(); + const wrapper = getOverlayWrapper(getWrapper({ router: mockRouter({ push }) })); click(wrapper.find('.js-new-project')); - expect(openProjectOnboarding).toBeCalled(); + expect(push).toBeCalled(); }); it('should display create new project link when user has permission only', () => { @@ -81,7 +81,6 @@ function getWrapper(props = {}, globalPermissions?: string[]) { permissions: { global: globalPermissions || ['provisioning'] } } as T.LoggedInUser } - openProjectOnboarding={jest.fn()} router={mockRouter()} {...props} /> diff --git a/server/sonar-web/src/main/js/app/components/nav/global/__tests__/__snapshots__/GlobalNav-test.tsx.snap b/server/sonar-web/src/main/js/app/components/nav/global/__tests__/__snapshots__/GlobalNav-test.tsx.snap index c6743186aa0..502966742f5 100644 --- a/server/sonar-web/src/main/js/app/components/nav/global/__tests__/__snapshots__/GlobalNav-test.tsx.snap +++ b/server/sonar-web/src/main/js/app/components/nav/global/__tests__/__snapshots__/GlobalNav-test.tsx.snap @@ -76,11 +76,21 @@ exports[`should render correctly if there are new features 1`] = ` } } /> - <ContextConsumer - data-test="global-nav-plus" - > - <Component /> - </ContextConsumer> + <GlobalNavPlus + appState={ + Object { + "canAdmin": false, + "globalPages": Array [], + "organizationsEnabled": false, + "qualifiers": Array [], + } + } + currentUser={ + Object { + "isLoggedIn": true, + } + } + /> <Connect(withRouter(GlobalNavUser)) appState={ Object { @@ -100,13 +110,13 @@ exports[`should render correctly if there are new features 1`] = ` </NavBar> `; -exports[`should render for SonarCloud 1`] = ` +exports[`should render correctly: anonymous users 1`] = ` <NavBar className="navbar-global" height={48} id="global-navigation" > - <SonarCloudNavBranding /> + <Connect(GlobalNavBranding) /> <GlobalNavMenu accessToken="token" appState={ @@ -119,7 +129,7 @@ exports[`should render for SonarCloud 1`] = ` } currentUser={ Object { - "isLoggedIn": true, + "isLoggedIn": false, } } location={ @@ -132,13 +142,6 @@ exports[`should render for SonarCloud 1`] = ` <ul className="global-navbar-menu global-navbar-menu-right" > - <GlobalNavExplore - location={ - Object { - "pathname": "", - } - } - /> <EmbedDocsPopupHelper /> <withRouter(Search) appState={ @@ -151,15 +154,10 @@ exports[`should render for SonarCloud 1`] = ` } currentUser={ Object { - "isLoggedIn": true, + "isLoggedIn": false, } } /> - <ContextConsumer - data-test="global-nav-plus" - > - <Component /> - </ContextConsumer> <Connect(withRouter(GlobalNavUser)) appState={ Object { @@ -171,7 +169,7 @@ exports[`should render for SonarCloud 1`] = ` } currentUser={ Object { - "isLoggedIn": true, + "isLoggedIn": false, } } /> @@ -179,7 +177,7 @@ exports[`should render for SonarCloud 1`] = ` </NavBar> `; -exports[`should render for SonarQube 1`] = ` +exports[`should render correctly: logged in users 1`] = ` <NavBar className="navbar-global" height={48} @@ -198,7 +196,7 @@ exports[`should render for SonarQube 1`] = ` } currentUser={ Object { - "isLoggedIn": false, + "isLoggedIn": true, } } location={ @@ -223,7 +221,22 @@ exports[`should render for SonarQube 1`] = ` } currentUser={ Object { - "isLoggedIn": false, + "isLoggedIn": true, + } + } + /> + <GlobalNavPlus + appState={ + Object { + "canAdmin": false, + "globalPages": Array [], + "organizationsEnabled": false, + "qualifiers": Array [], + } + } + currentUser={ + Object { + "isLoggedIn": true, } } /> @@ -238,7 +251,7 @@ exports[`should render for SonarQube 1`] = ` } currentUser={ Object { - "isLoggedIn": false, + "isLoggedIn": true, } } /> diff --git a/server/sonar-web/src/main/js/apps/organizations/components/OrganizationEmpty.tsx b/server/sonar-web/src/main/js/apps/organizations/components/OrganizationEmpty.tsx index dc5b6718064..1b7d6cc8994 100644 --- a/server/sonar-web/src/main/js/apps/organizations/components/OrganizationEmpty.tsx +++ b/server/sonar-web/src/main/js/apps/organizations/components/OrganizationEmpty.tsx @@ -20,24 +20,17 @@ import * as React from 'react'; import { Button } from 'sonar-ui-common/components/controls/buttons'; import OnboardingAddMembersIcon from 'sonar-ui-common/components/icons/OnboardingAddMembersIcon'; -import OnboardingProjectIcon from 'sonar-ui-common/components/icons/OnboardingProjectIcon'; import { translate } from 'sonar-ui-common/helpers/l10n'; -import { OnboardingContextShape } from '../../../app/components/OnboardingContext'; import { Router, withRouter } from '../../../components/hoc/withRouter'; import '../../tutorials/styles.css'; import './OrganizationEmpty.css'; interface Props { - openProjectOnboarding: OnboardingContextShape; organization: T.Organization; router: Pick<Router, 'push'>; } export class OrganizationEmpty extends React.PureComponent<Props> { - handleNewProjectClick = () => { - this.props.openProjectOnboarding(this.props.organization); - }; - handleAddMembersClick = () => { const { organization } = this.props; this.props.router.push(`/organizations/${organization.key}/members`); @@ -51,10 +44,6 @@ export class OrganizationEmpty extends React.PureComponent<Props> { <div className="organization-empty"> <h3 className="text-center">{translate('onboarding.create_organization.ready')}</h3> <div className="display-flex-space-around huge-spacer-top"> - <Button className="button-huge" onClick={this.handleNewProjectClick}> - <OnboardingProjectIcon className="big-spacer-bottom" /> - <p className="medium spacer-top">{translate('provisioning.analyze_new_project')}</p> - </Button> {!memberSyncActivated && ( <Button className="button-huge" onClick={this.handleAddMembersClick}> <OnboardingAddMembersIcon /> diff --git a/server/sonar-web/src/main/js/apps/organizations/components/__tests__/OrganizationEmpty-test.tsx b/server/sonar-web/src/main/js/apps/organizations/components/__tests__/OrganizationEmpty-test.tsx index 4b17d0725e1..37757840977 100644 --- a/server/sonar-web/src/main/js/apps/organizations/components/__tests__/OrganizationEmpty-test.tsx +++ b/server/sonar-web/src/main/js/apps/organizations/components/__tests__/OrganizationEmpty-test.tsx @@ -33,14 +33,6 @@ it('should render', () => { expect(shallowRender()).toMatchSnapshot(); }); -it('should create new project', () => { - const openProjectOnboarding = jest.fn(); - const wrapper = shallowRender({ openProjectOnboarding }); - - click(wrapper.find('Button').first()); - expect(openProjectOnboarding).toBeCalledWith({ key: 'foo', name: 'Foo' }); -}); - it('should add members', () => { const push = jest.fn(); const wrapper = shallowRender({ router: mockRouter({ push }) }); @@ -56,11 +48,6 @@ it('should hide add members button when member sync activated', () => { function shallowRender(props: Partial<OrganizationEmpty['props']> = {}) { return shallow( - <OrganizationEmpty - openProjectOnboarding={jest.fn()} - organization={organization} - router={mockRouter()} - {...props} - /> + <OrganizationEmpty organization={organization} router={mockRouter()} {...props} /> ); } diff --git a/server/sonar-web/src/main/js/apps/organizations/components/__tests__/__snapshots__/OrganizationEmpty-test.tsx.snap b/server/sonar-web/src/main/js/apps/organizations/components/__tests__/__snapshots__/OrganizationEmpty-test.tsx.snap index 82a33f255a1..446b6447e13 100644 --- a/server/sonar-web/src/main/js/apps/organizations/components/__tests__/__snapshots__/OrganizationEmpty-test.tsx.snap +++ b/server/sonar-web/src/main/js/apps/organizations/components/__tests__/__snapshots__/OrganizationEmpty-test.tsx.snap @@ -11,21 +11,7 @@ exports[`should hide add members button when member sync activated 1`] = ` </h3> <div className="display-flex-space-around huge-spacer-top" - > - <Button - className="button-huge" - onClick={[Function]} - > - <OnboardingProjectIcon - className="big-spacer-bottom" - /> - <p - className="medium spacer-top" - > - provisioning.analyze_new_project - </p> - </Button> - </div> + /> </div> `; @@ -45,19 +31,6 @@ exports[`should render 1`] = ` className="button-huge" onClick={[Function]} > - <OnboardingProjectIcon - className="big-spacer-bottom" - /> - <p - className="medium spacer-top" - > - provisioning.analyze_new_project - </p> - </Button> - <Button - className="button-huge" - onClick={[Function]} - > <OnboardingAddMembersIcon /> <p className="medium spacer-top" diff --git a/server/sonar-web/src/main/js/apps/projects/components/AllProjects.tsx b/server/sonar-web/src/main/js/apps/projects/components/AllProjects.tsx index 89e22be3c20..b8702d7f68a 100644 --- a/server/sonar-web/src/main/js/apps/projects/components/AllProjects.tsx +++ b/server/sonar-web/src/main/js/apps/projects/components/AllProjects.tsx @@ -307,7 +307,6 @@ export class AllProjects extends React.PureComponent<Props, State> { handleFavorite={this.handleFavorite} isFavorite={this.props.isFavorite} isFiltered={hasFilterParams(this.state.query)} - organization={this.props.organization} projects={this.state.projects} query={this.state.query} /> diff --git a/server/sonar-web/src/main/js/apps/projects/components/EmptyInstance.tsx b/server/sonar-web/src/main/js/apps/projects/components/EmptyInstance.tsx index d15daa761af..dbc5f8b8f4d 100644 --- a/server/sonar-web/src/main/js/apps/projects/components/EmptyInstance.tsx +++ b/server/sonar-web/src/main/js/apps/projects/components/EmptyInstance.tsx @@ -18,49 +18,46 @@ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ import * as React from 'react'; +import { WithRouterProps } from 'react-router'; import { Button } from 'sonar-ui-common/components/controls/buttons'; import { translate } from 'sonar-ui-common/helpers/l10n'; -import { OnboardingContextShape } from '../../../app/components/OnboardingContext'; -import { isSonarCloud } from '../../../helpers/system'; +import { withRouter } from '../../../components/hoc/withRouter'; import { hasGlobalPermission, isLoggedIn } from '../../../helpers/users'; -interface Props { +export interface EmptyInstanceProps { currentUser: T.CurrentUser; - openProjectOnboarding: OnboardingContextShape; - organization?: T.Organization; + router: WithRouterProps['router']; } -export default class EmptyInstance extends React.PureComponent<Props> { - analyzeNewProject = () => { - this.props.openProjectOnboarding(this.props.organization); - }; +export function EmptyInstance(props: EmptyInstanceProps) { + const { currentUser, router } = props; + const showNewProjectButton = + isLoggedIn(currentUser) && hasGlobalPermission(currentUser, 'provisioning'); - render() { - const { currentUser, organization } = this.props; - const showNewProjectButton = isSonarCloud() - ? organization && organization.actions && organization.actions.provision - : isLoggedIn(currentUser) && hasGlobalPermission(currentUser, 'provisioning'); - - return ( - <div className="projects-empty-list"> - <h3> - {showNewProjectButton - ? translate('projects.no_projects.empty_instance.new_project') - : translate('projects.no_projects.empty_instance')} - </h3> - {showNewProjectButton && ( - <div> - <p className="big-spacer-top"> - {translate('projects.no_projects.empty_instance.how_to_add_projects')} - </p> - <p className="big-spacer-top"> - <Button onClick={this.analyzeNewProject}> - {translate('my_account.create_new.TRK')} - </Button> - </p> - </div> - )} - </div> - ); - } + return ( + <div className="projects-empty-list"> + <h3> + {showNewProjectButton + ? translate('projects.no_projects.empty_instance.new_project') + : translate('projects.no_projects.empty_instance')} + </h3> + {showNewProjectButton && ( + <div> + <p className="big-spacer-top"> + {translate('projects.no_projects.empty_instance.how_to_add_projects')} + </p> + <p className="big-spacer-top"> + <Button + onClick={() => { + router.push('/projects/create'); + }}> + {translate('my_account.create_new.TRK')} + </Button> + </p> + </div> + )} + </div> + ); } + +export default withRouter(EmptyInstance); diff --git a/server/sonar-web/src/main/js/apps/projects/components/NoFavoriteProjects.tsx b/server/sonar-web/src/main/js/apps/projects/components/NoFavoriteProjects.tsx index 6f1ce8a4ebb..e8d1b9efa82 100644 --- a/server/sonar-web/src/main/js/apps/projects/components/NoFavoriteProjects.tsx +++ b/server/sonar-web/src/main/js/apps/projects/components/NoFavoriteProjects.tsx @@ -17,79 +17,23 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -import { sortBy } from 'lodash'; import * as React from 'react'; -import { connect } from 'react-redux'; import { Link } from 'react-router'; -import { Button } from 'sonar-ui-common/components/controls/buttons'; -import Dropdown from 'sonar-ui-common/components/controls/Dropdown'; -import DropdownIcon from 'sonar-ui-common/components/icons/DropdownIcon'; import { translate } from 'sonar-ui-common/helpers/l10n'; -import { OnboardingContextShape } from '../../../app/components/OnboardingContext'; -import OrganizationListItem from '../../../components/ui/OrganizationListItem'; -import { isSonarCloud } from '../../../helpers/system'; -import { getMyOrganizations, Store } from '../../../store/rootReducer'; -interface OwnProps { - openProjectOnboarding: OnboardingContextShape; -} - -interface StateProps { - organizations: T.Organization[]; -} - -export function NoFavoriteProjects(props: StateProps & OwnProps) { +export default function NoFavoriteProjects() { return ( <div className="projects-empty-list"> <h3>{translate('projects.no_favorite_projects')}</h3> - {isSonarCloud() ? ( - <div className="spacer-top"> - <p>{translate('projects.no_favorite_projects.how_to_add_projects')}</p> - <div className="huge-spacer-top"> - <Button onClick={props.openProjectOnboarding}> - {translate('provisioning.analyze_new_project')} - </Button> - {props.organizations.length > 0 && ( - <Dropdown - className="display-inline-block big-spacer-left" - overlay={ - <ul className="menu"> - {sortBy(props.organizations, org => org.name.toLowerCase()).map( - organization => ( - <OrganizationListItem key={organization.key} organization={organization} /> - ) - )} - </ul> - }> - <a className="button" href="#"> - {translate('projects.no_favorite_projects.favorite_projects_from_orgs')} - <DropdownIcon className="little-spacer-left" /> - </a> - </Dropdown> - )} - - <Link className="button big-spacer-left" to="/explore/projects"> - {translate('projects.no_favorite_projects.favorite_public_projects')} - </Link> - </div> - </div> - ) : ( - <div> - <p className="big-spacer-top">{translate('projects.no_favorite_projects.engagement')}</p> - <p className="big-spacer-top"> - <Link className="button" to="/projects/all"> - {translate('projects.explore_projects')} - </Link> - </p> - </div> - )} + <div> + <p className="big-spacer-top">{translate('projects.no_favorite_projects.engagement')}</p> + <p className="big-spacer-top"> + <Link className="button" to="/projects/all"> + {translate('projects.explore_projects')} + </Link> + </p> + </div> </div> ); } - -const mapStateToProps = (state: Store): StateProps => ({ - organizations: getMyOrganizations(state) -}); - -export default connect(mapStateToProps)(NoFavoriteProjects); diff --git a/server/sonar-web/src/main/js/apps/projects/components/ProjectCard.tsx b/server/sonar-web/src/main/js/apps/projects/components/ProjectCard.tsx index 12e28acdc9f..b4a318602e5 100644 --- a/server/sonar-web/src/main/js/apps/projects/components/ProjectCard.tsx +++ b/server/sonar-web/src/main/js/apps/projects/components/ProjectCard.tsx @@ -33,7 +33,6 @@ import { ComponentQualifier } from '../../../types/component'; import { Project } from '../types'; import { formatDuration } from '../utils'; import ProjectCardLeakMeasures from './ProjectCardLeakMeasures'; -import ProjectCardOrganizationContainer from './ProjectCardOrganizationContainer'; import ProjectCardOverallMeasures from './ProjectCardOverallMeasures'; import ProjectCardQualityGate from './ProjectCardQualityGate'; @@ -41,7 +40,6 @@ interface Props { currentUser: T.CurrentUser; handleFavorite: (component: string, isFavorite: boolean) => void; height: number; - organization: T.Organization | undefined; project: Project; type?: string; } @@ -61,7 +59,7 @@ function getDates(project: Project, type: string | undefined) { } function renderHeader(props: Props) { - const { organization, project } = props; + const { project } = props; const hasTags = project.tags.length > 0; return ( <div className="project-card-header"> @@ -75,16 +73,13 @@ function renderHeader(props: Props) { /> )} <h2 className="project-card-name"> - {!organization && <ProjectCardOrganizationContainer organization={project.organization} />} <Link to={getProjectUrl(project.key)}>{project.name}</Link> </h2> {project.analysisDate && <ProjectCardQualityGate status={project.measures['alert_status']} />} <div className="project-card-header-right"> <PrivacyBadgeContainer className="spacer-left" - organization={organization || project.organization} qualifier={project.qualifier} - tooltipProps={{ projectKey: project.key }} visibility={project.visibility} /> diff --git a/server/sonar-web/src/main/js/apps/projects/components/ProjectsList.tsx b/server/sonar-web/src/main/js/apps/projects/components/ProjectsList.tsx index 7aa126cd99a..535e3b80a09 100644 --- a/server/sonar-web/src/main/js/apps/projects/components/ProjectsList.tsx +++ b/server/sonar-web/src/main/js/apps/projects/components/ProjectsList.tsx @@ -22,7 +22,6 @@ import { AutoSizer } from 'react-virtualized/dist/commonjs/AutoSizer'; import { List, ListRowProps } from 'react-virtualized/dist/commonjs/List'; import { WindowScroller } from 'react-virtualized/dist/commonjs/WindowScroller'; import { translate } from 'sonar-ui-common/helpers/l10n'; -import { OnboardingContext } from '../../../app/components/OnboardingContext'; import EmptySearch from '../../../components/common/EmptySearch'; import { Query } from '../query'; import { Project } from '../types'; @@ -37,7 +36,6 @@ interface Props { handleFavorite: (component: string, isFavorite: boolean) => void; isFavorite: boolean; isFiltered: boolean; - organization: T.Organization | undefined; projects: Project[]; query: Query; } @@ -48,27 +46,11 @@ export default class ProjectsList extends React.PureComponent<Props> { }; renderNoProjects() { - const { currentUser, isFavorite, isFiltered, organization, query } = this.props; + const { currentUser, isFavorite, isFiltered, query } = this.props; if (isFiltered) { return isFavorite ? <EmptyFavoriteSearch query={query} /> : <EmptySearch />; } - return isFavorite ? ( - <OnboardingContext.Consumer> - {openProjectOnboarding => ( - <NoFavoriteProjects openProjectOnboarding={openProjectOnboarding} /> - )} - </OnboardingContext.Consumer> - ) : ( - <OnboardingContext.Consumer> - {openProjectOnboarding => ( - <EmptyInstance - currentUser={currentUser} - openProjectOnboarding={openProjectOnboarding} - organization={organization} - /> - )} - </OnboardingContext.Consumer> - ); + return isFavorite ? <NoFavoriteProjects /> : <EmptyInstance currentUser={currentUser} />; } renderRow = ({ index, key, style }: ListRowProps) => { @@ -82,7 +64,6 @@ export default class ProjectsList extends React.PureComponent<Props> { handleFavorite={this.props.handleFavorite} height={height} key={project.key} - organization={this.props.organization} project={project} type={this.props.cardType} /> diff --git a/server/sonar-web/src/main/js/apps/projects/components/__tests__/EmptyInstance-test.tsx b/server/sonar-web/src/main/js/apps/projects/components/__tests__/EmptyInstance-test.tsx index f41e72dece5..69525edb964 100644 --- a/server/sonar-web/src/main/js/apps/projects/components/__tests__/EmptyInstance-test.tsx +++ b/server/sonar-web/src/main/js/apps/projects/components/__tests__/EmptyInstance-test.tsx @@ -19,52 +19,14 @@ */ import { shallow } from 'enzyme'; import * as React from 'react'; -import { isSonarCloud } from '../../../../helpers/system'; import EmptyInstance from '../EmptyInstance'; -jest.mock('../../../../helpers/system', () => ({ - isSonarCloud: jest.fn() -})); - it('renders correctly for SQ', () => { - (isSonarCloud as jest.Mock<any>).mockReturnValue(false); - expect( - shallow( - <EmptyInstance - currentUser={{ isLoggedIn: false }} - openProjectOnboarding={jest.fn()} - organization={undefined} - /> - ) - ).toMatchSnapshot(); + expect(shallow(<EmptyInstance currentUser={{ isLoggedIn: false }} />)).toMatchSnapshot(); expect( shallow( <EmptyInstance currentUser={{ isLoggedIn: true, permissions: { global: ['provisioning'] } }} - openProjectOnboarding={jest.fn()} - organization={undefined} - /> - ) - ).toMatchSnapshot(); -}); - -it('renders correctly for SC', () => { - (isSonarCloud as jest.Mock<any>).mockReturnValue(true); - expect( - shallow( - <EmptyInstance - currentUser={{ isLoggedIn: false }} - openProjectOnboarding={jest.fn()} - organization={{ key: 'foo', name: 'Foo' }} - /> - ) - ).toMatchSnapshot(); - expect( - shallow( - <EmptyInstance - currentUser={{ isLoggedIn: false }} - openProjectOnboarding={jest.fn()} - organization={{ actions: { provision: true }, key: 'foo', name: 'Foo' }} /> ) ).toMatchSnapshot(); diff --git a/server/sonar-web/src/main/js/apps/projects/components/__tests__/NoFavoriteProjects-test.tsx b/server/sonar-web/src/main/js/apps/projects/components/__tests__/NoFavoriteProjects-test.tsx index 7ca88bf3d58..511181e8aaf 100644 --- a/server/sonar-web/src/main/js/apps/projects/components/__tests__/NoFavoriteProjects-test.tsx +++ b/server/sonar-web/src/main/js/apps/projects/components/__tests__/NoFavoriteProjects-test.tsx @@ -19,32 +19,8 @@ */ import { shallow } from 'enzyme'; import * as React from 'react'; -import { isSonarCloud } from '../../../../helpers/system'; -import { NoFavoriteProjects } from '../NoFavoriteProjects'; - -jest.mock('../../../../helpers/system', () => ({ isSonarCloud: jest.fn() })); +import NoFavoriteProjects from '../NoFavoriteProjects'; it('renders', () => { - (isSonarCloud as jest.Mock).mockImplementation(() => false); - expect( - shallow(<NoFavoriteProjects openProjectOnboarding={jest.fn()} organizations={[]} />) - ).toMatchSnapshot(); -}); - -it('renders for SonarCloud without organizations', () => { - (isSonarCloud as jest.Mock).mockImplementation(() => true); - expect( - shallow(<NoFavoriteProjects openProjectOnboarding={jest.fn()} organizations={[]} />) - ).toMatchSnapshot(); -}); - -it('renders for SonarCloud with organizations', () => { - (isSonarCloud as jest.Mock).mockImplementation(() => true); - const organizations: T.Organization[] = [ - { actions: { admin: true }, key: 'org1', name: 'org1', projectVisibility: 'public' }, - { actions: { admin: false }, key: 'org2', name: 'org2', projectVisibility: 'public' } - ]; - expect( - shallow(<NoFavoriteProjects openProjectOnboarding={jest.fn()} organizations={organizations} />) - ).toMatchSnapshot(); + expect(shallow(<NoFavoriteProjects />)).toMatchSnapshot(); }); diff --git a/server/sonar-web/src/main/js/apps/projects/components/__tests__/ProjectCard-test.tsx b/server/sonar-web/src/main/js/apps/projects/components/__tests__/ProjectCard-test.tsx index 7b74ad36e93..2425c5b5d75 100644 --- a/server/sonar-web/src/main/js/apps/projects/components/__tests__/ProjectCard-test.tsx +++ b/server/sonar-web/src/main/js/apps/projects/components/__tests__/ProjectCard-test.tsx @@ -19,6 +19,7 @@ */ import { shallow } from 'enzyme'; import * as React from 'react'; +import PrivacyBadgeContainer from '../../../../components/common/PrivacyBadgeContainer'; import { mockCurrentUser, mockLoggedInUser } from '../../../../helpers/testMocks'; import { ComponentQualifier } from '../../../../types/component'; import { Project } from '../../types'; @@ -85,7 +86,7 @@ it('should display private badge', () => { const project: Project = { ...PROJECT, visibility: 'private' }; expect( shallowRender(project) - .find('Connect(PrivacyBadge)') + .find(PrivacyBadgeContainer) .exists() ).toBe(true); }); @@ -117,12 +118,6 @@ it('should display applications', () => { function shallowRender(project: Project, user: T.CurrentUser = USER_LOGGED_OUT) { return shallow( - <ProjectCard - currentUser={user} - handleFavorite={jest.fn()} - height={100} - organization={undefined} - project={project} - /> + <ProjectCard currentUser={user} handleFavorite={jest.fn()} height={100} project={project} /> ); } diff --git a/server/sonar-web/src/main/js/apps/projects/components/__tests__/__snapshots__/EmptyInstance-test.tsx.snap b/server/sonar-web/src/main/js/apps/projects/components/__tests__/__snapshots__/EmptyInstance-test.tsx.snap index dff9398a724..3c17a844515 100644 --- a/server/sonar-web/src/main/js/apps/projects/components/__tests__/__snapshots__/EmptyInstance-test.tsx.snap +++ b/server/sonar-web/src/main/js/apps/projects/components/__tests__/__snapshots__/EmptyInstance-test.tsx.snap @@ -1,73 +1,26 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`renders correctly for SC 1`] = ` -<div - className="projects-empty-list" -> - <h3> - projects.no_projects.empty_instance - </h3> -</div> -`; - -exports[`renders correctly for SC 2`] = ` -<div - className="projects-empty-list" -> - <h3> - projects.no_projects.empty_instance.new_project - </h3> - <div> - <p - className="big-spacer-top" - > - projects.no_projects.empty_instance.how_to_add_projects - </p> - <p - className="big-spacer-top" - > - <Button - onClick={[Function]} - > - my_account.create_new.TRK - </Button> - </p> - </div> -</div> -`; - exports[`renders correctly for SQ 1`] = ` -<div - className="projects-empty-list" -> - <h3> - projects.no_projects.empty_instance - </h3> -</div> +<EmptyInstance + currentUser={ + Object { + "isLoggedIn": false, + } + } +/> `; exports[`renders correctly for SQ 2`] = ` -<div - className="projects-empty-list" -> - <h3> - projects.no_projects.empty_instance.new_project - </h3> - <div> - <p - className="big-spacer-top" - > - projects.no_projects.empty_instance.how_to_add_projects - </p> - <p - className="big-spacer-top" - > - <Button - onClick={[Function]} - > - my_account.create_new.TRK - </Button> - </p> - </div> -</div> +<EmptyInstance + currentUser={ + Object { + "isLoggedIn": true, + "permissions": Object { + "global": Array [ + "provisioning", + ], + }, + } + } +/> `; diff --git a/server/sonar-web/src/main/js/apps/projects/components/__tests__/__snapshots__/NoFavoriteProjects-test.tsx.snap b/server/sonar-web/src/main/js/apps/projects/components/__tests__/__snapshots__/NoFavoriteProjects-test.tsx.snap index 0aa5d44907e..0b9b729d5f0 100644 --- a/server/sonar-web/src/main/js/apps/projects/components/__tests__/__snapshots__/NoFavoriteProjects-test.tsx.snap +++ b/server/sonar-web/src/main/js/apps/projects/components/__tests__/__snapshots__/NoFavoriteProjects-test.tsx.snap @@ -28,114 +28,3 @@ exports[`renders 1`] = ` </div> </div> `; - -exports[`renders for SonarCloud with organizations 1`] = ` -<div - className="projects-empty-list" -> - <h3> - projects.no_favorite_projects - </h3> - <div - className="spacer-top" - > - <p> - projects.no_favorite_projects.how_to_add_projects - </p> - <div - className="huge-spacer-top" - > - <Button - onClick={[MockFunction]} - > - provisioning.analyze_new_project - </Button> - <Dropdown - className="display-inline-block big-spacer-left" - overlay={ - <ul - className="menu" - > - <OrganizationListItem - organization={ - Object { - "actions": Object { - "admin": true, - }, - "key": "org1", - "name": "org1", - "projectVisibility": "public", - } - } - /> - <OrganizationListItem - organization={ - Object { - "actions": Object { - "admin": false, - }, - "key": "org2", - "name": "org2", - "projectVisibility": "public", - } - } - /> - </ul> - } - > - <a - className="button" - href="#" - > - projects.no_favorite_projects.favorite_projects_from_orgs - <DropdownIcon - className="little-spacer-left" - /> - </a> - </Dropdown> - <Link - className="button big-spacer-left" - onlyActiveOnIndex={false} - style={Object {}} - to="/explore/projects" - > - projects.no_favorite_projects.favorite_public_projects - </Link> - </div> - </div> -</div> -`; - -exports[`renders for SonarCloud without organizations 1`] = ` -<div - className="projects-empty-list" -> - <h3> - projects.no_favorite_projects - </h3> - <div - className="spacer-top" - > - <p> - projects.no_favorite_projects.how_to_add_projects - </p> - <div - className="huge-spacer-top" - > - <Button - onClick={[MockFunction]} - > - provisioning.analyze_new_project - </Button> - <Link - className="button big-spacer-left" - onlyActiveOnIndex={false} - style={Object {}} - to="/explore/projects" - > - projects.no_favorite_projects.favorite_public_projects - </Link> - </div> - </div> -</div> -`; diff --git a/server/sonar-web/src/main/js/apps/projects/components/__tests__/__snapshots__/ProjectCard-test.tsx.snap b/server/sonar-web/src/main/js/apps/projects/components/__tests__/__snapshots__/ProjectCard-test.tsx.snap index 9232fe2c56c..cc5f4dce330 100644 --- a/server/sonar-web/src/main/js/apps/projects/components/__tests__/__snapshots__/ProjectCard-test.tsx.snap +++ b/server/sonar-web/src/main/js/apps/projects/components/__tests__/__snapshots__/ProjectCard-test.tsx.snap @@ -17,14 +17,6 @@ exports[`should display applications 1`] = ` <h2 className="project-card-name" > - <Connect(ProjectCardOrganization) - organization={ - Object { - "key": "org", - "name": "org", - } - } - /> <Link onlyActiveOnIndex={false} style={Object {}} @@ -47,20 +39,9 @@ exports[`should display applications 1`] = ` <div className="project-card-header-right" > - <Connect(PrivacyBadge) + <PrivacyBadgeContainer className="spacer-left" - organization={ - Object { - "key": "org", - "name": "org", - } - } qualifier="APP" - tooltipProps={ - Object { - "projectKey": "foo", - } - } visibility="public" /> </div> @@ -115,14 +96,6 @@ exports[`should display applications: with project count 1`] = ` <h2 className="project-card-name" > - <Connect(ProjectCardOrganization) - organization={ - Object { - "key": "org", - "name": "org", - } - } - /> <Link onlyActiveOnIndex={false} style={Object {}} @@ -145,20 +118,9 @@ exports[`should display applications: with project count 1`] = ` <div className="project-card-header-right" > - <Connect(PrivacyBadge) + <PrivacyBadgeContainer className="spacer-left" - organization={ - Object { - "key": "org", - "name": "org", - } - } qualifier="APP" - tooltipProps={ - Object { - "projectKey": "foo", - } - } visibility="public" /> </div> @@ -216,14 +178,6 @@ exports[`should display configure analysis button for logged in user 1`] = ` <h2 className="project-card-name" > - <Connect(ProjectCardOrganization) - organization={ - Object { - "key": "org", - "name": "org", - } - } - /> <Link onlyActiveOnIndex={false} style={Object {}} @@ -243,20 +197,9 @@ exports[`should display configure analysis button for logged in user 1`] = ` <div className="project-card-header-right" > - <Connect(PrivacyBadge) + <PrivacyBadgeContainer className="spacer-left" - organization={ - Object { - "key": "org", - "name": "org", - } - } qualifier="TRK" - tooltipProps={ - Object { - "projectKey": "foo", - } - } visibility="public" /> </div> @@ -307,14 +250,6 @@ exports[`should display not analyzed yet 1`] = ` <h2 className="project-card-name" > - <Connect(ProjectCardOrganization) - organization={ - Object { - "key": "org", - "name": "org", - } - } - /> <Link onlyActiveOnIndex={false} style={Object {}} @@ -334,20 +269,9 @@ exports[`should display not analyzed yet 1`] = ` <div className="project-card-header-right" > - <Connect(PrivacyBadge) + <PrivacyBadgeContainer className="spacer-left" - organization={ - Object { - "key": "org", - "name": "org", - } - } qualifier="TRK" - tooltipProps={ - Object { - "projectKey": "foo", - } - } visibility="public" /> </div> @@ -382,14 +306,6 @@ exports[`should display the overall measures and quality gate 1`] = ` <h2 className="project-card-name" > - <Connect(ProjectCardOrganization) - organization={ - Object { - "key": "org", - "name": "org", - } - } - /> <Link onlyActiveOnIndex={false} style={Object {}} @@ -412,20 +328,9 @@ exports[`should display the overall measures and quality gate 1`] = ` <div className="project-card-header-right" > - <Connect(PrivacyBadge) + <PrivacyBadgeContainer className="spacer-left" - organization={ - Object { - "key": "org", - "name": "org", - } - } qualifier="TRK" - tooltipProps={ - Object { - "projectKey": "foo", - } - } visibility="public" /> </div> diff --git a/server/sonar-web/src/main/js/apps/projects/components/__tests__/__snapshots__/ProjectsList-test.tsx.snap b/server/sonar-web/src/main/js/apps/projects/components/__tests__/__snapshots__/ProjectsList-test.tsx.snap index beb61d2d3fb..7df128ac05e 100644 --- a/server/sonar-web/src/main/js/apps/projects/components/__tests__/__snapshots__/ProjectsList-test.tsx.snap +++ b/server/sonar-web/src/main/js/apps/projects/components/__tests__/__snapshots__/ProjectsList-test.tsx.snap @@ -64,9 +64,13 @@ exports[`renders different types of "no projects" 1`] = ` <div className="projects-list" > - <ContextConsumer> - <Component /> - </ContextConsumer> + <withRouter(EmptyInstance) + currentUser={ + Object { + "isLoggedIn": true, + } + } + /> </div> `; @@ -82,8 +86,6 @@ exports[`renders different types of "no projects" 3`] = ` <div className="projects-list" > - <ContextConsumer> - <Component /> - </ContextConsumer> + <NoFavoriteProjects /> </div> `; diff --git a/server/sonar-web/src/main/js/apps/projectsManagement/ProjectRow.tsx b/server/sonar-web/src/main/js/apps/projectsManagement/ProjectRow.tsx index a12364c1a7f..c04d80194dd 100644 --- a/server/sonar-web/src/main/js/apps/projectsManagement/ProjectRow.tsx +++ b/server/sonar-web/src/main/js/apps/projectsManagement/ProjectRow.tsx @@ -69,12 +69,7 @@ export default class ProjectRow extends React.PureComponent<Props> { </td> <td className="thin nowrap"> - <PrivacyBadgeContainer - organization={organization} - qualifier={project.qualifier} - tooltipProps={{ projectKey: project.key }} - visibility={project.visibility} - /> + <PrivacyBadgeContainer qualifier={project.qualifier} visibility={project.visibility} /> </td> <td className="nowrap hide-overflow project-row-text-cell"> diff --git a/server/sonar-web/src/main/js/apps/projectsManagement/__tests__/__snapshots__/ProjectRow-test.tsx.snap b/server/sonar-web/src/main/js/apps/projectsManagement/__tests__/__snapshots__/ProjectRow-test.tsx.snap index 15c4f5964f2..52589366e34 100644 --- a/server/sonar-web/src/main/js/apps/projectsManagement/__tests__/__snapshots__/ProjectRow-test.tsx.snap +++ b/server/sonar-web/src/main/js/apps/projectsManagement/__tests__/__snapshots__/ProjectRow-test.tsx.snap @@ -47,13 +47,8 @@ exports[`renders 1`] = ` <td className="thin nowrap" > - <Connect(PrivacyBadge) + <PrivacyBadgeContainer qualifier="TRK" - tooltipProps={ - Object { - "projectKey": "project", - } - } visibility="private" /> </td> @@ -148,13 +143,8 @@ exports[`renders: portfolio 1`] = ` <td className="thin nowrap" > - <Connect(PrivacyBadge) + <PrivacyBadgeContainer qualifier="VW" - tooltipProps={ - Object { - "projectKey": "project", - } - } visibility="private" /> </td> @@ -250,13 +240,8 @@ exports[`renders: with lastAnalysisDate 1`] = ` <td className="thin nowrap" > - <Connect(PrivacyBadge) + <PrivacyBadgeContainer qualifier="TRK" - tooltipProps={ - Object { - "projectKey": "project", - } - } visibility="private" /> </td> diff --git a/server/sonar-web/src/main/js/components/common/PrivacyBadgeContainer.tsx b/server/sonar-web/src/main/js/components/common/PrivacyBadgeContainer.tsx index a6ad94e485a..4f4881d846b 100644 --- a/server/sonar-web/src/main/js/components/common/PrivacyBadgeContainer.tsx +++ b/server/sonar-web/src/main/js/components/common/PrivacyBadgeContainer.tsx @@ -19,121 +19,27 @@ */ import * as classNames from 'classnames'; import * as React from 'react'; -import { connect } from 'react-redux'; import Tooltip from 'sonar-ui-common/components/controls/Tooltip'; -import VisibleIcon from 'sonar-ui-common/components/icons/VisibleIcon'; import { translate } from 'sonar-ui-common/helpers/l10n'; -import { colors } from '../../app/theme'; -import { isCurrentUserMemberOf, isPaidOrganization } from '../../helpers/organizations'; -import { isSonarCloud } from '../../helpers/system'; -import { - getCurrentUser, - getMyOrganizations, - getOrganizationByKey, - Store -} from '../../store/rootReducer'; -import DocTooltip from '../docs/DocTooltip'; -interface StateToProps { - currentUser: T.CurrentUser; - organization?: T.Organization; - userOrganizations: T.Organization[]; -} - -interface OwnProps { +interface PrivacyBadgeContainerProps { className?: string; - organization: T.Organization | string | undefined; qualifier: string; - tooltipProps?: { projectKey: string }; visibility: T.Visibility; } -interface Props extends OwnProps, StateToProps { - organization: T.Organization | undefined; -} - -export function PrivacyBadge({ +export default function PrivacyBadgeContainer({ className, - currentUser, - organization, qualifier, - userOrganizations, - tooltipProps, visibility -}: Props) { - const onSonarCloud = isSonarCloud(); - if ( - visibility !== 'private' && - (!onSonarCloud || !isCurrentUserMemberOf(currentUser, organization, userOrganizations)) - ) { +}: PrivacyBadgeContainerProps) { + if (visibility !== 'private') { return null; } - let icon = null; - if (isPaidOrganization(organization) && visibility === 'public') { - icon = <VisibleIcon className="little-spacer-right" fill={colors.blue} />; - } - - const badge = ( - <div - className={classNames('badge', className, { - 'badge-info': Boolean(icon) - })}> - {icon} - {translate('visibility', visibility)} - </div> - ); - - if (onSonarCloud && organization) { - return ( - <DocTooltip - className={className} - doc={getDoc(visibility, icon, organization)} - overlayProps={{ ...tooltipProps, organization: organization.key }}> - {badge} - </DocTooltip> - ); - } - return ( <Tooltip overlay={translate('visibility', visibility, 'description', qualifier)}> - {badge} + <div className={classNames('badge', className)}>{translate('visibility', visibility)}</div> </Tooltip> ); } - -const mapStateToProps = (state: Store, { organization }: OwnProps) => { - if (typeof organization === 'string') { - organization = getOrganizationByKey(state, organization); - } - return { - currentUser: getCurrentUser(state), - organization, - userOrganizations: getMyOrganizations(state) - }; -}; - -export default connect(mapStateToProps)(PrivacyBadge); - -function getDoc(visibility: T.Visibility, icon: JSX.Element | null, organization: T.Organization) { - let doc; - const { actions = {} } = organization; - if (visibility === 'private') { - doc = import(/* webpackMode: "eager" */ 'Docs/tooltips/project/visibility-private.md'); - } else if (icon) { - if (actions.admin) { - doc = import( - /* webpackMode: "eager" */ 'Docs/tooltips/project/visibility-public-paid-org-admin.md' - ); - } else { - doc = import( - /* webpackMode: "eager" */ 'Docs/tooltips/project/visibility-public-paid-org.md' - ); - } - } else if (actions.admin) { - doc = import(/* webpackMode: "eager" */ 'Docs/tooltips/project/visibility-public-admin.md'); - } else { - doc = import(/* webpackMode: "eager" */ 'Docs/tooltips/project/visibility-public.md'); - } - return doc; -} diff --git a/server/sonar-web/src/main/js/components/common/__tests__/PrivacyBadgeContainer-test.tsx b/server/sonar-web/src/main/js/components/common/__tests__/PrivacyBadgeContainer-test.tsx index 07b8277a29a..c655dfaf777 100644 --- a/server/sonar-web/src/main/js/components/common/__tests__/PrivacyBadgeContainer-test.tsx +++ b/server/sonar-web/src/main/js/components/common/__tests__/PrivacyBadgeContainer-test.tsx @@ -19,13 +19,8 @@ */ import { shallow } from 'enzyme'; import * as React from 'react'; -import { isSonarCloud } from '../../../helpers/system'; -import { PrivacyBadge } from '../PrivacyBadgeContainer'; - -jest.mock('../../../helpers/system', () => ({ isSonarCloud: jest.fn().mockReturnValue(false) })); - -const organization: T.Organization = { key: 'foo', name: 'Foo' }; -const loggedInUser = { isLoggedIn: true, login: 'luke', name: 'Skywalker' }; +import { ComponentQualifier } from '../../../types/component'; +import PrivacyBadge from '../PrivacyBadgeContainer'; it('renders', () => { expect(getWrapper()).toMatchSnapshot(); @@ -35,34 +30,8 @@ it('do not render', () => { expect(getWrapper({ visibility: 'public' })).toMatchSnapshot(); }); -it('renders public', () => { - (isSonarCloud as jest.Mock<any>).mockReturnValueOnce(true); - expect(getWrapper({ visibility: 'public' })).toMatchSnapshot(); -}); - -it('renders public with icon', () => { - (isSonarCloud as jest.Mock<any>).mockReturnValueOnce(true); - expect( - getWrapper({ - organization: { - ...organization, - actions: { admin: true }, - subscription: 'PAID' - }, - visibility: 'public' - }) - ).toMatchSnapshot(); -}); - function getWrapper(props = {}) { return shallow( - <PrivacyBadge - currentUser={loggedInUser} - organization={organization} - qualifier="TRK" - userOrganizations={[organization]} - visibility="private" - {...props} - /> + <PrivacyBadge qualifier={ComponentQualifier.Project} visibility="private" {...props} /> ); } diff --git a/server/sonar-web/src/main/js/components/common/__tests__/__snapshots__/PrivacyBadgeContainer-test.tsx.snap b/server/sonar-web/src/main/js/components/common/__tests__/__snapshots__/PrivacyBadgeContainer-test.tsx.snap index 68240d974ee..45a670ff6a1 100644 --- a/server/sonar-web/src/main/js/components/common/__tests__/__snapshots__/PrivacyBadgeContainer-test.tsx.snap +++ b/server/sonar-web/src/main/js/components/common/__tests__/__snapshots__/PrivacyBadgeContainer-test.tsx.snap @@ -13,41 +13,3 @@ exports[`renders 1`] = ` </div> </Tooltip> `; - -exports[`renders public 1`] = ` -<DocTooltip - doc={Promise {}} - overlayProps={ - Object { - "organization": "foo", - } - } -> - <div - className="badge" - > - visibility.public - </div> -</DocTooltip> -`; - -exports[`renders public with icon 1`] = ` -<DocTooltip - doc={Promise {}} - overlayProps={ - Object { - "organization": "foo", - } - } -> - <div - className="badge badge-info" - > - <VisibleIcon - className="little-spacer-right" - fill="#4b9fd5" - /> - visibility.public - </div> -</DocTooltip> -`; |