diff --git a/public/app/features/browse-dashboards/api/browseDashboardsAPI.ts b/public/app/features/browse-dashboards/api/browseDashboardsAPI.ts index 29e02e8f2c6..66b40ae8417 100644 --- a/public/app/features/browse-dashboards/api/browseDashboardsAPI.ts +++ b/public/app/features/browse-dashboards/api/browseDashboardsAPI.ts @@ -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({ 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({ 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((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(`/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 }; }, }), }), diff --git a/public/app/features/browse-dashboards/components/BrowseActions/MoveModal.test.tsx b/public/app/features/browse-dashboards/components/BrowseActions/MoveModal.test.tsx index 5ac7b077728..b5e34cdb623 100644 --- a/public/app/features/browse-dashboards/components/BrowseActions/MoveModal.test.tsx +++ b/public/app/features/browse-dashboards/components/BrowseActions/MoveModal.test.tsx @@ -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, diff --git a/public/app/features/browse-dashboards/state/actions.ts b/public/app/features/browse-dashboards/state/actions.ts index ed0ad9541a2..8ee42212b5d 100644 --- a/public/app/features/browse-dashboards/state/actions.ts +++ b/public/app/features/browse-dashboards/state/actions.ts @@ -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 }, }); }); diff --git a/public/app/types/folders.ts b/public/app/types/folders.ts index 9f5bc9628a0..96b372f8ff4 100644 --- a/public/app/types/folders.ts +++ b/public/app/types/folders.ts @@ -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.