I am trying to update/save the XML via the modeler.saveXML() function when the user updates the bpmn diagram but anytime I grab the xml it is always the original XML file I am using and never what xml equivalent if what is on the screen/user created. I feel like I have tried just about everything and am running out of ideas. I think it is because I have to create the modeler component in use effect, if I try to do it at the beginning of the react functional component the page has an error, so it always getting the original bpmnModeler component’s xml.
I have also tried using modeler.on() to detect a user change, which it does but then why I try to save the xml and look at it it is still the same. I have tried creating the modeler object in useState but it causes the app to crash when I do so.
Any help getting me going in the right direction would be greatly appreciated as I have been stuck on this for the past 3 days.
I have highlighted the more important parts. Here is my code:
const BpmnModelerComponent = () => {
let modeler: any = null
// const [modeler, setModeler] = useState(new BpmnModeler({
// container: '#bpmnview',
// keyboard: {
// bindTo: window
// }
// }))
const [xmlModalIsOpen, setXmlModalIsOpen] = useState(false);
const [svgModalIsOpen, setSvgModalIsOpen] = useState(false)
const [xmlText, setXmlText] = useState('')
const openXmlModal = () => {
setXmlModalIsOpen(true);
}
const closeXmlModal = () => {
setXmlModalIsOpen(false);
}
const exportArtifacts = (modeler: any) => {
saveModelerXml(modeler);
console.log('xml saved')
}
const openXMLPanel = (modeler: any) => {
openXmlModal()
saveModelerXml(modeler)
}
const saveModelerXml = async (modeler: any) => {
try {
const result = await modeler.saveXML();
const { xml } = result;
getXml(result)
console.log(xml);
} catch (err) {
console.log(err);
}
}
**const getXml = (model: any) => {
const { xml } = model
console.log('xml = ' + xml)
setXml(xml)
}
const setXml = (xml: string) => {
setXmlText(xml)
console.log(xmlText)
}
const downloadXml = async (modeler: any, xml: string) => {
encodeURIComponent(xmlText)
}
**useEffect(() => {
console.log('use effect')
let newModeler = new BpmnModeler({
container: '#bpmnview',
keyboard: {
bindTo: window
}
})
newBpmnDiagram(modeler)
})
useEffect(() => {
'here'
modeler.on('commandStack.changed', () => {
console.log('user changed something')
// modeler.moddle.tomXML(modeler.definitions, { format: true }, function (err, updatedXML) {
// console.log('xml stuff')
// })
// modeler.saveXML({ format: true }, function(err, updatedXML) {
// console.log(updatedXML)
// })
saveModelerXml(modeler)
});
}, [])
const newBpmnDiagram = (modeler: any) => {
openBpmnDiagram(modeler, emptyBpmn)
}
const openBpmnDiagram = async (modeler: any, xml: any) => {
try {
const result = await modeler.importXML(xml);
const { warnings } = result;
console.log(warnings);
} catch (err) {
console.log(err.message, err.warnings);
}
let canvas = modeler.get('canvas')
canvas.zoom('fit-viewport')
}
return(
<div id="bpmncontainer" style={{height: '80%'}}>
<div id="bpmnview" style={{ width: '100%', height: '120vh', float: 'left', overflowX: 'auto' }}></div>
<Button variant='outlined' style={buttonXML} onClick={() => {openXMLPanel(modeler)}}>XML</Button>
<Button variant='outlined' style={buttonSVG} >SVG</Button>
<Button variant='outlined' style={buttonSave} onClick={() => {saveModelerXml(modeler)}}>Save XML</Button>
<Modal
open={xmlModalIsOpen}
onClose={closeXmlModal}
aria-labelledby="modal-modal-title"
aria-describedby="modal-modal-description"
>
<Box sx={style}>
<h3 style={{ position: 'absolute', color: 'black', alignContent: 'flex-start', top: '5%', left: '5%'}}>XML</h3>
<Typography id="modal-modal-description" sx={{ position: 'absolute', top: '10%', left: '5%', color: 'black', width: '100%' }}>
{xmlText}
</Typography>
<Button variant='contained' style={downloadButtonXML} onClick={() => {downloadXml(modeler, xmlText)}}>Download XML</Button>
</Box>
</Modal>
</div>
)
};