utils.tsx 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156
  1. import type {Organization} from 'sentry/types/organization';
  2. import localStorage from 'sentry/utils/localStorage';
  3. import {isEmptyObject} from 'sentry/utils/object/isEmptyObject';
  4. import type {MetricsEnhancedSettingContext} from 'sentry/utils/performance/contexts/metricsEnhancedSetting';
  5. import {
  6. canUseMetricsData,
  7. MEPState,
  8. } from 'sentry/utils/performance/contexts/metricsEnhancedSetting';
  9. import type {ProjectPerformanceType} from '../../utils';
  10. import {PerformanceWidgetSetting} from './widgetDefinitions';
  11. export const QUERY_LIMIT_PARAM = 4;
  12. export const TOTAL_EXPANDABLE_ROWS_HEIGHT = 37 * QUERY_LIMIT_PARAM;
  13. export const eventsRequestQueryProps = [
  14. 'children',
  15. 'organization',
  16. 'yAxis',
  17. 'period',
  18. 'start',
  19. 'end',
  20. 'environment',
  21. 'project',
  22. 'referrer',
  23. ] as const;
  24. function setWidgetStorageObject(localObject: Record<string, string>) {
  25. localStorage.setItem(getContainerLocalStorageObjectKey, JSON.stringify(localObject));
  26. }
  27. const mepQueryParamBase = {};
  28. export function getMEPQueryParams(
  29. mepContext: MetricsEnhancedSettingContext,
  30. forceAuto?: boolean
  31. ) {
  32. let queryParams = {};
  33. const base = mepQueryParamBase;
  34. if (mepContext.shouldQueryProvideMEPAutoParams || forceAuto) {
  35. queryParams = {
  36. ...queryParams,
  37. ...base,
  38. dataset: 'metricsEnhanced',
  39. };
  40. if (forceAuto) {
  41. return queryParams;
  42. }
  43. }
  44. if (mepContext.shouldQueryProvideMEPTransactionParams) {
  45. queryParams = {...queryParams, ...base, dataset: 'discover'};
  46. }
  47. if (mepContext.shouldQueryProvideMEPMetricParams) {
  48. queryParams = {...queryParams, ...base, dataset: 'metrics'};
  49. }
  50. // Disallow any performance request from using aggregates since they aren't currently possible in all visualizations and we don't want to mix modes.
  51. return isEmptyObject(queryParams) ? undefined : queryParams;
  52. }
  53. export function getMetricOnlyQueryParams() {
  54. return {...mepQueryParamBase, dataset: 'metrics'};
  55. }
  56. export const WIDGET_MAP_DENY_LIST = [
  57. PerformanceWidgetSetting.MOST_RELATED_ERRORS,
  58. PerformanceWidgetSetting.MOST_RELATED_ISSUES,
  59. ];
  60. /**
  61. * Some widgets, such as Related Issues, are inherently not possible w/ metrics at the moment since they use event.type:error under the hood.
  62. */
  63. export function getMEPParamsIfApplicable(
  64. mepContext: MetricsEnhancedSettingContext,
  65. widget: PerformanceWidgetSetting
  66. ) {
  67. if (WIDGET_MAP_DENY_LIST.includes(widget)) {
  68. return undefined;
  69. }
  70. return getMEPQueryParams(mepContext);
  71. }
  72. const getContainerLocalStorageObjectKey = 'landing-chart-container';
  73. const getContainerKey = (
  74. index: number,
  75. performanceType: ProjectPerformanceType,
  76. height: number
  77. ) => `landing-chart-container#${performanceType}#${height}#${index}`;
  78. function getWidgetStorageObject() {
  79. const localObject = JSON.parse(
  80. localStorage.getItem(getContainerLocalStorageObjectKey) || '{}'
  81. );
  82. return localObject;
  83. }
  84. export const getChartSetting = (
  85. index: number,
  86. height: number,
  87. performanceType: ProjectPerformanceType,
  88. defaultType: PerformanceWidgetSetting,
  89. forceDefaultChartSetting?: boolean // Used for testing.
  90. ): PerformanceWidgetSetting => {
  91. if (forceDefaultChartSetting) {
  92. return defaultType;
  93. }
  94. const key = getContainerKey(index, performanceType, height);
  95. const localObject = getWidgetStorageObject();
  96. const value = localObject?.[key];
  97. if (
  98. value &&
  99. Object.values(PerformanceWidgetSetting).includes(value as PerformanceWidgetSetting)
  100. ) {
  101. const _value: PerformanceWidgetSetting = value as PerformanceWidgetSetting;
  102. return _value;
  103. }
  104. return defaultType;
  105. };
  106. export const _setChartSetting = (
  107. index: number,
  108. height: number,
  109. performanceType: ProjectPerformanceType,
  110. setting: PerformanceWidgetSetting
  111. ) => {
  112. const key = getContainerKey(index, performanceType, height);
  113. const localObject = getWidgetStorageObject();
  114. localObject[key] = setting;
  115. setWidgetStorageObject(localObject);
  116. };
  117. const DISALLOWED_CHARTS_METRICS = [
  118. PerformanceWidgetSetting.DURATION_HISTOGRAM,
  119. PerformanceWidgetSetting.FCP_HISTOGRAM,
  120. PerformanceWidgetSetting.LCP_HISTOGRAM,
  121. PerformanceWidgetSetting.FID_HISTOGRAM,
  122. ];
  123. export function filterAllowedChartsMetrics(
  124. organization: Organization,
  125. allowedCharts: PerformanceWidgetSetting[],
  126. mepSetting: MetricsEnhancedSettingContext
  127. ) {
  128. if (
  129. !canUseMetricsData(organization) ||
  130. organization.features.includes('performance-mep-reintroduce-histograms') ||
  131. mepSetting.metricSettingState === MEPState.TRANSACTIONS_ONLY
  132. ) {
  133. return allowedCharts;
  134. }
  135. return allowedCharts.filter(c => !DISALLOWED_CHARTS_METRICS.includes(c));
  136. }