mirror of
https://github.com/hanzoai/sentinel.git
synced 2026-09-29 22:34:33 +00:00
136 lines
3.6 KiB
TypeScript
136 lines
3.6 KiB
TypeScript
import {Fragment, useCallback, useEffect, useState} from 'react';
|
|
|
|
import {EventDataSection} from 'sentry/components/events/eventDataSection';
|
|
import {t} from 'sentry/locale';
|
|
import plugins from 'sentry/plugins';
|
|
import type {Group} from 'sentry/types';
|
|
import type {Event} from 'sentry/types/event';
|
|
import {defined, toTitleCase} from 'sentry/utils';
|
|
|
|
import {getContextComponent, getSourcePlugin} from './utils';
|
|
|
|
type Props = {
|
|
alias: string;
|
|
event: Event;
|
|
type: string;
|
|
group?: Group;
|
|
value?: Record<string, any>;
|
|
};
|
|
|
|
function getTitle({value = {}, alias, type}: Pick<Props, 'alias' | 'type' | 'value'>) {
|
|
if (defined(value.title) && typeof value.title !== 'object') {
|
|
return value.title;
|
|
}
|
|
|
|
if (!defined(type)) {
|
|
return toTitleCase(alias);
|
|
}
|
|
|
|
switch (type) {
|
|
case 'app':
|
|
return t('App');
|
|
case 'device':
|
|
return t('Device');
|
|
case 'os':
|
|
return t('Operating System');
|
|
case 'user':
|
|
return t('User');
|
|
case 'gpu':
|
|
return t('Graphics Processing Unit');
|
|
case 'runtime':
|
|
return t('Runtime');
|
|
case 'trace':
|
|
return t('Trace Details');
|
|
case 'otel':
|
|
return t('OpenTelemetry');
|
|
case 'unity':
|
|
return t('Unity');
|
|
case 'memory_info': // Future new value for memory info
|
|
case 'Memory Info': // Current value for memory info
|
|
return t('Memory Info');
|
|
case 'threadpool_info': // Future new value for thread pool info
|
|
case 'ThreadPool Info': // Current value for thread pool info
|
|
return t('Thread Pool Info');
|
|
case 'default':
|
|
if (alias === 'state') {
|
|
return t('Application State');
|
|
}
|
|
return toTitleCase(alias);
|
|
default:
|
|
return toTitleCase(type);
|
|
}
|
|
}
|
|
|
|
export function Chunk({group, type, alias, value = {}, event}: Props) {
|
|
const [pluginLoading, setPluginLoading] = useState(false);
|
|
|
|
const syncPlugin = useCallback(() => {
|
|
// If we don't have a grouped event we can't sync with plugins.
|
|
if (!group) {
|
|
return;
|
|
}
|
|
|
|
// Search using `alias` first because old plugins rely on it and type is set to "default"
|
|
// e.g. sessionstack
|
|
const sourcePlugin =
|
|
type === 'default'
|
|
? getSourcePlugin(group.pluginContexts, alias) ||
|
|
getSourcePlugin(group.pluginContexts, type)
|
|
: getSourcePlugin(group.pluginContexts, type);
|
|
|
|
if (!sourcePlugin) {
|
|
setPluginLoading(false);
|
|
return;
|
|
}
|
|
|
|
setPluginLoading(true);
|
|
|
|
plugins.load(sourcePlugin, () => {
|
|
setPluginLoading(false);
|
|
});
|
|
}, [alias, type, group]);
|
|
|
|
useEffect(() => {
|
|
syncPlugin();
|
|
}, [type, group?.id, syncPlugin]);
|
|
|
|
// if we are currently loading the plugin, just render nothing for now.
|
|
if (pluginLoading) {
|
|
return null;
|
|
}
|
|
|
|
// we intentionally hide reprocessing context to not imply it was sent by the SDK.
|
|
if (alias === 'reprocessing') {
|
|
return null;
|
|
}
|
|
|
|
const ContextComponent =
|
|
type === 'default'
|
|
? getContextComponent(alias) || getContextComponent(type)
|
|
: getContextComponent(type);
|
|
|
|
const isObjectValueEmpty = Object.values(value).filter(v => defined(v)).length === 0;
|
|
|
|
// this can happen if the component does not exist
|
|
if (!ContextComponent || isObjectValueEmpty) {
|
|
return null;
|
|
}
|
|
|
|
return (
|
|
<EventDataSection
|
|
key={`context-${alias}`}
|
|
type={`context-${alias}`}
|
|
title={
|
|
<Fragment>
|
|
{getTitle({value, alias, type})}
|
|
{defined(type) && type !== 'default' && alias !== type && (
|
|
<small>({alias})</small>
|
|
)}
|
|
</Fragment>
|
|
}
|
|
>
|
|
<ContextComponent alias={alias} event={event} data={value} />
|
|
</EventDataSection>
|
|
);
|
|
}
|