mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Dashboard schema: strip null values from save model (#41385)
This commit is contained in:
parent
24ad769831
commit
0e419e9af1
28
public/app/core/utils/object.test.ts
Normal file
28
public/app/core/utils/object.test.ts
Normal file
@ -0,0 +1,28 @@
|
||||
import { sortedDeepCloneWithoutNulls } from './object';
|
||||
|
||||
describe('objects', () => {
|
||||
const value = {
|
||||
hello: null,
|
||||
world: {
|
||||
deeper: 10,
|
||||
foo: null,
|
||||
arr: [null, 1, 'hello'],
|
||||
},
|
||||
bar: undefined,
|
||||
simple: 'A',
|
||||
};
|
||||
|
||||
it('returns a clean copy', () => {
|
||||
const copy = sortedDeepCloneWithoutNulls(value);
|
||||
expect(copy).toMatchObject({
|
||||
world: {
|
||||
deeper: 10,
|
||||
arr: [null, 1, 'hello'],
|
||||
},
|
||||
simple: 'A',
|
||||
});
|
||||
expect(value.hello).toBeNull();
|
||||
expect(value.world.foo).toBeNull();
|
||||
expect(value.bar).toBeUndefined();
|
||||
});
|
||||
});
|
20
public/app/core/utils/object.ts
Normal file
20
public/app/core/utils/object.ts
Normal file
@ -0,0 +1,20 @@
|
||||
import { isArray, isPlainObject } from 'lodash';
|
||||
|
||||
/** @returns a deep clone of the object, but with any null value removed */
|
||||
export function sortedDeepCloneWithoutNulls<T>(value: T): T {
|
||||
if (isArray(value)) {
|
||||
return (value.map(sortedDeepCloneWithoutNulls) as unknown) as T;
|
||||
}
|
||||
if (isPlainObject(value)) {
|
||||
return Object.keys(value)
|
||||
.sort()
|
||||
.reduce((acc: any, key) => {
|
||||
const v = (value as any)[key];
|
||||
if (v != null) {
|
||||
acc[key] = sortedDeepCloneWithoutNulls(v);
|
||||
}
|
||||
return acc;
|
||||
}, {});
|
||||
}
|
||||
return value;
|
||||
}
|
@ -1,17 +0,0 @@
|
||||
import { isArray, isPlainObject, keys } from 'lodash';
|
||||
|
||||
export default function sortByKeys(input: any): any {
|
||||
if (isArray(input)) {
|
||||
return input.map(sortByKeys);
|
||||
}
|
||||
|
||||
if (isPlainObject(input)) {
|
||||
const sortedObject: any = {};
|
||||
for (const key of keys(input).sort()) {
|
||||
sortedObject[key] = sortByKeys(input[key]);
|
||||
}
|
||||
return sortedObject;
|
||||
}
|
||||
|
||||
return input;
|
||||
}
|
@ -56,11 +56,13 @@ describe('DashboardModel', () => {
|
||||
describe('getSaveModelClone', () => {
|
||||
it('should sort keys', () => {
|
||||
const model = new DashboardModel({});
|
||||
model.autoUpdate = null;
|
||||
|
||||
const saveModel = model.getSaveModelClone();
|
||||
const keys = _keys(saveModel);
|
||||
|
||||
expect(keys[0]).toBe('annotations');
|
||||
expect(keys[1]).toBe('autoUpdate');
|
||||
expect(keys[1]).toBe('editable');
|
||||
});
|
||||
|
||||
it('should remove add panel panels', () => {
|
||||
|
@ -18,7 +18,6 @@ import { DEFAULT_ANNOTATION_COLOR } from '@grafana/ui';
|
||||
import { GRID_CELL_HEIGHT, GRID_CELL_VMARGIN, GRID_COLUMN_COUNT, REPEAT_DIR_VERTICAL } from 'app/core/constants';
|
||||
// Utils & Services
|
||||
import { contextSrv } from 'app/core/services/context_srv';
|
||||
import sortByKeys from 'app/core/utils/sort_by_keys';
|
||||
// Types
|
||||
import { GridPos, PanelModel } from './PanelModel';
|
||||
import { DashboardMigrator } from './DashboardMigrator';
|
||||
@ -47,6 +46,7 @@ import { getTimeSrv } from '../services/TimeSrv';
|
||||
import { mergePanels, PanelMergeInfo } from '../utils/panelMerge';
|
||||
import { isOnTheSameGridRow } from './utils';
|
||||
import { RefreshEvent, TimeRangeUpdatedEvent } from '@grafana/runtime';
|
||||
import { sortedDeepCloneWithoutNulls } from 'app/core/utils/object';
|
||||
import { Subscription } from 'rxjs';
|
||||
import { appEvents } from '../../../core/core';
|
||||
import {
|
||||
@ -264,7 +264,7 @@ export class DashboardModel {
|
||||
copy.panels = this.getPanelSaveModels();
|
||||
|
||||
// sort by keys
|
||||
copy = sortByKeys(copy);
|
||||
copy = sortedDeepCloneWithoutNulls(copy);
|
||||
copy.getVariables = () => {
|
||||
return copy.templating.list;
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user