useFunctions.tsx 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135
  1. import {useEffect, useState} from 'react';
  2. import * as Sentry from '@sentry/react';
  3. import {Client} from 'sentry/api';
  4. import {normalizeDateTimeParams} from 'sentry/components/organizations/pageFilters/parse';
  5. import {t} from 'sentry/locale';
  6. import {Organization, PageFilters, Project, RequestState} from 'sentry/types';
  7. import {SuspectFunction} from 'sentry/types/profiling/core';
  8. import {MutableSearch} from 'sentry/utils/tokenizeSearch';
  9. import useApi from 'sentry/utils/useApi';
  10. import useOrganization from 'sentry/utils/useOrganization';
  11. type FunctionsResult = {
  12. functions: SuspectFunction[];
  13. pageLinks: string | null;
  14. };
  15. interface UseFunctionsOptions {
  16. project: Project;
  17. query: string;
  18. sort: string;
  19. transaction: string;
  20. cursor?: string;
  21. functionType?: 'application' | 'system' | 'all';
  22. selection?: PageFilters;
  23. }
  24. function useFunctions({
  25. functionType,
  26. project,
  27. query,
  28. transaction,
  29. sort,
  30. cursor,
  31. selection,
  32. }: UseFunctionsOptions): RequestState<FunctionsResult> {
  33. const api = useApi();
  34. const organization = useOrganization();
  35. const [requestState, setRequestState] = useState<RequestState<FunctionsResult>>({
  36. type: 'initial',
  37. });
  38. useEffect(() => {
  39. if (selection === undefined) {
  40. return undefined;
  41. }
  42. setRequestState({type: 'loading'});
  43. fetchFunctions(api, organization, {
  44. functionType,
  45. projectSlug: project.slug,
  46. query,
  47. selection,
  48. sort,
  49. transaction,
  50. cursor,
  51. })
  52. .then(([functions, , response]) => {
  53. setRequestState({
  54. type: 'resolved',
  55. data: {
  56. functions: functions.functions ?? [],
  57. pageLinks: response?.getResponseHeader('Link') ?? null,
  58. },
  59. });
  60. })
  61. .catch(err => {
  62. setRequestState({type: 'errored', error: t('Error: Unable to load functions')});
  63. Sentry.captureException(err);
  64. });
  65. return () => api.clear();
  66. }, [
  67. api,
  68. cursor,
  69. functionType,
  70. organization,
  71. project.slug,
  72. query,
  73. selection,
  74. sort,
  75. transaction,
  76. ]);
  77. return requestState;
  78. }
  79. function fetchFunctions(
  80. api: Client,
  81. organization: Organization,
  82. {
  83. cursor,
  84. functionType,
  85. projectSlug,
  86. query,
  87. selection,
  88. sort,
  89. transaction,
  90. }: {
  91. cursor: string | undefined;
  92. functionType: 'application' | 'system' | 'all' | undefined;
  93. projectSlug: Project['slug'];
  94. query: string;
  95. selection: PageFilters;
  96. sort: string;
  97. transaction: string;
  98. }
  99. ) {
  100. const conditions = new MutableSearch(query);
  101. conditions.setFilterValues('transaction_name', [transaction]);
  102. return api.requestPromise(
  103. `/projects/${organization.slug}/${projectSlug}/profiling/functions/`,
  104. {
  105. method: 'GET',
  106. includeAllArgs: true,
  107. query: {
  108. cursor,
  109. environment: selection.environments,
  110. ...normalizeDateTimeParams(selection.datetime),
  111. query: conditions.formatString(),
  112. sort,
  113. is_application:
  114. functionType === 'application'
  115. ? '1'
  116. : functionType === 'system'
  117. ? '0'
  118. : undefined,
  119. },
  120. }
  121. );
  122. }
  123. export {useFunctions};