mirror of
https://github.com/hanzoai/sentinel.git
synced 2026-09-29 22:34:33 +00:00
One family. Font stacks name Zen and fall back to the native faces, tokens name the role rather than a face, and the packages that used to supply a face now point at @hanzo/font. Self-hosted @font-face blocks are removed rather than renamed: rewriting the family in one would leave a src pointing at a file this repo no longer ships. @hanzo/font carries the binaries and declares the faces, so the local copies go with the declaration that used them. Comments naming a face we no longer use are deleted, not reworded.
80 lines
2.5 KiB
TypeScript
80 lines
2.5 KiB
TypeScript
import {keyframes} from '@emotion/react';
|
|
import styled from '@emotion/styled';
|
|
|
|
import ExternalLink from 'sentry/components/links/externalLink';
|
|
import SentryAppComponentIcon from 'sentry/components/sentryAppComponentIcon';
|
|
import {Tooltip} from 'sentry/components/tooltip';
|
|
import {space} from 'sentry/styles/space';
|
|
import type {SentryAppComponent, SentryAppSchemaStacktraceLink} from 'sentry/types';
|
|
import {addQueryParamsToExistingUrl} from 'sentry/utils/queryString';
|
|
import {recordInteraction} from 'sentry/utils/recordSentryAppInteraction';
|
|
|
|
type Props = {
|
|
components: SentryAppComponent<SentryAppSchemaStacktraceLink>[];
|
|
filename: string;
|
|
lineNo: number | null;
|
|
};
|
|
|
|
function OpenInContextLine({lineNo, filename, components}: Props) {
|
|
const handleRecordInteraction =
|
|
(slug: SentryAppComponent<SentryAppSchemaStacktraceLink>['sentryApp']['slug']) =>
|
|
() => {
|
|
recordInteraction(slug, 'sentry_app_component_interacted', {
|
|
componentType: 'stacktrace-link',
|
|
});
|
|
};
|
|
|
|
const getUrl = (url: SentryAppSchemaStacktraceLink['url']) => {
|
|
return addQueryParamsToExistingUrl(url, {lineNo, filename});
|
|
};
|
|
|
|
return (
|
|
<OpenInContainer>
|
|
{components.map(component => {
|
|
const url = getUrl(component.schema.url);
|
|
const {slug} = component.sentryApp;
|
|
const onClickRecordInteraction = handleRecordInteraction(slug);
|
|
return (
|
|
<Tooltip key={component.uuid} title={component.sentryApp.name} skipWrapper>
|
|
<OpenInLink
|
|
aria-label={component.sentryApp.name}
|
|
href={url}
|
|
onClick={onClickRecordInteraction}
|
|
onContextMenu={onClickRecordInteraction}
|
|
openInNewTab
|
|
>
|
|
<SentryAppComponentIcon sentryAppComponent={component} size={16} />
|
|
</OpenInLink>
|
|
</Tooltip>
|
|
);
|
|
})}
|
|
</OpenInContainer>
|
|
);
|
|
}
|
|
|
|
export {OpenInContextLine};
|
|
|
|
const fadeIn = keyframes`
|
|
from { opacity: 0; }
|
|
to { opacity: 1; }
|
|
`;
|
|
|
|
const OpenInContainer = styled('div')`
|
|
display: flex;
|
|
gap: ${space(1)};
|
|
align-items: center;
|
|
z-index: 1;
|
|
font-family: Zen, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif{p => p.theme.text.family};
|
|
text-indent: initial;
|
|
overflow: auto;
|
|
white-space: nowrap;
|
|
animation: ${fadeIn} 0.2s ease-in-out forwards;
|
|
`;
|
|
|
|
const OpenInLink = styled(ExternalLink)`
|
|
display: flex;
|
|
gap: ${space(0.75)};
|
|
align-items: center;
|
|
color: ${p => p.theme.gray300};
|
|
`;
|