bmc_hub/app/devportal/frontend/editor.html

215 lines
6.5 KiB
HTML
Raw Normal View History

{% extends "shared/frontend/base.html" %}
{% block title %}Workflow Editor - DEV Portal{% endblock %}
{% block extra_css %}
<style>
#diagramContainer {
width: 100%;
height: calc(100vh - 200px);
border: 1px solid #ddd;
border-radius: 8px;
overflow: hidden;
}
.editor-toolbar {
background: var(--bg-card);
padding: 1rem;
border-radius: 8px;
margin-bottom: 1rem;
}
</style>
{% endblock %}
{% block content %}
<div class="mb-4">
<a href="/devportal" class="btn btn-light">
<i class="bi bi-arrow-left me-2"></i>Tilbage til DEV Portal
</a>
</div>
<div class="editor-toolbar">
<div class="row align-items-center">
<div class="col-md-4">
<input type="text" class="form-control" id="workflowTitle" placeholder="Workflow titel...">
</div>
<div class="col-md-3">
<input type="text" class="form-control" id="workflowDescription" placeholder="Beskrivelse...">
</div>
<div class="col-md-2">
<select class="form-select" id="workflowCategory">
<option value="flowchart">Flowchart</option>
<option value="process">Proces</option>
<option value="system_diagram">System Diagram</option>
<option value="other">Andet</option>
</select>
</div>
<div class="col-md-3 text-end">
<button class="btn btn-success" onclick="saveWorkflow()">
<i class="bi bi-save me-2"></i>Gem Workflow
</button>
</div>
</div>
</div>
<div id="diagramContainer">
<iframe id="diagramFrame" frameborder="0" style="width: 100%; height: 100%;"></iframe>
</div>
{% endblock %}
{% block extra_js %}
<script>
let currentWorkflowId = {{ workflow_id if workflow_id else 'null' }};
let diagramXml = null;
function initEditor() {
const iframe = document.getElementById('diagramFrame');
// Build draw.io embed URL with parameters
const params = new URLSearchParams({
embed: '1',
ui: 'kennedy',
spin: '1',
proto: 'json',
configure: '1',
noSaveBtn: '1',
noExitBtn: '1',
libraries: '1',
saveAndExit: '0'
});
iframe.src = `https://embed.diagrams.net/?${params.toString()}`;
// Listen for messages from draw.io
window.addEventListener('message', function(evt) {
if (evt.data.length > 0) {
try {
const msg = JSON.parse(evt.data);
// When editor is ready
if (msg.event === 'init') {
iframe.contentWindow.postMessage(JSON.stringify({
action: 'load',
autosave: 1,
xml: diagramXml || '' // Load existing diagram if editing
}), '*');
}
// When diagram is exported
if (msg.event === 'export') {
diagramXml = msg.xml;
}
// Auto-save on every change
if (msg.event === 'autosave') {
diagramXml = msg.xml;
}
// Request export when saving
if (msg.event === 'save') {
iframe.contentWindow.postMessage(JSON.stringify({
action: 'export',
format: 'xml'
}), '*');
}
} catch (e) {
// Ignore non-JSON messages
}
}
});
}
async function loadWorkflow() {
if (!currentWorkflowId) return;
try {
const response = await fetch(`/api/v1/devportal/workflows/${currentWorkflowId}`);
const workflow = await response.json();
document.getElementById('workflowTitle').value = workflow.title;
document.getElementById('workflowDescription').value = workflow.description || '';
document.getElementById('workflowCategory').value = workflow.category || 'flowchart';
diagramXml = workflow.diagram_xml;
// Reinitialize editor with loaded data
initEditor();
} catch (error) {
console.error('Error loading workflow:', error);
}
}
async function saveWorkflow() {
const title = document.getElementById('workflowTitle').value;
const description = document.getElementById('workflowDescription').value;
const category = document.getElementById('workflowCategory').value;
if (!title) {
alert('Indtast venligst en titel');
return;
}
// Request export from draw.io
const iframe = document.getElementById('diagramFrame');
iframe.contentWindow.postMessage(JSON.stringify({
action: 'export',
format: 'xml'
}), '*');
// Wait a bit for export to complete
setTimeout(async () => {
if (!diagramXml) {
alert('Kunne ikke eksportere diagram. Prøv igen.');
return;
}
const workflow = {
title,
description,
category,
diagram_xml: diagramXml
};
try {
let response;
if (currentWorkflowId) {
// Update existing
response = await fetch(`/api/v1/devportal/workflows/${currentWorkflowId}`, {
method: 'PUT',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(workflow)
});
} else {
// Create new
response = await fetch('/api/v1/devportal/workflows', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(workflow)
});
}
if (response.ok) {
const result = await response.json();
alert('Workflow gemt!');
window.location.href = '/devportal';
} else {
alert('Fejl ved gemning af workflow');
}
} catch (error) {
console.error('Error saving workflow:', error);
alert('Fejl ved gemning af workflow');
}
}, 500);
}
// Initialize on load
document.addEventListener('DOMContentLoaded', () => {
if (currentWorkflowId) {
loadWorkflow();
} else {
initEditor();
}
});
</script>
{% endblock %}