getWidgetExploreUrl.tsx 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  1. import pick from 'lodash/pick';
  2. import * as qs from 'query-string';
  3. import type {PageFilters} from 'sentry/types/core';
  4. import type {Organization} from 'sentry/types/organization';
  5. import {defined} from 'sentry/utils';
  6. import {
  7. getAggregateAlias,
  8. isAggregateFieldOrEquation,
  9. } from 'sentry/utils/discover/fields';
  10. import {DisplayType, type Widget} from 'sentry/views/dashboards/types';
  11. import {
  12. eventViewFromWidget,
  13. getFieldsFromEquations,
  14. getWidgetInterval,
  15. } from 'sentry/views/dashboards/utils';
  16. import type {ResultMode} from 'sentry/views/explore/hooks/useResultsMode';
  17. import {ChartType} from 'sentry/views/insights/common/components/chart';
  18. export function getWidgetExploreUrl(
  19. widget: Widget,
  20. selection: PageFilters,
  21. organization: Organization
  22. ) {
  23. const eventView = eventViewFromWidget(widget.title, widget.queries[0], selection);
  24. const {query: locationQueryParams} = eventView.getResultsViewUrlTarget(
  25. organization.slug,
  26. false,
  27. undefined
  28. );
  29. // Pull a max of 3 valid Y-Axis from the widget
  30. const yAxisOptions = eventView.getYAxisOptions().map(({value}) => value);
  31. locationQueryParams.yAxes = [
  32. ...new Set(
  33. widget.queries[0].aggregates.filter(aggregate => yAxisOptions.includes(aggregate))
  34. ),
  35. ].slice(0, 3);
  36. // Visualization specific transforms
  37. let exploreMode: ResultMode | undefined = undefined;
  38. switch (widget.displayType) {
  39. case DisplayType.BAR:
  40. exploreMode = 'aggregate';
  41. locationQueryParams.chartType = ChartType.BAR.toString();
  42. break;
  43. case DisplayType.LINE:
  44. exploreMode = 'aggregate';
  45. locationQueryParams.chartType = ChartType.LINE.toString();
  46. break;
  47. case DisplayType.AREA:
  48. exploreMode = 'aggregate';
  49. locationQueryParams.chartType = ChartType.AREA.toString();
  50. break;
  51. case DisplayType.TABLE:
  52. case DisplayType.BIG_NUMBER:
  53. exploreMode = 'samples';
  54. break;
  55. default:
  56. break;
  57. }
  58. // Equation fields need to have their terms explicitly selected as columns in the discover table
  59. const fields =
  60. Array.isArray(locationQueryParams.field) || !defined(locationQueryParams.field)
  61. ? locationQueryParams.field
  62. : [locationQueryParams.field];
  63. const query = widget.queries[0];
  64. const queryFields = defined(query.fields)
  65. ? query.fields
  66. : [...query.columns, ...query.aggregates];
  67. // Updates fields by adding any individual terms from equation fields as a column
  68. getFieldsFromEquations(queryFields).forEach(term => {
  69. if (Array.isArray(fields) && !fields.includes(term)) {
  70. fields.unshift(term);
  71. }
  72. });
  73. locationQueryParams.field = fields;
  74. const queryParams = {
  75. // Page filters should propagate
  76. ...pick(locationQueryParams, [
  77. 'start',
  78. 'end',
  79. 'statsPeriod',
  80. 'project',
  81. 'environment',
  82. ]),
  83. mode: exploreMode,
  84. visualize: JSON.stringify(pick(locationQueryParams, ['yAxes', 'chartType'])),
  85. groupBy: fields?.filter(field => !isAggregateFieldOrEquation(field)),
  86. field: locationQueryParams.field,
  87. query: locationQueryParams.query,
  88. sort:
  89. defined(fields) && defined(locationQueryParams.sort)
  90. ? _getSort(fields, locationQueryParams.sort as string)
  91. : undefined,
  92. interval:
  93. locationQueryParams.interval ??
  94. getWidgetInterval(widget.displayType, selection.datetime),
  95. };
  96. return `/traces/?${qs.stringify(queryParams)}`;
  97. }
  98. function _getSort(fields: string[], sort: string) {
  99. const descending = sort.startsWith('-');
  100. const rawSort = descending ? sort.slice(1) : sort;
  101. const sortedField = fields?.find(field => getAggregateAlias(field) === rawSort);
  102. return descending ? `-${sortedField}` : sortedField;
  103. }