mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Scenes: Fix issue where unsaved changes prompt is shown when quickly adding panel to new dashboard (#85518)
Closes #84577
This commit is contained in:
parent
f6a94837c5
commit
85127464a3
@ -2401,9 +2401,6 @@ exports[`better eslint`] = {
|
|||||||
"public/app/features/dashboard-scene/panel-edit/PanelDataPane/PanelDataPane.tsx:5381": [
|
"public/app/features/dashboard-scene/panel-edit/PanelDataPane/PanelDataPane.tsx:5381": [
|
||||||
[0, 0, 0, "Do not use any type assertions.", "0"]
|
[0, 0, 0, "Do not use any type assertions.", "0"]
|
||||||
],
|
],
|
||||||
"public/app/features/dashboard-scene/saving/DashboardPrompt.tsx:5381": [
|
|
||||||
[0, 0, 0, "Do not use any type assertions.", "0"]
|
|
||||||
],
|
|
||||||
"public/app/features/dashboard-scene/saving/DetectChangesWorker.ts:5381": [
|
"public/app/features/dashboard-scene/saving/DetectChangesWorker.ts: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"]
|
||||||
|
@ -1,11 +1,11 @@
|
|||||||
import { css } from '@emotion/css';
|
import { css } from '@emotion/css';
|
||||||
import * as H from 'history';
|
import * as H from 'history';
|
||||||
import React, { useState, useContext, useEffect } from 'react';
|
import React, { useContext, useEffect, useMemo } from 'react';
|
||||||
import { Prompt } from 'react-router';
|
import { Prompt } from 'react-router';
|
||||||
|
|
||||||
import { locationService } from '@grafana/runtime';
|
import { locationService } from '@grafana/runtime';
|
||||||
import { Dashboard } from '@grafana/schema/dist/esm/index.gen';
|
import { Dashboard } from '@grafana/schema/dist/esm/index.gen';
|
||||||
import { ModalsContext, Modal, Button } from '@grafana/ui';
|
import { ModalsContext, Modal, Button, useStyles2 } from '@grafana/ui';
|
||||||
import { contextSrv } from 'app/core/services/context_srv';
|
import { contextSrv } from 'app/core/services/context_srv';
|
||||||
|
|
||||||
import { DashboardScene } from '../scene/DashboardScene';
|
import { DashboardScene } from '../scene/DashboardScene';
|
||||||
@ -14,32 +14,17 @@ interface DashboardPromptProps {
|
|||||||
dashboard: DashboardScene;
|
dashboard: DashboardScene;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface DashboardPromptState {
|
|
||||||
originalPath?: string;
|
|
||||||
}
|
|
||||||
export const DashboardPrompt = React.memo(({ dashboard }: DashboardPromptProps) => {
|
export const DashboardPrompt = React.memo(({ dashboard }: DashboardPromptProps) => {
|
||||||
const [state, setState] = useState<DashboardPromptState>({ originalPath: undefined });
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
const { originalPath } = state;
|
const originalPath = useMemo(() => locationService.getLocation().pathname, [dashboard]);
|
||||||
const { showModal, hideModal } = useContext(ModalsContext);
|
const { showModal, hideModal } = useContext(ModalsContext);
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
// This timeout delay is to wait for panels to load and migrate scheme before capturing the original state
|
|
||||||
// This is to minimize unsaved changes warnings due to automatic schema migrations
|
|
||||||
const timeoutId = setTimeout(() => {
|
|
||||||
const originalPath = locationService.getLocation().pathname;
|
|
||||||
setState({ originalPath });
|
|
||||||
}, 1000);
|
|
||||||
|
|
||||||
return () => {
|
|
||||||
clearTimeout(timeoutId);
|
|
||||||
};
|
|
||||||
}, [dashboard, originalPath]);
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const handleUnload = (event: BeforeUnloadEvent) => {
|
const handleUnload = (event: BeforeUnloadEvent) => {
|
||||||
if (ignoreChanges(dashboard, dashboard.getInitialSaveModel())) {
|
if (ignoreChanges(dashboard, dashboard.getInitialSaveModel())) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dashboard.state.isDirty) {
|
if (dashboard.state.isDirty) {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
// No browser actually displays this message anymore.
|
// No browser actually displays this message anymore.
|
||||||
@ -47,6 +32,7 @@ export const DashboardPrompt = React.memo(({ dashboard }: DashboardPromptProps)
|
|||||||
event.returnValue = '';
|
event.returnValue = '';
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
window.addEventListener('beforeunload', handleUnload);
|
window.addEventListener('beforeunload', handleUnload);
|
||||||
return () => window.removeEventListener('beforeunload', handleUnload);
|
return () => window.removeEventListener('beforeunload', handleUnload);
|
||||||
}, [dashboard]);
|
}, [dashboard]);
|
||||||
@ -121,6 +107,7 @@ function moveToBlockedLocationAfterReactStateUpdate(location?: H.Location | null
|
|||||||
setTimeout(() => locationService.push(location), 10);
|
setTimeout(() => locationService.push(location), 10);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
interface UnsavedChangesModalProps {
|
interface UnsavedChangesModalProps {
|
||||||
onDiscard: () => void;
|
onDiscard: () => void;
|
||||||
onDismiss: () => void;
|
onDismiss: () => void;
|
||||||
@ -128,7 +115,8 @@ interface UnsavedChangesModalProps {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export const UnsavedChangesModal = ({ onDiscard, onDismiss, onSaveDashboardClick }: UnsavedChangesModalProps) => {
|
export const UnsavedChangesModal = ({ onDiscard, onDismiss, onSaveDashboardClick }: UnsavedChangesModalProps) => {
|
||||||
const styles = getStyles();
|
const styles = useStyles2(getStyles);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Modal
|
<Modal
|
||||||
isOpen={true}
|
isOpen={true}
|
||||||
@ -166,7 +154,7 @@ export function ignoreChanges(current: DashboardScene | null, original?: Dashboa
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Ignore changes if original is unsaved
|
// Ignore changes if original is unsaved
|
||||||
if ((original as Dashboard).version === 0) {
|
if (original.version === 0) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user