Nested folders: hook up getAffectedItems to the backend count route (#67677)

* hook up getAffectedItems to the backend count route

* mock out backendSrv in unit tests

* Don't delete alert rules while API doesn't return counts

* Show alert rule counts when API returns them

* use components for modal styles

* Revert "use components for modal styles"

This reverts commit 80ac1152f8.

---------

Co-authored-by: joshhunt <josh@trtr.co>
This commit is contained in:
Ashley Harrison
2023-05-02 21:20:30 +00:00
committed by GitHub
co-authored by joshhunt
parent 765735092a
commit 5d5a54979c
4 changed files with 49 additions and 46 deletions
@@ -3,7 +3,7 @@ import { lastValueFrom } from 'rxjs';
import { isTruthy } from '@grafana/data';
import { BackendSrvRequest, getBackendSrv } from '@grafana/runtime';
import { FolderDTO } from 'app/types';
import { DescendantCount, DescendantCountDTO, FolderDTO } from 'app/types';
import { DashboardTreeSelection } from '../types';
@@ -38,56 +38,33 @@ export const browseDashboardsAPI = createApi({
getFolder: builder.query<FolderDTO, string>({
query: (folderUID) => ({ url: `/folders/${folderUID}` }),
}),
getAffectedItems: builder.query<
// TODO move to folder types file once structure is finalised
{
folder: number;
dashboard: number;
libraryPanel: number;
alertRule: number;
},
DashboardTreeSelection
>({
getAffectedItems: builder.query<DescendantCount, DashboardTreeSelection>({
queryFn: async (selectedItems) => {
const folderUIDs = Object.keys(selectedItems.folder).filter((uid) => selectedItems.folder[uid]);
// Mock descendant count
// TODO convert to real implementation
const mockDescendantCount = {
folder: 1,
dashboard: 1,
libraryPanel: 1,
alertRule: 1,
};
const promises = folderUIDs.map((id) => {
return new Promise<typeof mockDescendantCount>((resolve, reject) => {
// Artificial delay to simulate network request
setTimeout(() => {
resolve(mockDescendantCount);
// reject(new Error('Uh oh!'));
}, 1000);
});
const promises = folderUIDs.map((folderUID) => {
return getBackendSrv().get<DescendantCountDTO>(`/api/folders/${folderUID}/counts`);
});
const results = await Promise.all(promises);
const aggregatedResults = results.reduce(
(acc, val) => ({
folder: acc.folder + val.folder,
dashboard: acc.dashboard + val.dashboard,
libraryPanel: acc.libraryPanel + val.libraryPanel,
alertRule: acc.alertRule + val.alertRule,
}),
{
folder: 0,
dashboard: 0,
libraryPanel: 0,
alertRule: 0,
}
);
// Add in the top level selected items
aggregatedResults.folder += Object.values(selectedItems.folder).filter(isTruthy).length;
aggregatedResults.dashboard += Object.values(selectedItems.dashboard).filter(isTruthy).length;
return { data: aggregatedResults };
const totalCounts = {
folder: Object.values(selectedItems.folder).filter(isTruthy).length,
dashboard: Object.values(selectedItems.dashboard).filter(isTruthy).length,
libraryPanel: 0,
alertRule: 0,
};
for (const folderCounts of results) {
totalCounts.folder += folderCounts.folder;
totalCounts.dashboard += folderCounts.dashboard;
totalCounts.alertRule += folderCounts.alertrule ?? 0;
// TODO enable these once the backend correctly returns them
// totalCounts.libraryPanel += folderCounts.libraryPanel;
}
return { data: totalCounts };
},
}),
}),
@@ -4,6 +4,8 @@ import React from 'react';
import { TestProvider } from 'test/helpers/TestProvider';
import { selectOptionInTest } from 'test/helpers/selectOptionInTest';
import { setBackendSrv } from '@grafana/runtime';
import { backendSrv } from 'app/core/services/__mocks__/backend_srv';
import * as api from 'app/features/manage-dashboards/state/actions';
import { DashboardSearchHit } from 'app/features/search/types';
@@ -22,6 +24,14 @@ describe('browse-dashboards MoveModal', () => {
];
let props: Props;
beforeAll(() => {
setBackendSrv(backendSrv);
jest.spyOn(backendSrv, 'get').mockResolvedValue({
dashboard: 0,
folder: 0,
});
});
beforeEach(() => {
props = {
isOpen: true,
@@ -19,7 +19,9 @@ export const deleteDashboard = createAsyncThunk('browseDashboards/deleteDashboar
export const deleteFolder = createAsyncThunk('browseDashboards/deleteFolder', async (folderUID: string) => {
return getBackendSrv().delete(`/api/folders/${folderUID}`, undefined, {
params: { forceDeleteRules: true },
// TODO: Once backend returns alert rule counts, set this back to true
// when this is merged https://github.com/grafana/grafana/pull/67259
params: { forceDeleteRules: false },
});
});
+14
View File
@@ -27,6 +27,20 @@ export interface FolderState {
canViewFolderPermissions: boolean;
}
export interface DescendantCountDTO {
folder: number;
dashboard: number;
libraryPanel: number;
alertrule?: number;
}
export interface DescendantCount {
folder: number;
dashboard: number;
libraryPanel: number;
alertRule: number;
}
export interface FolderInfo {
/**
* @deprecated use uid instead.