useCreateDashboard.tsx 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126
  1. import {useCallback, useMemo} from 'react';
  2. import {openCreateDashboardFromMetrics} from 'sentry/actionCreators/modal';
  3. import {isVirtualMetric} from 'sentry/utils/metrics';
  4. import {convertToDashboardWidget} from 'sentry/utils/metrics/dashboard';
  5. import {
  6. isMetricsEquationWidget,
  7. type MetricDisplayType,
  8. MetricExpressionType,
  9. type MetricsWidget,
  10. } from 'sentry/utils/metrics/types';
  11. import {useVirtualMetricsContext} from 'sentry/utils/metrics/virtualMetricsContext';
  12. import useOrganization from 'sentry/utils/useOrganization';
  13. import usePageFilters from 'sentry/utils/usePageFilters';
  14. import useRouter from 'sentry/utils/useRouter';
  15. import type {Widget} from 'sentry/views/dashboards/types';
  16. import type {useFormulaDependencies} from 'sentry/views/metrics/utils/useFormulaDependencies';
  17. export function useCreateDashboard(
  18. widgets: MetricsWidget[],
  19. formulaDependencies: ReturnType<typeof useFormulaDependencies>,
  20. isMultiChartMode: boolean
  21. ) {
  22. const router = useRouter();
  23. const {resolveVirtualMRI} = useVirtualMetricsContext();
  24. const organization = useOrganization();
  25. const {selection} = usePageFilters();
  26. const convertWidget = useCallback(
  27. (metricsQueries: MetricsWidget[], displayType: MetricDisplayType) => {
  28. const resolvedwidgets = metricsQueries.map(widget => {
  29. if (
  30. isMetricsEquationWidget(widget) ||
  31. !isVirtualMetric(widget) ||
  32. !widget.condition
  33. ) {
  34. return widget;
  35. }
  36. const {mri, aggregation} = resolveVirtualMRI(
  37. widget.mri,
  38. widget.condition,
  39. widget.aggregation
  40. );
  41. return {
  42. ...widget,
  43. mri,
  44. aggregation,
  45. };
  46. });
  47. return convertToDashboardWidget(resolvedwidgets, displayType);
  48. },
  49. [resolveVirtualMRI]
  50. );
  51. const dashboardWidgets = useMemo(() => {
  52. if (!isMultiChartMode) {
  53. const queryIdsInArray = new Set<number>();
  54. const widgetsWithDependencies = widgets.reduce<MetricsWidget[]>((acc, widget) => {
  55. if (isMetricsEquationWidget(widget)) {
  56. const {dependencies, isError} = formulaDependencies[widget.id];
  57. if (isError) {
  58. return acc;
  59. }
  60. // Only add dependencies that are not already in the list of widgets
  61. const filteredDependencies: MetricsWidget[] = [];
  62. dependencies.forEach(dependency => {
  63. if (!queryIdsInArray.has(dependency.id)) {
  64. filteredDependencies.push({...dependency, isHidden: true});
  65. queryIdsInArray.add(dependency.id);
  66. }
  67. });
  68. return [...filteredDependencies, ...acc, widget];
  69. }
  70. if (queryIdsInArray.has(widget.id)) {
  71. return acc;
  72. }
  73. queryIdsInArray.add(widget.id);
  74. return [...acc, widget];
  75. }, []);
  76. return [convertWidget(widgetsWithDependencies, widgets[0].displayType)];
  77. }
  78. return widgets
  79. .map(widget => {
  80. if (widget.type !== MetricExpressionType.EQUATION) {
  81. return convertWidget([widget], widget.displayType);
  82. }
  83. const {dependencies, isError} = formulaDependencies[widget.id];
  84. if (isError) {
  85. return null;
  86. }
  87. return convertWidget(
  88. [...dependencies.map(query => ({...query, isHidden: true})), widget],
  89. widget.displayType
  90. );
  91. })
  92. .filter((widget): widget is Widget => widget !== null);
  93. }, [isMultiChartMode, widgets, convertWidget, formulaDependencies]);
  94. return useMemo(() => {
  95. return function () {
  96. const newDashboard = {
  97. title: 'Metrics Dashboard',
  98. description: '',
  99. widgets: dashboardWidgets.slice(0, 30),
  100. projects: selection.projects,
  101. environment: selection.environments,
  102. start: selection.datetime.start as string,
  103. end: selection.datetime.end as string,
  104. period: selection.datetime.period as string,
  105. filters: {},
  106. utc: selection.datetime.utc ?? false,
  107. id: 'ddm-scratchpad',
  108. dateCreated: '',
  109. };
  110. openCreateDashboardFromMetrics({newDashboard, router, organization});
  111. };
  112. }, [selection, organization, router, dashboardWidgets]);
  113. }