-
Notifications
You must be signed in to change notification settings - Fork 454
Expand file tree
/
Copy pathuseOrganizationEnterpriseConnectionTestRuns.tsx
More file actions
180 lines (160 loc) · 5.85 KB
/
Copy pathuseOrganizationEnterpriseConnectionTestRuns.tsx
File metadata and controls
180 lines (160 loc) · 5.85 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
import { useCallback, useEffect, useState } from 'react';
import type {
EnterpriseConnectionTestRunResource,
GetEnterpriseConnectionTestRunsParams,
} from '../../types/enterpriseConnectionTestRun';
import { useClerkInstanceContext } from '../contexts';
import { defineKeepPreviousDataFn } from '../query/keep-previous-data';
import { useClerkQueryClient } from '../query/use-clerk-query-client';
import { useClerkQuery } from '../query/useQuery';
import { useOrganizationBase } from './base/useOrganizationBase';
import { useClearQueriesOnSignOut } from './useClearQueriesOnSignOut';
import { useOrganizationEnterpriseConnectionTestRunsCacheKeys } from './useOrganizationEnterpriseConnectionTestRuns.shared';
const DEFAULT_POLL_INTERVAL_MS = 2_000;
export type UseOrganizationEnterpriseConnectionTestRunsParams = {
enterpriseConnectionId: string | null;
/**
* Pass-through fetch parameters (pagination, status filter).
* Defaults to `{ initialPage: 1, pageSize: 10 }`.
*/
params?: GetEnterpriseConnectionTestRunsParams;
/**
* Polling interval (ms) applied between `revalidate()` and the moment the
* first record arrives in the response.
*
* @default 2000
*/
pollIntervalMs?: number;
/**
* If `false`, the hook is dormant — no fetch, no polling.
*
* @default true
*/
enabled?: boolean;
/**
* When `true`, a background refetch keeps the previously-loaded page visible
* (`isFetching` stays `true`, `isLoading` does not flip back to `true`) instead
* of clearing to a cold-load state.
*
* @default false
*/
keepPreviousData?: boolean;
};
export type UseOrganizationEnterpriseConnectionTestRunsReturn = {
data: EnterpriseConnectionTestRunResource[] | undefined;
totalCount: number | undefined;
error: Error | null;
isLoading: boolean;
isFetching: boolean;
/**
* `true` while the hook is actively polling for the first record to appear
*/
isPolling: boolean;
/**
* Force a refetch.
*
* By default this also arms polling when the list is currently empty, so a run
* kicked off elsewhere is picked up as it lands. Pass `{ armPolling: false }`
* for an entry/pagination refetch that should never arm polling merely because
* the list happens to be empty — polling is then armed only by an explicit
* `revalidate()` (or `revalidate({ armPolling: true })`) after a run is kicked
* off.
*/
revalidate: (options?: RevalidateTestRunsOptions) => Promise<void>;
};
export type RevalidateTestRunsOptions = {
/**
* Whether to arm polling for the first record when the list is currently
* empty.
*
* @default true
*/
armPolling?: boolean;
};
/**
* Subscribes to the list of enterprise-connection test runs for the active organization
*
* @internal
*/
function useOrganizationEnterpriseConnectionTestRuns(
params: UseOrganizationEnterpriseConnectionTestRunsParams,
): UseOrganizationEnterpriseConnectionTestRunsReturn {
const {
enterpriseConnectionId,
params: fetchParams = { initialPage: 1, pageSize: 10 },
pollIntervalMs = DEFAULT_POLL_INTERVAL_MS,
enabled = true,
keepPreviousData = false,
} = params;
const clerk = useClerkInstanceContext();
const organization = useOrganizationBase();
const [queryClient] = useClerkQueryClient();
const { queryKey, invalidationKey, stableKey, authenticated } = useOrganizationEnterpriseConnectionTestRunsCacheKeys({
organizationId: organization?.id ?? null,
enterpriseConnectionId,
args: fetchParams,
});
useClearQueriesOnSignOut({
isSignedOut: organization === null,
authenticated,
stableKeys: stableKey,
});
const queryEnabled = enabled && clerk.loaded && Boolean(organization) && Boolean(enterpriseConnectionId);
const [shouldPoll, setShouldPoll] = useState(false);
useEffect(() => {
// Polling intent is scoped to the current connection — clear it when the
// connection changes so a reset/recreate doesn't inherit a stale armed poll.
setShouldPoll(false);
}, [enterpriseConnectionId]);
const query = useClerkQuery({
queryKey,
queryFn: () => {
if (!enterpriseConnectionId) {
throw new Error('enterpriseConnectionId is required to fetch test runs');
}
return organization?.getEnterpriseConnectionTestRuns(enterpriseConnectionId, fetchParams);
},
refetchInterval: q => {
if (!shouldPoll) {
return false;
}
const hasRows = (q.state.data?.data?.length ?? 0) > 0;
return hasRows ? false : pollIntervalMs;
},
enabled: queryEnabled,
refetchIntervalInBackground: false,
placeholderData: defineKeepPreviousDataFn(keepPreviousData),
});
const hasRows = (query.data?.data?.length ?? 0) > 0;
useEffect(() => {
if (shouldPoll && hasRows) {
setShouldPoll(false);
}
}, [shouldPoll, hasRows]);
const revalidate = useCallback(
async (options?: RevalidateTestRunsOptions) => {
// Arm polling only when the caller opts in (the default) AND there is
// nothing in the list yet. An entry/pagination refetch passes
// `armPolling: false` so an empty list on entry never arms polling on its
// own — that stays the job of an explicit refetch after a run is kicked
// off. Once any record has been seen, this is a one-shot refetch.
const armPolling = options?.armPolling ?? true;
if (armPolling && !hasRows) {
setShouldPoll(true);
}
await queryClient.invalidateQueries({ queryKey: invalidationKey });
},
[queryClient, invalidationKey, hasRows],
);
const isPolling = queryEnabled && shouldPoll && !hasRows;
return {
data: query.data?.data,
totalCount: query.data?.total_count,
error: query.error ?? null,
isLoading: query.isLoading,
isFetching: query.isFetching,
isPolling,
revalidate,
};
}
export { useOrganizationEnterpriseConnectionTestRuns as __internal_useOrganizationEnterpriseConnectionTestRuns };