From 8c700defc1c31ca87f707caf7e8bb8022fdbddb5 Mon Sep 17 00:00:00 2001 From: Ryan Albrecht Date: Sun, 19 Jul 2026 19:55:27 +0000 Subject: [PATCH 1/4] fix(coding-conventions): Ensure stable component identity for InlineEventAttachment --- .../inlineEventAttachment.tsx | 47 +++++++++++++++++-- 1 file changed, 43 insertions(+), 4 deletions(-) diff --git a/static/app/views/issueDetails/groupEventAttachments/inlineEventAttachment.tsx b/static/app/views/issueDetails/groupEventAttachments/inlineEventAttachment.tsx index 6f32486e7ca7..12957d7c39bd 100644 --- a/static/app/views/issueDetails/groupEventAttachments/inlineEventAttachment.tsx +++ b/static/app/views/issueDetails/groupEventAttachments/inlineEventAttachment.tsx @@ -1,6 +1,15 @@ import styled from '@emotion/styled'; -import {getInlineAttachmentRenderer} from 'sentry/components/events/attachmentViewers/previewAttachmentTypes'; +import {ImageViewer} from 'sentry/components/events/attachmentViewers/imageViewer'; +import {JsonViewer} from 'sentry/components/events/attachmentViewers/jsonViewer'; +import {LogFileViewer} from 'sentry/components/events/attachmentViewers/logFileViewer'; +import { + getInlineAttachmentRenderer, + imageMimeTypes, + webmMimeTypes, +} from 'sentry/components/events/attachmentViewers/previewAttachmentTypes'; +import {RRWebJsonViewer} from 'sentry/components/events/attachmentViewers/rrwebJsonViewer'; +import {VideoViewer} from 'sentry/components/events/attachmentViewers/videoViewer'; import {PanelItem} from 'sentry/components/panels/panelItem'; import type {Event} from 'sentry/types/event'; import type {IssueAttachment} from 'sentry/types/group'; @@ -12,21 +21,51 @@ interface InlineAttachmentsProps { projectSlug: string; } +interface AttachmentViewerProps { + attachment: IssueAttachment; + eventId: string; + orgSlug: string; + projectSlug: string; +} + +const logFileMimeTypes = ['text/css', 'text/csv', 'text/html', 'text/javascript', 'text/plain']; +const jsonMimeTypes = ['application/json', 'application/ld+json', 'text/json', 'text/x-json']; + +function AttachmentViewer({attachment, orgSlug, projectSlug, eventId}: AttachmentViewerProps) { + const commonProps = {attachment, orgSlug, projectSlug, eventId}; + + if (imageMimeTypes.includes(attachment.mimetype)) { + return ; + } + if (webmMimeTypes.includes(attachment.mimetype)) { + return ; + } + if (logFileMimeTypes.includes(attachment.mimetype)) { + return ; + } + if (jsonMimeTypes.includes(attachment.mimetype)) { + if (attachment.name === 'rrweb.json' || attachment.name.startsWith('rrweb-')) { + return ; + } + return ; + } + return null; +} + export function InlineEventAttachment({ attachment, projectSlug, eventId, }: InlineAttachmentsProps) { const organization = useOrganization(); - const AttachmentComponent = getInlineAttachmentRenderer(attachment); - if (!AttachmentComponent) { + if (!getInlineAttachmentRenderer(attachment)) { return null; } return ( - Date: Sun, 19 Jul 2026 19:56:41 +0000 Subject: [PATCH 2/4] :hammer_and_wrench: apply pre-commit fixes --- .../inlineEventAttachment.tsx | 22 ++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/static/app/views/issueDetails/groupEventAttachments/inlineEventAttachment.tsx b/static/app/views/issueDetails/groupEventAttachments/inlineEventAttachment.tsx index 12957d7c39bd..f58365742bb1 100644 --- a/static/app/views/issueDetails/groupEventAttachments/inlineEventAttachment.tsx +++ b/static/app/views/issueDetails/groupEventAttachments/inlineEventAttachment.tsx @@ -28,10 +28,26 @@ interface AttachmentViewerProps { projectSlug: string; } -const logFileMimeTypes = ['text/css', 'text/csv', 'text/html', 'text/javascript', 'text/plain']; -const jsonMimeTypes = ['application/json', 'application/ld+json', 'text/json', 'text/x-json']; +const logFileMimeTypes = [ + 'text/css', + 'text/csv', + 'text/html', + 'text/javascript', + 'text/plain', +]; +const jsonMimeTypes = [ + 'application/json', + 'application/ld+json', + 'text/json', + 'text/x-json', +]; -function AttachmentViewer({attachment, orgSlug, projectSlug, eventId}: AttachmentViewerProps) { +function AttachmentViewer({ + attachment, + orgSlug, + projectSlug, + eventId, +}: AttachmentViewerProps) { const commonProps = {attachment, orgSlug, projectSlug, eventId}; if (imageMimeTypes.includes(attachment.mimetype)) { From d93a9689d365ca8e25d950797e2d598624a3d3ff Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Tue, 21 Jul 2026 15:20:26 +0000 Subject: [PATCH 3/4] refactor(attachments): Remove getInlineAttachmentRenderer usage and fix code duplication - Export logFileMimeTypes, jsonMimeTypes, and nonPreviewableExtensions from previewAttachmentTypes.tsx for reuse - Remove duplicated MIME type arrays from inlineEventAttachment.tsx - Remove getInlineAttachmentRenderer import and usage - Add missing nonPreviewableExtensions check to AttachmentViewer component - Simplify InlineEventAttachment by removing redundant guard check Co-authored-by: Ryan Albrecht --- .../previewAttachmentTypes.tsx | 6 ++--- .../inlineEventAttachment.tsx | 26 +++++-------------- 2 files changed, 10 insertions(+), 22 deletions(-) diff --git a/static/app/components/events/attachmentViewers/previewAttachmentTypes.tsx b/static/app/components/events/attachmentViewers/previewAttachmentTypes.tsx index 94b231c76a6a..d432f6716025 100644 --- a/static/app/components/events/attachmentViewers/previewAttachmentTypes.tsx +++ b/static/app/components/events/attachmentViewers/previewAttachmentTypes.tsx @@ -15,7 +15,7 @@ export const imageMimeTypes = [ 'image/avif', ]; -const logFileMimeTypes = [ +export const logFileMimeTypes = [ 'text/css', 'text/csv', 'text/html', @@ -23,7 +23,7 @@ const logFileMimeTypes = [ 'text/plain', ]; -const jsonMimeTypes = [ +export const jsonMimeTypes = [ 'application/json', 'application/ld+json', 'text/json', @@ -50,7 +50,7 @@ export const getImageAttachmentRenderer = ( return undefined; }; -const nonPreviewableExtensions = ['.prosperodmp', '.prosperomemdmp']; +export const nonPreviewableExtensions = ['.prosperodmp', '.prosperomemdmp']; export const getInlineAttachmentRenderer = ( attachment: IssueAttachment diff --git a/static/app/views/issueDetails/groupEventAttachments/inlineEventAttachment.tsx b/static/app/views/issueDetails/groupEventAttachments/inlineEventAttachment.tsx index f58365742bb1..72d02fc4c6b6 100644 --- a/static/app/views/issueDetails/groupEventAttachments/inlineEventAttachment.tsx +++ b/static/app/views/issueDetails/groupEventAttachments/inlineEventAttachment.tsx @@ -4,8 +4,10 @@ import {ImageViewer} from 'sentry/components/events/attachmentViewers/imageViewe import {JsonViewer} from 'sentry/components/events/attachmentViewers/jsonViewer'; import {LogFileViewer} from 'sentry/components/events/attachmentViewers/logFileViewer'; import { - getInlineAttachmentRenderer, imageMimeTypes, + jsonMimeTypes, + logFileMimeTypes, + nonPreviewableExtensions, webmMimeTypes, } from 'sentry/components/events/attachmentViewers/previewAttachmentTypes'; import {RRWebJsonViewer} from 'sentry/components/events/attachmentViewers/rrwebJsonViewer'; @@ -28,20 +30,6 @@ interface AttachmentViewerProps { projectSlug: string; } -const logFileMimeTypes = [ - 'text/css', - 'text/csv', - 'text/html', - 'text/javascript', - 'text/plain', -]; -const jsonMimeTypes = [ - 'application/json', - 'application/ld+json', - 'text/json', - 'text/x-json', -]; - function AttachmentViewer({ attachment, orgSlug, @@ -50,6 +38,10 @@ function AttachmentViewer({ }: AttachmentViewerProps) { const commonProps = {attachment, orgSlug, projectSlug, eventId}; + if (nonPreviewableExtensions.some(ext => attachment.name.endsWith(ext))) { + return null; + } + if (imageMimeTypes.includes(attachment.mimetype)) { return ; } @@ -75,10 +67,6 @@ export function InlineEventAttachment({ }: InlineAttachmentsProps) { const organization = useOrganization(); - if (!getInlineAttachmentRenderer(attachment)) { - return null; - } - return ( Date: Tue, 21 Jul 2026 15:22:12 +0000 Subject: [PATCH 4/4] refactor(attachments): Use hasInlineAttachmentRenderer guard to prevent empty renders Add guard check using the shared hasInlineAttachmentRenderer function to avoid rendering an empty PanelItem when the attachment cannot be previewed. This prevents unnecessary DOM elements for non-previewable attachments. Co-authored-by: Ryan Albrecht --- .../groupEventAttachments/inlineEventAttachment.tsx | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/static/app/views/issueDetails/groupEventAttachments/inlineEventAttachment.tsx b/static/app/views/issueDetails/groupEventAttachments/inlineEventAttachment.tsx index 72d02fc4c6b6..d5ce9b28db4e 100644 --- a/static/app/views/issueDetails/groupEventAttachments/inlineEventAttachment.tsx +++ b/static/app/views/issueDetails/groupEventAttachments/inlineEventAttachment.tsx @@ -4,6 +4,7 @@ import {ImageViewer} from 'sentry/components/events/attachmentViewers/imageViewe import {JsonViewer} from 'sentry/components/events/attachmentViewers/jsonViewer'; import {LogFileViewer} from 'sentry/components/events/attachmentViewers/logFileViewer'; import { + hasInlineAttachmentRenderer, imageMimeTypes, jsonMimeTypes, logFileMimeTypes, @@ -67,6 +68,10 @@ export function InlineEventAttachment({ }: InlineAttachmentsProps) { const organization = useOrganization(); + if (!hasInlineAttachmentRenderer(attachment)) { + return null; + } + return (