39145-vm/update_js.py
2026-03-13 11:47:52 +00:00

115 lines
4.9 KiB
Python

import os
with open("core/templates/core/project_detail.html", "r") as f:
html = f.read()
# Replace the node clicked block
old_block = """
const nodeId = params.nodes[0];
const node = data.nodes.get(nodeId);
detailsPanel.innerHTML = `
<h6 class="mb-2 fw-bold text-dark">${node.label}</h6>
<span class="badge bg-secondary mb-2 bg-opacity-75">${node.category}</span>
<p class="small mb-0 text-dark"><strong>Summary:</strong><br>${node.summary}</p>
`;
"""
new_block = """
const nodeId = params.nodes[0];
const node = data.nodes.get(nodeId);
// remove emoji from label for editing
const cleanLabel = node.label.replace(/^.*? /, '');
detailsPanel.innerHTML = `
<div id="node-view-${nodeId}">
<h6 class="mb-2 fw-bold text-dark">${cleanLabel}</h6>
<span class="badge bg-secondary mb-2 bg-opacity-75">${node.category}</span>
<p class="small mb-2 text-dark"><strong>Summary:</strong><br>${node.summary}</p>
<button class="btn btn-sm btn-outline-primary" onclick="editNodeUI(${nodeId})">Edit</button>
</div>
<div id="node-edit-${nodeId}" class="d-none">
<input type="text" id="edit-node-title-${nodeId}" class="form-control form-control-sm mb-2" value="${cleanLabel}">
<input type="text" id="edit-node-category-${nodeId}" class="form-control form-control-sm mb-2" value="${node.category}">
<textarea id="edit-node-summary-${nodeId}" class="form-control form-control-sm mb-2" rows="3">${node.summary}</textarea>
<button class="btn btn-sm btn-primary me-1" onclick="saveNode(${nodeId}, event)">Save</button>
<button class="btn btn-sm btn-outline-secondary" onclick="cancelEditNode(${nodeId})">Cancel</button>
</div>
`;
"""
html = html.replace(old_block, new_block)
new_scripts = """
function editNodeUI(nodeId) {
document.getElementById(`node-view-${nodeId}`).classList.add('d-none');
document.getElementById(`node-edit-${nodeId}`).classList.remove('d-none');
}
function cancelEditNode(nodeId) {
document.getElementById(`node-edit-${nodeId}`).classList.add('d-none');
document.getElementById(`node-view-${nodeId}`).classList.remove('d-none');
}
function saveNode(nodeId, event) {
const title = document.getElementById(`edit-node-title-${nodeId}`).value;
const category = document.getElementById(`edit-node-category-${nodeId}`).value;
const summary = document.getElementById(`edit-node-summary-${nodeId}`).value;
const saveBtn = event.target;
saveBtn.disabled = true;
saveBtn.innerText = 'Saving...';
let csrfToken = '';
const csrfInput = document.querySelector('[name=csrfmiddlewaretoken]');
if (csrfInput) {
csrfToken = csrfInput.value;
} else {
// fallback, get from form if present elsewhere
console.warn("CSRF token not found via input name. Ensure it exists on the page.");
}
const url = "{% url 'edit_node' project.pk 0 %}".replace('/0/', '/' + nodeId + '/');
fetch(url, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-CSRFToken': csrfToken
},
body: JSON.stringify({ title: title, category: category, summary: summary })
})
.then(response => response.json())
.then(res => {
if (res.status === 'success') {
const node = res.node;
const emoji = getNodeEmoji(node.category);
const color = getNodeColor(node.category);
data.nodes.update({
id: node.id,
label: emoji + " " + node.title,
title: `<strong>${node.title}</strong><br>${node.summary}<br><em>Category: ${node.category}</em>`,
summary: node.summary,
category: node.category,
color: color
});
// re-render details
network.emit('click', { nodes: [nodeId], edges: [] });
} else {
alert('Error saving node: ' + res.message);
saveBtn.disabled = false;
saveBtn.innerText = 'Save';
}
})
.catch(err => {
alert('Error saving node');
saveBtn.disabled = false;
saveBtn.innerText = 'Save';
});
}
"""
html = html.replace(' // AI Chat Handler', new_scripts + '\n // AI Chat Handler')
with open("core/templates/core/project_detail.html", "w") as f:
f.write(html)