@@ -39,21 +39,20 @@ import {
3939 useQueryClient ,
4040} from '@tanstack/react-query' ;
4141import { useEffect , useRef } from 'react' ;
42- import { request } from './hooks' ;
42+ import { isRunActive , request } from './hooks' ;
4343import type {
4444 OmInventoryHost ,
4545 OmInventoryRun ,
4646 OmInventoryRunAccepted ,
4747 OmInventoryRunDetail ,
4848 OmInventoryService ,
4949 OmInventorySetting ,
50- OmTopologyRunStatus ,
5150} from './types' ;
5251
53- const hostsKey = [ 'om' , 'inventory' , 'hosts' ] as const ;
54- const servicesKey = [ 'om' , 'inventory' , 'services' ] as const ;
55- const runsKey = [ 'om' , 'inventory' , 'runs' ] as const ;
56- const configKey = [ 'om' , 'inventory' , 'config' ] as const ;
52+ const HOSTS_KEY = [ 'om' , 'inventory' , 'hosts' ] as const ;
53+ const SERVICES_KEY = [ 'om' , 'inventory' , 'services' ] as const ;
54+ const RUNS_KEY = [ 'om' , 'inventory' , 'runs' ] as const ;
55+ const CONFIG_KEY = [ 'om' , 'inventory' , 'config' ] as const ;
5756
5857/** Poll cadence while a refresh is in flight (ms). */
5958const REFRESH_POLL_MS = 3000 ;
@@ -113,7 +112,7 @@ function toQuery(filters: OmHostFilters): string {
113112export function useOmInventoryHosts ( filters : OmHostFilters = { } ) {
114113 const query = toQuery ( filters ) ;
115114 return useQuery < OmInventoryHost [ ] > ( {
116- queryKey : [ ...hostsKey , query ] ,
115+ queryKey : [ ...HOSTS_KEY , query ] ,
117116 placeholderData : keepPreviousData ,
118117 queryFn : async ( ) => {
119118 const { hosts } = await request < { hosts : OmInventoryHost [ ] } > (
@@ -137,7 +136,7 @@ export function useOmInventoryHosts(filters: OmHostFilters = {}) {
137136 */
138137export function useOmInventoryServices ( ) {
139138 return useQuery < OmInventoryService [ ] > ( {
140- queryKey : servicesKey ,
139+ queryKey : SERVICES_KEY ,
141140 placeholderData : keepPreviousData ,
142141 queryFn : async ( ) => {
143142 const { services } = await request < { services : OmInventoryService [ ] } > (
@@ -149,28 +148,16 @@ export function useOmInventoryServices() {
149148 } ) ;
150149}
151150
152- /**
153- * True while a refresh has not reached a terminal status.
154- *
155- * Typed on the union rather than on `string`, because the compiler is the only thing
156- * that would have caught this comparison going stale when the wire values changed.
157- */
158- export function isRefreshActive (
159- status : OmTopologyRunStatus | undefined
160- ) : boolean {
161- return status === 'RUN_STATUS_RUNNING' ;
162- }
163-
164151/**
165152 * Refresh history, newest first.
166153 *
167- * Polls fast while the newest refresh is in flight and slowly otherwise, rather than
168- * stopping: the schedule starts sweeps nobody here asked for, and a history that only
169- * updated on reload could not show them.
154+ * Polls fast while any refresh is in flight and slowly otherwise, rather than stopping:
155+ * the schedule starts sweeps nobody here asked for, and a history that only updated on
156+ * reload could not show them.
170157 */
171158export function useOmInventoryRuns ( limit = 25 ) {
172159 return useQuery < OmInventoryRun [ ] > ( {
173- queryKey : [ ...runsKey , limit ] ,
160+ queryKey : [ ...RUNS_KEY , limit ] ,
174161 queryFn : async ( ) => {
175162 const { runs } = await request < { runs : OmInventoryRun [ ] } > (
176163 `/inventory/runs?limit=${ limit } `
@@ -181,7 +168,7 @@ export function useOmInventoryRuns(limit = 25) {
181168 // overlap -- and a narrow one started later can finish first, which would leave
182169 // data[0] terminal while a broader run is still probing.
183170 refetchInterval : ( query ) =>
184- ( query . state . data ?? [ ] ) . some ( ( run ) => isRefreshActive ( run . status ) )
171+ ( query . state . data ?? [ ] ) . some ( ( run ) => isRunActive ( run . status ) )
185172 ? REFRESH_POLL_MS
186173 : ESTATE_POLL_MS ,
187174 } ) ;
@@ -211,12 +198,12 @@ export function useInvalidateEstateOnRefreshEnd(
211198 const queryClient = useQueryClient ( ) ;
212199 const wasActive = useRef ( false ) ;
213200
214- const anyActive = ( runs ?? [ ] ) . some ( ( run ) => isRefreshActive ( run . status ) ) ;
201+ const anyActive = ( runs ?? [ ] ) . some ( ( run ) => isRunActive ( run . status ) ) ;
215202
216203 useEffect ( ( ) => {
217204 if ( wasActive . current && ! anyActive ) {
218- queryClient . invalidateQueries ( { queryKey : hostsKey } ) ;
219- queryClient . invalidateQueries ( { queryKey : servicesKey } ) ;
205+ queryClient . invalidateQueries ( { queryKey : HOSTS_KEY } ) ;
206+ queryClient . invalidateQueries ( { queryKey : SERVICES_KEY } ) ;
220207 }
221208 wasActive . current = anyActive ;
222209 } , [ anyActive , queryClient ] ) ;
@@ -238,15 +225,20 @@ export function useInvalidateEstateOnRefreshEnd(
238225export function useRefreshInventory ( ) {
239226 const queryClient = useQueryClient ( ) ;
240227 return useMutation < OmInventoryRunAccepted , Error , string [ ] | undefined > ( {
228+ // A body only when there is a scope to state. `body: "*"` on the method plus
229+ // grpc-gateway tolerating io.EOF means an unscoped sweep needs no `{}` to say
230+ // "everything"; the absent body already says it.
241231 mutationFn : ( nodeIds ) =>
242232 request < OmInventoryRunAccepted > ( '/inventory/runs:trigger' , {
243233 method : 'POST' ,
244- body : JSON . stringify ( nodeIds ?. length ? { node_ids : nodeIds } : { } ) ,
234+ body : nodeIds ?. length
235+ ? JSON . stringify ( { node_ids : nodeIds } )
236+ : undefined ,
245237 } ) ,
246238 // onSettled rather than onSuccess: a 409 means a sweep is in flight and the estate
247239 // is about to change, which is exactly when a refetch is most wanted.
248240 onSettled : ( ) => {
249- queryClient . invalidateQueries ( { queryKey : runsKey } ) ;
241+ queryClient . invalidateQueries ( { queryKey : RUNS_KEY } ) ;
250242 } ,
251243 } ) ;
252244}
@@ -267,8 +259,8 @@ export function useForgetHost() {
267259 method : 'DELETE' ,
268260 } ) ,
269261 onSuccess : ( ) => {
270- queryClient . invalidateQueries ( { queryKey : hostsKey } ) ;
271- queryClient . invalidateQueries ( { queryKey : servicesKey } ) ;
262+ queryClient . invalidateQueries ( { queryKey : HOSTS_KEY } ) ;
263+ queryClient . invalidateQueries ( { queryKey : SERVICES_KEY } ) ;
272264 } ,
273265 } ) ;
274266}
@@ -282,8 +274,8 @@ export function useForgetService() {
282274 method : 'DELETE' ,
283275 } ) ,
284276 onSuccess : ( ) => {
285- queryClient . invalidateQueries ( { queryKey : hostsKey } ) ;
286- queryClient . invalidateQueries ( { queryKey : servicesKey } ) ;
277+ queryClient . invalidateQueries ( { queryKey : HOSTS_KEY } ) ;
278+ queryClient . invalidateQueries ( { queryKey : SERVICES_KEY } ) ;
287279 } ,
288280 } ) ;
289281}
@@ -298,13 +290,13 @@ export function useForgetService() {
298290 */
299291export function useOmInventoryRun ( runId : string | undefined ) {
300292 return useQuery < OmInventoryRunDetail > ( {
301- queryKey : [ ...runsKey , 'detail' , runId ] ,
293+ queryKey : [ ...RUNS_KEY , 'detail' , runId ] ,
302294 enabled : Boolean ( runId ) ,
303295 queryFn : ( ) => request < OmInventoryRunDetail > ( `/inventory/runs/${ runId } ` ) ,
304296 // A run still going gains entities as its dispatches land, so the open panel
305297 // follows it; a finished one never changes again.
306298 refetchInterval : ( query ) =>
307- isRefreshActive ( query . state . data ?. run . status ) ? REFRESH_POLL_MS : false ,
299+ isRunActive ( query . state . data ?. run . status ) ? REFRESH_POLL_MS : false ,
308300 } ) ;
309301}
310302
@@ -317,7 +309,7 @@ export function useOmInventoryRun(runId: string | undefined) {
317309 */
318310export function useOmInventoryConfig ( ) {
319311 return useQuery < OmInventorySetting [ ] > ( {
320- queryKey : configKey ,
312+ queryKey : CONFIG_KEY ,
321313 queryFn : async ( ) => {
322314 const { settings } = await request < { settings : OmInventorySetting [ ] } > (
323315 '/inventory/config'
@@ -358,10 +350,10 @@ export function useUpdateOmInventoryConfig() {
358350 body : JSON . stringify ( values ) ,
359351 } ) ,
360352 onSettled : ( ) => {
361- queryClient . invalidateQueries ( { queryKey : configKey } ) ;
353+ queryClient . invalidateQueries ( { queryKey : CONFIG_KEY } ) ;
362354 // The schedule drives when the next refresh runs, so the history's idea of
363355 // "due" changes with it.
364- queryClient . invalidateQueries ( { queryKey : runsKey } ) ;
356+ queryClient . invalidateQueries ( { queryKey : RUNS_KEY } ) ;
365357 } ,
366358 } ) ;
367359}
@@ -375,7 +367,7 @@ export function useResetOmInventoryConfig() {
375367 method : 'DELETE' ,
376368 } ) ,
377369 onSettled : ( ) => {
378- queryClient . invalidateQueries ( { queryKey : configKey } ) ;
370+ queryClient . invalidateQueries ( { queryKey : CONFIG_KEY } ) ;
379371 } ,
380372 } ) ;
381373}
0 commit comments