]> source.dussan.org Git - sonarqube.git/commitdiff
SC-781 Remove special behavior to bind personal organization
authorGrégoire Aubert <gregoire.aubert@sonarsource.com>
Fri, 21 Jun 2019 07:10:32 +0000 (09:10 +0200)
committerSonarTech <sonartech@sonarsource.com>
Fri, 5 Jul 2019 18:21:11 +0000 (20:21 +0200)
* Update documentation talking about personal orgs
* Drop unused organization/delete route

31 files changed:
server/sonar-docs/src/pages/analysis/overview.md
server/sonar-docs/src/pages/sonarcloud/organizations/index.md
server/sonar-web/src/main/js/app/types.d.ts
server/sonar-web/src/main/js/apps/create/organization/AutoPersonalOrganizationBind.tsx [deleted file]
server/sonar-web/src/main/js/apps/create/organization/CreateOrganization.tsx
server/sonar-web/src/main/js/apps/create/organization/OrganizationDetailsForm.tsx
server/sonar-web/src/main/js/apps/create/organization/__tests__/AutoOrganizationCreate-test.tsx
server/sonar-web/src/main/js/apps/create/organization/__tests__/AutoPersonalOrganizationBind-test.tsx [deleted file]
server/sonar-web/src/main/js/apps/create/organization/__tests__/CreateOrganization-test.tsx
server/sonar-web/src/main/js/apps/create/organization/__tests__/PlanStep-test.tsx
server/sonar-web/src/main/js/apps/create/organization/__tests__/__snapshots__/AutoOrganizationCreate-test.tsx.snap
server/sonar-web/src/main/js/apps/create/organization/__tests__/__snapshots__/AutoPersonalOrganizationBind-test.tsx.snap [deleted file]
server/sonar-web/src/main/js/apps/create/organization/__tests__/__snapshots__/CreateOrganization-test.tsx.snap
server/sonar-web/src/main/js/apps/create/organization/__tests__/__snapshots__/PlanStep-test.tsx.snap
server/sonar-web/src/main/js/apps/create/organization/__tests__/actions-test.ts
server/sonar-web/src/main/js/apps/create/organization/actions.ts
server/sonar-web/src/main/js/apps/organizationMembers/MembersListHeader.tsx
server/sonar-web/src/main/js/apps/organizationMembers/OrganizationMembers.tsx
server/sonar-web/src/main/js/apps/organizationMembers/__tests__/MembersListHeader-test.tsx
server/sonar-web/src/main/js/apps/organizationMembers/__tests__/__snapshots__/MembersListHeader-test.tsx.snap
server/sonar-web/src/main/js/apps/organizationMembers/__tests__/__snapshots__/OrganizationMembers-test.tsx.snap
server/sonar-web/src/main/js/apps/organizations/components/OrganizationAccessContainer.tsx
server/sonar-web/src/main/js/apps/organizations/routes.ts
server/sonar-web/src/main/js/apps/tutorials/onboarding/OnboardingModal.tsx
server/sonar-web/src/main/js/apps/tutorials/onboarding/__tests__/OnboardingModal-test.tsx
server/sonar-web/src/main/js/apps/tutorials/onboarding/__tests__/__snapshots__/OnboardingModal-test.tsx.snap
server/sonar-web/src/main/js/components/hoc/utils.ts
server/sonar-web/src/main/js/helpers/__tests__/almIntegrations-test.ts
server/sonar-web/src/main/js/helpers/almIntegrations.ts
server/sonar-web/src/main/js/helpers/testMocks.ts
sonar-core/src/main/resources/org/sonar/l10n/core.properties

index e807b6e755e65b7cdc8641a86354e3d58ce5ff42..b5577af5461ad608de2d4d7c166d693c2f5d5ed8 100644 (file)
@@ -6,10 +6,10 @@ url: /analysis/overview/
 <!-- sonarcloud -->
 ## Prepare your organization
 
-A project must belong to an [organization](/organizations/overview/). Create one if you intend to collaborate with your team mates, or use your personal organization for test purposes.
+A project must belong to an [organization](/organizations/overview/). You need to create one to analyze a project and collaborate with your team mates.
 
 [[info]]
-| ** Important note for private code:** Newly created organizations and personal organizations are under a free plan by default. This means projects analyzed on these organizations are public by default: the code will be browsable by anyone. If you want private projects, you should [upgrade your organization to a paid plan](/sonarcloud-pricing/).
+| ** Important note for private code:** Newly created organizations are under a free plan by default. This means projects analyzed on these organizations are public by default: the code will be browsable by anyone. If you want private projects, you should [upgrade your organization to a paid plan](/sonarcloud-pricing/).
 
 Find the key of your organization, you will need it at later stages. It can be found on the top right corner of your organization's header.
 
index 33694461f68e33c8f15b49857e7c50f12a0cd1d0..22d57f1dee47df58d013c9938a6a839b5e3bd390 100644 (file)
@@ -12,10 +12,6 @@ An organization consists of:
 * [Members](/organizations/manage-team/), who can have different permissions on the projects
 * [Quality Profiles](/instance-administration/quality-profiles/) and [Quality Gates](/user-guide/quality-gates/), which can be customized and shared accross projects
 
-There are 2 kind of organizations:
-* **Personal organizations**. Each account has a personal organization linked to it. This is typically where open-source developers host their personal projects. It is not possible to delete this kind of organization.
-* **Standard organization**. This is the kind of organization that users want to create for their companies or for their open-source communities. As soon as you want to collaborate, it is a good idea to create such an organization.
-
 Organizations can be on:
 * **Free plan**. This is the default plan. Every project in an organization on the free plan is public.
 * **Paid plan**. This plan unlocks the ability to have private projects. Go to the "Billing" page of your organization to upgrade it to the paid plan.
index 7e741303ff7556f400f3e50d3fd5a88f3cddf83c..2f0712d6aeb9208c2e8859bed6aa9a88864eb948 100644 (file)
@@ -37,7 +37,6 @@ declare namespace T {
   export interface AlmOrganization extends OrganizationBase {
     almUrl: string;
     key: string;
-    personal: boolean;
     privateRepos: number;
     publicRepos: number;
   }
@@ -440,7 +439,6 @@ declare namespace T {
     local?: boolean;
     login: string;
     name: string;
-    personalOrganization?: string;
     scmAccounts: string[];
     settings?: CurrentUserSetting[];
   }
@@ -519,7 +517,6 @@ declare namespace T {
     alm?: { key: string; membersSync: boolean; url: string };
     adminPages?: Extension[];
     canUpdateProjectsVisibilityToPrivate?: boolean;
-    guarded?: boolean;
     isDefault?: boolean;
     key: string;
     pages?: Extension[];
diff --git a/server/sonar-web/src/main/js/apps/create/organization/AutoPersonalOrganizationBind.tsx b/server/sonar-web/src/main/js/apps/create/organization/AutoPersonalOrganizationBind.tsx
deleted file mode 100644 (file)
index 9a1afec..0000000
+++ /dev/null
@@ -1,122 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2019 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 { FormattedMessage } from 'react-intl';
-import OrganizationDetailsForm from './OrganizationDetailsForm';
-import OrganizationDetailsStep from './OrganizationDetailsStep';
-import PlanStep from './PlanStep';
-import { Step } from './utils';
-import { ClearButton } from '../../../components/ui/buttons';
-import OrganizationAvatar from '../../../components/common/OrganizationAvatar';
-import { getBaseUrl } from '../../../helpers/urls';
-import { translate } from '../../../helpers/l10n';
-import { sanitizeAlmId } from '../../../helpers/almIntegrations';
-
-interface Props {
-  almApplication: T.AlmApplication;
-  almInstallId?: string;
-  almOrganization: T.AlmOrganization;
-  handleCancelImport: () => void;
-  handleOrgDetailsFinish: (organization: T.Organization) => Promise<void>;
-  handleOrgDetailsStepOpen: () => void;
-  importPersonalOrg: T.Organization;
-  onDone: () => void;
-  organization?: T.Organization;
-  step: Step;
-  subscriptionPlans?: T.SubscriptionPlan[];
-  updateOrganization: (
-    organization: T.Organization & { installationId?: string }
-  ) => Promise<string>;
-}
-
-export default class AutoPersonalOrganizationBind extends React.PureComponent<Props> {
-  handleCreateOrganization = () => {
-    const { organization } = this.props;
-    if (!organization) {
-      return Promise.reject();
-    }
-    return this.props.updateOrganization({
-      ...organization,
-      installationId: this.props.almInstallId
-    });
-  };
-
-  handleOrgDetailsFinish = (organization: T.Organization) => {
-    return this.props.handleOrgDetailsFinish({
-      ...organization,
-      key: this.props.importPersonalOrg.key
-    });
-  };
-
-  render() {
-    const { almApplication, importPersonalOrg, organization, step, subscriptionPlans } = this.props;
-    return (
-      <>
-        <OrganizationDetailsStep
-          finished={organization !== undefined}
-          onOpen={this.props.handleOrgDetailsStepOpen}
-          open={step === Step.OrganizationDetails}
-          organization={organization}
-          stepTitle={translate('onboarding.import_organization.personal.import_org_details')}>
-          <div className="display-flex-center big-spacer-bottom">
-            <FormattedMessage
-              defaultMessage={translate('onboarding.import_personal_organization_x')}
-              id="onboarding.import_personal_organization_x"
-              values={{
-                avatar: (
-                  <img
-                    alt={almApplication.name}
-                    className="little-spacer-left"
-                    src={`${getBaseUrl()}/images/sonarcloud/${sanitizeAlmId(
-                      almApplication.key
-                    )}.svg`}
-                    width={16}
-                  />
-                ),
-                name: <strong>{this.props.almOrganization.name}</strong>,
-                personalAvatar: importPersonalOrg && (
-                  <OrganizationAvatar organization={importPersonalOrg} small={true} />
-                ),
-                personalName: importPersonalOrg && <strong>{importPersonalOrg.name}</strong>
-              }}
-            />
-            <ClearButton className="little-spacer-left" onClick={this.props.handleCancelImport} />
-          </div>
-          <OrganizationDetailsForm
-            keyReadOnly={true}
-            onContinue={this.handleOrgDetailsFinish}
-            organization={importPersonalOrg}
-            submitText={translate('continue')}
-          />
-        </OrganizationDetailsStep>
-        {subscriptionPlans !== undefined && (
-          <PlanStep
-            almApplication={this.props.almApplication}
-            almOrganization={this.props.almOrganization}
-            createOrganization={this.handleCreateOrganization}
-            onDone={this.props.onDone}
-            open={step === Step.Plan}
-            subscriptionPlans={subscriptionPlans}
-          />
-        )}
-      </>
-    );
-  }
-}
index a08e71d5859589edd3fab62a1701cd4c950e855c..824127e48107559699839056571c0a5ed035e174 100644 (file)
@@ -24,7 +24,7 @@ import { times } from 'lodash';
 import { connect } from 'react-redux';
 import { Helmet } from 'react-helmet';
 import { withRouter, WithRouterProps } from 'react-router';
-import { createOrganization, updateOrganization } from './actions';
+import { createOrganization } from './actions';
 import {
   ORGANIZATION_IMPORT_REDIRECT_TO_PROJECT_TIMESTAMP,
   parseQuery,
@@ -37,7 +37,6 @@ import {
 } from './utils';
 import AlmApplicationInstalling from './AlmApplicationInstalling';
 import AutoOrganizationCreate from './AutoOrganizationCreate';
-import AutoPersonalOrganizationBind from './AutoPersonalOrganizationBind';
 import ManualOrganizationCreate from './ManualOrganizationCreate';
 import RemoteOrganizationChoose from './RemoteOrganizationChoose';
 import A11ySkipTarget from '../../../app/components/a11y/A11ySkipTarget';
@@ -55,11 +54,7 @@ import {
 } from '../../../api/alm-integration';
 import { getSubscriptionPlans } from '../../../api/billing';
 import * as api from '../../../api/organizations';
-import {
-  hasAdvancedALMIntegration,
-  isPersonal,
-  sanitizeAlmId
-} from '../../../helpers/almIntegrations';
+import { hasAdvancedALMIntegration, sanitizeAlmId } from '../../../helpers/almIntegrations';
 import { translate, translateWithParameters } from '../../../helpers/l10n';
 import { addWhitePageClass, removeWhitePageClass } from '../../../helpers/pages';
 import { get, remove } from '../../../helpers/storage';
@@ -75,9 +70,6 @@ interface Props {
   ) => Promise<string>;
   currentUser: T.LoggedInUser;
   deleteOrganization: (key: string) => Promise<void>;
-  updateOrganization: (
-    organization: T.Organization & { installationId?: string }
-  ) => Promise<string>;
   userOrganizations: T.Organization[];
   skipOnboarding: () => void;
 }
@@ -287,11 +279,9 @@ export class CreateOrganization extends React.PureComponent<Props & WithRouterPr
     );
   }
 
-  getHeader = (bindingExistingOrg: boolean, importPersonalOrg: boolean) => {
+  getHeader = (bindingExistingOrg: boolean) => {
     if (bindingExistingOrg) {
       return translate('onboarding.binding_organization');
-    } else if (importPersonalOrg) {
-      return translate('onboarding.import_organization.personal.page.header');
     } else {
       return translate('onboarding.create_organization.page.header');
     }
@@ -336,8 +326,8 @@ export class CreateOrganization extends React.PureComponent<Props & WithRouterPr
     });
   };
 
-  renderContent = (almInstallId?: string, importPersonalOrg?: T.Organization) => {
-    const { currentUser, location } = this.props;
+  renderContent = (almInstallId?: string) => {
+    const { location } = this.props;
     const { state } = this;
     const { organization, step, subscriptionPlans } = state;
     const { tab = 'auto' } = (location.state || {}) as LocationState;
@@ -365,21 +355,6 @@ export class CreateOrganization extends React.PureComponent<Props & WithRouterPr
 
     const { almApplication, almOrganization, boundOrganization } = state;
 
-    if (importPersonalOrg && almOrganization && almApplication) {
-      return (
-        <AutoPersonalOrganizationBind
-          {...commonProps}
-          almApplication={almApplication}
-          almInstallId={almInstallId}
-          almOrganization={almOrganization}
-          handleCancelImport={this.handleCancelImport}
-          importPersonalOrg={importPersonalOrg}
-          subscriptionPlans={subscriptionPlans}
-          updateOrganization={this.props.updateOrganization}
-        />
-      );
-    }
-
     return (
       <>
         <Tabs<TabKeys>
@@ -419,8 +394,7 @@ export class CreateOrganization extends React.PureComponent<Props & WithRouterPr
             onOrgCreated={this.handleOrgCreated}
             onUpgradeFail={this.deleteOrganization}
             unboundOrganizations={this.props.userOrganizations.filter(
-              ({ actions = {}, alm, key }) =>
-                !alm && key !== currentUser.personalOrganization && actions.admin
+              ({ actions = {}, alm }) => !alm && actions.admin
             )}
           />
         ) : (
@@ -438,19 +412,15 @@ export class CreateOrganization extends React.PureComponent<Props & WithRouterPr
   };
 
   render() {
-    const { currentUser, location } = this.props;
+    const { location } = this.props;
     const query = parseQuery(location.query);
 
     if (this.state.almOrgLoading) {
       return <AlmApplicationInstalling almKey={query.almKey} />;
     }
 
-    const { almOrganization, bindingExistingOrg, subscriptionPlans } = this.state;
-    const importPersonalOrg = isPersonal(almOrganization)
-      ? this.props.userOrganizations.find(o => o.key === currentUser.personalOrganization)
-      : undefined;
-    const header = this.getHeader(bindingExistingOrg, !!importPersonalOrg);
-
+    const { bindingExistingOrg, subscriptionPlans } = this.state;
+    const header = this.getHeader(bindingExistingOrg);
     const startedPrice = subscriptionPlans && subscriptionPlans[0] && subscriptionPlans[0].price;
 
     return (
@@ -463,17 +433,13 @@ export class CreateOrganization extends React.PureComponent<Props & WithRouterPr
             <h1 className="page-title huge big-spacer-bottom">
               <strong>{header}</strong>
             </h1>
-            {!importPersonalOrg && startedPrice !== undefined && (
+            {startedPrice !== undefined && (
               <p className="page-description">
                 {translate('onboarding.create_organization.page.description')}
               </p>
             )}
           </header>
-          {this.state.loading ? (
-            <DeferredSpinner />
-          ) : (
-            this.renderContent(query.almInstallId, importPersonalOrg)
-          )}
+          {this.state.loading ? <DeferredSpinner /> : this.renderContent(query.almInstallId)}
         </div>
       </>
     );
@@ -483,7 +449,6 @@ export class CreateOrganization extends React.PureComponent<Props & WithRouterPr
 const mapDispatchToProps = {
   createOrganization: createOrganization as any,
   deleteOrganization: deleteOrganization as any,
-  updateOrganization: updateOrganization as any,
   skipOnboarding: skipOnboarding as any
 };
 
index 921a90dfcabcf2ec91901298a3b22e8648738399..90014303707efb5c08bc52bd3328f15f8cee718a 100644 (file)
@@ -30,7 +30,6 @@ type RequiredOrganization = Required<T.OrganizationBase>;
 
 interface Props {
   infoBlock?: React.ReactNode;
-  keyReadOnly?: boolean;
   onContinue: (organization: T.Organization) => Promise<void>;
   organization?: T.Organization;
   submitText: string;
@@ -132,12 +131,10 @@ export default class OrganizationDetailsForm extends React.PureComponent<Props,
 
   render() {
     const { submitting } = this.state;
-    const { infoBlock, keyReadOnly } = this.props;
+    const { infoBlock } = this.props;
     return (
       <form id="organization-form" onSubmit={this.handleSubmit}>
-        {!keyReadOnly && (
-          <OrganizationKeyInput initialValue={this.state.key} onChange={this.handleKeyUpdate} />
-        )}
+        <OrganizationKeyInput initialValue={this.state.key} onChange={this.handleKeyUpdate} />
         <div className="big-spacer-top">
           <ResetButtonLink onClick={this.handleAdditionalClick}>
             {translate(
index 1ce72fbeece152f6b6bca6180e38e79524cb350f..0deff24f1954f5573a1dc2ce7ec3e7af1a327a15 100644 (file)
@@ -107,7 +107,7 @@ function shallowRender(props: Partial<AutoOrganizationCreate['props']> = {}) {
     <AutoOrganizationCreate
       almApplication={mockAlmApplication()}
       almInstallId="id-foo"
-      almOrganization={{ ...organization, personal: false }}
+      almOrganization={organization}
       createOrganization={jest.fn()}
       handleCancelImport={jest.fn()}
       handleOrgDetailsFinish={jest.fn()}
diff --git a/server/sonar-web/src/main/js/apps/create/organization/__tests__/AutoPersonalOrganizationBind-test.tsx b/server/sonar-web/src/main/js/apps/create/organization/__tests__/AutoPersonalOrganizationBind-test.tsx
deleted file mode 100644 (file)
index a66aa36..0000000
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2019 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 { shallow } from 'enzyme';
-import AutoPersonalOrganizationBind from '../AutoPersonalOrganizationBind';
-import { waitAndUpdate, click } from '../../../../helpers/testUtils';
-import { Step } from '../utils';
-import { mockAlmOrganization } from '../../../../helpers/testMocks';
-
-const personalOrg = { key: 'personalorg', name: 'Personal Org' };
-const almOrganization = mockAlmOrganization({ personal: true });
-
-it('should render correctly', async () => {
-  const updateOrganization = jest.fn().mockResolvedValue({ key: personalOrg.key });
-  const handleOrgDetailsFinish = jest.fn();
-  const wrapper = shallowRender({
-    almInstallId: 'id-foo',
-    importPersonalOrg: personalOrg,
-    handleOrgDetailsFinish,
-    updateOrganization
-  });
-
-  expect(wrapper).toMatchSnapshot();
-
-  wrapper.find('OrganizationDetailsForm').prop<Function>('onContinue')(personalOrg);
-  await waitAndUpdate(wrapper);
-  expect(handleOrgDetailsFinish).toBeCalled();
-
-  wrapper.setProps({ organization: personalOrg });
-  wrapper.find('PlanStep').prop<Function>('createOrganization')();
-  expect(updateOrganization).toBeCalledWith({ ...personalOrg, installationId: 'id-foo' });
-});
-
-it('should allow to cancel org import', () => {
-  const handleCancelImport = jest.fn();
-  const wrapper = shallowRender({
-    almInstallId: 'id-foo',
-    importPersonalOrg: personalOrg,
-    handleCancelImport
-  });
-
-  click(wrapper.find('ClearButton'));
-  expect(handleCancelImport).toBeCalled();
-});
-
-function shallowRender(props: Partial<AutoPersonalOrganizationBind['props']> = {}) {
-  return shallow(
-    <AutoPersonalOrganizationBind
-      almApplication={{
-        backgroundColor: '#0052CC',
-        iconPath: '"/static/authbitbucket/bitbucket.svg"',
-        installationUrl: 'https://bitbucket.org/install/app',
-        key: 'bitbucket',
-        name: 'BitBucket'
-      }}
-      almOrganization={almOrganization}
-      handleCancelImport={jest.fn()}
-      handleOrgDetailsFinish={jest.fn()}
-      handleOrgDetailsStepOpen={jest.fn()}
-      importPersonalOrg={{ key: 'personalorg', name: 'Personal Org' }}
-      onDone={jest.fn()}
-      step={Step.OrganizationDetails}
-      subscriptionPlans={[{ maxNcloc: 100000, price: 10 }, { maxNcloc: 250000, price: 75 }]}
-      updateOrganization={jest.fn()}
-      {...props}
-    />
-  );
-}
index 0f9760727c9578a25b8565568f9fa0bbe524ba9c..7a529d39c70c5e905b693b9c61f965e08d1dc816 100644 (file)
@@ -63,7 +63,6 @@ jest.mock('../../../../api/alm-integration', () => ({
       description: 'Continuous Code Quality',
       key: 'sonarsource',
       name: 'SonarSource',
-      personal: false,
       privateRepos: 0,
       publicRepos: 3,
       url: 'https://www.sonarsource.com'
@@ -83,12 +82,11 @@ jest.mock('../../../../helpers/storage', () => ({
 }));
 
 const user = mockLoggedInUser();
-const fooAlmOrganization = mockAlmOrganization({ personal: true });
+const fooAlmOrganization = mockAlmOrganization();
 const fooBarAlmOrganization = mockAlmOrganization({
   avatar: 'https://avatars3.githubusercontent.com/u/37629810?v=4',
   key: 'Foo&Bar',
-  name: 'Foo & Bar',
-  personal: true
+  name: 'Foo & Bar'
 });
 
 const boundOrganization = { key: 'foobar', name: 'Foo & Bar' };
@@ -132,22 +130,9 @@ it('should render with auto tab selected and manual disabled', async () => {
   expect(getOrganizations).toHaveBeenCalled();
 });
 
-it('should render with auto personal organization bind page', async () => {
-  (getAlmOrganization as jest.Mock<any>).mockResolvedValueOnce({
-    almOrganization: fooAlmOrganization
-  });
-  const wrapper = shallowRender({
-    currentUser: { ...user, externalProvider: 'github', personalOrganization: 'foo' },
-    location: { query: { installation_id: 'foo' } } as Location
-  });
-  expect(wrapper).toMatchSnapshot();
-  await waitAndUpdate(wrapper);
-  expect(wrapper).toMatchSnapshot();
-});
-
 it('should render with organization bind page', async () => {
   (getAlmOrganization as jest.Mock<any>).mockResolvedValueOnce({
-    almOrganization: { ...fooAlmOrganization, personal: false }
+    almOrganization: fooAlmOrganization
   });
   const wrapper = shallowRender({
     currentUser: { ...user, externalProvider: 'github' },
@@ -235,7 +220,7 @@ it('should redirect to projects creation page after creation', async () => {
     state: { organization: 'foo', tab: 'manual' }
   });
 
-  wrapper.setState({ almOrganization: { ...fooAlmOrganization, personal: false } });
+  wrapper.setState({ almOrganization: fooAlmOrganization });
   (get as jest.Mock<any>).mockReturnValueOnce(Date.now().toString());
   wrapper.instance().handleOrgCreated('foo');
   expect(push).toHaveBeenCalledWith({
@@ -246,7 +231,7 @@ it('should redirect to projects creation page after creation', async () => {
 
 it('should display AutoOrganizationCreate with already bound organization', async () => {
   (getAlmOrganization as jest.Mock<any>).mockResolvedValueOnce({
-    almOrganization: { ...fooBarAlmOrganization, personal: false },
+    almOrganization: fooBarAlmOrganization,
     boundOrganization
   });
   (get as jest.Mock<any>)
@@ -344,7 +329,6 @@ function createComponent(props: Partial<CreateOrganization['props']> = {}) {
       router={mockRouter()}
       routes={[]}
       skipOnboarding={jest.fn()}
-      updateOrganization={jest.fn()}
       userOrganizations={[
         mockOrganizationWithAdminActions(),
         mockOrganizationWithAdminActions(mockOrganizationWithAlm({ key: 'bar', name: 'Bar' })),
index 58a2f95af78964dff1d51c56d44038330302043a..8cdf7afba7759773021c54edd20d6202ee9563ed 100644 (file)
@@ -80,7 +80,7 @@ it('should upgrade', async () => {
 it('should preselect paid plan', async () => {
   const wrapper = shallow(
     <PlanStep
-      almOrganization={mockAlmOrganization({ personal: true, privateRepos: 5, publicRepos: 0 })}
+      almOrganization={mockAlmOrganization({ privateRepos: 5, publicRepos: 0 })}
       createOrganization={jest.fn()}
       onDone={jest.fn()}
       onUpgradeFail={jest.fn()}
index 9b74fb68d4771d6606538dcdae83f07fe5eda854..21741e56c967c8563add427fbb6b3b16c1cf3ed0 100644 (file)
@@ -73,7 +73,6 @@ exports[`should display choice between import or creation 1`] = `
         "description": "description-foo",
         "key": "foo",
         "name": "foo",
-        "personal": false,
         "privateRepos": 0,
         "publicRepos": 3,
         "url": "http://example.com/foo",
@@ -163,7 +162,6 @@ exports[`should render prefilled and create org 1`] = `
           "description": "description-foo",
           "key": "foo",
           "name": "foo",
-          "personal": false,
           "privateRepos": 0,
           "publicRepos": 3,
           "url": "http://example.com/foo",
@@ -189,7 +187,6 @@ exports[`should render prefilled and create org 1`] = `
         "description": "description-foo",
         "key": "foo",
         "name": "foo",
-        "personal": false,
         "privateRepos": 0,
         "publicRepos": 3,
         "url": "http://example.com/foo",
diff --git a/server/sonar-web/src/main/js/apps/create/organization/__tests__/__snapshots__/AutoPersonalOrganizationBind-test.tsx.snap b/server/sonar-web/src/main/js/apps/create/organization/__tests__/__snapshots__/AutoPersonalOrganizationBind-test.tsx.snap
deleted file mode 100644 (file)
index d9ad62a..0000000
+++ /dev/null
@@ -1,100 +0,0 @@
-// Jest Snapshot v1, https://goo.gl/fbAQLP
-
-exports[`should render correctly 1`] = `
-<Fragment>
-  <OrganizationDetailsStep
-    finished={false}
-    onOpen={[MockFunction]}
-    open={true}
-    stepTitle="onboarding.import_organization.personal.import_org_details"
-  >
-    <div
-      className="display-flex-center big-spacer-bottom"
-    >
-      <FormattedMessage
-        defaultMessage="onboarding.import_personal_organization_x"
-        id="onboarding.import_personal_organization_x"
-        values={
-          Object {
-            "avatar": <img
-              alt="BitBucket"
-              className="little-spacer-left"
-              src="/images/sonarcloud/bitbucket.svg"
-              width={16}
-            />,
-            "name": <strong>
-              foo
-            </strong>,
-            "personalAvatar": <OrganizationAvatar
-              organization={
-                Object {
-                  "key": "personalorg",
-                  "name": "Personal Org",
-                }
-              }
-              small={true}
-            />,
-            "personalName": <strong>
-              Personal Org
-            </strong>,
-          }
-        }
-      />
-      <ClearButton
-        className="little-spacer-left"
-        onClick={[MockFunction]}
-      />
-    </div>
-    <OrganizationDetailsForm
-      keyReadOnly={true}
-      onContinue={[Function]}
-      organization={
-        Object {
-          "key": "personalorg",
-          "name": "Personal Org",
-        }
-      }
-      submitText="continue"
-    />
-  </OrganizationDetailsStep>
-  <PlanStep
-    almApplication={
-      Object {
-        "backgroundColor": "#0052CC",
-        "iconPath": "\\"/static/authbitbucket/bitbucket.svg\\"",
-        "installationUrl": "https://bitbucket.org/install/app",
-        "key": "bitbucket",
-        "name": "BitBucket",
-      }
-    }
-    almOrganization={
-      Object {
-        "almUrl": "https://github.com/foo",
-        "avatar": "http://example.com/avatar",
-        "description": "description-foo",
-        "key": "foo",
-        "name": "foo",
-        "personal": true,
-        "privateRepos": 0,
-        "publicRepos": 3,
-        "url": "http://example.com/foo",
-      }
-    }
-    createOrganization={[Function]}
-    onDone={[MockFunction]}
-    open={false}
-    subscriptionPlans={
-      Array [
-        Object {
-          "maxNcloc": 100000,
-          "price": 10,
-        },
-        Object {
-          "maxNcloc": 250000,
-          "price": 75,
-        },
-      ]
-    }
-  />
-</Fragment>
-`;
index aa76ac05400fd41b110894709253fdcb630a14b0..3e5bdda098aeeb21555161c1e8825e862ec06fd5 100644 (file)
@@ -1,92 +1,5 @@
 // Jest Snapshot v1, https://goo.gl/fbAQLP
 
-exports[`should render with auto personal organization bind page 1`] = `
-<AlmApplicationInstalling
-  almKey="github"
-/>
-`;
-
-exports[`should render with auto personal organization bind page 2`] = `
-<Fragment>
-  <HelmetWrapper
-    defer={true}
-    encodeSpecialCharacters={true}
-    title="onboarding.import_organization.personal.page.header"
-    titleTemplate="%s"
-  />
-  <div
-    className="page page-limited huge-spacer-top huge-spacer-bottom"
-  >
-    <A11ySkipTarget
-      anchor="create_org_main"
-    />
-    <header
-      className="page-header huge-spacer-bottom"
-    >
-      <h1
-        className="page-title huge big-spacer-bottom"
-      >
-        <strong>
-          onboarding.import_organization.personal.page.header
-        </strong>
-      </h1>
-    </header>
-    <AutoPersonalOrganizationBind
-      almApplication={
-        Object {
-          "backgroundColor": "blue",
-          "iconPath": "icon/path",
-          "installationUrl": "https://alm.installation.url",
-          "key": "github",
-          "name": "GitHub",
-        }
-      }
-      almInstallId="foo"
-      almOrganization={
-        Object {
-          "almUrl": "https://github.com/foo",
-          "avatar": "http://example.com/avatar",
-          "description": "description-foo",
-          "key": "foo",
-          "name": "foo",
-          "personal": true,
-          "privateRepos": 0,
-          "publicRepos": 3,
-          "url": "http://example.com/foo",
-        }
-      }
-      handleCancelImport={[Function]}
-      handleOrgDetailsFinish={[Function]}
-      handleOrgDetailsStepOpen={[Function]}
-      importPersonalOrg={
-        Object {
-          "actions": Object {
-            "admin": true,
-          },
-          "key": "foo",
-          "name": "Foo",
-        }
-      }
-      onDone={[Function]}
-      step={0}
-      subscriptionPlans={
-        Array [
-          Object {
-            "maxNcloc": 100000,
-            "price": 10,
-          },
-          Object {
-            "maxNcloc": 250000,
-            "price": 75,
-          },
-        ]
-      }
-      updateOrganization={[MockFunction]}
-    />
-  </div>
-</Fragment>
-`;
-
 exports[`should render with auto tab displayed 1`] = `
 <Fragment>
   <HelmetWrapper
@@ -261,7 +174,6 @@ exports[`should render with auto tab selected and manual disabled 2`] = `
           "description": "Continuous Code Quality",
           "key": "sonarsource",
           "name": "SonarSource",
-          "personal": false,
           "privateRepos": 0,
           "publicRepos": 3,
           "url": "https://www.sonarsource.com",
@@ -449,7 +361,6 @@ exports[`should render with organization bind page 2`] = `
           "description": "description-foo",
           "key": "foo",
           "name": "foo",
-          "personal": false,
           "privateRepos": 0,
           "publicRepos": 3,
           "url": "http://example.com/foo",
index f202fc7d3f9684479d6bd2fcd6dfc9eb8530ed52..0d38c7b12b9f7b0104216ac6051fd18edd41d15a 100644 (file)
@@ -30,7 +30,6 @@ exports[`should preselect paid plan 1`] = `
             "description": "description-foo",
             "key": "foo",
             "name": "foo",
-            "personal": true,
             "privateRepos": 5,
             "publicRepos": 0,
             "url": "http://example.com/foo",
index f95556451f880e4cee6b811471164d15764476d5..eb0a5cb17fca8926ea5ffa751759e88da4c4c2f0 100644 (file)
  * 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 actions from '../actions';
+import { createOrganization, syncMembers } from '../../../../api/organizations';
 import { mockOrganization, mockOrganizationWithAlm } from '../../../../helpers/testMocks';
-import { createOrganization, syncMembers, updateOrganization } from '../../../../api/organizations';
-import { bindAlmOrganization } from '../../../../api/alm-integration';
+import * as actions from '../actions';
 
 jest.mock('../../../../api/alm-integration', () => ({
   bindAlmOrganization: jest.fn().mockResolvedValue({})
@@ -64,26 +63,3 @@ describe('#createOrganization', () => {
     expect(syncMembers).toHaveBeenCalledWith(org.key);
   });
 });
-
-describe('#updateOrganization', () => {
-  it('should update and dispatch', async () => {
-    const org = mockOrganization();
-    const { key, ...changes } = org;
-    const promise = actions.updateOrganization(org)(dispatch);
-
-    expect(updateOrganization).toHaveBeenCalledWith(key, changes);
-    const returnValue = await promise;
-    expect(dispatch).toHaveBeenCalledWith({ changes, key, type: 'UPDATE_ORGANIZATION' });
-    expect(returnValue).toBe(key);
-  });
-
-  it('should update and bind', () => {
-    const org = { ...mockOrganization(), installationId: '1' };
-    const { key, installationId, ...changes } = org;
-    const promise = actions.updateOrganization(org)(dispatch);
-
-    expect(updateOrganization).toHaveBeenCalledWith(key, changes);
-    expect(bindAlmOrganization).toHaveBeenCalledWith({ organization: key, installationId });
-    return promise;
-  });
-});
index 38b90fff706cacb17b561dfd351d68235b713440..950156f2876aac487d6ce77b2b9d853f5011da8c 100644 (file)
@@ -18,7 +18,6 @@
  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
  */
 import { Dispatch } from 'redux';
-import { bindAlmOrganization } from '../../../api/alm-integration';
 import * as api from '../../../api/organizations';
 import * as actions from '../../../store/organizations';
 import { isGithub } from '../../../helpers/almIntegrations';
@@ -39,17 +38,3 @@ export function createOrganization({
       });
   };
 }
-
-export function updateOrganization(organization: T.Organization & { installationId?: string }) {
-  return (dispatch: Dispatch) => {
-    const { key, installationId, ...changes } = organization;
-    const promises = [api.updateOrganization(key, changes)];
-    if (installationId) {
-      promises.push(bindAlmOrganization({ organization: key, installationId }));
-    }
-    return Promise.all(promises).then(() => {
-      dispatch(actions.updateOrganization(key, changes));
-      return organization.key;
-    });
-  };
-}
index fa4f38355fb7f22c079b59dc142ced6807b3550c..012a3bd4d13762ed38bdb7ddf349fe3899e5677a 100644 (file)
@@ -25,18 +25,12 @@ import { translate, translateWithParameters } from '../../helpers/l10n';
 import { formatMeasure } from '../../helpers/measures';
 
 export interface Props {
-  currentUser: T.LoggedInUser;
   handleSearch: (query?: string) => void;
   organization: T.Organization;
   total?: number;
 }
 
-export default function MembersListHeader({
-  currentUser,
-  handleSearch,
-  organization,
-  total
-}: Props) {
+export default function MembersListHeader({ handleSearch, organization, total }: Props) {
   return (
     <div className="panel panel-vertical bordered-bottom spacer-bottom">
       <SearchBox
@@ -58,21 +52,18 @@ export default function MembersListHeader({
                       sanitizeAlmId(organization.alm.key)
                     )}
                   </p>
-                  {currentUser.personalOrganization !== organization.key && (
-                    <>
-                      <hr />
-                      <p>
-                        <a
-                          href={getAlmMembersUrl(organization.alm.key, organization.alm.url)}
-                          rel="noopener noreferrer"
-                          target="_blank">
-                          {translateWithParameters(
-                            'organization.members.see_all_members_on_x',
-                            translate(sanitizeAlmId(organization.alm.key))
-                          )}
-                        </a>
-                      </p>
-                    </>
+                  <hr />
+                  <p>
+                    <a
+                      href={getAlmMembersUrl(organization.alm.key, organization.alm.url)}
+                      rel="noopener noreferrer"
+                      target="_blank">
+                      {translateWithParameters(
+                        'organization.members.see_all_members_on_x',
+                        translate(sanitizeAlmId(organization.alm.key))
+                      )}
+                    </a>
+                  </p>
                   )}
                 </div>
               }
index 5440ef11efe149d809be70d932d72784179a185d..c0ee1942a5e27122f5c8fcc6b7d1113c15de9de9 100644 (file)
@@ -212,7 +212,6 @@ export default class OrganizationMembers extends React.PureComponent<Props, Stat
         {members !== undefined && paging !== undefined && (
           <>
             <MembersListHeader
-              currentUser={currentUser}
               handleSearch={this.handleSearchMembers}
               organization={organization}
               total={paging.total}
index 69e1a371773a4ae832e8f8be5c16b2be5c4ff232..5c2d17ddc1db7380e36ffef2e82eb567afcab43f 100644 (file)
 import * as React from 'react';
 import { shallow } from 'enzyme';
 import MembersListHeader, { Props } from '../MembersListHeader';
-import {
-  mockLoggedInUser,
-  mockOrganization,
-  mockOrganizationWithAlm
-} from '../../../helpers/testMocks';
+import { mockOrganization, mockOrganizationWithAlm } from '../../../helpers/testMocks';
 
 it('should render without the total', () => {
   expect(shallowRender({ total: undefined })).toMatchSnapshot();
@@ -50,19 +46,9 @@ it('should render a help tooltip', () => {
   ).toMatchSnapshot();
 });
 
-it('should not render link in help tooltip', () => {
-  expect(
-    shallowRender({
-      currentUser: mockLoggedInUser({ personalOrganization: 'foo' }),
-      organization: mockOrganizationWithAlm({}, { membersSync: true })
-    }).find('HelpTooltip')
-  ).toMatchSnapshot();
-});
-
 function shallowRender(props: Partial<Props> = {}) {
   return shallow(
     <MembersListHeader
-      currentUser={mockLoggedInUser()}
       handleSearch={jest.fn()}
       organization={mockOrganization()}
       total={8}
index e9852b6c3c397a9826d3289187dacd9edadc254a..301923d528dadc2cf54e89d2b97f903969b81c25 100644 (file)
@@ -1,6 +1,6 @@
 // Jest Snapshot v1, https://goo.gl/fbAQLP
 
-exports[`should not render link in help tooltip 1`] = `
+exports[`should render a help tooltip 1`] = `
 <HelpTooltip
   className="spacer-left"
   overlay={
@@ -10,33 +10,17 @@ exports[`should not render link in help tooltip 1`] = `
       <p>
         organization.members.auto_sync_total_help.github
       </p>
-    </div>
-  }
-/>
-`;
-
-exports[`should render a help tooltip 1`] = `
-<HelpTooltip
-  className="spacer-left"
-  overlay={
-    <div
-      className="abs-width-300 markdown cut-margins"
-    >
+      <hr />
       <p>
-        organization.members.auto_sync_total_help.github
+        <a
+          href="https://github.com/orgs/foo/people"
+          rel="noopener noreferrer"
+          target="_blank"
+        >
+          organization.members.see_all_members_on_x.github
+        </a>
       </p>
-      <React.Fragment>
-        <hr />
-        <p>
-          <a
-            href="https://github.com/orgs/foo/people"
-            rel="noopener noreferrer"
-            target="_blank"
-          >
-            organization.members.see_all_members_on_x.github
-          </a>
-        </p>
-      </React.Fragment>
+      )}
     </div>
   }
 />
@@ -52,18 +36,17 @@ exports[`should render a help tooltip 2`] = `
       <p>
         organization.members.auto_sync_total_help.bitbucket
       </p>
-      <React.Fragment>
-        <hr />
-        <p>
-          <a
-            href="https://bitbucket.com/foo/profile/members"
-            rel="noopener noreferrer"
-            target="_blank"
-          >
-            organization.members.see_all_members_on_x.bitbucket
-          </a>
-        </p>
-      </React.Fragment>
+      <hr />
+      <p>
+        <a
+          href="https://bitbucket.com/foo/profile/members"
+          rel="noopener noreferrer"
+          target="_blank"
+        >
+          organization.members.see_all_members_on_x.bitbucket
+        </a>
+      </p>
+      )}
     </div>
   }
 />
index 78bbd758aa1393efa03f636f993b530919cab66b..b10011aca008776fd367d9b87da9e2b4d09601ca 100644 (file)
@@ -72,15 +72,6 @@ exports[`should fetch members and render for non-admin 2`] = `
     refreshMembers={[Function]}
   />
   <MembersListHeader
-    currentUser={
-      Object {
-        "groups": Array [],
-        "isLoggedIn": true,
-        "login": "luke",
-        "name": "Skywalker",
-        "scmAccounts": Array [],
-      }
-    }
     handleSearch={[Function]}
     organization={
       Object {
index 7071c24e9ba350365171078cb52ed198e728243a..09cc660109c31a41f1b0446b710337a6fd21d736 100644 (file)
@@ -79,6 +79,6 @@ export function hasAdminAccess({
   );
 }
 
-export function OrganizationAdminAccess(props: OwnProps) {
+export default function OrganizationAdminAccess(props: OwnProps) {
   return <OrganizationAccessContainer hasAccess={hasAdminAccess} {...props} />;
 }
index 21f0dd439c797ad8024414801bf1678bdf7e5ad1..6a5e4df50a02db4df62d9161630af2d66f932056 100644 (file)
@@ -72,13 +72,8 @@ const routes = [
         childRoutes: qualityGatesRoutes
       },
       {
-        component: lazyLoad(() =>
-          import('./components/OrganizationAccessContainer').then(lib => ({
-            default: lib.OrganizationAdminAccess
-          }))
-        ),
+        component: lazyLoad(() => import('./components/OrganizationAccessContainer')),
         childRoutes: [
-          { path: 'delete', component: lazyLoad(() => import('./components/OrganizationDelete')) },
           { path: 'edit', component: lazyLoad(() => import('./components/OrganizationEdit')) },
           { path: 'groups', component: lazyLoad(() => import('../groups/components/App')) },
           {
index be329f2055eb6b8ed3dbbdbeb03936cf31a961d0..1228a602cced1a81b9f143eb0d87808feb6c0633 100644 (file)
@@ -29,16 +29,13 @@ import { translate } from '../../../helpers/l10n';
 import '../styles.css';
 
 export interface Props {
-  currentUser: T.LoggedInUser;
   onClose: VoidFunction;
   onOpenProjectOnboarding: VoidFunction;
   userOrganizations: T.Organization[];
 }
 
 export function OnboardingModal(props: Props) {
-  const { currentUser, onClose, onOpenProjectOnboarding, userOrganizations } = props;
-
-  const organizations = userOrganizations.filter(o => o.key !== currentUser.personalOrganization);
+  const { onClose, onOpenProjectOnboarding, userOrganizations } = props;
 
   const header = translate('onboarding.header');
   return (
@@ -46,7 +43,7 @@ export function OnboardingModal(props: Props) {
       contentLabel={header}
       onRequestClose={onClose}
       shouldCloseOnOverlayClick={false}
-      size={organizations.length > 0 ? 'medium' : 'small'}>
+      size={userOrganizations.length > 0 ? 'medium' : 'small'}>
       <div className="modal-head">
         <h2>{translate('onboarding.header')}</h2>
         <p className="spacer-top">{translate('onboarding.header.description')}</p>
@@ -59,7 +56,7 @@ export function OnboardingModal(props: Props) {
             {translate('onboarding.project.create')}
           </Button>
         </div>
-        {organizations.length > 0 && (
+        {userOrganizations.length > 0 && (
           <>
             <div className="vertical-pipe-separator">
               <div className="vertical-separator" />
@@ -69,7 +66,7 @@ export function OnboardingModal(props: Props) {
               <h3 className="big-spacer-bottom">
                 {translate('onboarding.browse_your_organizations')}
               </h3>
-              <OrganizationsShortList onClick={onClose} organizations={organizations} />
+              <OrganizationsShortList onClick={onClose} organizations={userOrganizations} />
             </div>
           </>
         )}
index 23ee2e84229d9680dc9a7f6c51b85f5ee559972e..722c04598fbf7629ecd3f3c79fbc64a1dd0a4ba7 100644 (file)
@@ -21,7 +21,7 @@ import * as React from 'react';
 import { shallow } from 'enzyme';
 import { OnboardingModal, Props } from '../OnboardingModal';
 import { click } from '../../../../helpers/testUtils';
-import { mockLoggedInUser, mockOrganization } from '../../../../helpers/testMocks';
+import { mockOrganization } from '../../../../helpers/testMocks';
 
 it('renders correctly', () => {
   expect(shallowRender()).toMatchSnapshot();
@@ -41,22 +41,20 @@ it('should open project create page', () => {
 
 it('should display organization list if any', () => {
   const wrapper = shallowRender({
-    currentUser: mockLoggedInUser({ personalOrganization: 'personal' }),
     userOrganizations: [
       mockOrganization({ key: 'a', name: 'Arthur' }),
-      mockOrganization({ key: 'd', name: 'Daniel Inc' }),
-      mockOrganization({ key: 'personal', name: 'Personal' })
+      mockOrganization({ key: 'b', name: 'Boston Co' }),
+      mockOrganization({ key: 'd', name: 'Daniel Inc' })
     ]
   });
 
   expect(wrapper).toMatchSnapshot();
-  expect(wrapper.find('OrganizationsShortList').prop('organizations')).toHaveLength(2);
+  expect(wrapper.find('OrganizationsShortList').prop('organizations')).toHaveLength(3);
 });
 
 function shallowRender(props: Partial<Props> = {}) {
   return shallow(
     <OnboardingModal
-      currentUser={mockLoggedInUser()}
       onClose={jest.fn()}
       onOpenProjectOnboarding={jest.fn()}
       userOrganizations={[]}
index bd1ed0ad54fbc1f2de55d4a102d71f96a8def499..eabae33e7ae2e8a1c945c509b3eac39c73c26b91 100644 (file)
@@ -117,6 +117,10 @@ exports[`should display organization list if any 1`] = `
               "key": "a",
               "name": "Arthur",
             },
+            Object {
+              "key": "b",
+              "name": "Boston Co",
+            },
             Object {
               "key": "d",
               "name": "Daniel Inc",
index 6548cae6a21771bb3b98acaeef3dd16d64bb5330..dd443262f607268115eb327ab51e58a61f5b146e 100644 (file)
  * along with this program; if not, write to the Free Software Foundation,
  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
  */
-export function getWrappedDisplayName(WrappedComponent: React.ComponentType, hocName: string) {
+export function getWrappedDisplayName<P>(
+  WrappedComponent: React.ComponentType<P>,
+  hocName: string
+) {
   const wrappedDisplayName = WrappedComponent.displayName || WrappedComponent.name || 'Component';
   return `${hocName}(${wrappedDisplayName})`;
 }
index 212af84369f494995e03b73d82f465972695d4ae..8d36e05525309d4dc0390c18de7f6933c63875f4 100644 (file)
@@ -20,7 +20,6 @@
 import {
   isBitbucket,
   isGithub,
-  isPersonal,
   isVSTS,
   sanitizeAlmId,
   getAlmMembersUrl,
@@ -53,19 +52,6 @@ it('#isVSTS', () => {
   expect(isVSTS('github')).toBeFalsy();
 });
 
-it('#isPersonal', () => {
-  const almOrg = {
-    almUrl: '',
-    key: 'foo',
-    name: 'Foo',
-    personal: true,
-    privateRepos: 0,
-    publicRepos: 3
-  };
-  expect(isPersonal(almOrg)).toBeTruthy();
-  expect(isPersonal({ ...almOrg, personal: false })).toBeFalsy();
-});
-
 it('#sanitizeAlmId', () => {
   expect(sanitizeAlmId('bitbucketcloud')).toBe('bitbucket');
   expect(sanitizeAlmId('bitbucket')).toBe('bitbucket');
index 16766f958c9f8e62e6902f8918a0a1a531316132..7c98feba4745fc08b60549bd2f74802e03c7605f 100644 (file)
@@ -53,10 +53,6 @@ export function isVSTS(almKey?: string): boolean {
   return almKey === 'microsoft';
 }
 
-export function isPersonal(organization?: T.AlmOrganization) {
-  return Boolean(organization && organization.personal);
-}
-
 export function sanitizeAlmId(almKey: string) {
   if (isBitbucket(almKey)) {
     return 'bitbucket';
index 9fd2c05f8f921d86f1a741cb877c801acd1c162d..7e9b7eb4d1e10e1ef3006433ae7431762b6c1de4 100644 (file)
@@ -43,7 +43,6 @@ export function mockAlmOrganization(overrides: Partial<T.AlmOrganization> = {}):
     description: 'description-foo',
     key: 'foo',
     name: 'foo',
-    personal: false,
     privateRepos: 0,
     publicRepos: 3,
     url: 'http://example.com/foo',
index 3a940ac84fe130d71e574ff92199d81889a9911c..f70d466e86659677a0088ce5e49d317a7fc9db0d 100644 (file)
@@ -2882,7 +2882,6 @@ onboarding.import_organization.choose_organization_button.github=Choose an organ
 onboarding.import_organization.choose_the_organization_button.bitbucket=Choose the team on Bitbucket
 onboarding.import_organization.choose_the_organization_button.github=Choose the organization on GitHub
 onboarding.import_organization.installing=Finalize installation of the {0} application...
-onboarding.import_organization.personal.page.header=Bind to your personal organization
 onboarding.import_organization.personal.import_org_details=Import personal organization details
 onboarding.import_organization.private.disabled=Selecting private repository is not available yet and will come soon. Meanwhile, you need to create the project manually.
 onboarding.import_organization.import_from_x=Import from {0}