66 lines
5.8 KiB
HTML
66 lines
5.8 KiB
HTML
<!DOCTYPE html><html lang="fr"><head><meta charset="UTF-8"><title>BPMN Studio Live — WEVIA EM</title>
|
||
<link rel="stylesheet" href="https://unpkg.com/bpmn-js@13.0.0/dist/assets/diagram-js.css">
|
||
<link rel="stylesheet" href="https://unpkg.com/bpmn-js@13.0.0/dist/assets/bpmn-font/css/bpmn.css">
|
||
<style>
|
||
*{box-sizing:border-box;margin:0;padding:0}body{font-family:-apple-system,sans-serif;background:#0a0e1a;color:#e2e8f0}
|
||
.hd{background:linear-gradient(135deg,#3b82f6,#1e40af);padding:16px 24px;display:flex;justify-content:space-between;align-items:center}
|
||
.hd h1{color:white;font-size:20px}.ctrls{display:flex;gap:8px}
|
||
.btn{background:#0a0e1a;color:white;border:1px solid #1e40af;padding:8px 14px;border-radius:6px;cursor:pointer;font-size:12px}
|
||
.btn:hover{background:#1e40af}
|
||
.wrap{display:grid;grid-template-columns:260px 1fr;height:calc(100vh - 60px)}
|
||
.side{background:#111827;border-right:1px solid #1e293b;overflow-y:auto;padding:12px}
|
||
.side h3{font-size:11px;color:#60a5fa;text-transform:uppercase;margin:10px 0 6px;letter-spacing:1px}
|
||
.r-item{padding:8px;margin:4px 0;background:#0a0e1a;border:1px solid #1e293b;border-radius:6px;cursor:pointer;font-size:12px}
|
||
.r-item:hover{border-color:#60a5fa}.r-item .dept{color:#64748b;font-size:10px;margin-top:2px}
|
||
#canvas{background:#fff;height:100%}
|
||
.toolbar{position:absolute;top:80px;right:20px;background:#111827;border:1px solid #1e293b;border-radius:8px;padding:8px;display:flex;flex-direction:column;gap:4px}
|
||
</style></head><body>
|
||
<div class="hd"><h1>🔄 BPMN Studio Live — Canvas + 110 Routines</h1>
|
||
<div class="ctrls">
|
||
<button class="btn" onclick="newD()">➕ Nouveau</button>
|
||
<button class="btn" onclick="saveD()">💾 Sauvegarder</button>
|
||
<button class="btn" onclick="exportXML()">📤 Export XML</button>
|
||
</div></div>
|
||
<div class="wrap">
|
||
<div class="side">
|
||
<h3>Routines existantes</h3>
|
||
<input id="f" placeholder="Filtrer..." oninput="filter()" style="width:100%;padding:6px;background:#0a0e1a;border:1px solid #1e293b;color:#e2e8f0;border-radius:4px;margin-bottom:10px;font-size:11px"/>
|
||
<div id="list">Chargement...</div>
|
||
</div>
|
||
<div id="canvas"></div>
|
||
</div>
|
||
<script src="https://unpkg.com/bpmn-js@13.0.0/dist/bpmn-modeler.development.js"></script>
|
||
<script>
|
||
let ROUTINES=[],modeler;
|
||
const INITIAL_XML=`<?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_1" targetNamespace="http://bpmn.io/schema/bpmn"><bpmn:process id="Process_1" isExecutable="false"><bpmn:startEvent id="StartEvent_1"/></bpmn:process><bpmndi:BPMNDiagram id="BPMNDiagram_1"><bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="Process_1"><bpmndi:BPMNShape id="_BPMNShape_StartEvent_2" bpmnElement="StartEvent_1"><dc:Bounds x="175" y="100" width="36" height="36"/></bpmndi:BPMNShape></bpmndi:BPMNPlane></bpmndi:BPMNDiagram></bpmn:definitions>`;
|
||
|
||
async function init(){
|
||
modeler = new BpmnJS({container:'#canvas'});
|
||
await modeler.importXML(INITIAL_XML);
|
||
modeler.get('canvas').zoom('fit-viewport');
|
||
const r = await fetch('/api/em/bpmn-routines?tenant=weval');
|
||
const d = await r.json();
|
||
ROUTINES = d.routines||[];
|
||
render(ROUTINES);
|
||
}
|
||
function render(items){
|
||
document.getElementById('list').innerHTML = items.map(r=>`<div class="r-item" onclick="loadR(${r.id})">${r.name}<div class="dept">[${r.dept}] ${r.sla_hours}h SLA</div></div>`).join('');
|
||
}
|
||
function filter(){const q=document.getElementById('f').value.toLowerCase();render(ROUTINES.filter(r=>r.name.toLowerCase().includes(q)||r.dept.toLowerCase().includes(q)))}
|
||
async function loadR(id){
|
||
const r = ROUTINES.find(x=>x.id===id); if(!r)return;
|
||
const steps = r.steps||[];
|
||
// Generate BPMN XML from steps
|
||
const nodes = steps.map((s,i)=>`<bpmn:task id="Task_${i}" name="${s.replace(/&/g,'&').replace(/</g,'<')}"/>`).join('');
|
||
const flows = steps.map((s,i)=>i<steps.length-1?`<bpmn:sequenceFlow id="Flow_${i}" sourceRef="${i===0?'Start_1':'Task_'+(i-1)}" targetRef="Task_${i}"/>`:`<bpmn:sequenceFlow id="FlowEnd" sourceRef="Task_${i-1}" targetRef="End_1"/>`).join('');
|
||
const shapes = steps.map((s,i)=>`<bpmndi:BPMNShape id="Shape_Task_${i}" bpmnElement="Task_${i}"><dc:Bounds x="${250+i*140}" y="80" width="100" height="80"/></bpmndi:BPMNShape>`).join('');
|
||
const xml = `<?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_1" targetNamespace="http://bpmn.io/schema/bpmn"><bpmn:process id="Process_${r.id}" isExecutable="false" name="${r.name.replace(/&/g,'&')}"><bpmn:startEvent id="Start_1" name="Start"/>${nodes}<bpmn:endEvent id="End_1" name="End"/>${flows}</bpmn:process><bpmndi:BPMNDiagram id="D_1"><bpmndi:BPMNPlane id="P_1" bpmnElement="Process_${r.id}"><bpmndi:BPMNShape id="Shape_Start_1" bpmnElement="Start_1"><dc:Bounds x="180" y="102" width="36" height="36"/></bpmndi:BPMNShape>${shapes}<bpmndi:BPMNShape id="Shape_End_1" bpmnElement="End_1"><dc:Bounds x="${250+steps.length*140}" y="102" width="36" height="36"/></bpmndi:BPMNShape></bpmndi:BPMNPlane></bpmndi:BPMNDiagram></bpmn:definitions>`;
|
||
await modeler.importXML(xml);
|
||
modeler.get('canvas').zoom('fit-viewport');
|
||
}
|
||
async function newD(){await modeler.importXML(INITIAL_XML);modeler.get('canvas').zoom('fit-viewport')}
|
||
async function saveD(){const {xml}=await modeler.saveXML({format:true});alert('Sauvegarde à câbler sur POST /api/em/bpmn/save (wire prochaine session)\\n\\n'+xml.substring(0,200))}
|
||
async function exportXML(){const {xml}=await modeler.saveXML({format:true});const b=new Blob([xml],{type:'text/xml'});const u=URL.createObjectURL(b);const a=document.createElement('a');a.href=u;a.download='bpmn-diagram.bpmn';a.click()}
|
||
init();
|
||
</script></body></html>
|