diff --git a/src/sentry/preprod/api/endpoints/preprod_artifact_snapshot.py b/src/sentry/preprod/api/endpoints/preprod_artifact_snapshot.py index 1dbc03c8ddf82f..898134a5c091ec 100644 --- a/src/sentry/preprod/api/endpoints/preprod_artifact_snapshot.py +++ b/src/sentry/preprod/api/endpoints/preprod_artifact_snapshot.py @@ -344,7 +344,12 @@ def get(self, request: Request, organization: Organization, snapshot_id: str) -> if pending_or_failed_state is not None: comparison_state = PreprodSnapshotComparison.State(pending_or_failed_state).name - comparison_type = "diff" if comparison_manifest is not None else "solo" + if comparison_manifest is not None: + comparison_type = "diff" + elif commit_comparison and commit_comparison.base_sha and pending_or_failed_state is None: + comparison_type = "waiting_for_base" + else: + comparison_type = "solo" run_info: SnapshotComparisonRunInfo | None = None if comparison_state is not None: diff --git a/src/sentry/preprod/api/models/project_preprod_build_details_models.py b/src/sentry/preprod/api/models/project_preprod_build_details_models.py index ee936c16ca36ea..e56bccf27a3770 100644 --- a/src/sentry/preprod/api/models/project_preprod_build_details_models.py +++ b/src/sentry/preprod/api/models/project_preprod_build_details_models.py @@ -91,7 +91,9 @@ class PostedStatusChecks(BaseModel): class SnapshotComparisonInfo(BaseModel): image_count: int - comparison_state: Literal["pending", "processing", "success", "failed"] | None = None + comparison_state: ( + Literal["pending", "processing", "success", "failed", "waiting_for_base"] | None + ) = None comparison_error_message: str | None = None images_added: int = 0 images_removed: int = 0 @@ -299,7 +301,11 @@ def to_snapshot_comparison_info(head_artifact: PreprodArtifact) -> SnapshotCompa reverse=True, ) comparison = comparisons[0] if comparisons else None - if comparison: + if not comparison: + cc = head_artifact.commit_comparison + if cc and cc.base_sha: + comparison_state = "waiting_for_base" + elif comparison: comparison_state = PreprodSnapshotComparison.State(comparison.state).name.lower() if comparison.state == PreprodSnapshotComparison.State.SUCCESS: images_added = comparison.images_added diff --git a/static/app/components/preprod/preprodBuildsSnapshotTable.tsx b/static/app/components/preprod/preprodBuildsSnapshotTable.tsx index 2f82ccb2b9ff12..6977703f52eacf 100644 --- a/static/app/components/preprod/preprodBuildsSnapshotTable.tsx +++ b/static/app/components/preprod/preprodBuildsSnapshotTable.tsx @@ -65,6 +65,17 @@ function ChangeCounts({ if (!comparisonState) { return {t('Base')}; } + if (comparisonState === 'waiting_for_base') { + return ( + + {t('Waiting for base')} + + ); + } if (comparisonState === 'pending') { return ( diff --git a/static/app/views/preprod/snapshots/main/snapshotMainContent.tsx b/static/app/views/preprod/snapshots/main/snapshotMainContent.tsx index 52190ddc6742e2..848320cf331f39 100644 --- a/static/app/views/preprod/snapshots/main/snapshotMainContent.tsx +++ b/static/app/views/preprod/snapshots/main/snapshotMainContent.tsx @@ -54,7 +54,7 @@ export interface NavButtonRefs { interface SnapshotMainContentProps { canNavigateNext: boolean; canNavigatePrev: boolean; - comparisonType: 'diff' | 'solo' | undefined; + comparisonType: 'diff' | 'solo' | 'waiting_for_base' | undefined; diffImageBaseUrl: string; diffMode: DiffMode; hasDiffComparison: boolean; @@ -192,6 +192,16 @@ export function SnapshotMainContent({ ); } else if (comparisonType === 'solo') { soloDiffToggle = {t('Base')}; + } else if (comparisonType === 'waiting_for_base') { + soloDiffToggle = ( + + {t('Waiting for base')} + + ); } if (viewMode === 'list') { diff --git a/static/app/views/preprod/snapshots/snapshots.tsx b/static/app/views/preprod/snapshots/snapshots.tsx index 7aac75fd30b41e..1e773a8d9c9007 100644 --- a/static/app/views/preprod/snapshots/snapshots.tsx +++ b/static/app/views/preprod/snapshots/snapshots.tsx @@ -266,7 +266,7 @@ export default function SnapshotsPage() { viewOverride === 'solo' ? 'solo' : (data?.comparison_type ?? 'solo'); const comparisonRunInfo = data?.comparison_run_info; - const isSoloView = comparisonType === 'solo'; + const isSoloView = comparisonType === 'solo' || comparisonType === 'waiting_for_base'; const handleToggleView = useCallback(() => { const {view: _view, ...restQuery} = location.query; if (isSoloView) { diff --git a/static/app/views/preprod/types/buildDetailsTypes.ts b/static/app/views/preprod/types/buildDetailsTypes.ts index 2b538cdcacf63c..92557d103ab9aa 100644 --- a/static/app/views/preprod/types/buildDetailsTypes.ts +++ b/static/app/views/preprod/types/buildDetailsTypes.ts @@ -194,7 +194,12 @@ export function isStatusCheckFailure( return result?.success === false; } -export type SnapshotComparisonState = 'pending' | 'processing' | 'success' | 'failed'; +export type SnapshotComparisonState = + | 'pending' + | 'processing' + | 'success' + | 'failed' + | 'waiting_for_base'; export type SnapshotApprovalStatus = 'approved' | 'requires_approval'; interface SnapshotComparisonInfo { diff --git a/static/app/views/preprod/types/snapshotTypes.ts b/static/app/views/preprod/types/snapshotTypes.ts index 32b84062e3a3b3..60e6ebe42aa79f 100644 --- a/static/app/views/preprod/types/snapshotTypes.ts +++ b/static/app/views/preprod/types/snapshotTypes.ts @@ -40,7 +40,7 @@ interface SnapshotApprovalInfo { } export interface SnapshotDetailsApiResponse { - comparison_type: 'solo' | 'diff'; + comparison_type: 'solo' | 'diff' | 'waiting_for_base'; head_artifact_id: string; image_count: number; images: SnapshotImage[];