Provisioning: Re-fetch folders after creating or deleting a repository (#108778)

* refetch folder

* Simplify refetches

* Cleanup

* Tests

* More test mocks

* Function selectors

* Comment

* Remove unused selector
This commit is contained in:
Alex Khomenko
2025-07-28 17:55:28 +03:00
committed by GitHub
parent 6b4d93b8ec
commit 4c6888654c
4 changed files with 30 additions and 20 deletions
@@ -3,6 +3,8 @@ import { isFetchError } from '@grafana/runtime';
import { notifyApp } from '../../../../core/actions';
import { createSuccessNotification, createErrorNotification } from '../../../../core/copy/appNotification';
import { PAGE_SIZE } from '../../../../features/browse-dashboards/api/services';
import { refetchChildren } from '../../../../features/browse-dashboards/state/actions';
import { createOnCacheEntryAdded } from '../utils/createOnCacheEntryAdded';
import {
@@ -59,6 +61,12 @@ export const provisioningAPIv0alpha1 = generatedAPI.enhanceEndpoints({
);
}
}
// Refetch dashboards and folders after deleting a provisioned repository.
// We need to add timeout to ensure that the deletion is processed before refetching since the deletion is done
// via a background job.
setTimeout(() => {
dispatch(refetchChildren({ parentUID: undefined, pageSize: PAGE_SIZE }));
}, 1000);
},
},
deletecollectionRepository: {
@@ -84,6 +92,9 @@ export const provisioningAPIv0alpha1 = generatedAPI.enhanceEndpoints({
);
}
}
setTimeout(() => {
dispatch(refetchChildren({ parentUID: undefined, pageSize: PAGE_SIZE }));
}, 1000);
},
},
createRepositoryTest: {
@@ -189,6 +200,8 @@ export const provisioningAPIv0alpha1 = generatedAPI.enhanceEndpoints({
);
}
}
// Refetch dashboards and folders after creating/updating a provisioned repository
dispatch(refetchChildren({ parentUID: undefined, pageSize: PAGE_SIZE }));
},
},
},
@@ -73,7 +73,7 @@ export function ToolbarActions({ dashboard }: Props) {
// Means we are not in settings view, fullscreen panel or edit panel
const isShowingDashboard = !editview && !isViewingPanel && !isEditingPanel;
const isEditingAndShowingDashboard = isEditing && isShowingDashboard;
const folderRepo = useSelector((state) => selectFolderRepository(state, meta.folderUid));
const folderRepo = useSelector((state) => selectFolderRepository()(state, meta.folderUid));
const isManaged = Boolean(dashboard.isManagedRepository() || folderRepo);
// Internal only;
@@ -38,6 +38,10 @@ jest.mock('app/api/clients/provisioning/v0alpha1', () => ({
useCreateRepositoryJobsMutation: jest.fn(),
}));
jest.mock('app/features/browse-dashboards/api/services', () => ({
PAGE_SIZE: 20,
}));
const mockUseCreateOrUpdateRepository = useCreateOrUpdateRepository as jest.MockedFunction<
typeof useCreateOrUpdateRepository
>;
@@ -1,28 +1,21 @@
import { createSelector } from '@reduxjs/toolkit';
import { RootState } from 'app/store/configureStore';
import { Repository, provisioningAPIv0alpha1 as provisioningAPI } from '../../../api/clients/provisioning/v0alpha1';
const emptyRepos: Repository[] = [];
const baseSelector = provisioningAPI.endpoints.listRepository.select({});
const getBaseSelector = () => provisioningAPI.endpoints.listRepository.select({});
export const selectAllRepos = createSelector(baseSelector, (result) => result.data?.items || emptyRepos);
export const selectAllRepos = () => createSelector(getBaseSelector(), (result) => result.data?.items || emptyRepos);
export const selectFolderRepository = createSelector(
selectAllRepos,
(_, folderUid?: string) => folderUid,
(repositories: Repository[], folderUid) => {
if (!folderUid) {
return undefined;
export const selectFolderRepository = () =>
createSelector(
selectAllRepos(),
(_, folderUid?: string) => folderUid,
(repositories: Repository[], folderUid) => {
if (!folderUid) {
return undefined;
}
return repositories.find((repo: Repository) => repo.metadata?.name === folderUid);
}
return repositories.find((repo: Repository) => repo.metadata?.name === folderUid);
}
);
export const selectRepoByName = createSelector(
selectAllRepos,
(state: RootState, id: string) => id,
(repositories: Repository[], name) => repositories.find((repo: Repository) => repo.metadata?.name === name)
);
);