mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
ManageDashboards: Fix error when deleting all dashboards from folder view (#46877)
* user essentials mob! 🔱
* draft tests
* tests!
* better default ids for test data
This commit is contained in:
parent
987afeee38
commit
89757cf58f
@ -2,7 +2,6 @@ import React, { FC } from 'react';
|
||||
import { css } from '@emotion/css';
|
||||
import { GrafanaTheme } from '@grafana/data';
|
||||
import { ConfirmModal, stylesFactory, useTheme } from '@grafana/ui';
|
||||
import { locationService } from '@grafana/runtime';
|
||||
import { DashboardSection, OnDeleteItems } from '../types';
|
||||
import { getCheckedUids } from '../utils';
|
||||
import { deleteFoldersAndDashboards } from 'app/features/manage-dashboards/state/actions';
|
||||
@ -40,8 +39,6 @@ export const ConfirmDeleteModal: FC<Props> = ({ results, onDeleteItems, isOpen,
|
||||
const deleteItems = () => {
|
||||
deleteFoldersAndDashboards(folders, dashboards).then(() => {
|
||||
onDismiss();
|
||||
// Redirect to /dashboard in case folder was deleted from f/:folder.uid
|
||||
locationService.push('/dashboards');
|
||||
onDeleteItems(folders, dashboards);
|
||||
});
|
||||
};
|
||||
|
@ -1,4 +1,31 @@
|
||||
import { DashboardSearchItemType, DashboardSection } from './types';
|
||||
import { DashboardSearchItemType, DashboardSection, DashboardSectionItem } from './types';
|
||||
|
||||
function makeSection(sectionPartial: Partial<DashboardSection>): DashboardSection {
|
||||
return {
|
||||
title: 'Default title',
|
||||
id: Number.MAX_SAFE_INTEGER - 1,
|
||||
score: -99,
|
||||
expanded: true,
|
||||
type: DashboardSearchItemType.DashFolder,
|
||||
items: [],
|
||||
url: '/default-url',
|
||||
...sectionPartial,
|
||||
};
|
||||
}
|
||||
|
||||
const makeSectionItem = (itemPartial: Partial<DashboardSectionItem>): DashboardSectionItem => {
|
||||
return {
|
||||
id: Number.MAX_SAFE_INTEGER - 2,
|
||||
uid: 'default-uid',
|
||||
title: 'Default dashboard title',
|
||||
type: DashboardSearchItemType.DashDB,
|
||||
isStarred: false,
|
||||
tags: [],
|
||||
uri: 'db/default-slug',
|
||||
url: '/d/default-uid/default-slug',
|
||||
...itemPartial,
|
||||
};
|
||||
};
|
||||
|
||||
export const generalFolder: DashboardSection = {
|
||||
id: 0,
|
||||
@ -52,61 +79,62 @@ export const searchResults: DashboardSection[] = [
|
||||
];
|
||||
|
||||
// Search results with more info
|
||||
export const sections = [
|
||||
{
|
||||
export const sections: DashboardSection[] = [
|
||||
makeSection({
|
||||
title: 'Starred',
|
||||
score: -2,
|
||||
expanded: true,
|
||||
items: [
|
||||
{
|
||||
makeSectionItem({
|
||||
id: 1,
|
||||
uid: 'lBdLINUWk',
|
||||
title: 'Prom dash',
|
||||
type: DashboardSearchItemType.DashDB,
|
||||
},
|
||||
}),
|
||||
],
|
||||
},
|
||||
{
|
||||
}),
|
||||
|
||||
makeSection({
|
||||
title: 'Recent',
|
||||
icon: 'clock-o',
|
||||
score: -1,
|
||||
removable: true,
|
||||
expanded: false,
|
||||
items: [
|
||||
{
|
||||
makeSectionItem({
|
||||
id: 4072,
|
||||
uid: 'OzAIf_rWz',
|
||||
title: 'New dashboard Copy 3',
|
||||
|
||||
type: DashboardSearchItemType.DashDB,
|
||||
isStarred: false,
|
||||
},
|
||||
{
|
||||
}),
|
||||
makeSectionItem({
|
||||
id: 46,
|
||||
uid: '8DY63kQZk',
|
||||
title: 'Stocks',
|
||||
type: DashboardSearchItemType.DashDB,
|
||||
isStarred: false,
|
||||
},
|
||||
{
|
||||
}),
|
||||
makeSectionItem({
|
||||
id: 20,
|
||||
uid: '7MeksYbmk',
|
||||
title: 'Alerting with TestData',
|
||||
type: DashboardSearchItemType.DashDB,
|
||||
isStarred: false,
|
||||
folderId: 2,
|
||||
},
|
||||
{
|
||||
}),
|
||||
makeSectionItem({
|
||||
id: 4073,
|
||||
uid: 'j9SHflrWk',
|
||||
title: 'New dashboard Copy 4',
|
||||
type: DashboardSearchItemType.DashDB,
|
||||
isStarred: false,
|
||||
folderId: 2,
|
||||
},
|
||||
}),
|
||||
],
|
||||
},
|
||||
{
|
||||
}),
|
||||
|
||||
makeSection({
|
||||
id: 2,
|
||||
uid: 'JB_zdOUWk',
|
||||
title: 'gdev dashboards',
|
||||
@ -115,8 +143,9 @@ export const sections = [
|
||||
icon: 'folder',
|
||||
score: 2,
|
||||
items: [],
|
||||
},
|
||||
{
|
||||
}),
|
||||
|
||||
makeSection({
|
||||
id: 2568,
|
||||
uid: 'search-test-data',
|
||||
title: 'Search test data folder',
|
||||
@ -125,8 +154,9 @@ export const sections = [
|
||||
url: '/dashboards/f/search-test-data/search-test-data-folder',
|
||||
icon: 'folder',
|
||||
score: 3,
|
||||
},
|
||||
{
|
||||
}),
|
||||
|
||||
makeSection({
|
||||
id: 4074,
|
||||
uid: 'iN5TFj9Zk',
|
||||
title: 'Test',
|
||||
@ -135,38 +165,197 @@ export const sections = [
|
||||
url: '/dashboards/f/iN5TFj9Zk/test',
|
||||
icon: 'folder',
|
||||
score: 4,
|
||||
},
|
||||
{
|
||||
}),
|
||||
|
||||
makeSection({
|
||||
id: 0,
|
||||
title: 'General',
|
||||
icon: 'folder-open',
|
||||
score: 5,
|
||||
expanded: true,
|
||||
items: [
|
||||
{
|
||||
makeSectionItem({
|
||||
id: 4069,
|
||||
uid: 'LCFWfl9Zz',
|
||||
title: 'New dashboard Copy',
|
||||
uri: 'db/new-dashboard-copy',
|
||||
url: '/d/LCFWfl9Zz/new-dashboard-copy',
|
||||
slug: '',
|
||||
type: DashboardSearchItemType.DashDB,
|
||||
isStarred: false,
|
||||
},
|
||||
{
|
||||
}),
|
||||
makeSectionItem({
|
||||
id: 4072,
|
||||
uid: 'OzAIf_rWz',
|
||||
title: 'New dashboard Copy 3',
|
||||
type: DashboardSearchItemType.DashDB,
|
||||
isStarred: false,
|
||||
},
|
||||
{
|
||||
}),
|
||||
makeSectionItem({
|
||||
id: 1,
|
||||
uid: 'lBdLINUWk',
|
||||
title: 'Prom dash',
|
||||
type: DashboardSearchItemType.DashDB,
|
||||
isStarred: true,
|
||||
},
|
||||
}),
|
||||
],
|
||||
},
|
||||
}),
|
||||
];
|
||||
|
||||
export const checkedGeneralFolder: DashboardSection[] = [
|
||||
makeSection({
|
||||
id: 4074,
|
||||
uid: 'other-folder-dash',
|
||||
title: 'Test',
|
||||
expanded: false,
|
||||
type: DashboardSearchItemType.DashFolder,
|
||||
items: [
|
||||
makeSectionItem({
|
||||
id: 4072,
|
||||
uid: 'other-folder-dash-abc',
|
||||
title: 'New dashboard Copy 3',
|
||||
type: DashboardSearchItemType.DashDB,
|
||||
isStarred: false,
|
||||
}),
|
||||
makeSectionItem({
|
||||
id: 46,
|
||||
uid: 'other-folder-dash-def',
|
||||
title: 'Stocks',
|
||||
type: DashboardSearchItemType.DashDB,
|
||||
isStarred: false,
|
||||
}),
|
||||
],
|
||||
url: '/dashboards/f/iN5TFj9Zk/test',
|
||||
icon: 'folder',
|
||||
score: 4,
|
||||
}),
|
||||
|
||||
makeSection({
|
||||
id: 0,
|
||||
title: 'General',
|
||||
uid: 'other-folder-abc',
|
||||
score: 5,
|
||||
expanded: true,
|
||||
checked: true,
|
||||
type: DashboardSearchItemType.DashFolder,
|
||||
items: [
|
||||
makeSectionItem({
|
||||
id: 4069,
|
||||
uid: 'general-abc',
|
||||
title: 'New dashboard Copy',
|
||||
uri: 'db/new-dashboard-copy',
|
||||
url: '/d/LCFWfl9Zz/new-dashboard-copy',
|
||||
type: DashboardSearchItemType.DashDB,
|
||||
isStarred: false,
|
||||
checked: true,
|
||||
}),
|
||||
makeSectionItem({
|
||||
id: 4072,
|
||||
uid: 'general-def',
|
||||
title: 'New dashboard Copy 3',
|
||||
type: DashboardSearchItemType.DashDB,
|
||||
isStarred: false,
|
||||
checked: true,
|
||||
}),
|
||||
makeSectionItem({
|
||||
id: 1,
|
||||
uid: 'general-ghi',
|
||||
title: 'Prom dash',
|
||||
type: DashboardSearchItemType.DashDB,
|
||||
isStarred: true,
|
||||
checked: true,
|
||||
}),
|
||||
],
|
||||
}),
|
||||
];
|
||||
|
||||
export const checkedOtherFolder: DashboardSection[] = [
|
||||
makeSection({
|
||||
id: 4074,
|
||||
uid: 'other-folder-abc',
|
||||
title: 'Test',
|
||||
expanded: false,
|
||||
checked: true,
|
||||
type: DashboardSearchItemType.DashFolder,
|
||||
items: [
|
||||
makeSectionItem({
|
||||
id: 4072,
|
||||
uid: 'other-folder-dash-abc',
|
||||
title: 'New dashboard Copy 3',
|
||||
type: DashboardSearchItemType.DashDB,
|
||||
isStarred: false,
|
||||
checked: true,
|
||||
}),
|
||||
makeSectionItem({
|
||||
id: 46,
|
||||
uid: 'other-folder-dash-def',
|
||||
title: 'Stocks',
|
||||
type: DashboardSearchItemType.DashDB,
|
||||
isStarred: false,
|
||||
checked: true,
|
||||
}),
|
||||
],
|
||||
url: '/dashboards/f/iN5TFj9Zk/test',
|
||||
icon: 'folder',
|
||||
score: 4,
|
||||
}),
|
||||
|
||||
makeSection({
|
||||
id: 0,
|
||||
title: 'General',
|
||||
icon: 'folder-open',
|
||||
score: 5,
|
||||
expanded: true,
|
||||
type: DashboardSearchItemType.DashFolder,
|
||||
items: [
|
||||
makeSectionItem({
|
||||
id: 4069,
|
||||
uid: 'general-abc',
|
||||
title: 'New dashboard Copy',
|
||||
uri: 'db/new-dashboard-copy',
|
||||
url: '/d/LCFWfl9Zz/new-dashboard-copy',
|
||||
type: DashboardSearchItemType.DashDB,
|
||||
isStarred: false,
|
||||
}),
|
||||
makeSectionItem({
|
||||
id: 4072,
|
||||
uid: 'general-def',
|
||||
title: 'New dashboard Copy 3',
|
||||
type: DashboardSearchItemType.DashDB,
|
||||
isStarred: false,
|
||||
}),
|
||||
makeSectionItem({
|
||||
id: 1,
|
||||
uid: 'general-ghi',
|
||||
title: 'Prom dash',
|
||||
type: DashboardSearchItemType.DashDB,
|
||||
isStarred: true,
|
||||
}),
|
||||
],
|
||||
}),
|
||||
];
|
||||
|
||||
export const folderViewAllChecked: DashboardSection[] = [
|
||||
makeSection({
|
||||
checked: true,
|
||||
selected: true,
|
||||
title: '',
|
||||
items: [
|
||||
makeSectionItem({
|
||||
id: 4072,
|
||||
uid: 'other-folder-dash-abc',
|
||||
title: 'New dashboard Copy 3',
|
||||
type: DashboardSearchItemType.DashDB,
|
||||
isStarred: false,
|
||||
checked: true,
|
||||
}),
|
||||
makeSectionItem({
|
||||
id: 46,
|
||||
uid: 'other-folder-dash-def',
|
||||
title: 'Stocks',
|
||||
type: DashboardSearchItemType.DashDB,
|
||||
isStarred: false,
|
||||
checked: true,
|
||||
}),
|
||||
],
|
||||
}),
|
||||
];
|
||||
|
@ -7,7 +7,7 @@ import {
|
||||
mergeReducers,
|
||||
parseRouteParams,
|
||||
} from './utils';
|
||||
import { sections, searchResults } from './testData';
|
||||
import { sections, searchResults, checkedGeneralFolder, checkedOtherFolder, folderViewAllChecked } from './testData';
|
||||
import { SearchQueryParams } from './types';
|
||||
|
||||
describe('Search utils', () => {
|
||||
@ -131,21 +131,35 @@ describe('Search utils', () => {
|
||||
});
|
||||
|
||||
describe('getCheckedUids', () => {
|
||||
it('should return object with empty arrays if no checked items are available', () => {
|
||||
expect(getCheckedUids(sections as any[])).toEqual({ folders: [], dashboards: [] });
|
||||
it('should not return any UIDs if no items are checked', () => {
|
||||
expect(getCheckedUids(sections)).toEqual({ folders: [], dashboards: [] });
|
||||
});
|
||||
|
||||
it('should return uids for all checked items', () => {
|
||||
expect(getCheckedUids(searchResults as any[])).toEqual({
|
||||
folders: ['JB_zdOUWk'],
|
||||
dashboards: ['lBdLINUWk', '8DY63kQZk'],
|
||||
it('should return only dashboard UIDs if the General folder is checked', () => {
|
||||
expect(getCheckedUids(checkedGeneralFolder)).toEqual({
|
||||
folders: [],
|
||||
dashboards: ['general-abc', 'general-def', 'general-ghi'],
|
||||
});
|
||||
});
|
||||
|
||||
it('should return only dashboard UIDs if all items are checked when viewing a folder', () => {
|
||||
expect(getCheckedUids(folderViewAllChecked)).toEqual({
|
||||
folders: [],
|
||||
dashboards: ['other-folder-dash-abc', 'other-folder-dash-def'],
|
||||
});
|
||||
});
|
||||
|
||||
it('should return folder + dashboard UIDs when folder is checked in the root view', () => {
|
||||
expect(getCheckedUids(checkedOtherFolder)).toEqual({
|
||||
folders: ['other-folder-abc'],
|
||||
dashboards: ['other-folder-dash-abc', 'other-folder-dash-def'],
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('getCheckedDashboardsUids', () => {
|
||||
it('should get uids of all checked dashboards', () => {
|
||||
expect(getCheckedDashboardsUids(searchResults as any[])).toEqual(['lBdLINUWk', '8DY63kQZk']);
|
||||
expect(getCheckedDashboardsUids(searchResults)).toEqual(['lBdLINUWk', '8DY63kQZk']);
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -165,7 +165,7 @@ export const getCheckedUids = (sections: DashboardSection[]): UidsToDelete => {
|
||||
}
|
||||
|
||||
return sections.reduce((result, section) => {
|
||||
if (section?.id !== 0 && section.checked) {
|
||||
if (section?.id !== 0 && section.checked && section.uid) {
|
||||
return { ...result, folders: [...result.folders, section.uid] } as UidsToDelete;
|
||||
} else {
|
||||
return { ...result, dashboards: getCheckedDashboardsUids(sections) } as UidsToDelete;
|
||||
|
Loading…
Reference in New Issue
Block a user