disabledSelectorItems.tsx 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150
  1. import styled from '@emotion/styled';
  2. import omit from 'lodash/omit';
  3. import type {Item} from 'sentry/components/dropdownAutoComplete/types';
  4. import type SelectorItems from 'sentry/components/timeRangeSelector/selectorItems';
  5. import {DEFAULT_RELATIVE_PERIODS, MAX_PICKABLE_DAYS} from 'sentry/constants';
  6. import {IconBusiness} from 'sentry/icons';
  7. import {t} from 'sentry/locale';
  8. import {space} from 'sentry/styles/space';
  9. import UpsellProvider from 'getsentry/components/upsellProvider';
  10. import withSubscription from 'getsentry/components/withSubscription';
  11. import type {Subscription} from 'getsentry/types';
  12. const PREMIUM_PERIODS = ['90d'];
  13. type Props = React.ComponentProps<typeof SelectorItems> & {
  14. subscription: Subscription;
  15. };
  16. function DisabledSelectorItems({
  17. subscription,
  18. relativePeriods: relativePeriodsProp,
  19. shouldShowAbsolute,
  20. shouldShowRelative,
  21. handleSelectRelative,
  22. children,
  23. }: Props) {
  24. let hasFeature: boolean;
  25. if (!subscription || !subscription.planDetails) {
  26. hasFeature = true;
  27. } else {
  28. hasFeature = subscription.planDetails.retentionDays === MAX_PICKABLE_DAYS;
  29. }
  30. const relativePeriods = relativePeriodsProp ?? DEFAULT_RELATIVE_PERIODS;
  31. const hasPremiumPeriods = PREMIUM_PERIODS.some(period =>
  32. relativePeriods.hasOwnProperty(period)
  33. );
  34. const shouldOmitPremiumPeriods = !hasFeature && hasPremiumPeriods;
  35. const omittedRelativePeriods = shouldOmitPremiumPeriods
  36. ? omit(relativePeriods, PREMIUM_PERIODS)
  37. : relativePeriods;
  38. const omittedRelativeArr = Object.entries(omittedRelativePeriods);
  39. const items: Item[] = [
  40. ...(shouldShowRelative
  41. ? omittedRelativeArr.map(([value, itemLabel], index) => ({
  42. index,
  43. value,
  44. searchKey: typeof itemLabel === 'string' ? itemLabel : String(value),
  45. label: <SelectorItemLabel>{itemLabel}</SelectorItemLabel>,
  46. 'data-test-id': value,
  47. }))
  48. : []),
  49. ...(shouldOmitPremiumPeriods
  50. ? [
  51. {
  52. index: omittedRelativeArr.length,
  53. value: '90d-trial',
  54. searchKey:
  55. typeof relativePeriods['90d'] === 'string'
  56. ? relativePeriods['90d']
  57. : '90d-trial',
  58. label: (
  59. <UpsellProvider
  60. source="90-day"
  61. onTrialStarted={() => handleSelectRelative('90d')}
  62. showConfirmation
  63. >
  64. {({canTrial, onClick}) => {
  65. const text = canTrial
  66. ? t('Start Trial for Last 90 Days')
  67. : t('Upgrade for Last 90 Days');
  68. return (
  69. <SelectorItemLabel>
  70. <UpsellClickZone
  71. onClick={e => {
  72. e.preventDefault();
  73. e.stopPropagation();
  74. onClick();
  75. }}
  76. />
  77. <UpsellLabelWrap>
  78. {relativePeriods['90d']}
  79. <StyledIconBusiness gradient data-test-id="power-icon" />
  80. </UpsellLabelWrap>
  81. <UpsellMessage>{text}</UpsellMessage>
  82. </SelectorItemLabel>
  83. );
  84. }}
  85. </UpsellProvider>
  86. ),
  87. 'data-test-id': '90d',
  88. },
  89. ]
  90. : []),
  91. ...(shouldShowAbsolute
  92. ? [
  93. {
  94. index: omittedRelativeArr.length + 1,
  95. value: 'absolute',
  96. searchKey: 'absolute',
  97. label: <SelectorItemLabel>{t('Absolute date')}</SelectorItemLabel>,
  98. 'data-test-id': 'absolute',
  99. },
  100. ]
  101. : []),
  102. ];
  103. return children(items);
  104. }
  105. const SelectorItemLabel = styled('div')`
  106. margin-left: ${space(0.5)};
  107. margin-top: ${space(0.25)};
  108. margin-bottom: ${space(0.25)};
  109. `;
  110. const UpsellLabelWrap = styled('div')`
  111. display: flex;
  112. align-items: center;
  113. `;
  114. const UpsellMessage = styled('p')`
  115. font-size: ${p => p.theme.fontSizeSmall};
  116. color: ${p => p.theme.subText};
  117. margin-bottom: 0;
  118. `;
  119. const UpsellClickZone = styled('div')`
  120. position: absolute;
  121. top: 0;
  122. left: 0;
  123. width: 100%;
  124. height: 100%;
  125. cursor: pointer;
  126. `;
  127. const StyledIconBusiness = styled(IconBusiness)`
  128. display: grid;
  129. align-items: center;
  130. margin-left: ${space(0.5)};
  131. `;
  132. export default withSubscription(DisabledSelectorItems, {noLoader: true});