extrapolationField.tsx 2.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576
  1. import {useEffect, useState} from 'react';
  2. import {
  3. addErrorMessage,
  4. addLoadingMessage,
  5. addSuccessMessage,
  6. } from 'sentry/actionCreators/indicator';
  7. import BooleanField from 'sentry/components/forms/fields/booleanField';
  8. import ExternalLink from 'sentry/components/links/externalLink';
  9. import Panel from 'sentry/components/panels/panel';
  10. import PanelBody from 'sentry/components/panels/panelBody';
  11. import {t, tct} from 'sentry/locale';
  12. import ProjectsStore from 'sentry/stores/projectsStore';
  13. import type {Project} from 'sentry/types/project';
  14. import {useMutation} from 'sentry/utils/queryClient';
  15. import type RequestError from 'sentry/utils/requestError/requestError';
  16. import useApi from 'sentry/utils/useApi';
  17. import useOrganization from 'sentry/utils/useOrganization';
  18. interface ExtrapolationFieldProps {
  19. project: Project;
  20. }
  21. export function ExtrapolationField({project}: ExtrapolationFieldProps) {
  22. const organization = useOrganization();
  23. const api = useApi();
  24. const [isToggleEnabled, setIsToggleEnabled] = useState(!project.extrapolateMetrics);
  25. // Reload from props if new project state is received
  26. useEffect(() => {
  27. setIsToggleEnabled(!project.extrapolateMetrics);
  28. }, [project.extrapolateMetrics]);
  29. const {mutate: handleToggleChange} = useMutation<Project, RequestError, boolean>({
  30. mutationFn: value => {
  31. return api.requestPromise(`/projects/${organization.slug}/${project.slug}/`, {
  32. method: 'PUT',
  33. data: {
  34. extrapolateMetrics: !value,
  35. },
  36. });
  37. },
  38. onMutate: () => {
  39. addLoadingMessage(t('Toggling sampled mode'));
  40. },
  41. onSuccess: updatedProject => {
  42. addSuccessMessage(t('Successfully toggled sampled mode'));
  43. ProjectsStore.onUpdateSuccess(updatedProject);
  44. },
  45. onError: () => {
  46. addErrorMessage(t('Failed to toggle sampled mode'));
  47. },
  48. });
  49. return (
  50. <Panel>
  51. <PanelBody>
  52. <BooleanField
  53. onChange={handleToggleChange}
  54. value={isToggleEnabled}
  55. name="metrics-extrapolation-toggle"
  56. disabled={!project.access.includes('project:write')} // admin, manager and owner of an organization will be able to edit this field
  57. label={t('Sampled Mode')}
  58. help={tct(
  59. 'Typically, Sentry uses weights to approximate original volume and correct sampling skew. Enable sampled mode to view raw event data, where sample rates are ignored in calculations. [link:Read the docs] to learn more.',
  60. {
  61. // TODO(telemetry-experience): Add link to metrics extrapolation docs when available
  62. link: <ExternalLink href="https://docs.sentry.io/product/metrics/" />,
  63. }
  64. )}
  65. />
  66. </PanelBody>
  67. </Panel>
  68. );
  69. }