trialSubscriptionAction.tsx 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151
  1. import {Component, Fragment} from 'react';
  2. import moment from 'moment-timezone';
  3. import {Alert} from 'sentry/components/core/alert';
  4. import NumberField from 'sentry/components/forms/fields/numberField';
  5. import SelectField from 'sentry/components/forms/fields/selectField';
  6. import type {
  7. AdminConfirmParams,
  8. AdminConfirmRenderProps,
  9. } from 'admin/components/adminConfirmationModal';
  10. import type {Subscription} from 'getsentry/types';
  11. import {PlanTier} from 'getsentry/types';
  12. type Props = AdminConfirmRenderProps & {
  13. subscription: Subscription;
  14. canUseTrialOverride?: boolean;
  15. startEnterpriseTrial?: boolean;
  16. };
  17. type State = {
  18. trialDays: number;
  19. trialPlanOverride?: string;
  20. trialTier?: PlanTier;
  21. };
  22. /**
  23. * Rendered as part of a openAdminConfirmModal call
  24. */
  25. class TrialSubscriptionAction extends Component<Props, State> {
  26. state: State = {
  27. trialDays: 14,
  28. trialTier: PlanTier.AM3,
  29. trialPlanOverride: undefined,
  30. };
  31. componentDidMount() {
  32. this.props.setConfirmCallback(this.handleConfirm);
  33. }
  34. handleConfirm = (_params: AdminConfirmParams) => {
  35. const {trialDays, trialTier, trialPlanOverride} = this.state;
  36. const {startEnterpriseTrial, onConfirm} = this.props;
  37. // XXX(epurkhiser): In the original implementation none of the audit params
  38. // were passed, is that an oversight?
  39. const data = {
  40. trialDays,
  41. ...(startEnterpriseTrial && {
  42. startEnterpriseTrial,
  43. trialTier,
  44. trialPlanOverride,
  45. }),
  46. };
  47. onConfirm?.(data);
  48. };
  49. onDaysChange = (value: string) => {
  50. const trialDays = parseInt(value, 10) || 0;
  51. this.setState({trialDays});
  52. this.props.disableConfirmButton(trialDays <= 0);
  53. };
  54. get actionLabel(): string {
  55. const {subscription, startEnterpriseTrial} = this.props;
  56. if (startEnterpriseTrial) {
  57. return 'Start Enterprise Trial';
  58. }
  59. return subscription.isTrial ? 'Extend Trial' : 'Start Trial';
  60. }
  61. render() {
  62. const {subscription, startEnterpriseTrial, canUseTrialOverride = false} = this.props;
  63. const {trialDays, trialTier, trialPlanOverride} = this.state;
  64. const AM3_ENTERPRISE_TRIAL_PLAN = 'am3_t_ent_ds';
  65. if (!subscription) {
  66. return null;
  67. }
  68. const currentTrialEnd = moment(
  69. (!startEnterpriseTrial && subscription.trialEnd) || undefined
  70. );
  71. const trialEndDate = currentTrialEnd.add(trialDays, 'days').format('MMMM Do YYYY');
  72. const tierChoices: Array<[string | PlanTier, string | PlanTier]> = [];
  73. // TODO(DS Spans): remove canUseTrialOverride once we've launched
  74. if (canUseTrialOverride) {
  75. // TODO(DS Spans): remove this if we ever put DS on the regular AM3 enterprise trial
  76. tierChoices.push([AM3_ENTERPRISE_TRIAL_PLAN, 'am3 with Dynamic Sampling']);
  77. }
  78. tierChoices.push(
  79. [PlanTier.AM3, PlanTier.AM3],
  80. [PlanTier.AM2, PlanTier.AM2],
  81. [PlanTier.AM1, PlanTier.AM1]
  82. );
  83. return (
  84. <Fragment>
  85. {startEnterpriseTrial && (
  86. <Alert.Container>
  87. <Alert type="info" showIcon>
  88. Spike protection will need to be manually disabled.
  89. </Alert>
  90. </Alert.Container>
  91. )}
  92. <NumberField
  93. inline={false}
  94. stacked
  95. flexibleControlStateSize
  96. label="Number of Days"
  97. help={
  98. <Fragment>
  99. Their trial will end on <strong>{trialEndDate}</strong>
  100. </Fragment>
  101. }
  102. name="days"
  103. value={trialDays}
  104. onChange={this.onDaysChange}
  105. />
  106. <div data-test-id="trial-plan-tier-choices">
  107. {startEnterpriseTrial && (
  108. <SelectField
  109. inline={false}
  110. stacked
  111. flexibleControlStateSize
  112. label="Trial Plan Tier"
  113. name="tier"
  114. value={trialPlanOverride ?? trialTier}
  115. onChange={(val: any) => {
  116. if (val === AM3_ENTERPRISE_TRIAL_PLAN) {
  117. this.setState({trialPlanOverride: val});
  118. } else {
  119. this.setState({trialTier: val, trialPlanOverride: undefined});
  120. }
  121. }}
  122. choices={tierChoices}
  123. />
  124. )}
  125. </div>
  126. </Fragment>
  127. );
  128. }
  129. }
  130. export default TrialSubscriptionAction;