115 lines
4.9 KiB
Python
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)
|