Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
48 commits
Select commit Hold shift + click to select a range
4ea5a35
Add /children endpoint
aocenas Jun 18, 2025
fe84c8c
Update folder client
aocenas Jun 19, 2025
a9c2f4c
Add comment
aocenas Jun 19, 2025
d867638
Add feature toggle
aocenas Jun 20, 2025
187e977
Add new version of useFoldersQuery
aocenas Jun 20, 2025
db5b914
Merge branch 'main' into aocenas/folders/migrate-api
Clarity-89 Jun 26, 2025
c70aaff
Error handling
Clarity-89 Jun 26, 2025
8e8ad40
Format
Clarity-89 Jun 26, 2025
2a00788
Rename feature toggle
aocenas Jul 1, 2025
c7f3908
Remove options and move root folder constant
aocenas Jul 1, 2025
eed14cd
Merge remote-tracking branch 'origin/aocenas/folders/migrate-api' int…
aocenas Jul 1, 2025
34bc654
Fix feature toggle merge
aocenas Jul 1, 2025
48af59b
Merge branch 'main' into aocenas/folders/migrate-api
aocenas Jul 1, 2025
d1d959d
Add feature toggle again
aocenas Jul 1, 2025
421958b
Rename useFoldersQuery files
aocenas Jul 1, 2025
d529ed1
Update API spec
aocenas Jul 1, 2025
ea906e8
Fix test
aocenas Jul 1, 2025
634cd2a
Add test
aocenas Jul 2, 2025
b86b98d
Migrate delete folder button
aocenas Jul 3, 2025
845bbe6
useGetFolderQueryFacade
aocenas Jul 3, 2025
a873b99
Merge branch 'main' into aocenas/folders/migrate-api-2
aocenas Jul 3, 2025
e7b4f3e
Use getFolder facade hook
aocenas Jul 4, 2025
06f0baa
Recreate legacy getFolder from the APIs
aocenas Jul 9, 2025
802fa46
Merge branch 'main' into aocenas/folders/migrate-api-2
aocenas Jul 9, 2025
7b30613
Fix imports
aocenas Jul 9, 2025
bd65f06
Add comment
aocenas Jul 9, 2025
2f5b2c9
Merge branch 'main' into aocenas/folders/migrate-api-2
Clarity-89 Jul 10, 2025
c8423b4
Rename function
aocenas Jul 10, 2025
dc229e0
Simulate virtual folders in the API client
aocenas Jul 14, 2025
320f469
Translations
aocenas Jul 14, 2025
7c6dbdd
Merge branch 'main' into aocenas/folders/migrate-api-2
aocenas Jul 14, 2025
9ba694d
Update test
aocenas Jul 14, 2025
18b12c7
Move the hook out of the index file
aocenas Jul 15, 2025
8fdb275
Fix undefined in test
aocenas Jul 16, 2025
24e5b2b
Better status combining
aocenas Jul 16, 2025
152612b
Merge branch 'main' into aocenas/folders/migrate-api-2
aocenas Jul 17, 2025
c8b3dd7
Use real access api for virtual folders
aocenas Jul 18, 2025
641c091
Add basic test for the hook
aocenas Jul 18, 2025
d715ddb
Remove commented import
aocenas Jul 21, 2025
d1b2fb9
Merge branch 'main' into aocenas/folders/migrate-api-2
aocenas Jul 21, 2025
558db2e
Merge branch 'main' into aocenas/folders/migrate-api-2
aocenas Jul 30, 2025
d55b439
Remove the access control api and use legacy api for it
aocenas Jul 31, 2025
11d2773
Update tests
aocenas Aug 4, 2025
449a2a2
Moved delete folder into facade hook
aocenas Aug 5, 2025
cafd38a
Merge branch 'main' into aocenas/folders/migrate-api-2
aocenas Aug 5, 2025
8254392
Remove namespace attribute from virtual folders
aocenas Aug 5, 2025
573923e
go lint
aocenas Aug 6, 2025
51056c7
Merge branch 'main' into aocenas/folders/migrate-api-2
aocenas Aug 6, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Moved delete folder into facade hook
  • Loading branch information
aocenas committed Aug 5, 2025
commit 449a2a24ad414d7e4edc02c29e0988c71426407e
46 changes: 43 additions & 3 deletions public/app/api/clients/folder/v1beta1/hooks.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
import { QueryStatus, skipToken } from '@reduxjs/toolkit/query';

import { config } from '@grafana/runtime';
import { useGetFolderQuery as useGetFolderQueryLegacy } from 'app/features/browse-dashboards/api/browseDashboardsAPI';
import { AppEvents } from '@grafana/data';
import { t } from '@grafana/i18n';
import { config, getAppEvents } from '@grafana/runtime';
import {
useDeleteFolderMutation as useDeleteFolderMutationLegacy,
useGetFolderQuery as useGetFolderQueryLegacy,
} from 'app/features/browse-dashboards/api/browseDashboardsAPI';
import { FolderDTO } from 'app/types/folders';

import kbn from '../../../../core/utils/kbn';
Expand All @@ -14,12 +19,15 @@ import {
DeprecatedInternalId,
ManagerKind,
} from '../../../../features/apiserver/types';
import { PAGE_SIZE } from '../../../../features/browse-dashboards/api/services';
import { refetchChildren } from '../../../../features/browse-dashboards/state/actions';
import { GENERAL_FOLDER_UID } from '../../../../features/search/constants';
import { useDispatch } from '../../../../types/store';
import { useGetDisplayMappingQuery } from '../../iam/v0alpha1';

import { rootFolder, sharedWithMeFolder } from './virtualFolders';

import { useGetFolderQuery, useGetFolderParentsQuery } from './index';
import { useGetFolderQuery, useGetFolderParentsQuery, useDeleteFolderMutation } from './index';

function getFolderUrl(uid: string, title: string): string {
// mimics https://github.com/grafana/grafana/blob/79fe8a9902335c7a28af30e467b904a4ccfac503/pkg/services/dashboards/models.go#L188
Expand Down Expand Up @@ -150,6 +158,38 @@ export function useGetFolderQueryFacade(uid?: string) {
};
}

export function useDeleteFolderMutationFacade() {
const [deleteFolder] = useDeleteFolderMutation();
const [deleteFolderLegacy] = useDeleteFolderMutationLegacy();
const dispatch = useDispatch();

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
// here and so it seemed easier to do it here.
dispatch(
refetchChildren({
parentUID: folder.parentUid || GENERAL_FOLDER_UID,
pageSize: PAGE_SIZE,
})
);
// 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.
getAppEvents().publish({
type: AppEvents.alertSuccess.name,
payload: [t('folders.api.folder-deleted-success', 'Folder deleted')],
});
}
return result;
} else {
return deleteFolderLegacy(folder);
}
};
}

function combinedState(
result: ReturnType<typeof useGetFolderQuery>,
resultParents: ReturnType<typeof useGetFolderParentsQuery>,
Expand Down
24 changes: 2 additions & 22 deletions public/app/api/clients/folder/v1beta1/index.ts
Original file line number Diff line number Diff line change
@@ -1,28 +1,8 @@
import { PAGE_SIZE } from '../../../../features/browse-dashboards/api/services';
import { refetchChildren } from '../../../../features/browse-dashboards/state/actions';
import { GENERAL_FOLDER_UID } from '../../../../features/search/constants';

import { generatedAPI } from './endpoints.gen';

export const folderAPIv1beta1 = generatedAPI.enhanceEndpoints({
endpoints: {
deleteFolder: {
onQueryStarted: (args, { queryFulfilled, dispatch }) => {
// Refetch for anything using the old API.
queryFulfilled.then(() => {
dispatch(
refetchChildren({
parentUID: GENERAL_FOLDER_UID,
pageSize: PAGE_SIZE,
})
);
});
},
},
},
});
export const folderAPIv1beta1 = generatedAPI.enhanceEndpoints({});

export const { useGetFolderQuery, useGetFolderParentsQuery, useGetFolderAccessQuery } = folderAPIv1beta1;
export const { useGetFolderQuery, useGetFolderParentsQuery, useDeleteFolderMutation } = folderAPIv1beta1;

// eslint-disable-next-line no-barrel-files/no-barrel-files
export { type Folder, type FolderList } from './endpoints.gen';
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,14 @@ import { AppEvents } from '@grafana/data';
import { Trans, t } from '@grafana/i18n';
import { config, locationService, reportInteraction } from '@grafana/runtime';
import { Button, Drawer, Dropdown, Icon, Menu, MenuItem } from '@grafana/ui';
import { folderAPIv1beta1 } from 'app/api/clients/folder/v1beta1';
import { Permissions } from 'app/core/components/AccessControl';
import { appEvents } from 'app/core/core';
import { ShowModalReactEvent } from 'app/types/events';
import { FolderDTO } from 'app/types/folders';

import { useDeleteFolderMutationFacade } from '../../../api/clients/folder/v1beta1/hooks';
import { ManagerKind } from '../../apiserver/types';
import { useDeleteFolderMutation, useMoveFolderMutation } from '../api/browseDashboardsAPI';
import { useMoveFolderMutation } from '../api/browseDashboardsAPI';
import { getFolderPermissions } from '../permissions';

import { DeleteModal } from './BrowseActions/DeleteModal';
Expand All @@ -28,8 +28,7 @@ export function FolderActionsButton({ folder }: Props) {
const [showDeleteProvisionedFolderDrawer, setShowDeleteProvisionedFolderDrawer] = useState(false);
const [moveFolder] = useMoveFolderMutation();

const [deleteFolderAppPlatform] = folderAPIv1beta1.useDeleteFolderMutation();
const [deleteFolderLegacy] = useDeleteFolderMutation();
const deleteFolder = useDeleteFolderMutationFacade();

const { canEditFolders, canDeleteFolders, canViewPermissions, canSetPermissions } = getFolderPermissions(folder);
const isProvisionedFolder = folder.managedBy === ManagerKind.Repo;
Expand All @@ -48,9 +47,7 @@ export function FolderActionsButton({ folder }: Props) {
};

const onDelete = async () => {
const result = await (config.featureToggles.foldersAppPlatformAPI
? deleteFolderAppPlatform({ name: folder.uid })
: deleteFolderLegacy(folder));
const result = await deleteFolder(folder);

if (result.error) {
appEvents.publish({
Expand Down
3 changes: 3 additions & 0 deletions public/locales/en-US/grafana.json
Original file line number Diff line number Diff line change
Expand Up @@ -7434,6 +7434,9 @@
"badge-text": "Provisioned"
},
"folders": {
"api": {
"folder-deleted-success": "Folder deleted"
},
"get-loading-nav": {
"main": {
"title": {
Expand Down
Loading