getMetricRuleDiscoverUrl.tsx 2.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788
  1. import type {NewQuery, Project} from 'sentry/types';
  2. import EventView from 'sentry/utils/discover/eventView';
  3. import {getAggregateAlias} from 'sentry/utils/discover/fields';
  4. import type {TimePeriodType} from 'sentry/views/alerts/rules/metric/details/constants';
  5. import type {MetricRule} from 'sentry/views/alerts/rules/metric/types';
  6. import {Dataset, TimePeriod} from 'sentry/views/alerts/rules/metric/types';
  7. import {DEFAULT_PROJECT_THRESHOLD} from 'sentry/views/performance/data';
  8. interface MetricRuleDiscoverUrlOptions {
  9. orgSlug: string;
  10. projects: Project[];
  11. timePeriod: Omit<TimePeriodType, 'display' | 'label'>;
  12. extraQueryParams?: Partial<NewQuery>;
  13. query?: string;
  14. rule?: MetricRule;
  15. }
  16. /**
  17. * Gets the URL for a discover view of the rule with the following default
  18. * parameters:
  19. *
  20. * - Ordered by the rule aggregate, descending
  21. * - yAxis maps to the aggregate
  22. * - Start and end are the period's values selected in the chart header
  23. */
  24. export function getMetricRuleDiscoverUrl({
  25. orgSlug,
  26. ...rest
  27. }: MetricRuleDiscoverUrlOptions) {
  28. const discoverView = getMetricRuleDiscoverQuery(rest);
  29. if (!discoverView || !rest.rule) {
  30. return '';
  31. }
  32. const {query, ...toObject} = discoverView.getResultsViewUrlTarget(orgSlug);
  33. const timeWindowString = `${rest.rule.timeWindow}m`;
  34. return {
  35. query: {...query, interval: timeWindowString},
  36. ...toObject,
  37. };
  38. }
  39. export function getMetricRuleDiscoverQuery({
  40. projects,
  41. rule,
  42. timePeriod,
  43. query,
  44. extraQueryParams,
  45. }: Omit<MetricRuleDiscoverUrlOptions, 'orgSlug'>) {
  46. if (!projects || !projects.length || !rule) {
  47. return null;
  48. }
  49. const aggregateAlias = getAggregateAlias(rule.aggregate);
  50. const timePeriodFields = timePeriod.usingPeriod
  51. ? {range: timePeriod.period === TimePeriod.SEVEN_DAYS ? '7d' : timePeriod.period}
  52. : {start: timePeriod.start, end: timePeriod.end};
  53. const fields =
  54. rule.dataset === Dataset.ERRORS
  55. ? ['issue', 'count()', 'count_unique(user)']
  56. : [
  57. 'transaction',
  58. 'project',
  59. `${rule.aggregate}`,
  60. 'count_unique(user)',
  61. `user_misery(${DEFAULT_PROJECT_THRESHOLD})`,
  62. ];
  63. const eventQuery: NewQuery = {
  64. id: undefined,
  65. name: rule?.name || 'Transactions',
  66. fields,
  67. orderby: `-${aggregateAlias}`,
  68. query: query ?? rule.query ?? '',
  69. version: 2,
  70. projects: projects
  71. .filter(({slug}) => rule.projects.includes(slug))
  72. .map(project => Number(project.id)),
  73. environment: rule.environment ? [rule.environment] : undefined,
  74. ...timePeriodFields,
  75. ...extraQueryParams,
  76. };
  77. return EventView.fromSavedQuery(eventQuery);
  78. }