wip editing bpmn diagrams w/ burnettk
This commit is contained in:
parent
e5c806b90a
commit
943e88c64e
|
@ -0,0 +1,13 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<bpmn:definitions xmlns:bpmn="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:dc="http://www.omg.org/spec/DD/20100524/DC" id="Definitions_96f6665" targetNamespace="http://bpmn.io/schema/bpmn" exporter="Camunda Modeler" exporterVersion="3.0.0-dev">
|
||||||
|
<bpmn:process id="Process_bd2e724" isExecutable="true">
|
||||||
|
<bpmn:startEvent id="StartEvent_1" />
|
||||||
|
</bpmn:process>
|
||||||
|
<bpmndi:BPMNDiagram id="BPMNDiagram_1">
|
||||||
|
<bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="Process_bd2e724">
|
||||||
|
<bpmndi:BPMNShape id="_BPMNShape_StartEvent_2" bpmnElement="StartEvent_1">
|
||||||
|
<dc:Bounds x="179" y="159" width="36" height="36" />
|
||||||
|
</bpmndi:BPMNShape>
|
||||||
|
</bpmndi:BPMNPlane>
|
||||||
|
</bpmndi:BPMNDiagram>
|
||||||
|
</bpmn:definitions>
|
|
@ -33,6 +33,7 @@ root.render(
|
||||||
|
|
||||||
<Route path="process-models/:process_group_id/new" element={<ProcessModelNew />} />
|
<Route path="process-models/:process_group_id/new" element={<ProcessModelNew />} />
|
||||||
<Route path="process-models/:process_group_id/:process_model_id" element={<ProcessModelShow />} />
|
<Route path="process-models/:process_group_id/:process_model_id" element={<ProcessModelShow />} />
|
||||||
|
<Route path="process-models/:process_group_id/:process_model_id/file" element={<ProcessModelEditDiagram />} />
|
||||||
<Route path="process-models/:process_group_id/:process_model_id/file/:file_name" element={<ProcessModelEditDiagram />} />
|
<Route path="process-models/:process_group_id/:process_model_id/file/:file_name" element={<ProcessModelEditDiagram />} />
|
||||||
<Route path="process-models/:process_group_id/:process_model_id/process-instances" element={<ProcessInstanceList />} />
|
<Route path="process-models/:process_group_id/:process_model_id/process-instances" element={<ProcessInstanceList />} />
|
||||||
</Routes>
|
</Routes>
|
||||||
|
|
|
@ -7,6 +7,8 @@ import React, { useEffect, useState } from "react";
|
||||||
import { BACKEND_BASE_URL } from './config';
|
import { BACKEND_BASE_URL } from './config';
|
||||||
import { HOT_AUTH_TOKEN } from './config';
|
import { HOT_AUTH_TOKEN } from './config';
|
||||||
|
|
||||||
|
import Button from 'react-bootstrap/Button';
|
||||||
|
|
||||||
import "bpmn-js/dist/assets/diagram-js.css";
|
import "bpmn-js/dist/assets/diagram-js.css";
|
||||||
import "bpmn-js/dist/assets/bpmn-font/css/bpmn-embedded.css";
|
import "bpmn-js/dist/assets/bpmn-font/css/bpmn-embedded.css";
|
||||||
import "bpmn-js-properties-panel/dist/assets/properties-panel.css"
|
import "bpmn-js-properties-panel/dist/assets/properties-panel.css"
|
||||||
|
@ -74,8 +76,10 @@ export default function ReactBpmnEditor(props) {
|
||||||
if (!diagramXML) {
|
if (!diagramXML) {
|
||||||
if (props.url) {
|
if (props.url) {
|
||||||
return fetchDiagramFromURL(props.url);
|
return fetchDiagramFromURL(props.url);
|
||||||
} else {
|
} else if (props.file_name) {
|
||||||
return fetchDiagramFromJsonAPI(props.process_model_id, props.file_name);
|
return fetchDiagramFromJsonAPI(props.process_model_id, props.file_name);
|
||||||
|
} else {
|
||||||
|
return fetchDiagramFromURL(process.env.PUBLIC_URL + '/new_bpmn_diagram.bpmn');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -113,7 +117,14 @@ export default function ReactBpmnEditor(props) {
|
||||||
}
|
}
|
||||||
}, [props, diagramXML, bpmnViewerState]);
|
}, [props, diagramXML, bpmnViewerState]);
|
||||||
|
|
||||||
|
function handleSave() {
|
||||||
|
bpmnViewerState.saveXML({ format: true })
|
||||||
|
.then(xml => props.saveDiagram(xml))
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div></div>
|
<div>
|
||||||
|
<Button onClick={handleSave} variant="danger">Save</Button>
|
||||||
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,21 +6,84 @@ import { useParams } from "react-router-dom";
|
||||||
import ReactBpmnEditor from "../react_bpmn_editor"
|
import ReactBpmnEditor from "../react_bpmn_editor"
|
||||||
import ProcessBreadcrumb from '../components/ProcessBreadcrumb'
|
import ProcessBreadcrumb from '../components/ProcessBreadcrumb'
|
||||||
|
|
||||||
|
import { Button, Modal } from 'react-bootstrap';
|
||||||
|
|
||||||
export default function ProcessModelEditDiagram() {
|
export default function ProcessModelEditDiagram() {
|
||||||
|
const [show, setShow] = useState(false);
|
||||||
|
const handleShow = () => setShow(true);
|
||||||
|
|
||||||
let params = useParams();
|
let params = useParams();
|
||||||
|
|
||||||
const [processModelFile, setProcessModelFile] = useState(null);
|
const [processModelFile, setProcessModelFile] = useState(null);
|
||||||
|
const [newFileName, setNewFileName] = useState("");
|
||||||
|
const [newBpmnXml, setNewBpmnXml] = useState(null);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
fetch(`${BACKEND_BASE_URL}/process-models/${params.process_model_id}/file/${params.file_name}`, {
|
if (params.file_name) {
|
||||||
headers: new Headers({
|
fetch(`${BACKEND_BASE_URL}/process-models/${params.process_model_id}/file/${params.file_name}`, {
|
||||||
'Authorization': `Bearer ${HOT_AUTH_TOKEN}`
|
headers: new Headers({
|
||||||
|
'Authorization': `Bearer ${HOT_AUTH_TOKEN}`
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
.then(res => res.json())
|
||||||
|
.then(
|
||||||
|
(result) => {
|
||||||
|
setProcessModelFile(result);
|
||||||
|
},
|
||||||
|
// Note: it's important to handle errors here
|
||||||
|
// instead of a catch() block so that we don't swallow
|
||||||
|
// exceptions from actual bugs in components.
|
||||||
|
(error) => {
|
||||||
|
console.log(error);
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}, [params]);
|
||||||
|
|
||||||
|
function onError(err) {
|
||||||
|
console.log('ERROR:', err);
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleFileNameCancel = () => setShow(false);
|
||||||
|
|
||||||
|
const handleFileNameSave = (() => {
|
||||||
|
setShow(false);
|
||||||
|
saveDiagram(newBpmnXml);
|
||||||
|
});
|
||||||
|
|
||||||
|
const saveDiagram = ((bpmnXML, fileName = params.file_name) => {
|
||||||
|
setNewBpmnXml(bpmnXML);
|
||||||
|
|
||||||
|
let url = `${BACKEND_BASE_URL}/process-models/${params.process_model_id}/file`;
|
||||||
|
let httpMethod = 'PUT'
|
||||||
|
|
||||||
|
if (newFileName) {
|
||||||
|
fileName = newFileName;
|
||||||
|
httpMethod = 'POST'
|
||||||
|
} else {
|
||||||
|
url += `/${fileName}`;
|
||||||
|
}
|
||||||
|
if (!fileName) {
|
||||||
|
handleShow();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
let bpmnFile = new File([bpmnXML.xml], fileName);
|
||||||
|
const formData = new FormData();
|
||||||
|
formData.append('file', bpmnFile);
|
||||||
|
formData.append('fileName', bpmnFile.name);
|
||||||
|
fetch(url, {
|
||||||
|
headers: new Headers({
|
||||||
|
'Authorization': `Bearer ${HOT_AUTH_TOKEN}`,
|
||||||
|
}),
|
||||||
|
method: httpMethod,
|
||||||
|
body: formData,
|
||||||
})
|
})
|
||||||
.then(res => res.json())
|
.then(res => res.json())
|
||||||
.then(
|
.then(
|
||||||
(result) => {
|
(result) => {
|
||||||
setProcessModelFile(result);
|
console.log(result);
|
||||||
},
|
},
|
||||||
// Note: it's important to handle errors here
|
// Note: it's important to handle errors here
|
||||||
// instead of a catch() block so that we don't swallow
|
// instead of a catch() block so that we don't swallow
|
||||||
|
@ -29,11 +92,7 @@ export default function ProcessModelEditDiagram() {
|
||||||
console.log(error);
|
console.log(error);
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
}, [params]);
|
});
|
||||||
|
|
||||||
function onError(err) {
|
|
||||||
console.log('ERROR:', err);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (processModelFile) {
|
if (processModelFile) {
|
||||||
return (
|
return (
|
||||||
|
@ -44,13 +103,54 @@ export default function ProcessModelEditDiagram() {
|
||||||
linkProcessModel="true"
|
linkProcessModel="true"
|
||||||
/>
|
/>
|
||||||
<h2>Process Model File: {processModelFile.name}</h2>
|
<h2>Process Model File: {processModelFile.name}</h2>
|
||||||
<div id="bpmn-js-container-thing"></div>
|
|
||||||
<ReactBpmnEditor
|
<ReactBpmnEditor
|
||||||
process_model_id={params.process_model_id}
|
process_model_id={params.process_model_id}
|
||||||
file_name={processModelFile.name}
|
file_name={processModelFile.name}
|
||||||
diagramXML={processModelFile.file_contents}
|
diagramXML={processModelFile.file_contents}
|
||||||
onError={ onError }
|
onError={ onError }
|
||||||
|
saveDiagram={ saveDiagram }
|
||||||
/>
|
/>
|
||||||
|
<div id="bpmn-js-container-thing"></div>
|
||||||
|
</main>
|
||||||
|
);
|
||||||
|
} else if (!params.file_name) {
|
||||||
|
return (
|
||||||
|
<main style={{ padding: "1rem 0" }}>
|
||||||
|
<ProcessBreadcrumb
|
||||||
|
processGroupId={params.process_group_id}
|
||||||
|
processModelId={params.process_model_id}
|
||||||
|
linkProcessModel="true"
|
||||||
|
/>
|
||||||
|
<h2>Process Model File</h2>
|
||||||
|
<ReactBpmnEditor
|
||||||
|
process_model_id={params.process_model_id}
|
||||||
|
onError={ onError }
|
||||||
|
saveDiagram={ saveDiagram }
|
||||||
|
/>
|
||||||
|
|
||||||
|
<Modal show={show} onHide={handleFileNameCancel}>
|
||||||
|
<Modal.Header closeButton>
|
||||||
|
<Modal.Title>Process Model File Name</Modal.Title>
|
||||||
|
</Modal.Header>
|
||||||
|
<label>File Name:</label>
|
||||||
|
<input
|
||||||
|
name='file_name'
|
||||||
|
type='text'
|
||||||
|
value={newFileName}
|
||||||
|
onChange={e => setNewFileName(e.target.value)}
|
||||||
|
/>
|
||||||
|
<Modal.Footer>
|
||||||
|
<Button variant="secondary" onClick={handleFileNameCancel}>
|
||||||
|
Close
|
||||||
|
</Button>
|
||||||
|
<Button variant="primary" onClick={handleFileNameSave}>
|
||||||
|
Save Changes
|
||||||
|
</Button>
|
||||||
|
</Modal.Footer>
|
||||||
|
</Modal>
|
||||||
|
|
||||||
|
|
||||||
|
<div id="bpmn-js-container-thing"></div>
|
||||||
</main>
|
</main>
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -107,6 +107,7 @@ export default function ProcessModelShow() {
|
||||||
<Stack direction="horizontal" gap={3}>
|
<Stack direction="horizontal" gap={3}>
|
||||||
<Button onClick={processModelRun} variant="primary">Run Primary</Button>
|
<Button onClick={processModelRun} variant="primary">Run Primary</Button>
|
||||||
<Button onClick={deleteProcessModel} variant="danger">Delete Process Model</Button>
|
<Button onClick={deleteProcessModel} variant="danger">Delete Process Model</Button>
|
||||||
|
<Button href={`/process-models/${processModel.process_group_id}/${processModel.id}/file`} variant="warning">Add New Process Model File</Button>
|
||||||
</Stack>
|
</Stack>
|
||||||
<br />
|
<br />
|
||||||
<br />
|
<br />
|
||||||
|
|
Loading…
Reference in New Issue