Skip to content

Commit 96775dd

Browse files
committed
fix: invalidate all detector lists
1 parent 24623d8 commit 96775dd

File tree

5 files changed

+47
-9
lines changed

5 files changed

+47
-9
lines changed

static/app/views/detectors/hooks/detectorListApiOptions.spec.tsx

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,10 @@ import {OrganizationFixture} from 'sentry-fixture/organization';
44
import type {Detector, UptimeDetector} from 'sentry/types/workflowEngine/detectors';
55
import type {ApiResponse} from 'sentry/utils/api/apiFetch';
66
import {parseQueryKey} from 'sentry/utils/api/apiQueryKey';
7-
import {detectorListApiOptions} from 'sentry/views/detectors/hooks';
7+
import {
8+
detectorListApiOptions,
9+
allDetectorListsQueryKey,
10+
} from 'sentry/views/detectors/hooks';
811

912
const organization = OrganizationFixture();
1013

@@ -102,4 +105,29 @@ describe('detectorListApiOptions', () => {
102105
.toEqualTypeOf<ApiResponse<UptimeDetector[]>>();
103106
});
104107
});
108+
109+
describe('allDetectorListsQueryKey', () => {
110+
it('produces a prefix key that matches all detector list queries', () => {
111+
const prefixKey = allDetectorListsQueryKey(organization);
112+
113+
// Should be a 2-element key (no options) so it prefix-matches everything
114+
expect(prefixKey).toHaveLength(2);
115+
expect(prefixKey).toEqual([
116+
{infinite: false, version: 'v2'},
117+
`/organizations/${organization.slug}/detectors/`,
118+
]);
119+
});
120+
121+
it('prefix-matches queries with different filters', () => {
122+
const prefixKey = allDetectorListsQueryKey(organization);
123+
const uptimeKey = detectorListApiOptions(organization, {
124+
type: 'uptime',
125+
}).queryKey;
126+
const defaultKey = detectorListApiOptions(organization).queryKey;
127+
128+
// The prefix (first 2 elements) should match both
129+
expect(uptimeKey.slice(0, 2)).toEqual(prefixKey);
130+
expect(defaultKey.slice(0, 2)).toEqual(prefixKey);
131+
});
132+
});
105133
});

static/app/views/detectors/hooks/index.ts

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,16 @@ export function detectorListApiOptions<
9696
});
9797
}
9898

99+
/**
100+
* Returns a query key prefix that matches all detector list queries
101+
* regardless of filters. Use with `invalidateQueries` after mutations.
102+
*/
103+
export function allDetectorListsQueryKey(organization: Organization) {
104+
return detectorListApiOptions(organization, {
105+
includeIssueStreamDetectors: true,
106+
}).queryKey;
107+
}
108+
99109
export function useCreateDetector<T extends Detector = Detector>() {
100110
const org = useOrganization();
101111
const api = useApi({persistInFlight: true});
@@ -117,7 +127,7 @@ export function useCreateDetector<T extends Detector = Detector>() {
117127
),
118128
onSuccess: _ => {
119129
queryClient.invalidateQueries({
120-
queryKey: detectorListApiOptions(org).queryKey,
130+
queryKey: allDetectorListsQueryKey(org),
121131
});
122132
},
123133
onError: _ => {
@@ -144,7 +154,7 @@ export function useUpdateDetector<T extends Detector = Detector>() {
144154
),
145155
onSuccess: (_, data) => {
146156
queryClient.invalidateQueries({
147-
queryKey: detectorListApiOptions(org).queryKey,
157+
queryKey: allDetectorListsQueryKey(org),
148158
});
149159
queryClient.invalidateQueries({
150160
queryKey: [

static/app/views/detectors/hooks/useDeleteDetectorMutation.tsx

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
import {addErrorMessage, addSuccessMessage} from 'sentry/actionCreators/indicator';
22
import {t} from 'sentry/locale';
3-
import type {ApiQueryKey} from 'sentry/utils/queryClient';
43
import {useMutation, useQueryClient} from 'sentry/utils/queryClient';
54
import type {RequestError} from 'sentry/utils/requestError/requestError';
65
import {useApi} from 'sentry/utils/useApi';
76
import {useOrganization} from 'sentry/utils/useOrganization';
7+
import {allDetectorListsQueryKey} from 'sentry/views/detectors/hooks';
88

99
export function useDeleteDetectorMutation() {
1010
const org = useOrganization();
@@ -18,9 +18,7 @@ export function useDeleteDetectorMutation() {
1818
}),
1919
onSuccess: () => {
2020
queryClient.invalidateQueries({
21-
// Invalidate list of detectors
22-
predicate: query =>
23-
(query.queryKey as ApiQueryKey)[0] === `/organizations/${org.slug}/detectors/`,
21+
queryKey: allDetectorListsQueryKey(org),
2422
});
2523
addSuccessMessage(t('Monitor deleted.'));
2624
},

static/app/views/detectors/hooks/useDeleteDetectorsMutation.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import {useMutation, useQueryClient} from 'sentry/utils/queryClient';
44
import type {RequestError} from 'sentry/utils/requestError/requestError';
55
import {useApi} from 'sentry/utils/useApi';
66
import {useOrganization} from 'sentry/utils/useOrganization';
7+
import {allDetectorListsQueryKey} from 'sentry/views/detectors/hooks';
78

89
/** Bulk delete detectors */
910
export function useDeleteDetectorsMutation() {
@@ -28,7 +29,7 @@ export function useDeleteDetectorsMutation() {
2829
},
2930
onSuccess: () => {
3031
queryClient.invalidateQueries({
31-
queryKey: [`/organizations/${org.slug}/detectors/`],
32+
queryKey: allDetectorListsQueryKey(org),
3233
});
3334
addSuccessMessage(t('Monitors deleted'));
3435
},

static/app/views/detectors/hooks/useEditDetectorsMutation.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import {useMutation, useQueryClient} from 'sentry/utils/queryClient';
44
import type {RequestError} from 'sentry/utils/requestError/requestError';
55
import {useApi} from 'sentry/utils/useApi';
66
import {useOrganization} from 'sentry/utils/useOrganization';
7+
import {allDetectorListsQueryKey} from 'sentry/views/detectors/hooks';
78

89
/** Bulk update detectors. Currently supports enabling/disabling detectors. */
910
export function useUpdateDetectorsMutation() {
@@ -29,7 +30,7 @@ export function useUpdateDetectorsMutation() {
2930
},
3031
onSuccess: (_, variables) => {
3132
queryClient.invalidateQueries({
32-
queryKey: [`/organizations/${org.slug}/detectors/`],
33+
queryKey: allDetectorListsQueryKey(org),
3334
});
3435
addSuccessMessage(
3536
variables.enabled ? t('Monitors enabled') : t('Monitors disabled')

0 commit comments

Comments
 (0)