mirror of
https://github.com/grafana/grafana.git
synced 2025-07-31 14:12:24 +08:00

* Provisioning: Refactor createOnCacheEntryAdded * Use custom list resource type * add generated types and transformers * Switch to type guards * Do not create new array
67 lines
2.2 KiB
TypeScript
67 lines
2.2 KiB
TypeScript
import { Subscription } from 'rxjs';
|
|
|
|
import { ScopedResourceClient } from 'app/features/apiserver/client';
|
|
import { ListOptions, GeneratedResourceList as ResourceList } from 'app/features/apiserver/types';
|
|
|
|
/**
|
|
* Creates a cache entry handler for RTK Query that watches for changes to a resource
|
|
* and updates the cache accordingly.
|
|
*/
|
|
export function createOnCacheEntryAdded<Spec, Status>(resourceName: string) {
|
|
return async function onCacheEntryAdded<List extends ResourceList<Spec, Status>>(
|
|
arg: ListOptions | undefined,
|
|
{
|
|
updateCachedData,
|
|
cacheDataLoaded,
|
|
cacheEntryRemoved,
|
|
}: {
|
|
updateCachedData: (fn: (draft: List) => void) => void;
|
|
cacheDataLoaded: Promise<{ data: List }>;
|
|
cacheEntryRemoved: Promise<void>;
|
|
}
|
|
) {
|
|
if (!arg?.watch) {
|
|
return;
|
|
}
|
|
|
|
const client = new ScopedResourceClient<Spec, Status>({
|
|
group: 'provisioning.grafana.app',
|
|
version: 'v0alpha1',
|
|
resource: resourceName,
|
|
});
|
|
|
|
let subscription: Subscription | null = null;
|
|
try {
|
|
// Wait for the initial query to resolve before proceeding
|
|
const response = await cacheDataLoaded;
|
|
const resourceVersion = response.data.metadata?.resourceVersion;
|
|
|
|
subscription = client.watch({ resourceVersion }).subscribe((event) => {
|
|
updateCachedData((draft) => {
|
|
if (!draft.items) {
|
|
draft.items = [];
|
|
}
|
|
// Find the item with the matching name
|
|
const existingIndex = draft.items.findIndex((item) => item.metadata?.name === event.object.metadata.name);
|
|
|
|
if (event.type === 'ADDED' && existingIndex === -1) {
|
|
draft.items.push(event.object);
|
|
} else if (event.type === 'DELETED' && existingIndex !== -1) {
|
|
// Remove the item if it exists
|
|
draft.items.splice(existingIndex, 1);
|
|
} else if (existingIndex !== -1) {
|
|
// Could be ADDED or MODIFIED
|
|
// Update the existing item if it exists
|
|
draft.items[existingIndex] = event.object;
|
|
}
|
|
});
|
|
});
|
|
} catch (error) {
|
|
console.error('Error in onCacheEntryAdded:', error);
|
|
}
|
|
|
|
await cacheEntryRemoved;
|
|
subscription?.unsubscribe();
|
|
};
|
|
}
|