resourceView.tsx 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139
  1. import {Fragment} from 'react';
  2. import styled from '@emotion/styled';
  3. import {CompactSelect} from 'sentry/components/compactSelect';
  4. import {t} from 'sentry/locale';
  5. import {space} from 'sentry/styles/space';
  6. import {trackAnalytics} from 'sentry/utils/analytics';
  7. import {browserHistory} from 'sentry/utils/browserHistory';
  8. import {useLocation} from 'sentry/utils/useLocation';
  9. import useOrganization from 'sentry/utils/useOrganization';
  10. import {getResourceTypeFilter} from 'sentry/views/insights/browser/common/queries/useResourcesQuery';
  11. import RenderBlockingSelector from 'sentry/views/insights/browser/resources/components/renderBlockingSelector';
  12. import ResourceTable from 'sentry/views/insights/browser/resources/components/tables/resourceTable';
  13. import {
  14. FONT_FILE_EXTENSIONS,
  15. IMAGE_FILE_EXTENSIONS,
  16. } from 'sentry/views/insights/browser/resources/constants';
  17. import {
  18. DEFAULT_RESOURCE_TYPES,
  19. RESOURCE_THROUGHPUT_UNIT,
  20. } from 'sentry/views/insights/browser/resources/settings';
  21. import {ResourceSpanOps} from 'sentry/views/insights/browser/resources/types';
  22. import {
  23. BrowserStarfishFields,
  24. useResourceModuleFilters,
  25. } from 'sentry/views/insights/browser/resources/utils/useResourceFilters';
  26. import {useResourceSort} from 'sentry/views/insights/browser/resources/utils/useResourceSort';
  27. import {QueryParameterNames} from 'sentry/views/insights/common/views/queryParameters';
  28. import {TransactionSelector} from 'sentry/views/insights/common/views/spans/selectors/transactionSelector';
  29. import {SpanTimeCharts} from 'sentry/views/insights/common/views/spans/spanTimeCharts';
  30. import type {ModuleFilters} from 'sentry/views/insights/common/views/spans/useModuleFilters';
  31. import {ModuleName} from 'sentry/views/insights/types';
  32. const {
  33. SPAN_OP: RESOURCE_TYPE,
  34. SPAN_DOMAIN,
  35. TRANSACTION,
  36. RESOURCE_RENDER_BLOCKING_STATUS,
  37. } = BrowserStarfishFields;
  38. type Option = {
  39. label: string | React.ReactElement;
  40. value: string;
  41. };
  42. function ResourceView() {
  43. const filters = useResourceModuleFilters();
  44. const sort = useResourceSort();
  45. const spanTimeChartsFilters: ModuleFilters = {
  46. 'span.op': `[${DEFAULT_RESOURCE_TYPES.join(',')}]`,
  47. ...(filters[SPAN_DOMAIN] ? {[SPAN_DOMAIN]: filters[SPAN_DOMAIN]} : {}),
  48. };
  49. const extraQuery = getResourceTypeFilter(undefined, DEFAULT_RESOURCE_TYPES);
  50. return (
  51. <Fragment>
  52. <SpanTimeChartsContainer>
  53. <SpanTimeCharts
  54. moduleName={ModuleName.RESOURCE}
  55. appliedFilters={spanTimeChartsFilters}
  56. throughputUnit={RESOURCE_THROUGHPUT_UNIT}
  57. extraQuery={extraQuery}
  58. />
  59. </SpanTimeChartsContainer>
  60. <DropdownContainer>
  61. <ResourceTypeSelector value={filters[RESOURCE_TYPE] || ''} />
  62. <TransactionSelector
  63. value={filters[TRANSACTION] || ''}
  64. defaultResourceTypes={DEFAULT_RESOURCE_TYPES}
  65. />
  66. <RenderBlockingSelector value={filters[RESOURCE_RENDER_BLOCKING_STATUS] || ''} />
  67. </DropdownContainer>
  68. <ResourceTable sort={sort} defaultResourceTypes={DEFAULT_RESOURCE_TYPES} />
  69. </Fragment>
  70. );
  71. }
  72. function ResourceTypeSelector({value}: {value?: string}) {
  73. const location = useLocation();
  74. const organization = useOrganization();
  75. const hasImageView = organization.features.includes('insights-initial-modules');
  76. const options: Option[] = [
  77. {value: '', label: 'All'},
  78. {value: 'resource.script', label: `${t('JavaScript')} (.js)`},
  79. {value: 'resource.css', label: `${t('Stylesheet')} (.css)`},
  80. {
  81. value: 'resource.font',
  82. label: `${t('Font')} (${FONT_FILE_EXTENSIONS.map(e => `.${e}`).join(', ')})`,
  83. },
  84. ...(hasImageView
  85. ? [
  86. {
  87. value: ResourceSpanOps.IMAGE,
  88. label: `${t('Image')} (${IMAGE_FILE_EXTENSIONS.map(e => `.${e}`).join(', ')})`,
  89. },
  90. ]
  91. : []),
  92. ];
  93. return (
  94. <CompactSelect
  95. style={{maxWidth: '200px'}}
  96. triggerProps={{prefix: `${t('Type')}`}}
  97. options={options}
  98. value={value ?? ''}
  99. onChange={newValue => {
  100. trackAnalytics('insight.asset.filter_by_type', {
  101. organization,
  102. filter: newValue?.value,
  103. });
  104. browserHistory.push({
  105. ...location,
  106. query: {
  107. ...location.query,
  108. [RESOURCE_TYPE]: newValue?.value,
  109. [QueryParameterNames.SPANS_CURSOR]: undefined,
  110. },
  111. });
  112. }}
  113. />
  114. );
  115. }
  116. export const SpanTimeChartsContainer = styled('div')`
  117. margin-bottom: ${space(2)};
  118. `;
  119. const DropdownContainer = styled('div')`
  120. display: flex;
  121. gap: ${space(2)};
  122. margin-bottom: ${space(2)};
  123. flex-wrap: wrap;
  124. `;
  125. export default ResourceView;