diff options
author | Grégoire Aubert <gregoire.aubert@sonarsource.com> | 2018-10-24 17:42:35 +0200 |
---|---|---|
committer | SonarTech <sonartech@sonarsource.com> | 2018-11-16 20:21:05 +0100 |
commit | 5abfbcd37980abad5ba8d127582476d1d58b7358 (patch) | |
tree | 14b5bf951e8dcc7405669ecd259f8bda3fe3c8a8 | |
parent | e7b860647b22904459d19a2bb5f8713d20322ef0 (diff) | |
download | sonarqube-5abfbcd37980abad5ba8d127582476d1d58b7358.tar.gz sonarqube-5abfbcd37980abad5ba8d127582476d1d58b7358.zip |
SONAR-11322 Display manual/auto tab on project and organization page depending on context
10 files changed, 69 insertions, 55 deletions
diff --git a/server/sonar-web/src/main/js/app/components/StartupModal.tsx b/server/sonar-web/src/main/js/app/components/StartupModal.tsx index 155c2984e5d..76d0083725f 100644 --- a/server/sonar-web/src/main/js/app/components/StartupModal.tsx +++ b/server/sonar-web/src/main/js/app/components/StartupModal.tsx @@ -21,7 +21,7 @@ import * as React from 'react'; import * as PropTypes from 'prop-types'; import { connect } from 'react-redux'; import { withRouter, WithRouterProps } from 'react-router'; -import { CurrentUser } from '../types'; +import { CurrentUser, Organization } from '../types'; import { differenceInDays, parseDate, toShortNotSoISOString } from '../../helpers/dates'; import { EditionKey } from '../../apps/marketplace/utils'; import { getCurrentUser, getAppState, Store } from '../../store/rootReducer'; @@ -121,10 +121,15 @@ export class StartupModal extends React.PureComponent<Props, State> { this.props.router.push({ pathname: '/create-organization', state: { paid: true } }); }; - openProjectOnboarding = (organization?: string) => { + openProjectOnboarding = (organization?: Organization) => { if (isSonarCloud()) { this.setState({ automatic: false, modal: undefined }); - this.props.router.push({ pathname: `/projects/create`, state: { organization } }); + const state: { organization?: string; tab?: string } = {}; + if (organization) { + state.organization = organization.key; + state.tab = organization.alm ? 'auto' : 'manual'; + } + this.props.router.push({ pathname: `/projects/create`, state }); } else { this.setState({ modal: ModalKey.projectOnboarding }); } diff --git a/server/sonar-web/src/main/js/apps/create/project/OrganizationInput.tsx b/server/sonar-web/src/main/js/apps/create/project/OrganizationInput.tsx index b917efd6125..e7fea91bbac 100644 --- a/server/sonar-web/src/main/js/apps/create/project/OrganizationInput.tsx +++ b/server/sonar-web/src/main/js/apps/create/project/OrganizationInput.tsx @@ -18,7 +18,7 @@ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ import * as React from 'react'; -import { Link } from 'react-router'; +import { WithRouterProps, withRouter } from 'react-router'; import OrganizationSelect from '../components/OrganizationSelect'; import { Organization } from '../../../app/types'; import { translate } from '../../../helpers/l10n'; @@ -30,28 +30,37 @@ interface Props { organizations: Organization[]; } -export default function OrganizationInput({ - autoImport, - onChange, - organization, - organizations -}: Props) { - return ( - <div className="form-field spacer-bottom"> - <label htmlFor="select-organization"> - {translate('onboarding.create_project.organization')} - <em className="mandatory">*</em> - </label> - <OrganizationSelect - onChange={onChange} - organization={organization} - organizations={organizations} - /> - <Link className="big-spacer-left js-new-org" to="/create-organization"> - {autoImport - ? translate('onboarding.create_project.import_new_org') - : translate('onboarding.create_project.create_new_org')} - </Link> - </div> - ); +export class OrganizationInput extends React.PureComponent<Props & WithRouterProps> { + handleLinkClick = (event: React.MouseEvent<HTMLAnchorElement>) => { + event.preventDefault(); + event.stopPropagation(); + this.props.router.push({ + pathname: '/create-organization', + state: { tab: this.props.autoImport ? 'auto' : 'manual' } + }); + }; + + render() { + const { autoImport, onChange, organization, organizations } = this.props; + return ( + <div className="form-field spacer-bottom"> + <label htmlFor="select-organization"> + {translate('onboarding.create_project.organization')} + <em className="mandatory">*</em> + </label> + <OrganizationSelect + onChange={onChange} + organization={organization} + organizations={organizations} + /> + <a className="big-spacer-left js-new-org" href="#" onClick={this.handleLinkClick}> + {autoImport + ? translate('onboarding.create_project.import_new_org') + : translate('onboarding.create_project.create_new_org')} + </a> + </div> + ); + } } + +export default withRouter(OrganizationInput); diff --git a/server/sonar-web/src/main/js/apps/create/project/__tests__/ManualProjectCreate-test.tsx b/server/sonar-web/src/main/js/apps/create/project/__tests__/ManualProjectCreate-test.tsx index e8e33a81ac1..aad0cab3ad2 100644 --- a/server/sonar-web/src/main/js/apps/create/project/__tests__/ManualProjectCreate-test.tsx +++ b/server/sonar-web/src/main/js/apps/create/project/__tests__/ManualProjectCreate-test.tsx @@ -38,7 +38,7 @@ it('should render correctly', () => { it('should correctly create a project', async () => { const onProjectCreate = jest.fn(); const wrapper = getWrapper({ onProjectCreate }); - wrapper.find('OrganizationInput').prop<Function>('onChange')({ key: 'foo' }); + wrapper.find('withRouter(OrganizationInput)').prop<Function>('onChange')({ key: 'foo' }); change(wrapper.find('#project-name'), 'Bar'); expect(wrapper.find('SubmitButton')).toMatchSnapshot(); diff --git a/server/sonar-web/src/main/js/apps/create/project/__tests__/OrganizationInput-test.tsx b/server/sonar-web/src/main/js/apps/create/project/__tests__/OrganizationInput-test.tsx index f6fcd45a248..b965f11602f 100644 --- a/server/sonar-web/src/main/js/apps/create/project/__tests__/OrganizationInput-test.tsx +++ b/server/sonar-web/src/main/js/apps/create/project/__tests__/OrganizationInput-test.tsx @@ -19,7 +19,8 @@ */ import * as React from 'react'; import { shallow } from 'enzyme'; -import OrganizationInput from '../OrganizationInput'; +import { OrganizationInput } from '../OrganizationInput'; +import { mockRouter } from '../../../../helpers/testUtils'; const organizations = [ { key: 'foo', name: 'Foo' }, @@ -27,21 +28,23 @@ const organizations = [ ]; it('should render correctly', () => { + expect(shallowRender()).toMatchSnapshot(); expect( - shallow( - <OrganizationInput onChange={jest.fn()} organization="bar" organizations={organizations} /> - ) - ).toMatchSnapshot(); - expect( - shallow( - <OrganizationInput - autoImport={true} - onChange={jest.fn()} - organization="bar" - organizations={organizations} - /> - ) + shallowRender({ autoImport: true }) .find('.js-new-org') .contains('onboarding.create_project.import_new_org') ).toBe(true); }); + +function shallowRender(props: Partial<OrganizationInput['props']> = {}) { + return shallow( + // @ts-ignore avoid passing everything from WithRouterProps + <OrganizationInput + onChange={jest.fn()} + organization="bar" + organizations={organizations} + router={mockRouter()} + {...props} + /> + ); +} diff --git a/server/sonar-web/src/main/js/apps/create/project/__tests__/__snapshots__/AutoProjectCreate-test.tsx.snap b/server/sonar-web/src/main/js/apps/create/project/__tests__/__snapshots__/AutoProjectCreate-test.tsx.snap index 6623016dd4f..cd98e6da4c2 100644 --- a/server/sonar-web/src/main/js/apps/create/project/__tests__/__snapshots__/AutoProjectCreate-test.tsx.snap +++ b/server/sonar-web/src/main/js/apps/create/project/__tests__/__snapshots__/AutoProjectCreate-test.tsx.snap @@ -2,7 +2,7 @@ exports[`should display the bounded organizations dropdown with the list of repositories 1`] = ` <Fragment> - <OrganizationInput + <withRouter(OrganizationInput) autoImport={true} onChange={[Function]} organization="foo" diff --git a/server/sonar-web/src/main/js/apps/create/project/__tests__/__snapshots__/ManualProjectCreate-test.tsx.snap b/server/sonar-web/src/main/js/apps/create/project/__tests__/__snapshots__/ManualProjectCreate-test.tsx.snap index 4f38672a053..7f1e64d67e9 100644 --- a/server/sonar-web/src/main/js/apps/create/project/__tests__/__snapshots__/ManualProjectCreate-test.tsx.snap +++ b/server/sonar-web/src/main/js/apps/create/project/__tests__/__snapshots__/ManualProjectCreate-test.tsx.snap @@ -21,7 +21,7 @@ exports[`should render correctly 1`] = ` <form onSubmit={[Function]} > - <OrganizationInput + <withRouter(OrganizationInput) onChange={[Function]} organization="" organizations={ diff --git a/server/sonar-web/src/main/js/apps/create/project/__tests__/__snapshots__/OrganizationInput-test.tsx.snap b/server/sonar-web/src/main/js/apps/create/project/__tests__/__snapshots__/OrganizationInput-test.tsx.snap index fe6c8d4e3f6..265fe1d1fe8 100644 --- a/server/sonar-web/src/main/js/apps/create/project/__tests__/__snapshots__/OrganizationInput-test.tsx.snap +++ b/server/sonar-web/src/main/js/apps/create/project/__tests__/__snapshots__/OrganizationInput-test.tsx.snap @@ -34,13 +34,12 @@ exports[`should render correctly 1`] = ` ] } /> - <Link + <a className="big-spacer-left js-new-org" - onlyActiveOnIndex={false} - style={Object {}} - to="/create-organization" + href="#" + onClick={[Function]} > onboarding.create_project.create_new_org - </Link> + </a> </div> `; diff --git a/server/sonar-web/src/main/js/apps/organizations/components/OrganizationJustCreated.tsx b/server/sonar-web/src/main/js/apps/organizations/components/OrganizationJustCreated.tsx index c77fabe8c26..c1ad4439f60 100644 --- a/server/sonar-web/src/main/js/apps/organizations/components/OrganizationJustCreated.tsx +++ b/server/sonar-web/src/main/js/apps/organizations/components/OrganizationJustCreated.tsx @@ -37,7 +37,7 @@ export class OrganizationJustCreated extends React.PureComponent<Props & WithRou }; handleNewProjectClick = () => { - this.context.openProjectOnboarding(this.props.organization.key); + this.context.openProjectOnboarding(this.props.organization); }; handleAddMembersClick = () => { diff --git a/server/sonar-web/src/main/js/apps/organizations/components/__tests__/OrganizationJustCreated-test.tsx b/server/sonar-web/src/main/js/apps/organizations/components/__tests__/OrganizationJustCreated-test.tsx index cc6298cd304..ef6c0c10ea6 100644 --- a/server/sonar-web/src/main/js/apps/organizations/components/__tests__/OrganizationJustCreated-test.tsx +++ b/server/sonar-web/src/main/js/apps/organizations/components/__tests__/OrganizationJustCreated-test.tsx @@ -37,7 +37,7 @@ it('should create new project', () => { context: { openProjectOnboarding } }); click(wrapper.find('Button').first()); - expect(openProjectOnboarding).toBeCalledWith('foo'); + expect(openProjectOnboarding).toBeCalledWith({ key: 'foo', name: 'Foo' }); }); it('should add members', () => { 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 42fa6f2f116..09668bcd0e5 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 @@ -36,9 +36,7 @@ export default class EmptyInstance extends React.PureComponent<Props> { }; analyzeNewProject = () => { - const { organization } = this.props; - const organizationKey = organization && organization.key; - this.context.openProjectOnboarding(organizationKey); + this.context.openProjectOnboarding(this.props.organization); }; render() { |