Skip to content

Commit

Permalink
feat(new-trace) Rendering resource.img span assets in drawer (#81955)
Browse files Browse the repository at this point in the history
<img width="1280" alt="Screenshot 2024-12-10 at 4 58 46 PM"
src="https://github.com/user-attachments/assets/2c778be5-e2f0-4a25-a332-3d7fa6f0f219">

------------------------

<img width="1279" alt="Screenshot 2024-12-10 at 5 00 33 PM"
src="https://github.com/user-attachments/assets/7f5945a9-b871-404a-986c-bba8befb47d1">

---------

Co-authored-by: Abdullah Khan <[email protected]>
Co-authored-by: Ash <[email protected]>
Co-authored-by: getsantry[bot] <66042841+getsantry[bot]@users.noreply.github.com>
  • Loading branch information
4 people authored Dec 11, 2024
1 parent 6566ddb commit d4dbf62
Show file tree
Hide file tree
Showing 2 changed files with 133 additions and 6 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -156,16 +156,21 @@ function SampleImagesChartPanelBody(props: {
);
}

function DisabledImages(props: {onClickShowLinks?: () => void}) {
export function DisabledImages(props: {
onClickShowLinks?: () => void;
projectSlug?: string;
}) {
const {onClickShowLinks} = props;
const organization = useOrganization();
const {
selection: {projects: selectedProjects},
} = usePageFilters();
const {projects} = useProjects();
const firstProjectSelected = projects.find(
project => project.id === selectedProjects[0].toString()
);
const firstProjectSelected = props.projectSlug
? {
slug: props.projectSlug,
}
: projects.find(project => project.id === selectedProjects[0]?.toString());

return (
<div>
Expand Down Expand Up @@ -244,7 +249,7 @@ function ImageContainer(props: {
);
}

function MissingImage() {
export function MissingImage() {
const theme = useTheme();

return (
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import {Fragment, useMemo} from 'react';
import {Fragment, useMemo, useState} from 'react';
import styled from '@emotion/styled';
import type {Location} from 'history';

Expand All @@ -7,6 +7,7 @@ import {CodeSnippet} from 'sentry/components/codeSnippet';
import {CopyToClipboardButton} from 'sentry/components/copyToClipboardButton';
import SpanSummaryButton from 'sentry/components/events/interfaces/spans/spanSummaryButton';
import Link from 'sentry/components/links/link';
import LoadingIndicator from 'sentry/components/loadingIndicator';
import LinkHint from 'sentry/components/structuredEventData/linkHint';
import {IconGraph} from 'sentry/icons/iconGraph';
import {t} from 'sentry/locale';
Expand All @@ -15,6 +16,13 @@ import type {Organization} from 'sentry/types/organization';
import type {Project} from 'sentry/types/project';
import {trackAnalytics} from 'sentry/utils/analytics';
import {SQLishFormatter} from 'sentry/utils/sqlish/SQLishFormatter';
import {useLocalStorageState} from 'sentry/utils/useLocalStorageState';
import ResourceSize from 'sentry/views/insights/browser/resources/components/resourceSize';
import {
DisabledImages,
LOCAL_STORAGE_SHOW_LINKS,
MissingImage,
} from 'sentry/views/insights/browser/resources/components/sampleImages';
import {resolveSpanModule} from 'sentry/views/insights/common/utils/resolveSpanModule';
import {
MissingFrame,
Expand All @@ -28,6 +36,7 @@ import {
import {ModuleName} from 'sentry/views/insights/types';
import {useHasTraceNewUi} from 'sentry/views/performance/newTraceDetails/useHasTraceNewUi';
import {spanDetailsRouteWithQuery} from 'sentry/views/performance/transactionSummary/transactionSpans/spanDetails/utils';
import {usePerformanceGeneralProjectSettings} from 'sentry/views/performance/utils';

import type {TraceTree} from '../../../../traceModels/traceTree';
import type {TraceTreeNode} from '../../../../traceModels/traceTreeNode';
Expand Down Expand Up @@ -167,6 +176,8 @@ export function SpanDescription({
<MissingFrame />
)}
</CodeSnippetWrapper>
) : resolvedModule === ModuleName.RESOURCE && span.op === 'resource.img' ? (
<ResourceImageDescription formattedDescription={formattedDescription} node={node} />
) : (
<DescriptionWrapper>
{formattedDescription ? (
Expand Down Expand Up @@ -201,6 +212,112 @@ export function SpanDescription({
);
}

function ResourceImageDescription({
formattedDescription,
node,
}: {
formattedDescription: string;
node: TraceTreeNode<TraceTree.Span>;
}) {
const projectID = node.event?.projectID ? Number(node.event?.projectID) : undefined;
const span = node.value;

const {data: settings, isPending: isSettingsLoading} =
usePerformanceGeneralProjectSettings(Number(projectID));
const isImagesEnabled = settings?.enable_images ?? false;

const [showLinks, setShowLinks] = useLocalStorageState(LOCAL_STORAGE_SHOW_LINKS, false);
const size = span?.data?.['http.decoded_response_content_length'];

return (
<StyledDescriptionWrapper>
{isSettingsLoading ? (
<LoadingIndicator size={30} />
) : !isImagesEnabled ? (
<DisabledImages
onClickShowLinks={() => setShowLinks(true)}
projectSlug={span.project_slug}
/>
) : (
<ResourceImage
fileName={formattedDescription}
showImage={!showLinks}
size={size}
src={span.description ?? ''}
/>
)}
</StyledDescriptionWrapper>
);
}

function ResourceImage(props: {
fileName: string;
showImage: boolean;
size: number;
src: string;
}) {
const [hasError, setHasError] = useState(false);

const {fileName, size, src, showImage = true} = props;
const isRelativeUrl = src.startsWith('/');

return (
<ImageContainer>
<FilenameContainer>
<span>
{fileName} (<ResourceSize bytes={size} />)
</span>
<CopyToClipboardButton
borderless
size="zero"
iconSize="xs"
text={fileName}
title={t('Copy file name')}
/>
</FilenameContainer>
{showImage && !isRelativeUrl && !hasError ? (
<ImageWrapper>
<img
data-test-id="sample-image"
onError={() => setHasError(true)}
src={src}
style={{
width: '100%',
height: '100%',
objectFit: 'contain',
objectPosition: 'center',
}}
/>
</ImageWrapper>
) : (
<MissingImage />
)}
</ImageContainer>
);
}

const FilenameContainer = styled('div')`
width: 100%;
display: flex;
align-items: baseline;
gap: ${space(1)};
justify-content: space-between;
`;

const ImageWrapper = styled('div')`
width: 200px;
height: 180px;
margin: auto;
`;

const ImageContainer = styled('div')`
width: 100%;
display: flex;
flex-direction: column;
align-items: center;
gap: ${space(0.5)};
`;

const CodeSnippetWrapper = styled('div')`
display: flex;
flex-direction: column;
Expand Down Expand Up @@ -363,3 +480,8 @@ const DescriptionWrapper = styled('div')`
word-break: break-word;
padding: ${space(1)};
`;

const StyledDescriptionWrapper = styled(DescriptionWrapper)`
padding: ${space(1)};
justify-content: center;
`;

0 comments on commit d4dbf62

Please sign in to comment.