samplingModeField.tsx 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  1. import {Fragment} from 'react';
  2. import {css} from '@emotion/react';
  3. import {
  4. addErrorMessage,
  5. addLoadingMessage,
  6. addSuccessMessage,
  7. } from 'sentry/actionCreators/indicator';
  8. import {Button} from 'sentry/components/button';
  9. import Confirm from 'sentry/components/confirm';
  10. import FieldGroup from 'sentry/components/forms/fieldGroup';
  11. import ExternalLink from 'sentry/components/links/externalLink';
  12. import {t, tct} from 'sentry/locale';
  13. import useOrganization from 'sentry/utils/useOrganization';
  14. import {useUpdateOrganization} from 'sentry/views/settings/dynamicSampling/utils/useUpdateOrganization';
  15. import {useAccess} from 'sentry/views/settings/projectMetrics/access';
  16. const switchToManualMessage = tct(
  17. 'Switching to manual mode disables automatic adjustments. After the switch, you can configure individual sample rates for each project. Dynamic sampling priorities continue to apply within the projects. [link:Learn more]',
  18. {
  19. link: (
  20. <ExternalLink href="https://docs.sentry.io/product/performance/retention-priorities/" />
  21. ),
  22. }
  23. );
  24. const switchToAutoMessage = tct(
  25. 'Switching to automatic mode enables continuous adjustments for your projects based on a global target sample rate. Sentry boosts the sample rates of small projects and ensures equal visibility. [link:Learn more]',
  26. {
  27. link: (
  28. <ExternalLink href="https://docs.sentry.io/product/performance/retention-priorities/" />
  29. ),
  30. }
  31. );
  32. export function SamplingModeField() {
  33. const {samplingMode} = useOrganization();
  34. const {hasAccess} = useAccess({access: ['org:write']});
  35. const {mutate: updateOrganization, isPending} = useUpdateOrganization({
  36. onMutate: () => {
  37. addLoadingMessage(t('Switching sampling mode...'));
  38. },
  39. onSuccess: () => {
  40. addSuccessMessage(t('Changes applied.'));
  41. },
  42. onError: () => {
  43. addErrorMessage(t('Unable to save changes. Please try again.'));
  44. },
  45. });
  46. const handleSwitchMode = () => {
  47. updateOrganization({
  48. samplingMode: samplingMode === 'organization' ? 'project' : 'organization',
  49. });
  50. };
  51. return (
  52. <FieldGroup
  53. disabled={!hasAccess}
  54. label={t('Switch Mode')}
  55. help={
  56. samplingMode === 'organization'
  57. ? t('Take control over the individual sample rates in your projects.')
  58. : t('Let Sentry monitor span volume and adjust sample rates automatically.')
  59. }
  60. >
  61. <Confirm
  62. disabled={!hasAccess || isPending}
  63. message={
  64. <Fragment>
  65. <p>
  66. {samplingMode === 'organization'
  67. ? switchToManualMessage
  68. : switchToAutoMessage}
  69. </p>
  70. {samplingMode === 'organization' ? (
  71. <p>{t('You can switch back to automatic mode at any time.')}</p>
  72. ) : (
  73. <p>
  74. {tct(
  75. 'By switching [strong:you will lose your manually defined sample rates].',
  76. {
  77. strong: <strong />,
  78. }
  79. )}
  80. </p>
  81. )}
  82. </Fragment>
  83. }
  84. header={
  85. <h5>
  86. {samplingMode === 'organization'
  87. ? t('Switch to Manual Mode')
  88. : t('Switch to Automatic Mode')}
  89. </h5>
  90. }
  91. confirmText={t('Switch Mode')}
  92. cancelText={t('Cancel')}
  93. onConfirm={handleSwitchMode}
  94. >
  95. <Button
  96. css={css`
  97. width: max-content;
  98. `}
  99. >
  100. {samplingMode === 'organization'
  101. ? t('Switch to Manual')
  102. : t('Switch to Automatic')}
  103. </Button>
  104. </Confirm>
  105. </FieldGroup>
  106. );
  107. }