mirror of https://github.com/grafana/grafana.git
Folders: Migrate move folder to new API (#110550)
This commit is contained in:
parent
c9707a7463
commit
2958126c87
|
@ -12,10 +12,11 @@ import {
|
|||
useNewFolderMutation as useLegacyNewFolderMutation,
|
||||
useMoveFoldersMutation as useMoveFoldersMutationLegacy,
|
||||
useSaveFolderMutation as useLegacySaveFolderMutation,
|
||||
useMoveFolderMutation as useMoveFolderMutationLegacy,
|
||||
MoveFoldersArgs,
|
||||
DeleteFoldersArgs,
|
||||
MoveFolderArgs,
|
||||
} from 'app/features/browse-dashboards/api/browseDashboardsAPI';
|
||||
import { dispatch } from 'app/store/store';
|
||||
import { FolderDTO, NewFolder } from 'app/types/folders';
|
||||
|
||||
import kbn from '../../../../core/utils/kbn';
|
||||
|
@ -49,16 +50,6 @@ import {
|
|||
ReplaceFolderApiArg,
|
||||
} from './index';
|
||||
|
||||
/** Trigger necessary actions to ensure legacy folder stores are updated */
|
||||
function dispatchRefetchChildren(parentUID?: string) {
|
||||
dispatch(
|
||||
refetchChildren({
|
||||
parentUID: parentUID || GENERAL_FOLDER_UID,
|
||||
pageSize: PAGE_SIZE,
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
function getFolderUrl(uid: string, title: string): string {
|
||||
// mimics https://github.com/grafana/grafana/blob/79fe8a9902335c7a28af30e467b904a4ccfac503/pkg/services/dashboards/models.go#L188
|
||||
// Not the same slugify as on the backend https://github.com/grafana/grafana/blob/aac66e91198004bc044754105e18bfff8fbfd383/pkg/infra/slugify/slugify.go#L86
|
||||
|
@ -179,16 +170,16 @@ export function useGetFolderQueryFacade(uid?: string) {
|
|||
export function useDeleteFolderMutationFacade() {
|
||||
const [deleteFolder] = useDeleteFolderMutation();
|
||||
const [deleteFolderLegacy] = useDeleteFolderMutationLegacy();
|
||||
const refresh = useRefreshFolders();
|
||||
const notify = useAppNotification();
|
||||
|
||||
return async (folder: FolderDTO) => {
|
||||
if (config.featureToggles.foldersAppPlatformAPI) {
|
||||
const result = await deleteFolder({ name: folder.uid });
|
||||
if (!result.error) {
|
||||
// We need to update a legacy version of the folder storage for now until all is in the new API.
|
||||
// we could do it in the enhanceEndpoint method but we would also need to change the args as we need parentUID
|
||||
// we could do this in the enhanceEndpoint method, but we would also need to change the args as we need parentUID
|
||||
// here and so it seemed easier to do it here.
|
||||
dispatchRefetchChildren(folder.parentUid);
|
||||
refresh({ childrenOf: folder.parentUid });
|
||||
// Before this was done in backend srv automatically because the old API sent a message wiht 200 request. see
|
||||
// public/app/core/services/backend_srv.ts#L341-L361. New API does not do that so we do it here.
|
||||
notify.success(t('folders.api.folder-deleted-success', 'Folder deleted'));
|
||||
|
@ -204,6 +195,7 @@ export function useDeleteMultipleFoldersMutationFacade() {
|
|||
const [deleteFolders] = useDeleteFoldersMutationLegacy();
|
||||
const [deleteFolder] = useDeleteFolderMutation();
|
||||
const dispatch = useDispatch();
|
||||
const refresh = useRefreshFolders();
|
||||
|
||||
if (!config.featureToggles.foldersAppPlatformAPI) {
|
||||
return deleteFolders;
|
||||
|
@ -231,7 +223,7 @@ export function useDeleteMultipleFoldersMutationFacade() {
|
|||
}
|
||||
}
|
||||
|
||||
dispatch(refreshParents(folderUIDs));
|
||||
refresh({ parentsOf: folderUIDs });
|
||||
return { data: undefined };
|
||||
};
|
||||
}
|
||||
|
@ -240,6 +232,7 @@ export function useMoveMultipleFoldersMutationFacade() {
|
|||
const moveFoldersLegacyResult = useMoveFoldersMutationLegacy();
|
||||
const [updateFolder, updateFolderData] = useUpdateFolderMutation();
|
||||
const dispatch = useDispatch();
|
||||
const refetch = useRefreshFolders();
|
||||
|
||||
if (!config.featureToggles.foldersAppPlatformAPI) {
|
||||
return moveFoldersLegacyResult;
|
||||
|
@ -271,16 +264,7 @@ export function useMoveMultipleFoldersMutationFacade() {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Refresh the state of the parent folders to update the UI after folders are moved
|
||||
dispatch(
|
||||
refetchChildren({
|
||||
parentUID: destinationUID,
|
||||
pageSize: PAGE_SIZE,
|
||||
})
|
||||
);
|
||||
dispatch(refreshParents(folderUIDs));
|
||||
|
||||
refetch({ childrenOf: destinationUID, parentsOf: folderUIDs });
|
||||
return { data: undefined };
|
||||
}
|
||||
|
||||
|
@ -290,6 +274,7 @@ export function useMoveMultipleFoldersMutationFacade() {
|
|||
export function useCreateFolder() {
|
||||
const [createFolder, result] = useCreateFolderMutation();
|
||||
const legacyHook = useLegacyNewFolderMutation();
|
||||
const refresh = useRefreshFolders();
|
||||
|
||||
if (!config.featureToggles.foldersAppPlatformAPI) {
|
||||
return legacyHook;
|
||||
|
@ -312,7 +297,7 @@ export function useCreateFolder() {
|
|||
};
|
||||
|
||||
const result = await createFolder(payload);
|
||||
dispatchRefetchChildren(folder.parentUid);
|
||||
refresh({ childrenOf: folder.parentUid });
|
||||
|
||||
return {
|
||||
...result,
|
||||
|
@ -326,6 +311,7 @@ export function useCreateFolder() {
|
|||
export function useUpdateFolder() {
|
||||
const [updateFolder, result] = useReplaceFolderMutation();
|
||||
const legacyHook = useLegacySaveFolderMutation();
|
||||
const refresh = useRefreshFolders();
|
||||
|
||||
if (!config.featureToggles.foldersAppPlatformAPI) {
|
||||
return legacyHook;
|
||||
|
@ -344,7 +330,7 @@ export function useUpdateFolder() {
|
|||
};
|
||||
|
||||
const result = await updateFolder(payload);
|
||||
dispatchRefetchChildren(folder.parentUid);
|
||||
refresh({ childrenOf: folder.parentUid });
|
||||
|
||||
return {
|
||||
...result,
|
||||
|
@ -355,6 +341,55 @@ export function useUpdateFolder() {
|
|||
return [updateFolderAppPlatform, result] as const;
|
||||
}
|
||||
|
||||
export function useMoveFolderMutationFacade() {
|
||||
const [updateFolder, updateFolderData] = useUpdateFolderMutation();
|
||||
const moveFolderResult = useMoveFolderMutationLegacy();
|
||||
const refresh = useRefreshFolders();
|
||||
const notify = useAppNotification();
|
||||
|
||||
if (!config.featureToggles.foldersAppPlatformAPI) {
|
||||
return moveFolderResult;
|
||||
}
|
||||
|
||||
async function moveFolder({ folderUID, destinationUID }: MoveFolderArgs) {
|
||||
const result = await updateFolder({
|
||||
name: folderUID,
|
||||
patch: { metadata: { annotations: { [AnnoKeyFolder]: destinationUID } } },
|
||||
});
|
||||
if (!result.error) {
|
||||
refresh({ parentsOf: [folderUID], childrenOf: destinationUID });
|
||||
// Before this was done in backend srv automatically because the old API sent a message with 200 request. see
|
||||
// public/app/core/services/backend_srv.ts#L341-L361. New API does not do that so we do it here.
|
||||
notify.success(t('folders.api.folder-moved-success', 'Folder moved'));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
return [moveFolder, updateFolderData] as const;
|
||||
}
|
||||
|
||||
/**
|
||||
* Refresh the state of the folders to update the UI after folders are updated. This refreshes legacy storage
|
||||
* of the folder structure outside the RTK query. Once all is migrated to new API this should not be needed.
|
||||
*/
|
||||
function useRefreshFolders() {
|
||||
const dispatch = useDispatch();
|
||||
|
||||
return (options: { parentsOf?: string[]; childrenOf?: string }) => {
|
||||
if (options.parentsOf) {
|
||||
dispatch(refreshParents(options.parentsOf));
|
||||
}
|
||||
if (options.childrenOf) {
|
||||
dispatch(
|
||||
refetchChildren({
|
||||
parentUID: options.childrenOf,
|
||||
pageSize: PAGE_SIZE,
|
||||
})
|
||||
);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
function combinedState(
|
||||
result: ReturnType<typeof useGetFolderQuery>,
|
||||
resultParents: ReturnType<typeof useGetFolderParentsQuery>,
|
||||
|
|
|
@ -44,6 +44,11 @@ export interface MoveFoldersArgs {
|
|||
folderUIDs: string[];
|
||||
}
|
||||
|
||||
export interface MoveFolderArgs {
|
||||
folderUID: string;
|
||||
destinationUID: string;
|
||||
}
|
||||
|
||||
export interface ImportInputs {
|
||||
name: string;
|
||||
type: string;
|
||||
|
@ -141,22 +146,16 @@ export const browseDashboardsAPI = createApi({
|
|||
}),
|
||||
|
||||
// move an *individual* folder. used in the folder actions menu.
|
||||
moveFolder: builder.mutation<void, { folder: FolderDTO; destinationUID: string }>({
|
||||
moveFolder: builder.mutation<void, MoveFolderArgs>({
|
||||
invalidatesTags: ['getFolder'],
|
||||
query: ({ folder, destinationUID }) => ({
|
||||
url: `/folders/${folder.uid}/move`,
|
||||
query: ({ folderUID, destinationUID }) => ({
|
||||
url: `/folders/${folderUID}/move`,
|
||||
method: 'POST',
|
||||
body: { parentUID: destinationUID },
|
||||
}),
|
||||
onQueryStarted: ({ folder, destinationUID }, { queryFulfilled, dispatch }) => {
|
||||
const { parentUid } = folder;
|
||||
onQueryStarted: ({ folderUID, destinationUID }, { queryFulfilled, dispatch }) => {
|
||||
queryFulfilled.then(() => {
|
||||
dispatch(
|
||||
refetchChildren({
|
||||
parentUID: parentUid,
|
||||
pageSize: PAGE_SIZE,
|
||||
})
|
||||
);
|
||||
dispatch(refreshParents([folderUID]));
|
||||
dispatch(
|
||||
refetchChildren({
|
||||
parentUID: destinationUID,
|
||||
|
|
|
@ -12,9 +12,8 @@ import { getReadOnlyTooltipText } from 'app/features/provisioning/utils/reposito
|
|||
import { ShowModalReactEvent } from 'app/types/events';
|
||||
import { FolderDTO } from 'app/types/folders';
|
||||
|
||||
import { useDeleteFolderMutationFacade } from '../../../api/clients/folder/v1beta1/hooks';
|
||||
import { useDeleteFolderMutationFacade, useMoveFolderMutationFacade } from '../../../api/clients/folder/v1beta1/hooks';
|
||||
import { ManagerKind } from '../../apiserver/types';
|
||||
import { useMoveFolderMutation } from '../api/browseDashboardsAPI';
|
||||
import { getFolderPermissions } from '../permissions';
|
||||
|
||||
import { DeleteModal } from './BrowseActions/DeleteModal';
|
||||
|
@ -30,7 +29,7 @@ export function FolderActionsButton({ folder, repoType, isReadOnlyRepo }: Props)
|
|||
const [isOpen, setIsOpen] = useState(false);
|
||||
const [showPermissionsDrawer, setShowPermissionsDrawer] = useState(false);
|
||||
const [showDeleteProvisionedFolderDrawer, setShowDeleteProvisionedFolderDrawer] = useState(false);
|
||||
const [moveFolder] = useMoveFolderMutation();
|
||||
const [moveFolder] = useMoveFolderMutationFacade();
|
||||
|
||||
const deleteFolder = useDeleteFolderMutationFacade();
|
||||
|
||||
|
@ -40,7 +39,7 @@ export function FolderActionsButton({ folder, repoType, isReadOnlyRepo }: Props)
|
|||
const canMoveFolder = canEditFolders && !isProvisionedFolder;
|
||||
|
||||
const onMove = async (destinationUID: string) => {
|
||||
await moveFolder({ folder, destinationUID });
|
||||
await moveFolder({ folderUID: folder.uid, destinationUID: destinationUID });
|
||||
reportInteraction('grafana_manage_dashboards_item_moved', {
|
||||
item_counts: {
|
||||
folder: 1,
|
||||
|
|
Loading…
Reference in New Issue