do not navigate away from diagram editor page if there are changes w/ burnettk
This commit is contained in:
parent
26de48193c
commit
7b78ff42da
|
@ -57,6 +57,7 @@
|
|||
"react-icons": "^4.4.0",
|
||||
"react-jsonschema-form": "^1.8.1",
|
||||
"react-markdown": "^8.0.3",
|
||||
"react-router": "^6.3.0",
|
||||
"react-router-dom": "^6.3.0",
|
||||
"react-scripts": "^5.0.1",
|
||||
"remark-gfm": "^3.0.1",
|
||||
|
|
|
@ -53,6 +53,7 @@
|
|||
"react-jsonschema-form": "^1.8.1",
|
||||
"react-markdown": "^8.0.3",
|
||||
"react-router-dom": "^6.3.0",
|
||||
"react-router": "^6.3.0",
|
||||
"react-scripts": "^5.0.1",
|
||||
"remark-gfm": "^3.0.1",
|
||||
"serve": "^14.0.0",
|
||||
|
|
|
@ -84,6 +84,7 @@ type OwnProps = {
|
|||
onJsonFilesRequested?: (..._args: any[]) => any;
|
||||
onDmnFilesRequested?: (..._args: any[]) => any;
|
||||
onSearchProcessModels?: (..._args: any[]) => any;
|
||||
onElementsChanged?: (..._args: any[]) => any;
|
||||
url?: string;
|
||||
};
|
||||
|
||||
|
@ -109,6 +110,7 @@ export default function ReactDiagramEditor({
|
|||
onJsonFilesRequested,
|
||||
onDmnFilesRequested,
|
||||
onSearchProcessModels,
|
||||
onElementsChanged,
|
||||
url,
|
||||
}: OwnProps) {
|
||||
const [diagramXMLString, setDiagramXMLString] = useState('');
|
||||
|
@ -291,6 +293,11 @@ export default function ReactDiagramEditor({
|
|||
diagramModeler.on('element.click', (element: any) => {
|
||||
handleElementClick(element);
|
||||
});
|
||||
diagramModeler.on('elements.changed', (event: any) => {
|
||||
if (onElementsChanged) {
|
||||
onElementsChanged(event);
|
||||
}
|
||||
});
|
||||
|
||||
diagramModeler.on('spiff.service_tasks.requested', (event: any) => {
|
||||
handleServiceTasksRequested(event);
|
||||
|
@ -330,6 +337,7 @@ export default function ReactDiagramEditor({
|
|||
onJsonFilesRequested,
|
||||
onDmnFilesRequested,
|
||||
onSearchProcessModels,
|
||||
onElementsChanged,
|
||||
]);
|
||||
|
||||
useEffect(() => {
|
||||
|
|
|
@ -0,0 +1,58 @@
|
|||
/**
|
||||
* These hooks re-implement the now removed useBlocker and usePrompt hooks in 'react-router-dom'.
|
||||
* Thanks for the idea @piecyk https://github.com/remix-run/react-router/issues/8139#issuecomment-953816315
|
||||
* Source: https://github.com/remix-run/react-router/commit/256cad70d3fd4500b1abcfea66f3ee622fb90874#diff-b60f1a2d4276b2a605c05e19816634111de2e8a4186fe9dd7de8e344b65ed4d3L344-L381
|
||||
*/
|
||||
|
||||
import { useCallback, useContext, useEffect } from 'react';
|
||||
import { UNSAFE_NavigationContext as NavigationContext } from 'react-router-dom';
|
||||
|
||||
/**
|
||||
* Blocks all navigation attempts. This is useful for preventing the page from
|
||||
* changing until some condition is met, like saving form data.
|
||||
*
|
||||
* @param blocker
|
||||
* @param when
|
||||
* @see https://reactrouter.com/api/useBlocker
|
||||
*/
|
||||
export function useBlocker(blocker: any, when: any = true) {
|
||||
const { navigator } = useContext(NavigationContext);
|
||||
|
||||
useEffect(() => {
|
||||
if (!when) return null;
|
||||
|
||||
const unblock = (navigator as any).block((tx: any) => {
|
||||
const autoUnblockingTx = {
|
||||
...tx,
|
||||
retry() {
|
||||
// Automatically unblock the transition so it can play all the way
|
||||
// through before retrying it. TODO: Figure out how to re-enable
|
||||
// this block if the transition is cancelled for some reason.
|
||||
unblock();
|
||||
tx.retry();
|
||||
},
|
||||
};
|
||||
|
||||
blocker(autoUnblockingTx);
|
||||
});
|
||||
|
||||
return unblock;
|
||||
}, [navigator, blocker, when]);
|
||||
}
|
||||
/**
|
||||
* Prompts the user with an Alert before they leave the current screen.
|
||||
*
|
||||
* @param message
|
||||
* @param when
|
||||
*/
|
||||
export function usePrompt(message: any, when: any = true) {
|
||||
const blocker = useCallback(
|
||||
(tx: any) => {
|
||||
// eslint-disable-next-line no-alert
|
||||
if (window.confirm(message)) tx.retry();
|
||||
},
|
||||
[message]
|
||||
);
|
||||
|
||||
useBlocker(blocker, when);
|
||||
}
|
|
@ -35,11 +35,13 @@ import {
|
|||
} from '../interfaces';
|
||||
import ProcessSearch from '../components/ProcessSearch';
|
||||
import { Notification } from '../components/Notification';
|
||||
import { usePrompt } from '../hooks/UsePrompt';
|
||||
|
||||
export default function ProcessModelEditDiagram() {
|
||||
const [showFileNameEditor, setShowFileNameEditor] = useState(false);
|
||||
const handleShowFileNameEditor = () => setShowFileNameEditor(true);
|
||||
const [processModel, setProcessModel] = useState<ProcessModel | null>(null);
|
||||
const [diagramHasChanges, setDiagramHasChanges] = useState<boolean>(false);
|
||||
|
||||
const [scriptText, setScriptText] = useState<string>('');
|
||||
const [scriptType, setScriptType] = useState<string>('');
|
||||
|
@ -112,6 +114,8 @@ export default function ProcessModelEditDiagram() {
|
|||
|
||||
const processModelPath = `process-models/${modifiedProcessModelId}`;
|
||||
|
||||
usePrompt('Changes you made may not be saved.', diagramHasChanges);
|
||||
|
||||
useEffect(() => {
|
||||
// Grab all available process models in case we need to search for them.
|
||||
// Taken from the Process Group List
|
||||
|
@ -206,6 +210,11 @@ export default function ProcessModelEditDiagram() {
|
|||
// after saving the file, make sure we null out newFileName
|
||||
// so it does not get used over the params
|
||||
setNewFileName('');
|
||||
setDiagramHasChanges(false);
|
||||
};
|
||||
|
||||
const onElementsChanged = () => {
|
||||
setDiagramHasChanges(true);
|
||||
};
|
||||
|
||||
const onDeleteFile = (fileName = params.file_name) => {
|
||||
|
@ -922,6 +931,7 @@ export default function ProcessModelEditDiagram() {
|
|||
onLaunchDmnEditor={onLaunchDmnEditor}
|
||||
onDmnFilesRequested={onDmnFilesRequested}
|
||||
onSearchProcessModels={onSearchProcessModels}
|
||||
onElementsChanged={onElementsChanged}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue