mirror of
https://github.com/grafana/grafana.git
synced 2025-02-14 09:33:34 -06:00
Add auto
to refresh picker (#85584)
This commit is contained in:
parent
040966220e
commit
9d44c8e8cf
@ -2511,10 +2511,6 @@ exports[`better eslint`] = {
|
|||||||
[0, 0, 0, "Unexpected any. Specify a different type.", "0"],
|
[0, 0, 0, "Unexpected any. Specify a different type.", "0"],
|
||||||
[0, 0, 0, "Unexpected any. Specify a different type.", "1"]
|
[0, 0, 0, "Unexpected any. Specify a different type.", "1"]
|
||||||
],
|
],
|
||||||
"public/app/features/dashboard-scene/saving/SaveDashboardForm.tsx:5381": [
|
|
||||||
[0, 0, 0, "Use data-testid for E2E selectors instead of aria-label", "0"],
|
|
||||||
[0, 0, 0, "Use data-testid for E2E selectors instead of aria-label", "1"]
|
|
||||||
],
|
|
||||||
"public/app/features/dashboard-scene/saving/getDashboardChanges.ts:5381": [
|
"public/app/features/dashboard-scene/saving/getDashboardChanges.ts:5381": [
|
||||||
[0, 0, 0, "Do not use any type assertions.", "0"],
|
[0, 0, 0, "Do not use any type assertions.", "0"],
|
||||||
[0, 0, 0, "Do not use any type assertions.", "1"]
|
[0, 0, 0, "Do not use any type assertions.", "1"]
|
||||||
@ -2523,9 +2519,6 @@ exports[`better eslint`] = {
|
|||||||
[0, 0, 0, "Do not use any type assertions.", "0"],
|
[0, 0, 0, "Do not use any type assertions.", "0"],
|
||||||
[0, 0, 0, "Do not use any type assertions.", "1"]
|
[0, 0, 0, "Do not use any type assertions.", "1"]
|
||||||
],
|
],
|
||||||
"public/app/features/dashboard-scene/saving/shared.tsx:5381": [
|
|
||||||
[0, 0, 0, "Use data-testid for E2E selectors instead of aria-label", "0"]
|
|
||||||
],
|
|
||||||
"public/app/features/dashboard-scene/scene/PanelMenuBehavior.tsx:5381": [
|
"public/app/features/dashboard-scene/scene/PanelMenuBehavior.tsx:5381": [
|
||||||
[0, 0, 0, "Unexpected any. Specify a different type.", "0"],
|
[0, 0, 0, "Unexpected any. Specify a different type.", "0"],
|
||||||
[0, 0, 0, "Unexpected any. Specify a different type.", "1"],
|
[0, 0, 0, "Unexpected any. Specify a different type.", "1"],
|
||||||
|
@ -255,7 +255,7 @@
|
|||||||
"@grafana/prometheus": "workspace:*",
|
"@grafana/prometheus": "workspace:*",
|
||||||
"@grafana/runtime": "workspace:*",
|
"@grafana/runtime": "workspace:*",
|
||||||
"@grafana/saga-icons": "workspace:*",
|
"@grafana/saga-icons": "workspace:*",
|
||||||
"@grafana/scenes": "^4.2.1",
|
"@grafana/scenes": "^4.5.3",
|
||||||
"@grafana/schema": "workspace:*",
|
"@grafana/schema": "workspace:*",
|
||||||
"@grafana/sql": "workspace:*",
|
"@grafana/sql": "workspace:*",
|
||||||
"@grafana/ui": "workspace:*",
|
"@grafana/ui": "workspace:*",
|
||||||
|
@ -226,6 +226,7 @@ export const Pages = {
|
|||||||
save: 'Dashboard settings Save Dashboard Modal Save button',
|
save: 'Dashboard settings Save Dashboard Modal Save button',
|
||||||
saveVariables: 'Dashboard settings Save Dashboard Modal Save variables checkbox',
|
saveVariables: 'Dashboard settings Save Dashboard Modal Save variables checkbox',
|
||||||
saveTimerange: 'Dashboard settings Save Dashboard Modal Save timerange checkbox',
|
saveTimerange: 'Dashboard settings Save Dashboard Modal Save timerange checkbox',
|
||||||
|
saveRefresh: 'Dashboard settings Save Dashboard Modal Save refresh checkbox',
|
||||||
},
|
},
|
||||||
SharePanelModal: {
|
SharePanelModal: {
|
||||||
linkToRenderedImage: 'Link to rendered image',
|
linkToRenderedImage: 'Link to rendered image',
|
||||||
|
@ -31,7 +31,10 @@ export class DashboardSceneChangeTracker {
|
|||||||
|
|
||||||
private onStateChanged({ payload }: SceneObjectStateChangedEvent) {
|
private onStateChanged({ payload }: SceneObjectStateChangedEvent) {
|
||||||
if (payload.changedObject instanceof SceneRefreshPicker) {
|
if (payload.changedObject instanceof SceneRefreshPicker) {
|
||||||
if (Object.prototype.hasOwnProperty.call(payload.partialUpdate, 'intervals')) {
|
if (
|
||||||
|
Object.prototype.hasOwnProperty.call(payload.partialUpdate, 'intervals') ||
|
||||||
|
Object.prototype.hasOwnProperty.call(payload.partialUpdate, 'refresh')
|
||||||
|
) {
|
||||||
this.detectChanges();
|
this.detectChanges();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,6 +5,6 @@ import debounce from 'lodash/debounce';
|
|||||||
import { getDashboardChanges } from './getDashboardChanges';
|
import { getDashboardChanges } from './getDashboardChanges';
|
||||||
|
|
||||||
self.onmessage = debounce((e: MessageEvent<{ initial: any; changed: any }>) => {
|
self.onmessage = debounce((e: MessageEvent<{ initial: any; changed: any }>) => {
|
||||||
const result = getDashboardChanges(e.data.initial, e.data.changed, false, false);
|
const result = getDashboardChanges(e.data.initial, e.data.changed, false, false, false);
|
||||||
self.postMessage(result);
|
self.postMessage(result);
|
||||||
}, 500);
|
}, 500);
|
||||||
|
@ -4,7 +4,7 @@ import React from 'react';
|
|||||||
import { TestProvider } from 'test/helpers/TestProvider';
|
import { TestProvider } from 'test/helpers/TestProvider';
|
||||||
|
|
||||||
import { selectors } from '@grafana/e2e-selectors';
|
import { selectors } from '@grafana/e2e-selectors';
|
||||||
import { sceneGraph } from '@grafana/scenes';
|
import { sceneGraph, SceneRefreshPicker } from '@grafana/scenes';
|
||||||
import { SaveDashboardResponseDTO } from 'app/types';
|
import { SaveDashboardResponseDTO } from 'app/types';
|
||||||
|
|
||||||
import { transformSaveModelToScene } from '../serialization/transformSaveModelToScene';
|
import { transformSaveModelToScene } from '../serialization/transformSaveModelToScene';
|
||||||
@ -31,7 +31,7 @@ describe('SaveDashboardDrawer', () => {
|
|||||||
setup().openAndRender();
|
setup().openAndRender();
|
||||||
|
|
||||||
expect(await screen.findByText('Save dashboard')).toBeInTheDocument();
|
expect(await screen.findByText('Save dashboard')).toBeInTheDocument();
|
||||||
expect(screen.queryByLabelText(selectors.pages.SaveDashboardModal.saveTimerange)).not.toBeInTheDocument();
|
expect(screen.queryByTestId(selectors.pages.SaveDashboardModal.saveTimerange)).not.toBeInTheDocument();
|
||||||
expect(screen.getByText('No changes to save')).toBeInTheDocument();
|
expect(screen.getByText('No changes to save')).toBeInTheDocument();
|
||||||
expect(screen.queryByLabelText('Tab Changes')).not.toBeInTheDocument();
|
expect(screen.queryByLabelText('Tab Changes')).not.toBeInTheDocument();
|
||||||
});
|
});
|
||||||
@ -49,7 +49,7 @@ describe('SaveDashboardDrawer', () => {
|
|||||||
openAndRender();
|
openAndRender();
|
||||||
|
|
||||||
expect(await screen.findByText('Save dashboard')).toBeInTheDocument();
|
expect(await screen.findByText('Save dashboard')).toBeInTheDocument();
|
||||||
expect(screen.queryByLabelText(selectors.pages.SaveDashboardModal.saveTimerange)).toBeInTheDocument();
|
expect(screen.queryByTestId(selectors.pages.SaveDashboardModal.saveTimerange)).toBeInTheDocument();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Should update diff when including time range is', async () => {
|
it('Should update diff when including time range is', async () => {
|
||||||
@ -60,10 +60,43 @@ describe('SaveDashboardDrawer', () => {
|
|||||||
openAndRender();
|
openAndRender();
|
||||||
|
|
||||||
expect(await screen.findByText('Save dashboard')).toBeInTheDocument();
|
expect(await screen.findByText('Save dashboard')).toBeInTheDocument();
|
||||||
expect(screen.queryByLabelText(selectors.pages.SaveDashboardModal.saveTimerange)).toBeInTheDocument();
|
expect(screen.queryByTestId(selectors.pages.SaveDashboardModal.saveTimerange)).toBeInTheDocument();
|
||||||
expect(screen.queryByLabelText('Tab Changes')).not.toBeInTheDocument();
|
expect(screen.queryByLabelText('Tab Changes')).not.toBeInTheDocument();
|
||||||
|
|
||||||
await userEvent.click(screen.getByLabelText(selectors.pages.SaveDashboardModal.saveTimerange));
|
await userEvent.click(screen.getByTestId(selectors.pages.SaveDashboardModal.saveTimerange));
|
||||||
|
|
||||||
|
expect(await screen.findByLabelText('Tab Changes')).toBeInTheDocument();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('When refresh changed show save refresh option', async () => {
|
||||||
|
const { dashboard, openAndRender } = setup();
|
||||||
|
|
||||||
|
const refreshPicker = sceneGraph.findObject(dashboard, (obj) => obj instanceof SceneRefreshPicker);
|
||||||
|
if (refreshPicker instanceof SceneRefreshPicker) {
|
||||||
|
refreshPicker.setState({ refresh: '5s' });
|
||||||
|
}
|
||||||
|
|
||||||
|
openAndRender();
|
||||||
|
|
||||||
|
expect(await screen.findByText('Save dashboard')).toBeInTheDocument();
|
||||||
|
expect(screen.queryByTestId(selectors.pages.SaveDashboardModal.saveRefresh)).toBeInTheDocument();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Should update diff when including time range is', async () => {
|
||||||
|
const { dashboard, openAndRender } = setup();
|
||||||
|
|
||||||
|
const refreshPicker = sceneGraph.findObject(dashboard, (obj) => obj instanceof SceneRefreshPicker);
|
||||||
|
if (refreshPicker instanceof SceneRefreshPicker) {
|
||||||
|
refreshPicker.setState({ refresh: '5s' });
|
||||||
|
}
|
||||||
|
|
||||||
|
openAndRender();
|
||||||
|
|
||||||
|
expect(await screen.findByText('Save dashboard')).toBeInTheDocument();
|
||||||
|
expect(screen.getByTestId(selectors.pages.SaveDashboardModal.saveRefresh)).toBeInTheDocument();
|
||||||
|
expect(screen.queryByLabelText('Tab Changes')).not.toBeInTheDocument();
|
||||||
|
|
||||||
|
await userEvent.click(screen.getByTestId(selectors.pages.SaveDashboardModal.saveRefresh));
|
||||||
|
|
||||||
expect(await screen.findByLabelText('Tab Changes')).toBeInTheDocument();
|
expect(await screen.findByLabelText('Tab Changes')).toBeInTheDocument();
|
||||||
});
|
});
|
||||||
@ -89,7 +122,7 @@ describe('SaveDashboardDrawer', () => {
|
|||||||
|
|
||||||
mockSaveDashboard();
|
mockSaveDashboard();
|
||||||
|
|
||||||
await userEvent.click(await screen.findByLabelText(selectors.pages.SaveDashboardModal.save));
|
await userEvent.click(await screen.findByTestId(selectors.pages.SaveDashboardModal.save));
|
||||||
|
|
||||||
const dataSent = saveDashboardMutationMock.mock.calls[0][0];
|
const dataSent = saveDashboardMutationMock.mock.calls[0][0];
|
||||||
expect(dataSent.dashboard.title).toEqual('New title');
|
expect(dataSent.dashboard.title).toEqual('New title');
|
||||||
@ -107,13 +140,13 @@ describe('SaveDashboardDrawer', () => {
|
|||||||
|
|
||||||
mockSaveDashboard({ saveError: 'version-mismatch' });
|
mockSaveDashboard({ saveError: 'version-mismatch' });
|
||||||
|
|
||||||
await userEvent.click(await screen.findByLabelText(selectors.pages.SaveDashboardModal.save));
|
await userEvent.click(await screen.findByTestId(selectors.pages.SaveDashboardModal.save));
|
||||||
|
|
||||||
expect(await screen.findByText('Someone else has updated this dashboard')).toBeInTheDocument();
|
expect(await screen.findByText('Someone else has updated this dashboard')).toBeInTheDocument();
|
||||||
expect(await screen.findByText('Save and overwrite')).toBeInTheDocument();
|
expect(await screen.findByText('Save and overwrite')).toBeInTheDocument();
|
||||||
|
|
||||||
// Now save and overwrite
|
// Now save and overwrite
|
||||||
await userEvent.click(await screen.findByLabelText(selectors.pages.SaveDashboardModal.save));
|
await userEvent.click(await screen.findByTestId(selectors.pages.SaveDashboardModal.save));
|
||||||
|
|
||||||
const dataSent = saveDashboardMutationMock.mock.calls[1][0];
|
const dataSent = saveDashboardMutationMock.mock.calls[1][0];
|
||||||
expect(dataSent.overwrite).toEqual(true);
|
expect(dataSent.overwrite).toEqual(true);
|
||||||
@ -129,7 +162,7 @@ describe('SaveDashboardDrawer', () => {
|
|||||||
|
|
||||||
mockSaveDashboard();
|
mockSaveDashboard();
|
||||||
|
|
||||||
await userEvent.click(await screen.findByLabelText(selectors.pages.SaveDashboardModal.save));
|
await userEvent.click(await screen.findByTestId(selectors.pages.SaveDashboardModal.save));
|
||||||
|
|
||||||
const dataSent = saveDashboardMutationMock.mock.calls[0][0];
|
const dataSent = saveDashboardMutationMock.mock.calls[0][0];
|
||||||
expect(dataSent.dashboard.uid).toEqual('');
|
expect(dataSent.dashboard.uid).toEqual('');
|
||||||
|
@ -16,6 +16,7 @@ interface SaveDashboardDrawerState extends SceneObjectState {
|
|||||||
showDiff?: boolean;
|
showDiff?: boolean;
|
||||||
saveTimeRange?: boolean;
|
saveTimeRange?: boolean;
|
||||||
saveVariables?: boolean;
|
saveVariables?: boolean;
|
||||||
|
saveRefresh?: boolean;
|
||||||
saveAsCopy?: boolean;
|
saveAsCopy?: boolean;
|
||||||
onSaveSuccess?: () => void;
|
onSaveSuccess?: () => void;
|
||||||
}
|
}
|
||||||
@ -33,9 +34,18 @@ export class SaveDashboardDrawer extends SceneObjectBase<SaveDashboardDrawerStat
|
|||||||
this.setState({ saveVariables: !this.state.saveVariables });
|
this.setState({ saveVariables: !this.state.saveVariables });
|
||||||
};
|
};
|
||||||
|
|
||||||
|
public onToggleSaveRefresh = () => {
|
||||||
|
this.setState({ saveRefresh: !this.state.saveRefresh });
|
||||||
|
};
|
||||||
|
|
||||||
static Component = ({ model }: SceneComponentProps<SaveDashboardDrawer>) => {
|
static Component = ({ model }: SceneComponentProps<SaveDashboardDrawer>) => {
|
||||||
const { showDiff, saveAsCopy, saveTimeRange, saveVariables } = model.useState();
|
const { showDiff, saveAsCopy, saveTimeRange, saveVariables, saveRefresh } = model.useState();
|
||||||
const changeInfo = getDashboardChangesFromScene(model.state.dashboardRef.resolve(), saveTimeRange, saveVariables);
|
const changeInfo = getDashboardChangesFromScene(
|
||||||
|
model.state.dashboardRef.resolve(),
|
||||||
|
saveTimeRange,
|
||||||
|
saveVariables,
|
||||||
|
saveRefresh
|
||||||
|
);
|
||||||
const { changedSaveModel, initialSaveModel, diffs, diffCount } = changeInfo;
|
const { changedSaveModel, initialSaveModel, diffs, diffCount } = changeInfo;
|
||||||
const dashboard = model.state.dashboardRef.resolve();
|
const dashboard = model.state.dashboardRef.resolve();
|
||||||
const isProvisioned = dashboard.state.meta.provisioned;
|
const isProvisioned = dashboard.state.meta.provisioned;
|
||||||
|
@ -130,8 +130,8 @@ export interface SaveDashboardFormCommonOptionsProps {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function SaveDashboardFormCommonOptions({ drawer, changeInfo }: SaveDashboardFormCommonOptionsProps) {
|
export function SaveDashboardFormCommonOptions({ drawer, changeInfo }: SaveDashboardFormCommonOptionsProps) {
|
||||||
const { saveVariables = false, saveTimeRange = false } = drawer.useState();
|
const { saveVariables = false, saveTimeRange = false, saveRefresh = false } = drawer.useState();
|
||||||
const { hasTimeChanges, hasVariableValueChanges } = changeInfo;
|
const { hasTimeChanges, hasVariableValueChanges, hasRefreshChange } = changeInfo;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
@ -141,7 +141,17 @@ export function SaveDashboardFormCommonOptions({ drawer, changeInfo }: SaveDashb
|
|||||||
id="save-timerange"
|
id="save-timerange"
|
||||||
checked={saveTimeRange}
|
checked={saveTimeRange}
|
||||||
onChange={drawer.onToggleSaveTimeRange}
|
onChange={drawer.onToggleSaveTimeRange}
|
||||||
aria-label={selectors.pages.SaveDashboardModal.saveTimerange}
|
data-testid={selectors.pages.SaveDashboardModal.saveTimerange}
|
||||||
|
/>
|
||||||
|
</Field>
|
||||||
|
)}
|
||||||
|
{hasRefreshChange && (
|
||||||
|
<Field label="Update default refresh value" description="Will make the current refresh the new default">
|
||||||
|
<Checkbox
|
||||||
|
id="save-refresh"
|
||||||
|
checked={saveRefresh}
|
||||||
|
onChange={drawer.onToggleSaveRefresh}
|
||||||
|
data-testid={selectors.pages.SaveDashboardModal.saveRefresh}
|
||||||
/>
|
/>
|
||||||
</Field>
|
</Field>
|
||||||
)}
|
)}
|
||||||
@ -151,7 +161,7 @@ export function SaveDashboardFormCommonOptions({ drawer, changeInfo }: SaveDashb
|
|||||||
id="save-variables"
|
id="save-variables"
|
||||||
checked={saveVariables}
|
checked={saveVariables}
|
||||||
onChange={drawer.onToggleSaveVariables}
|
onChange={drawer.onToggleSaveVariables}
|
||||||
aria-label={selectors.pages.SaveDashboardModal.saveVariables}
|
data-testid={selectors.pages.SaveDashboardModal.saveVariables}
|
||||||
/>
|
/>
|
||||||
</Field>
|
</Field>
|
||||||
)}
|
)}
|
||||||
|
@ -10,17 +10,23 @@ export function getDashboardChanges(
|
|||||||
initial: Dashboard,
|
initial: Dashboard,
|
||||||
changed: Dashboard,
|
changed: Dashboard,
|
||||||
saveTimeRange?: boolean,
|
saveTimeRange?: boolean,
|
||||||
saveVariables?: boolean
|
saveVariables?: boolean,
|
||||||
|
saveRefresh?: boolean
|
||||||
) {
|
) {
|
||||||
const initialSaveModel = initial;
|
const initialSaveModel = initial;
|
||||||
const changedSaveModel = changed;
|
const changedSaveModel = changed;
|
||||||
const hasTimeChanged = getHasTimeChanged(changedSaveModel, initialSaveModel);
|
const hasTimeChanged = getHasTimeChanged(changedSaveModel, initialSaveModel);
|
||||||
const hasVariableValueChanges = applyVariableChanges(changedSaveModel, initialSaveModel, saveVariables);
|
const hasVariableValueChanges = applyVariableChanges(changedSaveModel, initialSaveModel, saveVariables);
|
||||||
|
const hasRefreshChanged = changedSaveModel.refresh !== initialSaveModel.refresh;
|
||||||
|
|
||||||
if (!saveTimeRange) {
|
if (!saveTimeRange) {
|
||||||
changedSaveModel.time = initialSaveModel.time;
|
changedSaveModel.time = initialSaveModel.time;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!saveRefresh) {
|
||||||
|
changedSaveModel.refresh = initialSaveModel.refresh;
|
||||||
|
}
|
||||||
|
|
||||||
const diff = jsonDiff(initialSaveModel, changedSaveModel);
|
const diff = jsonDiff(initialSaveModel, changedSaveModel);
|
||||||
|
|
||||||
let diffCount = 0;
|
let diffCount = 0;
|
||||||
@ -36,6 +42,7 @@ export function getDashboardChanges(
|
|||||||
hasTimeChanges: hasTimeChanged,
|
hasTimeChanges: hasTimeChanged,
|
||||||
isNew: changedSaveModel.version === 0,
|
isNew: changedSaveModel.version === 0,
|
||||||
hasVariableValueChanges,
|
hasVariableValueChanges,
|
||||||
|
hasRefreshChange: hasRefreshChanged,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,5 +1,11 @@
|
|||||||
import { config } from '@grafana/runtime';
|
import { config } from '@grafana/runtime';
|
||||||
import { AdHocFiltersVariable, GroupByVariable, MultiValueVariable, sceneGraph } from '@grafana/scenes';
|
import {
|
||||||
|
AdHocFiltersVariable,
|
||||||
|
GroupByVariable,
|
||||||
|
MultiValueVariable,
|
||||||
|
sceneGraph,
|
||||||
|
SceneRefreshPicker,
|
||||||
|
} from '@grafana/scenes';
|
||||||
import { VariableModel } from '@grafana/schema';
|
import { VariableModel } from '@grafana/schema';
|
||||||
|
|
||||||
import { buildPanelEditScene } from '../panel-edit/PanelEditor';
|
import { buildPanelEditScene } from '../panel-edit/PanelEditor';
|
||||||
@ -38,6 +44,33 @@ describe('getDashboardChangesFromScene', () => {
|
|||||||
expect(result.diffCount).toBe(1);
|
expect(result.diffCount).toBe(1);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('Can detect refresh changed', () => {
|
||||||
|
const dashboard = setup();
|
||||||
|
|
||||||
|
const refreshPicker = sceneGraph.findObject(dashboard, (obj) => obj instanceof SceneRefreshPicker);
|
||||||
|
if (refreshPicker instanceof SceneRefreshPicker) {
|
||||||
|
refreshPicker.setState({ refresh: '5s' });
|
||||||
|
}
|
||||||
|
|
||||||
|
const result = getDashboardChangesFromScene(dashboard, false, false, false);
|
||||||
|
expect(result.hasChanges).toBe(false);
|
||||||
|
expect(result.diffCount).toBe(0);
|
||||||
|
expect(result.hasRefreshChange).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Can save refresh change', () => {
|
||||||
|
const dashboard = setup();
|
||||||
|
|
||||||
|
const refreshPicker = sceneGraph.findObject(dashboard, (obj) => obj instanceof SceneRefreshPicker);
|
||||||
|
if (refreshPicker instanceof SceneRefreshPicker) {
|
||||||
|
refreshPicker.setState({ refresh: '5s' });
|
||||||
|
}
|
||||||
|
|
||||||
|
const result = getDashboardChangesFromScene(dashboard, false, false, true);
|
||||||
|
expect(result.hasChanges).toBe(true);
|
||||||
|
expect(result.diffCount).toBe(1);
|
||||||
|
});
|
||||||
|
|
||||||
describe('variable changes', () => {
|
describe('variable changes', () => {
|
||||||
it('Can detect variable change', () => {
|
it('Can detect variable change', () => {
|
||||||
const dashboard = setup();
|
const dashboard = setup();
|
||||||
|
@ -3,12 +3,18 @@ import { transformSceneToSaveModel } from '../serialization/transformSceneToSave
|
|||||||
|
|
||||||
import { getDashboardChanges } from './getDashboardChanges';
|
import { getDashboardChanges } from './getDashboardChanges';
|
||||||
|
|
||||||
export function getDashboardChangesFromScene(scene: DashboardScene, saveTimeRange?: boolean, saveVariables?: boolean) {
|
export function getDashboardChangesFromScene(
|
||||||
|
scene: DashboardScene,
|
||||||
|
saveTimeRange?: boolean,
|
||||||
|
saveVariables?: boolean,
|
||||||
|
saveRefresh?: boolean
|
||||||
|
) {
|
||||||
const changeInfo = getDashboardChanges(
|
const changeInfo = getDashboardChanges(
|
||||||
scene.getInitialSaveModel()!,
|
scene.getInitialSaveModel()!,
|
||||||
transformSceneToSaveModel(scene),
|
transformSceneToSaveModel(scene),
|
||||||
saveTimeRange,
|
saveTimeRange,
|
||||||
saveVariables
|
saveVariables,
|
||||||
|
saveRefresh
|
||||||
);
|
);
|
||||||
return changeInfo;
|
return changeInfo;
|
||||||
}
|
}
|
||||||
|
@ -12,7 +12,8 @@ import { DashboardChangeInfo } from './shared';
|
|||||||
export function getSaveDashboardChange(
|
export function getSaveDashboardChange(
|
||||||
dashboard: DashboardScene,
|
dashboard: DashboardScene,
|
||||||
saveTimeRange?: boolean,
|
saveTimeRange?: boolean,
|
||||||
saveVariables?: boolean
|
saveVariables?: boolean,
|
||||||
|
saveRefresh?: boolean
|
||||||
): DashboardChangeInfo {
|
): DashboardChangeInfo {
|
||||||
const initialSaveModel = dashboard.getInitialSaveModel()!;
|
const initialSaveModel = dashboard.getInitialSaveModel()!;
|
||||||
|
|
||||||
@ -24,11 +25,16 @@ export function getSaveDashboardChange(
|
|||||||
const hasTimeChanged = getHasTimeChanged(changedSaveModel, initialSaveModel);
|
const hasTimeChanged = getHasTimeChanged(changedSaveModel, initialSaveModel);
|
||||||
|
|
||||||
const hasVariableValueChanges = applyVariableChanges(changedSaveModel, initialSaveModel, saveVariables);
|
const hasVariableValueChanges = applyVariableChanges(changedSaveModel, initialSaveModel, saveVariables);
|
||||||
|
const hasRefreshChanged = changedSaveModel.refresh !== initialSaveModel.refresh;
|
||||||
|
|
||||||
if (!saveTimeRange) {
|
if (!saveTimeRange) {
|
||||||
changedSaveModel.time = initialSaveModel.time;
|
changedSaveModel.time = initialSaveModel.time;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!saveRefresh) {
|
||||||
|
changedSaveModel.refresh = initialSaveModel.refresh;
|
||||||
|
}
|
||||||
|
|
||||||
const diff = jsonDiff(initialSaveModel, changedSaveModel);
|
const diff = jsonDiff(initialSaveModel, changedSaveModel);
|
||||||
|
|
||||||
let diffCount = 0;
|
let diffCount = 0;
|
||||||
@ -45,6 +51,7 @@ export function getSaveDashboardChange(
|
|||||||
hasTimeChanges: hasTimeChanged,
|
hasTimeChanges: hasTimeChanged,
|
||||||
isNew: changedSaveModel.version === 0,
|
isNew: changedSaveModel.version === 0,
|
||||||
hasVariableValueChanges,
|
hasVariableValueChanges,
|
||||||
|
hasRefreshChange: hasRefreshChanged,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -15,6 +15,7 @@ export interface DashboardChangeInfo {
|
|||||||
hasChanges: boolean;
|
hasChanges: boolean;
|
||||||
hasTimeChanges: boolean;
|
hasTimeChanges: boolean;
|
||||||
hasVariableValueChanges: boolean;
|
hasVariableValueChanges: boolean;
|
||||||
|
hasRefreshChange: boolean;
|
||||||
isNew?: boolean;
|
isNew?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -63,7 +64,7 @@ export function SaveButton({ overwrite, isLoading, isValid, onSave }: SaveButton
|
|||||||
<Button
|
<Button
|
||||||
disabled={!isValid || isLoading}
|
disabled={!isValid || isLoading}
|
||||||
icon={isLoading ? 'spinner' : undefined}
|
icon={isLoading ? 'spinner' : undefined}
|
||||||
aria-label={selectors.pages.SaveDashboardModal.save}
|
data-testid={selectors.pages.SaveDashboardModal.save}
|
||||||
onClick={() => onSave(overwrite)}
|
onClick={() => onSave(overwrite)}
|
||||||
variant={overwrite ? 'destructive' : 'primary'}
|
variant={overwrite ? 'destructive' : 'primary'}
|
||||||
>
|
>
|
||||||
|
@ -183,6 +183,7 @@ exports[`transformSceneToSaveModel Given a scene with rows Should transform back
|
|||||||
"type": "row",
|
"type": "row",
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
"refresh": "",
|
||||||
"schemaVersion": 39,
|
"schemaVersion": 39,
|
||||||
"tags": [
|
"tags": [
|
||||||
"templating",
|
"templating",
|
||||||
@ -449,6 +450,7 @@ exports[`transformSceneToSaveModel Given a simple scene with custom settings Sho
|
|||||||
"type": "text",
|
"type": "text",
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
"refresh": "5m",
|
||||||
"schemaVersion": 39,
|
"schemaVersion": 39,
|
||||||
"tags": [
|
"tags": [
|
||||||
"tag1",
|
"tag1",
|
||||||
@ -805,6 +807,7 @@ exports[`transformSceneToSaveModel Given a simple scene with variables Should tr
|
|||||||
"type": "text",
|
"type": "text",
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
"refresh": "",
|
||||||
"schemaVersion": 39,
|
"schemaVersion": 39,
|
||||||
"tags": [
|
"tags": [
|
||||||
"gdev",
|
"gdev",
|
||||||
|
@ -178,6 +178,7 @@ describe('transformSceneToSaveModel', () => {
|
|||||||
weekStart: 'monday',
|
weekStart: 'monday',
|
||||||
graphTooltip: 1,
|
graphTooltip: 1,
|
||||||
editable: false,
|
editable: false,
|
||||||
|
refresh: '5m',
|
||||||
timepicker: {
|
timepicker: {
|
||||||
...dashboard_to_load1.timepicker,
|
...dashboard_to_load1.timepicker,
|
||||||
refresh_intervals: ['5m', '15m', '30m', '1h'],
|
refresh_intervals: ['5m', '15m', '30m', '1h'],
|
||||||
|
@ -102,9 +102,11 @@ export function transformSceneToSaveModel(scene: DashboardScene, isSnapshot = fa
|
|||||||
|
|
||||||
const controlsState = state.controls?.state;
|
const controlsState = state.controls?.state;
|
||||||
|
|
||||||
|
const refreshPicker = controlsState?.refreshPicker;
|
||||||
|
|
||||||
const timePickerWithoutDefaults = removeDefaults<TimePickerConfig>(
|
const timePickerWithoutDefaults = removeDefaults<TimePickerConfig>(
|
||||||
{
|
{
|
||||||
refresh_intervals: controlsState?.refreshPicker.state.intervals,
|
refresh_intervals: refreshPicker?.state.intervals,
|
||||||
hidden: controlsState?.hideTimeControls,
|
hidden: controlsState?.hideTimeControls,
|
||||||
nowDelay: timeRange.UNSAFE_nowDelay,
|
nowDelay: timeRange.UNSAFE_nowDelay,
|
||||||
},
|
},
|
||||||
@ -146,6 +148,7 @@ export function transformSceneToSaveModel(scene: DashboardScene, isSnapshot = fa
|
|||||||
graphTooltip,
|
graphTooltip,
|
||||||
liveNow,
|
liveNow,
|
||||||
schemaVersion: DASHBOARD_SCHEMA_VERSION,
|
schemaVersion: DASHBOARD_SCHEMA_VERSION,
|
||||||
|
refresh: refreshPicker?.state.refresh,
|
||||||
};
|
};
|
||||||
|
|
||||||
return sortedDeepCloneWithoutNulls(dashboard);
|
return sortedDeepCloneWithoutNulls(dashboard);
|
||||||
|
10
yarn.lock
10
yarn.lock
@ -4170,9 +4170,9 @@ __metadata:
|
|||||||
languageName: unknown
|
languageName: unknown
|
||||||
linkType: soft
|
linkType: soft
|
||||||
|
|
||||||
"@grafana/scenes@npm:^4.2.1":
|
"@grafana/scenes@npm:^4.5.3":
|
||||||
version: 4.3.0
|
version: 4.5.3
|
||||||
resolution: "@grafana/scenes@npm:4.3.0"
|
resolution: "@grafana/scenes@npm:4.5.3"
|
||||||
dependencies:
|
dependencies:
|
||||||
"@grafana/e2e-selectors": "npm:10.3.3"
|
"@grafana/e2e-selectors": "npm:10.3.3"
|
||||||
react-grid-layout: "npm:1.3.4"
|
react-grid-layout: "npm:1.3.4"
|
||||||
@ -4186,7 +4186,7 @@ __metadata:
|
|||||||
"@grafana/ui": ^10.0.3
|
"@grafana/ui": ^10.0.3
|
||||||
react: ^18.0.0
|
react: ^18.0.0
|
||||||
react-dom: ^18.0.0
|
react-dom: ^18.0.0
|
||||||
checksum: 10/c8af6135ec96307c45cb2ed60fc17580abb5bd304c8f2948e1d901604394f48c3e7378d1274548a88eb9ae76fd6093fcb2194b746e105b08110a0e14423c6731
|
checksum: 10/f1bdfe216e630833f9641e07b2ce295e20ee2f1cebeb0f2115cd81f4aa2204bb525034268b0b067ef7ff6d5070b817aabb27c7649d228a0dbf37affa9220f490
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
@ -18651,7 +18651,7 @@ __metadata:
|
|||||||
"@grafana/prometheus": "workspace:*"
|
"@grafana/prometheus": "workspace:*"
|
||||||
"@grafana/runtime": "workspace:*"
|
"@grafana/runtime": "workspace:*"
|
||||||
"@grafana/saga-icons": "workspace:*"
|
"@grafana/saga-icons": "workspace:*"
|
||||||
"@grafana/scenes": "npm:^4.2.1"
|
"@grafana/scenes": "npm:^4.5.3"
|
||||||
"@grafana/schema": "workspace:*"
|
"@grafana/schema": "workspace:*"
|
||||||
"@grafana/sql": "workspace:*"
|
"@grafana/sql": "workspace:*"
|
||||||
"@grafana/tsconfig": "npm:^1.3.0-rc1"
|
"@grafana/tsconfig": "npm:^1.3.0-rc1"
|
||||||
|
Loading…
Reference in New Issue
Block a user