Skip to content

Commit d39d819

Browse files
mtopo27claude
andcommitted
ref(preprod): Extract getUpdatedQueryForDisplay to deduplicate display-change logic
Move the installable filter add/remove decision into a shared helper so both mobileBuilds and preprodBuilds call a single function instead of duplicating the same conditional block. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 585a54c commit d39d819

File tree

4 files changed

+58
-23
lines changed

4 files changed

+58
-23
lines changed

static/app/components/preprod/installableQueryUtils.spec.ts

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,10 @@
1-
import {addInstallableFilter, removeInstallableFilter} from './installableQueryUtils';
1+
import {PreprodBuildsDisplay} from 'sentry/components/preprod/preprodBuildsDisplay';
2+
3+
import {
4+
addInstallableFilter,
5+
getUpdatedQueryForDisplay,
6+
removeInstallableFilter,
7+
} from './installableQueryUtils';
28

39
describe('addInstallableFilter', () => {
410
it('adds installable:true to an empty query', () => {
@@ -45,3 +51,33 @@ describe('removeInstallableFilter', () => {
4551
expect(removeInstallableFilter('')).toBe('');
4652
});
4753
});
54+
55+
describe('getUpdatedQueryForDisplay', () => {
56+
it('adds installable:true for Distribution display', () => {
57+
expect(getUpdatedQueryForDisplay('', PreprodBuildsDisplay.DISTRIBUTION)).toBe(
58+
'installable:true'
59+
);
60+
});
61+
62+
it('removes installable filter for Size display', () => {
63+
expect(
64+
getUpdatedQueryForDisplay('installable:true', PreprodBuildsDisplay.SIZE)
65+
).toBeUndefined();
66+
});
67+
68+
it('handles null query', () => {
69+
expect(getUpdatedQueryForDisplay(null, PreprodBuildsDisplay.DISTRIBUTION)).toBe(
70+
'installable:true'
71+
);
72+
});
73+
74+
it('preserves other tokens when switching to Distribution', () => {
75+
expect(
76+
getUpdatedQueryForDisplay('app_id:com.example', PreprodBuildsDisplay.DISTRIBUTION)
77+
).toBe('app_id:com.example installable:true');
78+
});
79+
80+
it('returns undefined when result is empty', () => {
81+
expect(getUpdatedQueryForDisplay('', PreprodBuildsDisplay.SIZE)).toBeUndefined();
82+
});
83+
});

static/app/components/preprod/installableQueryUtils.ts

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import {PreprodBuildsDisplay} from 'sentry/components/preprod/preprodBuildsDisplay';
12
import {MutableSearch} from 'sentry/components/searchSyntax/mutableSearch';
23

34
const INSTALLABLE_KEY = 'installable';
@@ -24,3 +25,19 @@ export function removeInstallableFilter(query: string): string {
2425
search.removeFilter(INSTALLABLE_KEY);
2526
return search.formatString();
2627
}
28+
29+
/**
30+
* Returns the updated query string for a display change.
31+
* Distribution display adds `installable:true`; other displays strip it.
32+
*/
33+
export function getUpdatedQueryForDisplay(
34+
currentQuery: string | null,
35+
display: PreprodBuildsDisplay
36+
): string | undefined {
37+
const trimmed = (currentQuery ?? '').trim();
38+
const updated =
39+
display === PreprodBuildsDisplay.DISTRIBUTION
40+
? addInstallableFilter(trimmed)
41+
: removeInstallableFilter(trimmed);
42+
return updated || undefined;
43+
}

static/app/views/releases/detail/commitsAndFiles/preprodBuilds.tsx

Lines changed: 2 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,7 @@ import {Container} from '@sentry/scraps/layout';
55

66
import * as Layout from 'sentry/components/layouts/thirds';
77
import {LoadingError} from 'sentry/components/loadingError';
8-
import {
9-
addInstallableFilter,
10-
removeInstallableFilter,
11-
} from 'sentry/components/preprod/installableQueryUtils';
8+
import {getUpdatedQueryForDisplay} from 'sentry/components/preprod/installableQueryUtils';
129
import {
1310
getPreprodBuildsDisplay,
1411
PreprodBuildsDisplay,
@@ -127,19 +124,13 @@ export default function PreprodBuilds() {
127124

128125
const handleDisplayChange = useCallback(
129126
(display: PreprodBuildsDisplay) => {
130-
const currentQuery = (urlSearchQuery ?? '').trim();
131-
const updatedQuery =
132-
display === PreprodBuildsDisplay.DISTRIBUTION
133-
? addInstallableFilter(currentQuery)
134-
: removeInstallableFilter(currentQuery);
135-
136127
navigate({
137128
...location,
138129
query: {
139130
...location.query,
140131
cursor: undefined,
141132
display,
142-
query: updatedQuery || undefined,
133+
query: getUpdatedQueryForDisplay(urlSearchQuery, display),
143134
},
144135
});
145136
},

static/app/views/releases/list/mobileBuilds.tsx

Lines changed: 2 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,7 @@ import {Stack} from '@sentry/scraps/layout';
77
import {LoadingError} from 'sentry/components/loadingError';
88
import {LoadingIndicator} from 'sentry/components/loadingIndicator';
99
import {normalizeDateTimeParams} from 'sentry/components/pageFilters/parse';
10-
import {
11-
addInstallableFilter,
12-
removeInstallableFilter,
13-
} from 'sentry/components/preprod/installableQueryUtils';
10+
import {getUpdatedQueryForDisplay} from 'sentry/components/preprod/installableQueryUtils';
1411
import {
1512
getPreprodBuildsDisplay,
1613
PreprodBuildsDisplay,
@@ -97,19 +94,13 @@ export function MobileBuilds({organization, selectedProjectIds}: Props) {
9794

9895
const handleDisplayChange = useCallback(
9996
(display: PreprodBuildsDisplay) => {
100-
const currentQuery = (searchQuery ?? '').trim();
101-
const updatedQuery =
102-
display === PreprodBuildsDisplay.DISTRIBUTION
103-
? addInstallableFilter(currentQuery)
104-
: removeInstallableFilter(currentQuery);
105-
10697
navigate({
10798
...location,
10899
query: {
109100
...location.query,
110101
cursor: undefined,
111102
display,
112-
query: updatedQuery || undefined,
103+
query: getUpdatedQueryForDisplay(searchQuery, display),
113104
},
114105
});
115106
},

0 commit comments

Comments
 (0)