metricsRibbon.tsx 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  1. import type {ComponentProps} from 'react';
  2. import {useMemo} from 'react';
  3. import type {Polarity} from 'sentry/components/percentChange';
  4. import type {NewQuery} from 'sentry/types/organization';
  5. import type {TableData, TableDataRow} from 'sentry/utils/discover/discoverQuery';
  6. import EventView from 'sentry/utils/discover/eventView';
  7. import type {DiscoverDatasets} from 'sentry/utils/discover/types';
  8. import {MutableSearch} from 'sentry/utils/tokenizeSearch';
  9. import {useLocation} from 'sentry/utils/useLocation';
  10. import usePageFilters from 'sentry/utils/usePageFilters';
  11. import {MetricReadout} from 'sentry/views/insights/common/components/metricReadout';
  12. import {Ribbon} from 'sentry/views/insights/common/components/ribbon';
  13. import {useReleaseSelection} from 'sentry/views/insights/common/queries/useReleases';
  14. import {appendReleaseFilters} from 'sentry/views/insights/common/utils/releaseComparison';
  15. import useCrossPlatformProject from 'sentry/views/insights/mobile/common/queries/useCrossPlatformProject';
  16. import {useTableQuery} from 'sentry/views/insights/mobile/screenload/components/tables/screensTable';
  17. interface BlockProps {
  18. dataKey: string | ((data?: TableDataRow[]) => number | undefined);
  19. title: string;
  20. unit: ComponentProps<typeof MetricReadout>['unit'];
  21. allowZero?: boolean;
  22. preferredPolarity?: Polarity;
  23. }
  24. export function MobileMetricsRibbon({
  25. filters,
  26. blocks,
  27. fields,
  28. referrer,
  29. dataset,
  30. }: {
  31. blocks: BlockProps[];
  32. dataset: DiscoverDatasets;
  33. fields: string[];
  34. referrer: string;
  35. filters?: string[];
  36. }) {
  37. const {selection} = usePageFilters();
  38. const location = useLocation();
  39. const {
  40. primaryRelease,
  41. secondaryRelease,
  42. isLoading: isReleasesLoading,
  43. } = useReleaseSelection();
  44. const {isProjectCrossPlatform, selectedPlatform} = useCrossPlatformProject();
  45. const queryString = useMemo(() => {
  46. const searchQuery = new MutableSearch([...(filters ?? [])]);
  47. if (isProjectCrossPlatform) {
  48. searchQuery.addFilterValue('os.name', selectedPlatform);
  49. }
  50. return appendReleaseFilters(searchQuery, primaryRelease, secondaryRelease);
  51. }, [
  52. filters,
  53. isProjectCrossPlatform,
  54. primaryRelease,
  55. secondaryRelease,
  56. selectedPlatform,
  57. ]);
  58. const newQuery: NewQuery = {
  59. name: 'ScreenMetricsRibbon',
  60. fields,
  61. query: queryString,
  62. dataset,
  63. version: 2,
  64. projects: selection.projects,
  65. };
  66. const eventView = EventView.fromNewQueryWithLocation(newQuery, location);
  67. const {data, isLoading} = useTableQuery({
  68. eventView,
  69. enabled: !isReleasesLoading,
  70. referrer,
  71. });
  72. return (
  73. <Ribbon>
  74. {blocks.map(({title, dataKey, unit, preferredPolarity}) => (
  75. <MetricsBlock
  76. key={title}
  77. title={title}
  78. unit={unit}
  79. dataKey={dataKey}
  80. data={data}
  81. isLoading={isLoading}
  82. preferredPolarity={preferredPolarity}
  83. />
  84. ))}
  85. </Ribbon>
  86. );
  87. }
  88. function MetricsBlock({
  89. title,
  90. unit,
  91. data,
  92. dataKey,
  93. isLoading,
  94. allowZero,
  95. preferredPolarity,
  96. }: {
  97. isLoading: boolean;
  98. title: string;
  99. data?: TableData;
  100. release?: string;
  101. } & BlockProps) {
  102. const value =
  103. typeof dataKey === 'function'
  104. ? dataKey(data?.data)
  105. : (data?.data?.[0]?.[dataKey] as number);
  106. const hasData = (value && value !== 0) || (value === 0 && allowZero);
  107. return (
  108. <MetricReadout
  109. title={title}
  110. align="left"
  111. value={hasData ? value : undefined}
  112. isLoading={isLoading}
  113. unit={unit}
  114. preferredPolarity={preferredPolarity}
  115. />
  116. );
  117. }