Просмотр исходного кода

ref(issue-details): Refactor context items into separate functions (#68530)

Another PR similar to https://github.com/getsentry/sentry/pull/68349 to
help with simplifying https://github.com/getsentry/sentry/pull/68081

The goal of this PR is to extract the logic for how we display the
known/unknown key value pairs for context items into their own functions
and create a util function to easily receive a list of
`KeyValueListItem[]` objects which we'll be able to render in our new
component. This will prevent them from diverging while we're iterating
on the new UI.

I had to do this in the verbose helper function way since the logic for
converting context keys (e.g. `transaction.op` to `t('Operation Name')`)
is unique for EACH context, and lived within the component which
rendered the data. Now the data can be accessed outside that specific
component, which will make swapping it much easier. It also now defaults
to the `raw` data, rather than returning `<StructuredEventData />`
components which make the value inaccessible. That formatting can be
accessed by calling `getKnownStructuredData` on the result of
`getKnownData`.

todo
- [x] Add test for `getKnownStructuredData`
- [x] Ensure CI passes
Leander Rodrigues 11 месяцев назад
Родитель
Сommit
9c797a03fb

+ 2 - 7
static/app/components/events/contexts/app/getAppKnownDataDetails.tsx

@@ -1,23 +1,18 @@
 import {t} from 'sentry/locale';
 import type {Event} from 'sentry/types/event';
 
-import {getRelativeTimeFromEventDateCreated} from '../utils';
+import {getRelativeTimeFromEventDateCreated, type KnownDataDetails} from '../utils';
 
 import type {AppData} from './types';
 import {AppKnownDataType} from './types';
 
-type Output = {
-  subject: string;
-  value?: React.ReactNode;
-};
-
 type Props = {
   data: AppData;
   event: Event;
   type: AppKnownDataType;
 };
 
-export function getAppKnownDataDetails({data, event, type}: Props): Output | undefined {
+export function getAppKnownDataDetails({data, event, type}: Props): KnownDataDetails {
   switch (type) {
     case AppKnownDataType.ID:
       return {

+ 29 - 18
static/app/components/events/contexts/app/index.tsx

@@ -3,11 +3,15 @@ import {Fragment} from 'react';
 import ContextBlock from 'sentry/components/events/contexts/contextBlock';
 import type {Event} from 'sentry/types/event';
 
-import {getContextMeta, getKnownData, getUnknownData} from '../utils';
+import {
+  getContextMeta,
+  getKnownData,
+  getKnownStructuredData,
+  getUnknownData,
+} from '../utils';
 
 import {getAppKnownDataDetails} from './getAppKnownDataDetails';
-import type {AppData} from './types';
-import {AppKnownDataType} from './types';
+import {type AppData, AppKnownDataType} from './types';
 
 type Props = {
   data: AppData;
@@ -28,25 +32,32 @@ export const appKnownDataValues = [
 
 const appIgnoredDataValues = [];
 
+export function getKnownAppContextData({data, event, meta}: Props) {
+  return getKnownData<AppData, AppKnownDataType>({
+    data,
+    meta,
+    knownDataTypes: appKnownDataValues,
+    onGetKnownDataDetails: v => getAppKnownDataDetails({...v, event}),
+  });
+}
+
+export function getUnknownAppContextData({data, meta}: Pick<Props, 'data' | 'meta'>) {
+  return getUnknownData({
+    allData: data,
+    knownKeys: [...appKnownDataValues, ...appIgnoredDataValues],
+    meta,
+  });
+}
+
 export function AppEventContext({data, event, meta: propsMeta}: Props) {
   const meta = propsMeta ?? getContextMeta(event, 'app');
+  const knownData = getKnownAppContextData({data, event, meta});
+  const knownStructuredData = getKnownStructuredData(knownData, meta);
+  const unknownData = getUnknownAppContextData({data, meta});
   return (
     <Fragment>
-      <ContextBlock
-        data={getKnownData<AppData, AppKnownDataType>({
-          data,
-          meta,
-          knownDataTypes: appKnownDataValues,
-          onGetKnownDataDetails: v => getAppKnownDataDetails({...v, event}),
-        })}
-      />
-      <ContextBlock
-        data={getUnknownData({
-          allData: data,
-          knownKeys: [...appKnownDataValues, ...appIgnoredDataValues],
-          meta,
-        })}
-      />
+      <ContextBlock data={knownStructuredData} />
+      <ContextBlock data={unknownData} />
     </Fragment>
   );
 }

+ 2 - 6
static/app/components/events/contexts/browser/getBrowserKnownDataDetails.tsx

@@ -1,19 +1,15 @@
+import type {KnownDataDetails} from 'sentry/components/events/contexts/utils';
 import {t} from 'sentry/locale';
 
 import type {BrowserKnownData} from './types';
 import {BrowserKnownDataType} from './types';
 
-type Output = {
-  subject: string;
-  value: React.ReactNode | null;
-};
-
 type Props = {
   data: BrowserKnownData;
   type: BrowserKnownDataType;
 };
 
-export function getBrowserKnownDataDetails({data, type}: Props): Output | undefined {
+export function getBrowserKnownDataDetails({data, type}: Props): KnownDataDetails {
   switch (type) {
     case BrowserKnownDataType.NAME:
       return {

+ 28 - 16
static/app/components/events/contexts/browser/index.tsx

@@ -3,7 +3,12 @@ import {Fragment} from 'react';
 import ContextBlock from 'sentry/components/events/contexts/contextBlock';
 import type {Event} from 'sentry/types';
 
-import {getContextMeta, getKnownData, getUnknownData} from '../utils';
+import {
+  getContextMeta,
+  getKnownData,
+  getKnownStructuredData,
+  getUnknownData,
+} from '../utils';
 
 import {getBrowserKnownDataDetails} from './getBrowserKnownDataDetails';
 import type {BrowserKnownData} from './types';
@@ -20,25 +25,32 @@ export const browserKnownDataValues = [
   BrowserKnownDataType.VERSION,
 ];
 
+export function getKnownBrowserContextData({data, meta}: Pick<Props, 'data' | 'meta'>) {
+  return getKnownData<BrowserKnownData, BrowserKnownDataType>({
+    data,
+    meta,
+    knownDataTypes: browserKnownDataValues,
+    onGetKnownDataDetails: v => getBrowserKnownDataDetails(v),
+  });
+}
+
+export function getUnknownBrowserContextData({data, meta}: Pick<Props, 'data' | 'meta'>) {
+  return getUnknownData({
+    allData: data,
+    knownKeys: [...browserKnownDataValues],
+    meta,
+  });
+}
+
 export function BrowserEventContext({data, event, meta: propsMeta}: Props) {
   const meta = propsMeta ?? getContextMeta(event, 'browser');
+  const knownData = getKnownBrowserContextData({data, meta});
+  const knownStructuredData = getKnownStructuredData(knownData, meta);
+  const unknownData = getUnknownBrowserContextData({data, meta});
   return (
     <Fragment>
-      <ContextBlock
-        data={getKnownData<BrowserKnownData, BrowserKnownDataType>({
-          data,
-          meta,
-          knownDataTypes: browserKnownDataValues,
-          onGetKnownDataDetails: v => getBrowserKnownDataDetails(v),
-        })}
-      />
-      <ContextBlock
-        data={getUnknownData({
-          allData: data,
-          knownKeys: [...browserKnownDataValues],
-          meta,
-        })}
-      />
+      <ContextBlock data={knownStructuredData} />
+      <ContextBlock data={unknownData} />
     </Fragment>
   );
 }

+ 2 - 2
static/app/components/events/contexts/default.tsx

@@ -7,7 +7,7 @@ type Props = {
   event: Event;
 };
 
-function getKnownData(data: Props['data']) {
+export function getDefaultContextData(data: Props['data']) {
   return Object.entries(data)
     .filter(([k]) => k !== 'type' && k !== 'title')
     .map(([key, value]) => ({
@@ -18,5 +18,5 @@ function getKnownData(data: Props['data']) {
 }
 
 export function DefaultContext({data}: Props) {
-  return <ContextBlock data={getKnownData(data)} />;
+  return <ContextBlock data={getDefaultContextData(data)} />;
 }

+ 2 - 11
static/app/components/events/contexts/device/getDeviceKnownDataDetails.tsx

@@ -5,7 +5,7 @@ import type {DeviceContext, Event} from 'sentry/types/event';
 import {DeviceContextKey} from 'sentry/types/event';
 import {defined} from 'sentry/utils';
 
-import {getRelativeTimeFromEventDateCreated} from '../utils';
+import {getRelativeTimeFromEventDateCreated, type KnownDataDetails} from '../utils';
 
 import {formatMemory, formatStorage} from './utils';
 
@@ -18,22 +18,13 @@ export const deviceKnownDataValues = [
   'storage',
 ];
 
-type Output = {
-  subject: string;
-  value?: React.ReactNode;
-};
-
 type Props = {
   data: DeviceContext;
   event: Event;
   type: (typeof deviceKnownDataValues)[number];
 };
 
-export function getDeviceKnownDataDetails({
-  data,
-  event,
-  type,
-}: Props): Output | undefined {
+export function getDeviceKnownDataDetails({data, event, type}: Props): KnownDataDetails {
   switch (type) {
     case DeviceContextKey.NAME:
       return {

+ 33 - 20
static/app/components/events/contexts/device/index.tsx

@@ -3,7 +3,12 @@ import {Fragment} from 'react';
 import ContextBlock from 'sentry/components/events/contexts/contextBlock';
 import type {DeviceContext, Event} from 'sentry/types/event';
 
-import {getContextMeta, getKnownData, getUnknownData} from '../utils';
+import {
+  getContextMeta,
+  getKnownData,
+  getKnownStructuredData,
+  getUnknownData,
+} from '../utils';
 
 import {
   deviceKnownDataValues,
@@ -19,30 +24,38 @@ type Props = {
 
 const deviceIgnoredDataValues = [];
 
-export function DeviceEventContext({data, event, meta: propsMeta}: Props) {
+export function getKnownDeviceContextData({data, event, meta}: Props) {
+  const inferredData = getInferredData(data);
+  return getKnownData<DeviceContext, (typeof deviceKnownDataValues)[number]>({
+    data: inferredData,
+    meta,
+    knownDataTypes: deviceKnownDataValues,
+    onGetKnownDataDetails: v => getDeviceKnownDataDetails({...v, event}),
+  }).map(v => ({
+    ...v,
+    subjectDataTestId: `device-context-${v.key.toLowerCase()}-value`,
+  }));
+}
+
+export function getUnknownDeviceContextData({data, meta}: Pick<Props, 'data' | 'meta'>) {
   const inferredData = getInferredData(data);
+  return getUnknownData({
+    allData: inferredData,
+    knownKeys: [...deviceKnownDataValues, ...deviceIgnoredDataValues],
+    meta,
+  });
+}
+
+export function DeviceEventContext({data, event, meta: propsMeta}: Props) {
   const meta = propsMeta ?? getContextMeta(event, 'device');
+  const knownData = getKnownDeviceContextData({data, event, meta});
+  const knownStructuredData = getKnownStructuredData(knownData, meta);
+  const unknownData = getUnknownDeviceContextData({data, meta});
 
   return (
     <Fragment>
-      <ContextBlock
-        data={getKnownData<DeviceContext, (typeof deviceKnownDataValues)[number]>({
-          data: inferredData,
-          meta,
-          knownDataTypes: deviceKnownDataValues,
-          onGetKnownDataDetails: v => getDeviceKnownDataDetails({...v, event}),
-        }).map(v => ({
-          ...v,
-          subjectDataTestId: `device-context-${v.key.toLowerCase()}-value`,
-        }))}
-      />
-      <ContextBlock
-        data={getUnknownData({
-          allData: inferredData,
-          knownKeys: [...deviceKnownDataValues, ...deviceIgnoredDataValues],
-          meta,
-        })}
-      />
+      <ContextBlock data={knownStructuredData} />
+      <ContextBlock data={unknownData} />
     </Fragment>
   );
 }

+ 2 - 6
static/app/components/events/contexts/gpu/getGPUKnownDataDetails.tsx

@@ -1,20 +1,16 @@
+import type {KnownDataDetails} from 'sentry/components/events/contexts/utils';
 import {t} from 'sentry/locale';
 
 import formatMemory from './formatMemory';
 import type {GPUData} from './types';
 import {GPUKnownDataType} from './types';
 
-type Output = {
-  subject: string;
-  value?: React.ReactNode;
-};
-
 type Props = {
   data: GPUData;
   type: GPUKnownDataType;
 };
 
-export function getGPUKnownDataDetails({data, type}: Props): Output | undefined {
+export function getGPUKnownDataDetails({data, type}: Props): KnownDataDetails {
   switch (type) {
     case GPUKnownDataType.NAME:
       return {

+ 35 - 20
static/app/components/events/contexts/gpu/index.tsx

@@ -3,7 +3,12 @@ import {Fragment} from 'react';
 import ContextBlock from 'sentry/components/events/contexts/contextBlock';
 import type {Event} from 'sentry/types/event';
 
-import {getContextMeta, getKnownData, getUnknownData} from '../utils';
+import {
+  getContextMeta,
+  getKnownData,
+  getKnownStructuredData,
+  getUnknownData,
+} from '../utils';
 
 import {getGPUKnownDataDetails} from './getGPUKnownDataDetails';
 import type {GPUData} from './types';
@@ -27,35 +32,45 @@ export const gpuKnownDataValues = [
 
 const gpuIgnoredDataValues = [];
 
-export function GPUEventContext({data, event, meta: propsMeta}: Props) {
+function getGpuValues({data}: Pick<Props, 'data'>) {
   const gpuValues = [...gpuKnownDataValues];
-  const meta = propsMeta ?? getContextMeta(event, 'gpu');
-
   if (data.vendor_id > 0) {
     gpuValues.unshift(GPUKnownDataType.VENDOR_ID);
   }
-
   if (data.id > 0) {
     gpuValues.unshift(GPUKnownDataType.ID);
   }
+  return gpuValues;
+}
 
+export function getKnownGpuContextData({data, meta}: Pick<Props, 'data' | 'meta'>) {
+  const gpuValues = getGpuValues({data});
+  return getKnownData<GPUData, GPUKnownDataType>({
+    data,
+    meta,
+    knownDataTypes: gpuValues,
+    onGetKnownDataDetails: v => getGPUKnownDataDetails(v),
+  });
+}
+
+export function getUnknownGpuContextData({data, meta}: Pick<Props, 'data' | 'meta'>) {
+  const gpuValues = getGpuValues({data});
+  return getUnknownData({
+    allData: data,
+    knownKeys: [...gpuValues, ...gpuIgnoredDataValues],
+    meta,
+  });
+}
+
+export function GPUEventContext({data, event, meta: propsMeta}: Props) {
+  const meta = propsMeta ?? getContextMeta(event, 'gpu');
+  const knownData = getKnownGpuContextData({data, meta});
+  const knownStructuredData = getKnownStructuredData(knownData, meta);
+  const unknownData = getUnknownGpuContextData({data, meta});
   return (
     <Fragment>
-      <ContextBlock
-        data={getKnownData<GPUData, GPUKnownDataType>({
-          data,
-          meta,
-          knownDataTypes: gpuValues,
-          onGetKnownDataDetails: v => getGPUKnownDataDetails(v),
-        })}
-      />
-      <ContextBlock
-        data={getUnknownData({
-          allData: data,
-          knownKeys: [...gpuValues, ...gpuIgnoredDataValues],
-          meta,
-        })}
-      />
+      <ContextBlock data={knownStructuredData} />
+      <ContextBlock data={unknownData} />
     </Fragment>
   );
 }

+ 2 - 6
static/app/components/events/contexts/memoryInfo/getMemoryInfoKnownDataDetails.tsx

@@ -1,21 +1,17 @@
+import type {KnownDataDetails} from 'sentry/components/events/contexts/utils';
 import {t} from 'sentry/locale';
 import type {Event, MemoryInfoContext} from 'sentry/types/event';
 import {MemoryInfoContextKey} from 'sentry/types/event';
 
 export const memoryInfoKnownDataValues = Object.values(MemoryInfoContextKey);
 
-type Output = {
-  subject: string;
-  value: React.ReactNode | null;
-};
-
 type Props = {
   data: MemoryInfoContext;
   event: Event;
   type: (typeof memoryInfoKnownDataValues)[number];
 };
 
-export function getMemoryInfoKnownDataDetails({data, type}: Props): Output | undefined {
+export function getMemoryInfoKnownDataDetails({data, type}: Props): KnownDataDetails {
   switch (type) {
     case MemoryInfoContextKey.ALLOCATED_BYTES:
       return {

Некоторые файлы не были показаны из-за большого количества измененных файлов