diff options
author | Stas Vilchik <stas.vilchik@sonarsource.com> | 2018-09-28 16:49:25 +0200 |
---|---|---|
committer | SonarTech <sonartech@sonarsource.com> | 2018-10-12 20:20:58 +0200 |
commit | f52d0c2586ee1fffb12e882cc86c41e036b46ce0 (patch) | |
tree | 4476fce44ad69671550bd470e29097a709d2cc0e /server/sonar-web/src/main/js | |
parent | f0350c5cf3622e723e79e4ea7695741a47c0dbe2 (diff) | |
download | sonarqube-f52d0c2586ee1fffb12e882cc86c41e036b46ce0.tar.gz sonarqube-f52d0c2586ee1fffb12e882cc86c41e036b46ce0.zip |
SONARCLOUD-138 Make forms clearer when upgrading an organization (#761)
Diffstat (limited to 'server/sonar-web/src/main/js')
19 files changed, 53 insertions, 837 deletions
diff --git a/server/sonar-web/src/main/js/app/components/extensions/exposeLibraries.ts b/server/sonar-web/src/main/js/app/components/extensions/exposeLibraries.ts index 3198accbe06..c4fc23fa0db 100644 --- a/server/sonar-web/src/main/js/app/components/extensions/exposeLibraries.ts +++ b/server/sonar-web/src/main/js/app/components/extensions/exposeLibraries.ts @@ -62,6 +62,7 @@ import ActionsDropdown, { ActionsDropdownItem } from '../../../components/contro import ConfirmButton from '../../../components/controls/ConfirmButton'; import SimpleModal from '../../../components/controls/SimpleModal'; import SearchSelect from '../../../components/controls/SearchSelect'; +import RadioToggle from '../../../components/controls/RadioToggle'; const exposeLibraries = () => { const global = window as any; @@ -103,6 +104,7 @@ const exposeLibraries = () => { Modal, PullRequestIcon, QualifierIcon, + RadioToggle, Rating, ReloadButton, ResetButtonLink, diff --git a/server/sonar-web/src/main/js/apps/create/organization/BillingFormShim.tsx b/server/sonar-web/src/main/js/apps/create/organization/BillingFormShim.tsx index f08e3ffc80e..df4a59ebce6 100644 --- a/server/sonar-web/src/main/js/apps/create/organization/BillingFormShim.tsx +++ b/server/sonar-web/src/main/js/apps/create/organization/BillingFormShim.tsx @@ -18,37 +18,21 @@ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ import * as React from 'react'; -import { CurrentUser, SubscriptionPlan, Coupon } from '../../../app/types'; +import { CurrentUser, SubscriptionPlan } from '../../../app/types'; interface ChildrenProps { - alertError: string | undefined; - couponValue: string; onSubmit: React.FormEventHandler; - renderAdditionalInfo: () => React.ReactNode; - renderBillingNameInput: () => React.ReactNode; - renderBraintreeClient: () => React.ReactNode; - renderCountrySelect: () => React.ReactNode; - renderCouponInput: (children?: React.ReactNode) => React.ReactNode; - renderEmailInput: () => React.ReactNode; - renderNextCharge: () => React.ReactNode; - renderPlanSelect: () => React.ReactNode; - renderResetButton: () => React.ReactNode; - renderSpinner: () => React.ReactNode; - renderSubmitButton: (text?: string) => React.ReactNode; - renderTermsOfService: () => React.ReactNode; - renderTypeOfUseSelect: () => React.ReactNode; + renderFormFields: () => React.ReactElement<any>; + renderSubmitGroup: (submitText?: string) => React.ReactElement<any>; } interface Props { children: (props: ChildrenProps) => React.ReactElement<any>; - country?: string; + initialCountry?: string; currentUser: CurrentUser; - onClose: () => void; onCommit: () => void; - onCouponUpdate?: (coupon?: Coupon) => void; onFailToUpgrade?: () => void; organizationKey: string | (() => Promise<string>); - skipBraintreeInit?: boolean; subscriptionPlans: SubscriptionPlan[]; } diff --git a/server/sonar-web/src/main/js/apps/create/organization/CardForm.tsx b/server/sonar-web/src/main/js/apps/create/organization/CardForm.tsx deleted file mode 100644 index 39a739f8ff3..00000000000 --- a/server/sonar-web/src/main/js/apps/create/organization/CardForm.tsx +++ /dev/null @@ -1,91 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2018 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 * as classNames from 'classnames'; -import BillingFormShim from './BillingFormShim'; -import { withCurrentUser } from './withCurrentUser'; -import { CurrentUser, SubscriptionPlan } from '../../../app/types'; -import { translate } from '../../../helpers/l10n'; - -interface Props { - createOrganization: () => Promise<string>; - currentUser: CurrentUser; - onFailToUpgrade: () => void; - onSubmit: () => void; - subscriptionPlans: SubscriptionPlan[]; -} - -export class CardForm extends React.PureComponent<Props> { - handleClose = () => { - // do nothing - }; - - render() { - return ( - <div className="huge-spacer-top"> - <BillingFormShim - currentUser={this.props.currentUser} - onClose={this.handleClose} - onCommit={this.props.onSubmit} - onFailToUpgrade={this.props.onFailToUpgrade} - organizationKey={this.props.createOrganization} - subscriptionPlans={this.props.subscriptionPlans}> - {form => ( - <form onSubmit={form.onSubmit}> - <div className="columns column-show-overflow"> - <div className="column-half"> - <h3>{translate('billing.upgrade.billing_info')}</h3> - {form.renderEmailInput()} - {form.renderTypeOfUseSelect()} - {form.renderBillingNameInput()} - {form.renderCountrySelect()} - {form.renderAdditionalInfo()} - </div> - <div className="column-half"> - <h3>{translate('billing.upgrade.plan')}</h3> - {form.renderPlanSelect()} - <h3>{translate('billing.upgrade.card_info')}</h3> - {form.renderBraintreeClient()} - </div> - </div> - <div className="upgrade-footer big-spacer-top"> - {form.renderNextCharge()} - <hr className="big-spacer-bottom" /> - {form.alertError && <p className="alert alert-danger">{form.alertError}</p>} - </div> - <div - className={classNames({ - 'big-spacer-top': form.alertError !== undefined - })}> - {form.renderSpinner()} - {form.renderSubmitButton( - translate('onboarding.create_organization.create_and_upgrade') - )} - </div> - {form.renderTermsOfService()} - </form> - )} - </BillingFormShim> - </div> - ); - } -} - -export default withCurrentUser(CardForm); diff --git a/server/sonar-web/src/main/js/apps/create/organization/CouponForm.tsx b/server/sonar-web/src/main/js/apps/create/organization/CouponForm.tsx deleted file mode 100644 index fc0a7ab28fe..00000000000 --- a/server/sonar-web/src/main/js/apps/create/organization/CouponForm.tsx +++ /dev/null @@ -1,122 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2018 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 * as classNames from 'classnames'; -import BillingFormShim from './BillingFormShim'; -import { withCurrentUser } from './withCurrentUser'; -import { CurrentUser, Coupon } from '../../../app/types'; -import { translate } from '../../../helpers/l10n'; -import DocTooltip from '../../../components/docs/DocTooltip'; - -interface Props { - createOrganization: () => Promise<string>; - currentUser: CurrentUser; - onFailToUpgrade: () => void; - onSubmit: () => void; -} - -interface State { - coupon?: Coupon; -} - -export class CouponForm extends React.PureComponent<Props, State> { - state: State = {}; - - handleClose = () => { - // do nothing - }; - - handleCouponUpdate = (coupon?: Coupon) => { - this.setState({ coupon }); - }; - - renderBillingInformation() { - if (!this.state.coupon || !this.state.coupon.billing) { - return null; - } - const { billing } = this.state.coupon; - return ( - <div className="big-spacer-top big-spacer-bottom" id="coupon-billing-information"> - <h3 className="note">{translate('billing.upgrade.billing_info')}</h3> - <ul className="note"> - {Boolean(billing.name) && <li>{billing.name}</li>} - {Boolean(billing.address) && <li>{billing.address}</li>} - {Boolean(billing.country) && <li>{billing.country}</li>} - {Boolean(billing.email) && <li>{billing.email}</li>} - </ul> - </div> - ); - } - - render() { - return ( - <div className="huge-spacer-top"> - <BillingFormShim - currentUser={this.props.currentUser} - onClose={this.handleClose} - onCommit={this.props.onSubmit} - onCouponUpdate={this.handleCouponUpdate} - onFailToUpgrade={this.props.onFailToUpgrade} - organizationKey={this.props.createOrganization} - skipBraintreeInit={true} - subscriptionPlans={[]}> - {form => ( - <form onSubmit={form.onSubmit}> - {form.renderCouponInput( - <label htmlFor="coupon"> - {translate('billing.upgrade.coupon')} - <DocTooltip - className="little-spacer-left" - doc={import(/* webpackMode: "eager" */ 'Docs/tooltips/billing/coupon.md')} - /> - </label> - )} - {this.renderBillingInformation()} - {this.state.coupon && - !this.state.coupon.billing && ( - <> - <h3 className="big-spacer-top">{translate('billing.upgrade.billing_info')}</h3> - {form.renderEmailInput()} - {form.renderTypeOfUseSelect()} - {form.renderBillingNameInput()} - {form.renderCountrySelect()} - {form.renderAdditionalInfo()} - </> - )} - {this.state.coupon && ( - <div className="big-spacer-bottom">{form.renderNextCharge()}</div> - )} - {form.alertError && <p className="alert alert-danger">{form.alertError}</p>} - <div className={classNames({ 'big-spacer-top': form.alertError !== undefined })}> - {form.renderSpinner()} - {form.renderSubmitButton( - translate('onboarding.create_organization.create_and_upgrade') - )} - </div> - {form.renderTermsOfService()} - </form> - )} - </BillingFormShim> - </div> - ); - } -} - -export default withCurrentUser(CouponForm); diff --git a/server/sonar-web/src/main/js/apps/create/organization/PaymentMethodSelect.tsx b/server/sonar-web/src/main/js/apps/create/organization/PaymentMethodSelect.tsx deleted file mode 100644 index ddf53728c55..00000000000 --- a/server/sonar-web/src/main/js/apps/create/organization/PaymentMethodSelect.tsx +++ /dev/null @@ -1,57 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2018 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 RadioToggle from '../../../components/controls/RadioToggle'; -import { translate } from '../../../helpers/l10n'; - -export enum PaymentMethod { - Card = 'card', - Coupon = 'coupon' -} - -interface Props { - onChange: (paymentMethod: PaymentMethod) => void; - paymentMethod: PaymentMethod | undefined; -} - -export default class PaymentMethodSelect extends React.PureComponent<Props> { - render() { - const options = Object.values(PaymentMethod).map(value => ({ - label: translate('billing', value), - value - })); - - return ( - <div> - <label className="spacer-bottom"> - {translate('onboarding.create_organization.choose_payment_method')} - </label> - <div className="little-spacer-top"> - <RadioToggle - name="payment-method" - onCheck={this.props.onChange} - options={options} - value={this.props.paymentMethod} - /> - </div> - </div> - ); - } -} diff --git a/server/sonar-web/src/main/js/apps/create/organization/PlanStep.tsx b/server/sonar-web/src/main/js/apps/create/organization/PlanStep.tsx index f715a4f4d48..5118540ce81 100644 --- a/server/sonar-web/src/main/js/apps/create/organization/PlanStep.tsx +++ b/server/sonar-web/src/main/js/apps/create/organization/PlanStep.tsx @@ -18,9 +18,8 @@ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ import * as React from 'react'; -import PaymentMethodSelect, { PaymentMethod } from './PaymentMethodSelect'; -import CardForm from './CardForm'; -import CouponForm from './CouponForm'; +import BillingFormShim from './BillingFormShim'; +import { withCurrentUser } from './withCurrentUser'; import PlanSelect, { Plan } from './PlanSelect'; import Step from '../../tutorials/components/Step'; import { translate } from '../../../helpers/l10n'; @@ -29,6 +28,8 @@ import { SubscriptionPlan } from '../../../app/types'; import { SubmitButton } from '../../../components/ui/buttons'; import DeferredSpinner from '../../../components/common/DeferredSpinner'; +const BillingForm = withCurrentUser(BillingFormShim); + interface Props { createOrganization: () => Promise<string>; deleteOrganization: () => void; @@ -41,7 +42,6 @@ interface Props { } interface State { - paymentMethod?: PaymentMethod; plan: Plan; ready: boolean; submitting: boolean; @@ -79,10 +79,6 @@ export default class PlanStep extends React.PureComponent<Props, State> { this.setState({ plan }); }; - handlePaymentMethodChange = (paymentMethod: PaymentMethod) => { - this.setState({ paymentMethod }); - }; - stopSubmitting = () => { if (this.mounted) { this.setState({ submitting: false }); @@ -108,27 +104,22 @@ export default class PlanStep extends React.PureComponent<Props, State> { )} {this.state.plan === Plan.Paid ? ( - <> - <PaymentMethodSelect - onChange={this.handlePaymentMethodChange} - paymentMethod={this.state.paymentMethod} - /> - {this.state.paymentMethod === PaymentMethod.Card && ( - <CardForm - createOrganization={this.props.createOrganization} - onFailToUpgrade={this.props.deleteOrganization} - onSubmit={this.props.onPaidPlanChoose} - subscriptionPlans={this.props.subscriptionPlans} - /> - )} - {this.state.paymentMethod === PaymentMethod.Coupon && ( - <CouponForm - createOrganization={this.props.createOrganization} - onFailToUpgrade={this.props.deleteOrganization} - onSubmit={this.props.onPaidPlanChoose} - /> + <BillingForm + onCommit={this.props.onPaidPlanChoose} + onFailToUpgrade={this.props.deleteOrganization} + organizationKey={this.props.createOrganization} + subscriptionPlans={this.props.subscriptionPlans}> + {({ onSubmit, renderFormFields, renderSubmitGroup }) => ( + <form onSubmit={onSubmit}> + {renderFormFields()} + <div className="billing-input-large big-spacer-top"> + {renderSubmitGroup( + translate('onboarding.create_organization.create_and_upgrade') + )} + </div> + </form> )} - </> + </BillingForm> ) : ( <div className="display-flex-center big-spacer-top"> <SubmitButton disabled={this.state.submitting} onClick={this.handleFreePlanSubmit}> diff --git a/server/sonar-web/src/main/js/apps/create/organization/__mocks__/BillingFormShim.tsx b/server/sonar-web/src/main/js/apps/create/organization/__mocks__/BillingFormShim.tsx index 4c9b4e3596a..48f5e0dc984 100644 --- a/server/sonar-web/src/main/js/apps/create/organization/__mocks__/BillingFormShim.tsx +++ b/server/sonar-web/src/main/js/apps/create/organization/__mocks__/BillingFormShim.tsx @@ -24,22 +24,9 @@ export default class BillingFormShim extends React.Component<{ children: any }> return ( <div id="BillingFormShim"> {this.props.children({ - alertError: undefined, - couponValue: '', onSubmit: jest.fn(), - renderAdditionalInfo: () => <div id="additional-info" />, - renderBillingNameInput: () => <div id="billing-name" />, - renderBraintreeClient: () => <div id="braintree-client" />, - renderCountrySelect: () => <div id="country-select" />, - renderCouponInput: () => <div id="coupon-input" />, - renderEmailInput: () => <div id="email-input" />, - renderNextCharge: () => <div id="next-charge" />, - renderPlanSelect: () => <div id="plan-select" />, - renderResetButton: () => <div id="reset-button" />, - renderSpinner: () => <div id="spinner" />, - renderSubmitButton: () => <div id="submit-button" />, - renderTermsOfService: () => <div id="terms-of-service" />, - renderTypeOfUseSelect: () => <div id="type-of-use-select" /> + renderFormFields: () => <div id="form-fields" />, + renderSubmitGroup: () => <div id="submit-group" /> })} </div> ); diff --git a/server/sonar-web/src/main/js/apps/create/organization/__tests__/BillingFormShim-test.tsx b/server/sonar-web/src/main/js/apps/create/organization/__tests__/BillingFormShim-test.tsx index 91e2eb8a4ef..71119febaf6 100644 --- a/server/sonar-web/src/main/js/apps/create/organization/__tests__/BillingFormShim-test.tsx +++ b/server/sonar-web/src/main/js/apps/create/organization/__tests__/BillingFormShim-test.tsx @@ -38,7 +38,6 @@ it('should render', () => { shallow( <BillingFormShim currentUser={{ isLoggedIn: false }} - onClose={jest.fn()} onCommit={jest.fn()} organizationKey="org" subscriptionPlans={[]}> diff --git a/server/sonar-web/src/main/js/apps/create/organization/__tests__/CardForm-test.tsx b/server/sonar-web/src/main/js/apps/create/organization/__tests__/CardForm-test.tsx deleted file mode 100644 index 0d8c015ad02..00000000000 --- a/server/sonar-web/src/main/js/apps/create/organization/__tests__/CardForm-test.tsx +++ /dev/null @@ -1,38 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2018 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 { CardForm } from '../CardForm'; - -jest.mock('../BillingFormShim'); - -it('should render', () => { - const wrapper = shallow( - <CardForm - createOrganization={jest.fn()} - currentUser={{ isLoggedIn: false }} - onFailToUpgrade={jest.fn()} - onSubmit={jest.fn()} - subscriptionPlans={[{ maxNcloc: 100000, price: 10 }, { maxNcloc: 250000, price: 75 }]} - /> - ); - expect(wrapper).toMatchSnapshot(); - expect(wrapper.find('BillingFormShim').dive()).toMatchSnapshot(); -}); diff --git a/server/sonar-web/src/main/js/apps/create/organization/__tests__/CouponForm-test.tsx b/server/sonar-web/src/main/js/apps/create/organization/__tests__/CouponForm-test.tsx deleted file mode 100644 index 110e213413c..00000000000 --- a/server/sonar-web/src/main/js/apps/create/organization/__tests__/CouponForm-test.tsx +++ /dev/null @@ -1,36 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2018 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 { CouponForm } from '../CouponForm'; - -jest.mock('../BillingFormShim'); - -it('should render', () => { - const wrapper = shallow( - <CouponForm - createOrganization={jest.fn()} - currentUser={{ isLoggedIn: false }} - onFailToUpgrade={jest.fn()} - onSubmit={jest.fn()} - /> - ); - expect(wrapper).toMatchSnapshot(); -}); diff --git a/server/sonar-web/src/main/js/apps/create/organization/__tests__/PaymentMethodSelect-test.tsx b/server/sonar-web/src/main/js/apps/create/organization/__tests__/PaymentMethodSelect-test.tsx deleted file mode 100644 index fea97e71637..00000000000 --- a/server/sonar-web/src/main/js/apps/create/organization/__tests__/PaymentMethodSelect-test.tsx +++ /dev/null @@ -1,34 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2018 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 PaymentMethodSelect, { PaymentMethod } from '../PaymentMethodSelect'; - -it('should render and change', () => { - const onChange = jest.fn(); - const wrapper = shallow(<PaymentMethodSelect onChange={onChange} paymentMethod={undefined} />); - expect(wrapper).toMatchSnapshot(); - - wrapper.find('RadioToggle').prop<Function>('onCheck')(PaymentMethod.Card); - expect(onChange).toBeCalledWith(PaymentMethod.Card); - - wrapper.setProps({ paymentMethod: PaymentMethod.Card }); - expect(wrapper).toMatchSnapshot(); -}); diff --git a/server/sonar-web/src/main/js/apps/create/organization/__tests__/PlanStep-test.tsx b/server/sonar-web/src/main/js/apps/create/organization/__tests__/PlanStep-test.tsx index ff6937f0014..876a20f0bfd 100644 --- a/server/sonar-web/src/main/js/apps/create/organization/__tests__/PlanStep-test.tsx +++ b/server/sonar-web/src/main/js/apps/create/organization/__tests__/PlanStep-test.tsx @@ -22,7 +22,6 @@ import { shallow } from 'enzyme'; import PlanStep from '../PlanStep'; import { waitAndUpdate, click } from '../../../../helpers/testUtils'; import { Plan } from '../PlanSelect'; -import { PaymentMethod } from '../PaymentMethodSelect'; jest.mock('../../../../app/components/extensions/utils', () => ({ getExtensionStart: jest.fn().mockResolvedValue(undefined) @@ -49,7 +48,7 @@ it('should render and use free plan', async () => { expect(onFreePlanChoose).toBeCalled(); }); -it('should upgrade using card', async () => { +it('should upgrade', async () => { const onPaidPlanChoose = jest.fn(); const wrapper = shallow( <PlanStep @@ -72,48 +71,8 @@ it('should upgrade using card', async () => { wrapper .dive() - .find('PaymentMethodSelect') - .prop<Function>('onChange')(PaymentMethod.Card); - expect(wrapper.dive()).toMatchSnapshot(); - - wrapper - .dive() - .find('Connect(withCurrentUser(CardForm))') - .prop<Function>('onSubmit')(); - expect(onPaidPlanChoose).toBeCalled(); -}); - -it('should upgrade using coupon', async () => { - const onPaidPlanChoose = jest.fn(); - const wrapper = shallow( - <PlanStep - createOrganization={jest.fn().mockResolvedValue('org')} - deleteOrganization={jest.fn().mockResolvedValue(undefined)} - onFreePlanChoose={jest.fn().mockResolvedValue(undefined)} - onPaidPlanChoose={onPaidPlanChoose} - open={true} - startingPrice="10" - subscriptionPlans={[]} - /> - ); - await waitAndUpdate(wrapper); - - wrapper - .dive() - .find('PlanSelect') - .prop<Function>('onChange')(Plan.Paid); - expect(wrapper.dive()).toMatchSnapshot(); - - wrapper - .dive() - .find('PaymentMethodSelect') - .prop<Function>('onChange')(PaymentMethod.Coupon); - expect(wrapper.dive()).toMatchSnapshot(); - - wrapper - .dive() - .find('Connect(withCurrentUser(CouponForm))') - .prop<Function>('onSubmit')(); + .find('Connect(withCurrentUser(BillingFormShim))') + .prop<Function>('onCommit')(); expect(onPaidPlanChoose).toBeCalled(); }); diff --git a/server/sonar-web/src/main/js/apps/create/organization/__tests__/__snapshots__/BillingFormShim-test.tsx.snap b/server/sonar-web/src/main/js/apps/create/organization/__tests__/__snapshots__/BillingFormShim-test.tsx.snap index 5ed8a8cf920..3ab9b1995c6 100644 --- a/server/sonar-web/src/main/js/apps/create/organization/__tests__/__snapshots__/BillingFormShim-test.tsx.snap +++ b/server/sonar-web/src/main/js/apps/create/organization/__tests__/__snapshots__/BillingFormShim-test.tsx.snap @@ -7,7 +7,6 @@ exports[`should render 1`] = ` "isLoggedIn": false, } } - onClose={[MockFunction]} onCommit={[MockFunction]} organizationKey="org" subscriptionPlans={Array []} diff --git a/server/sonar-web/src/main/js/apps/create/organization/__tests__/__snapshots__/CardForm-test.tsx.snap b/server/sonar-web/src/main/js/apps/create/organization/__tests__/__snapshots__/CardForm-test.tsx.snap deleted file mode 100644 index 6d8afdea20e..00000000000 --- a/server/sonar-web/src/main/js/apps/create/organization/__tests__/__snapshots__/CardForm-test.tsx.snap +++ /dev/null @@ -1,107 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`should render 1`] = ` -<div - className="huge-spacer-top" -> - <BillingFormShim - currentUser={ - Object { - "isLoggedIn": false, - } - } - onClose={[Function]} - onCommit={[MockFunction]} - onFailToUpgrade={[MockFunction]} - organizationKey={[MockFunction]} - subscriptionPlans={ - Array [ - Object { - "maxNcloc": 100000, - "price": 10, - }, - Object { - "maxNcloc": 250000, - "price": 75, - }, - ] - } - /> -</div> -`; - -exports[`should render 2`] = ` -<div - id="BillingFormShim" -> - <form - onSubmit={[MockFunction]} - > - <div - className="columns column-show-overflow" - > - <div - className="column-half" - > - <h3> - billing.upgrade.billing_info - </h3> - <div - id="email-input" - /> - <div - id="type-of-use-select" - /> - <div - id="billing-name" - /> - <div - id="country-select" - /> - <div - id="additional-info" - /> - </div> - <div - className="column-half" - > - <h3> - billing.upgrade.plan - </h3> - <div - id="plan-select" - /> - <h3> - billing.upgrade.card_info - </h3> - <div - id="braintree-client" - /> - </div> - </div> - <div - className="upgrade-footer big-spacer-top" - > - <div - id="next-charge" - /> - <hr - className="big-spacer-bottom" - /> - </div> - <div - className="" - > - <div - id="spinner" - /> - <div - id="submit-button" - /> - </div> - <div - id="terms-of-service" - /> - </form> -</div> -`; diff --git a/server/sonar-web/src/main/js/apps/create/organization/__tests__/__snapshots__/CouponForm-test.tsx.snap b/server/sonar-web/src/main/js/apps/create/organization/__tests__/__snapshots__/CouponForm-test.tsx.snap deleted file mode 100644 index b6a054b1c6b..00000000000 --- a/server/sonar-web/src/main/js/apps/create/organization/__tests__/__snapshots__/CouponForm-test.tsx.snap +++ /dev/null @@ -1,22 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`should render 1`] = ` -<div - className="huge-spacer-top" -> - <BillingFormShim - currentUser={ - Object { - "isLoggedIn": false, - } - } - onClose={[Function]} - onCommit={[MockFunction]} - onCouponUpdate={[Function]} - onFailToUpgrade={[MockFunction]} - organizationKey={[MockFunction]} - skipBraintreeInit={true} - subscriptionPlans={Array []} - /> -</div> -`; diff --git a/server/sonar-web/src/main/js/apps/create/organization/__tests__/__snapshots__/PaymentMethodSelect-test.tsx.snap b/server/sonar-web/src/main/js/apps/create/organization/__tests__/__snapshots__/PaymentMethodSelect-test.tsx.snap deleted file mode 100644 index 101582f6012..00000000000 --- a/server/sonar-web/src/main/js/apps/create/organization/__tests__/__snapshots__/PaymentMethodSelect-test.tsx.snap +++ /dev/null @@ -1,79 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`should render and change 1`] = ` -<div> - <label - className="spacer-bottom" - > - onboarding.create_organization.choose_payment_method - </label> - <div - className="little-spacer-top" - > - <RadioToggle - disabled={false} - name="payment-method" - onCheck={[MockFunction]} - options={ - Array [ - Object { - "label": "billing.card", - "value": "card", - }, - Object { - "label": "billing.coupon", - "value": "coupon", - }, - ] - } - value={null} - /> - </div> -</div> -`; - -exports[`should render and change 2`] = ` -<div> - <label - className="spacer-bottom" - > - onboarding.create_organization.choose_payment_method - </label> - <div - className="little-spacer-top" - > - <RadioToggle - disabled={false} - name="payment-method" - onCheck={ - [MockFunction] { - "calls": Array [ - Array [ - "card", - ], - ], - "results": Array [ - Object { - "isThrow": false, - "value": undefined, - }, - ], - } - } - options={ - Array [ - Object { - "label": "billing.card", - "value": "card", - }, - Object { - "label": "billing.coupon", - "value": "coupon", - }, - ] - } - value="card" - /> - </div> -</div> -`; diff --git a/server/sonar-web/src/main/js/apps/create/organization/__tests__/__snapshots__/PlanStep-test.tsx.snap b/server/sonar-web/src/main/js/apps/create/organization/__tests__/__snapshots__/PlanStep-test.tsx.snap index 099c34d7256..d727d30c24b 100644 --- a/server/sonar-web/src/main/js/apps/create/organization/__tests__/__snapshots__/PlanStep-test.tsx.snap +++ b/server/sonar-web/src/main/js/apps/create/organization/__tests__/__snapshots__/PlanStep-test.tsx.snap @@ -35,11 +35,12 @@ exports[`should preselect paid plan 2`] = ` className="boxed-group-inner" > <React.Fragment> - <React.Fragment> - <PaymentMethodSelect - onChange={[Function]} - /> - </React.Fragment> + <Connect(withCurrentUser(BillingFormShim)) + onCommit={[MockFunction]} + onFailToUpgrade={[MockFunction]} + organizationKey={[MockFunction]} + subscriptionPlans={Array []} + /> </React.Fragment> </div> </div> @@ -102,46 +103,7 @@ exports[`should render and use free plan 2`] = ` </div> `; -exports[`should upgrade using card 1`] = ` -<div - className="boxed-group onboarding-step is-open" -> - <div - className="onboarding-step-number" - > - 2 - </div> - <div - className="boxed-group-header" - > - <h2> - onboarding.create_organization.choose_plan - </h2> - </div> - <div - className="" - > - <div - className="boxed-group-inner" - > - <React.Fragment> - <PlanSelect - onChange={[Function]} - plan="paid" - startingPrice="10" - /> - <React.Fragment> - <PaymentMethodSelect - onChange={[Function]} - /> - </React.Fragment> - </React.Fragment> - </div> - </div> -</div> -`; - -exports[`should upgrade using card 2`] = ` +exports[`should upgrade 1`] = ` <div className="boxed-group onboarding-step is-open" > @@ -169,102 +131,12 @@ exports[`should upgrade using card 2`] = ` plan="paid" startingPrice="10" /> - <React.Fragment> - <PaymentMethodSelect - onChange={[Function]} - paymentMethod="card" - /> - <Connect(withCurrentUser(CardForm)) - createOrganization={[MockFunction]} - onFailToUpgrade={[MockFunction]} - onSubmit={[MockFunction]} - subscriptionPlans={Array []} - /> - </React.Fragment> - </React.Fragment> - </div> - </div> -</div> -`; - -exports[`should upgrade using coupon 1`] = ` -<div - className="boxed-group onboarding-step is-open" -> - <div - className="onboarding-step-number" - > - 2 - </div> - <div - className="boxed-group-header" - > - <h2> - onboarding.create_organization.choose_plan - </h2> - </div> - <div - className="" - > - <div - className="boxed-group-inner" - > - <React.Fragment> - <PlanSelect - onChange={[Function]} - plan="paid" - startingPrice="10" - /> - <React.Fragment> - <PaymentMethodSelect - onChange={[Function]} - /> - </React.Fragment> - </React.Fragment> - </div> - </div> -</div> -`; - -exports[`should upgrade using coupon 2`] = ` -<div - className="boxed-group onboarding-step is-open" -> - <div - className="onboarding-step-number" - > - 2 - </div> - <div - className="boxed-group-header" - > - <h2> - onboarding.create_organization.choose_plan - </h2> - </div> - <div - className="" - > - <div - className="boxed-group-inner" - > - <React.Fragment> - <PlanSelect - onChange={[Function]} - plan="paid" - startingPrice="10" + <Connect(withCurrentUser(BillingFormShim)) + onCommit={[MockFunction]} + onFailToUpgrade={[MockFunction]} + organizationKey={[MockFunction]} + subscriptionPlans={Array []} /> - <React.Fragment> - <PaymentMethodSelect - onChange={[Function]} - paymentMethod="coupon" - /> - <Connect(withCurrentUser(CouponForm)) - createOrganization={[MockFunction]} - onFailToUpgrade={[MockFunction]} - onSubmit={[MockFunction]} - /> - </React.Fragment> </React.Fragment> </div> </div> diff --git a/server/sonar-web/src/main/js/apps/tutorials/styles.css b/server/sonar-web/src/main/js/apps/tutorials/styles.css index e7cc5a727f6..86f633a3a3b 100644 --- a/server/sonar-web/src/main/js/apps/tutorials/styles.css +++ b/server/sonar-web/src/main/js/apps/tutorials/styles.css @@ -32,6 +32,10 @@ line-height: var(--controlHeight); } +.onboarding-step hr { + margin-left: -54px; +} + .onboarding-step-number { position: absolute; top: 15px; diff --git a/server/sonar-web/src/main/js/components/controls/HelpTooltip.tsx b/server/sonar-web/src/main/js/components/controls/HelpTooltip.tsx index bc68b868f4d..0cba9b66e12 100644 --- a/server/sonar-web/src/main/js/components/controls/HelpTooltip.tsx +++ b/server/sonar-web/src/main/js/components/controls/HelpTooltip.tsx @@ -19,7 +19,7 @@ */ import * as React from 'react'; import * as classNames from 'classnames'; -import Tooltip from './Tooltip'; +import Tooltip, { Placement } from './Tooltip'; import HelpIcon from '../icons-components/HelpIcon'; import * as theme from '../../app/theme'; import './HelpTooltip.css'; @@ -29,6 +29,7 @@ interface Props { children?: React.ReactNode; onShow?: () => void; overlay: React.ReactNode; + placement?: Placement; tagName?: string; } @@ -38,7 +39,11 @@ export default function HelpTooltip(props: Props) { return React.createElement( tagName, { className: classNames('help-tooltip', props.className) }, - <Tooltip mouseLeaveDelay={0.25} onShow={props.onShow} overlay={props.overlay}> + <Tooltip + mouseLeaveDelay={0.25} + onShow={props.onShow} + overlay={props.overlay} + placement={props.placement}> <span className="display-inline-flex-center">{children}</span> </Tooltip> ); |