Dashboards: Fix moving to root folder (#111515)
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
import { GrafanaConfig, locationUtil } from '@grafana/data';
|
||||
import { backendSrv } from 'app/core/services/backend_srv';
|
||||
import { AnnoKeyFolder, AnnoReloadOnParamsChange } from 'app/features/apiserver/types';
|
||||
import { AnnoKeyFolder, AnnoKeyMessage, AnnoReloadOnParamsChange } from 'app/features/apiserver/types';
|
||||
import { DashboardDataDTO } from 'app/types/dashboard';
|
||||
|
||||
import { DashboardWithAccessInfo } from './types';
|
||||
@@ -316,6 +316,75 @@ describe('v1 dashboard API', () => {
|
||||
expect(result.url).toBe('/grafana/d/adh59cn/new-dashboard-saved');
|
||||
});
|
||||
});
|
||||
|
||||
it('should handle empty string folderUid for root folder', async () => {
|
||||
const api = new K8sDashboardAPI();
|
||||
const saveCommand = {
|
||||
dashboard: {
|
||||
uid: 'test-dash',
|
||||
title: 'Test Dashboard',
|
||||
tags: [],
|
||||
timezone: 'browser',
|
||||
panels: [],
|
||||
time: { from: 'now-6h', to: 'now' },
|
||||
timepicker: {},
|
||||
templating: { list: [] },
|
||||
annotations: { list: [] },
|
||||
refresh: '5s',
|
||||
schemaVersion: 16,
|
||||
version: 0,
|
||||
links: [],
|
||||
},
|
||||
folderUid: '',
|
||||
message: 'Move to root folder',
|
||||
};
|
||||
|
||||
await api.saveDashboard(saveCommand);
|
||||
|
||||
expect(mockPut).toHaveBeenCalledTimes(1);
|
||||
expect(mockPut).toHaveBeenCalledWith(
|
||||
'/apis/dashboard.grafana.app/v1beta1/namespaces/default/dashboards/test-dash',
|
||||
expect.objectContaining({
|
||||
metadata: expect.objectContaining({
|
||||
annotations: expect.objectContaining({
|
||||
[AnnoKeyFolder]: '',
|
||||
[AnnoKeyMessage]: 'Move to root folder',
|
||||
}),
|
||||
}),
|
||||
}),
|
||||
{ params: { fieldValidation: 'Ignore' } }
|
||||
);
|
||||
});
|
||||
|
||||
it('should not set folder annotation when folderUid is undefined', async () => {
|
||||
const api = new K8sDashboardAPI();
|
||||
const saveCommand = {
|
||||
dashboard: {
|
||||
uid: 'test-dash',
|
||||
title: 'Test Dashboard',
|
||||
tags: [],
|
||||
timezone: 'browser',
|
||||
panels: [],
|
||||
time: { from: 'now-6h', to: 'now' },
|
||||
timepicker: {},
|
||||
templating: { list: [] },
|
||||
annotations: { list: [] },
|
||||
refresh: '5s',
|
||||
schemaVersion: 16,
|
||||
version: 0,
|
||||
links: [],
|
||||
},
|
||||
message: 'Save without folder',
|
||||
};
|
||||
|
||||
await api.saveDashboard(saveCommand);
|
||||
|
||||
expect(mockPut).toHaveBeenCalledTimes(1);
|
||||
const callArgs = mockPut.mock.calls[0];
|
||||
const requestBody = callArgs[1];
|
||||
expect(requestBody.metadata.annotations).not.toHaveProperty(AnnoKeyFolder);
|
||||
expect(requestBody.metadata.annotations[AnnoKeyMessage]).toBe('Save without folder');
|
||||
});
|
||||
});
|
||||
|
||||
describe('version error handling', () => {
|
||||
|
||||
@@ -64,7 +64,7 @@ export class K8sDashboardAPI implements DashboardAPI<DashboardDTO, Dashboard> {
|
||||
delete obj.metadata.annotations[AnnoKeyMessage];
|
||||
}
|
||||
|
||||
if (options.folderUid) {
|
||||
if (options.folderUid !== undefined) {
|
||||
obj.metadata.annotations = {
|
||||
...obj.metadata.annotations,
|
||||
[AnnoKeyFolder]: options.folderUid,
|
||||
|
||||
@@ -252,6 +252,66 @@ describe('v2 dashboard API', () => {
|
||||
{ params: undefined }
|
||||
);
|
||||
});
|
||||
|
||||
it('should handle empty string folderUid for root folder', async () => {
|
||||
const api = new K8sDashboardV2API();
|
||||
const saveCommand = {
|
||||
dashboard: defaultDashboardV2Spec(),
|
||||
folderUid: '',
|
||||
message: 'Move to root folder',
|
||||
k8s: {
|
||||
name: 'existing-dash',
|
||||
annotations: {
|
||||
[AnnoKeyFolder]: 'some-previous-folder',
|
||||
[AnnoKeyFolderUrl]: 'some-folder-url',
|
||||
[AnnoKeyFolderTitle]: 'Some Folder Title',
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
await api.saveDashboard(saveCommand);
|
||||
|
||||
expect(mockPut).toHaveBeenCalledTimes(1);
|
||||
expect(mockPut).toHaveBeenCalledWith(
|
||||
'/apis/dashboard.grafana.app/v2beta1/namespaces/default/dashboards/existing-dash',
|
||||
{
|
||||
metadata: {
|
||||
name: 'existing-dash',
|
||||
annotations: {
|
||||
[AnnoKeyFolder]: '',
|
||||
[AnnoKeyMessage]: 'Move to root folder',
|
||||
[AnnoKeySavedFromUI]: '10.0.0',
|
||||
},
|
||||
},
|
||||
spec: defaultDashboardV2Spec(),
|
||||
},
|
||||
{ params: undefined }
|
||||
);
|
||||
|
||||
const callArgs = mockPut.mock.calls[0];
|
||||
const requestBody = callArgs[1];
|
||||
expect(requestBody.metadata.annotations).not.toHaveProperty(AnnoKeyFolderUrl);
|
||||
expect(requestBody.metadata.annotations).not.toHaveProperty(AnnoKeyFolderTitle);
|
||||
});
|
||||
|
||||
it('should not set folder annotation when folderUid is undefined', async () => {
|
||||
const api = new K8sDashboardV2API();
|
||||
const saveCommand = {
|
||||
dashboard: defaultDashboardV2Spec(),
|
||||
message: 'Save without folder',
|
||||
k8s: {
|
||||
name: 'existing-dash',
|
||||
},
|
||||
};
|
||||
|
||||
await api.saveDashboard(saveCommand);
|
||||
expect(mockPut).toHaveBeenCalledTimes(1);
|
||||
|
||||
const callArgs = mockPut.mock.calls[0];
|
||||
const requestBody = callArgs[1];
|
||||
expect(requestBody.metadata.annotations).not.toHaveProperty(AnnoKeyFolder);
|
||||
expect(requestBody.metadata.annotations[AnnoKeyMessage]).toBe('Save without folder');
|
||||
});
|
||||
});
|
||||
|
||||
describe('version error handling', () => {
|
||||
|
||||
@@ -130,7 +130,7 @@ export class K8sDashboardV2API
|
||||
}
|
||||
|
||||
// add folder annotation
|
||||
if (options.folderUid) {
|
||||
if (options.folderUid !== undefined) {
|
||||
// remove frontend folder annotations
|
||||
delete obj.metadata.annotations?.[AnnoKeyFolderTitle];
|
||||
delete obj.metadata.annotations?.[AnnoKeyFolderUrl];
|
||||
|
||||
Reference in New Issue
Block a user