diff --git a/frontend/assets/js/app.js b/frontend/assets/js/app.js
index 5730baa..d2c65ff 100644
--- a/frontend/assets/js/app.js
+++ b/frontend/assets/js/app.js
@@ -49,10 +49,10 @@ document.addEventListener('DOMContentLoaded', () => {
window.addEventListener('resize', () => { resizeCanvas(); renderNetwork(); });
document.addEventListener('keydown', (e) => {
- if (e.key === 'Delete' || e.key === 'Backspace') {
+ if (e.key === 'Delete') {
if (!document.activeElement || document.activeElement.tagName !== 'INPUT') {
- if (selectedNodeId) deleteSelectedNode();
- else if (selectedShapeId) deleteSelectedShape();
+ if (selectedNodeId) deleteSelectedNode(selectedNodeId);
+ else if (selectedShapeId) deleteSelectedShape(selectedShapeId);
}
}
if (e.key === 'Escape') {
@@ -204,9 +204,9 @@ async function loadNetworkData() {
apiFetch('links'),
apiFetch('shapes')
]);
- nodes = n;
- links = l;
- shapes = s;
+ nodes = Array.isArray(n) ? n : [];
+ links = Array.isArray(l) ? l : [];
+ shapes = Array.isArray(s) ? s : [];
populateNodeSelects();
renderNodeList();
renderShapeList();
@@ -265,7 +265,7 @@ function selectNode(id) {
Type: ${n.node_type}
Status: ${n.status}
Group: ${n.group_name}
-
+
`;
}
@@ -282,24 +282,43 @@ function selectShape(id) {
renderNetwork();
}
-async function deleteSelectedNode() {
- if (!selectedNodeId) return;
- if (!confirm('Delete this node and its connections?')) return;
- const id = selectedNodeId;
+async function deleteSelectedNode(id) {
+ if (!id) return;
+ const ok = await showConfirm('Delete this node and its connections?');
+ if (!ok) return;
selectedNodeId = null;
await apiFetch(`nodes/${id}`, { method: 'DELETE' });
loadNetworkData();
}
-async function deleteSelectedShape() {
- if (!selectedShapeId) return;
- if (!confirm('Delete this shape?')) return;
- const id = selectedShapeId;
+async function deleteSelectedShape(id) {
+ if (!id) return;
+ const ok = await showConfirm('Delete this shape?');
+ if (!ok) return;
selectedShapeId = null;
await apiFetch(`shapes/${id}`, { method: 'DELETE' });
loadNetworkData();
}
+function showConfirm(msg) {
+ return new Promise((resolve) => {
+ const modalEl = document.getElementById('confirmModal');
+ const modal = new bootstrap.Modal(modalEl);
+ document.getElementById('confirmMsg').textContent = msg;
+ const btn = document.getElementById('confirmBtn');
+ let resolved = false;
+ const cleanup = () => {
+ btn.removeEventListener('click', onClick);
+ modalEl.removeEventListener('hidden.bs.modal', onHidden);
+ };
+ const onClick = () => { resolved = true; cleanup(); modal.hide(); resolve(true); };
+ const onHidden = () => { if (!resolved) { cleanup(); resolve(false); } };
+ btn.addEventListener('click', onClick);
+ modalEl.addEventListener('hidden.bs.modal', onHidden);
+ modal.show();
+ });
+}
+
async function saveNode() {
const data = {
label: document.getElementById('nodeLabel').value,
diff --git a/frontend/index.html b/frontend/index.html
index 54ddc20..2ee12b4 100644
--- a/frontend/index.html
+++ b/frontend/index.html
@@ -329,6 +329,22 @@
+
+
+
+
+
+
+
Are you sure?
+
+
+
+
+
+
+
+
+