node src dest display
This commit is contained in:
parent
2974312278
commit
41d556e2ce
@ -282,6 +282,12 @@ class GraphManager:
|
||||
attributes = node_data['attributes']
|
||||
if node_type == 'domain' and attributes.get('certificates', {}).get('has_valid_cert') is False:
|
||||
node_data['color'] = {'background': '#c7c7c7', 'border': '#999'} # Gray for invalid cert
|
||||
|
||||
# Add incoming and outgoing edges to node data
|
||||
if self.graph.has_node(node_id):
|
||||
node_data['incoming_edges'] = [{'from': u, 'data': d} for u, _, d in self.graph.in_edges(node_id, data=True)]
|
||||
node_data['outgoing_edges'] = [{'to': v, 'data': d} for _, v, d in self.graph.out_edges(node_id, data=True)]
|
||||
|
||||
nodes.append(node_data)
|
||||
|
||||
edges = []
|
||||
|
@ -196,8 +196,11 @@ class GraphManager {
|
||||
if (this.network.isCluster(nodeId)) {
|
||||
this.network.openCluster(nodeId);
|
||||
} else {
|
||||
this.showNodeDetails(nodeId);
|
||||
this.highlightNodeConnections(nodeId);
|
||||
const node = this.nodes.get(nodeId);
|
||||
if (node) {
|
||||
this.showNodeDetails(node);
|
||||
this.highlightNodeConnections(nodeId);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
this.clearHighlights();
|
||||
@ -346,7 +349,9 @@ class GraphManager {
|
||||
attributes: node.attributes || {},
|
||||
description: node.description || '',
|
||||
metadata: node.metadata || {},
|
||||
type: node.type
|
||||
type: node.type,
|
||||
incoming_edges: node.incoming_edges || [],
|
||||
outgoing_edges: node.outgoing_edges || []
|
||||
};
|
||||
|
||||
// Add confidence-based styling
|
||||
@ -556,12 +561,9 @@ class GraphManager {
|
||||
|
||||
/**
|
||||
* Show node details in modal
|
||||
* @param {string} nodeId - Node identifier
|
||||
* @param {Object} node - Node object
|
||||
*/
|
||||
showNodeDetails(nodeId) {
|
||||
const node = this.nodes.get(nodeId);
|
||||
if (!node) return;
|
||||
|
||||
showNodeDetails(node) {
|
||||
// Trigger custom event for main application to handle
|
||||
const event = new CustomEvent('nodeSelected', {
|
||||
detail: { node }
|
||||
|
@ -635,7 +635,7 @@ class DNSReconApp {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Update connection status indicator
|
||||
* @param {string} status - Connection status
|
||||
@ -793,39 +793,61 @@ class DNSReconApp {
|
||||
}
|
||||
|
||||
/**
|
||||
* **FIX**: Generates the HTML for the node details view using the new data model.
|
||||
* Generates the HTML for the node details view using the new data model.
|
||||
* @param {Object} node - The node object.
|
||||
* @returns {string} The HTML string for the node details.
|
||||
*/
|
||||
generateNodeDetailsHtml(node) {
|
||||
if(!node) return '<div class="detail-row"><span class="detail-value">Details not available.</span></div>';
|
||||
|
||||
if (!node) return '<div class="detail-row"><span class="detail-value">Details not available.</span></div>';
|
||||
|
||||
let detailsHtml = '<div class="modal-details-grid">';
|
||||
|
||||
// Section for Incoming Edges (Source Nodes)
|
||||
if (node.incoming_edges && node.incoming_edges.length > 0) {
|
||||
detailsHtml += '<div class="modal-section">';
|
||||
detailsHtml += '<h4>Source Nodes (Incoming)</h4>';
|
||||
detailsHtml += '<ul>';
|
||||
node.incoming_edges.forEach(edge => {
|
||||
detailsHtml += `<li><a href="#" class="node-link" data-node-id="${edge.from}">${edge.from}</a> (${edge.data.relationship_type})</li>`;
|
||||
});
|
||||
detailsHtml += '</ul></div>';
|
||||
}
|
||||
|
||||
// Section for Outgoing Edges (Destination Nodes)
|
||||
if (node.outgoing_edges && node.outgoing_edges.length > 0) {
|
||||
detailsHtml += '<div class="modal-section">';
|
||||
detailsHtml += '<h4>Destination Nodes (Outgoing)</h4>';
|
||||
detailsHtml += '<ul>';
|
||||
node.outgoing_edges.forEach(edge => {
|
||||
detailsHtml += `<li><a href="#" class="node-link" data-node-id="${edge.to}">${edge.to}</a> (${edge.data.relationship_type})</li>`;
|
||||
});
|
||||
detailsHtml += '</ul></div>';
|
||||
}
|
||||
|
||||
// Section for Attributes
|
||||
detailsHtml += '<div class="modal-section">';
|
||||
detailsHtml += '<h4>Attributes</h4>';
|
||||
detailsHtml += this.formatObjectToHtml(node.attributes);
|
||||
detailsHtml += '</div>';
|
||||
|
||||
|
||||
// Section for Description
|
||||
detailsHtml += '<div class="modal-section">';
|
||||
detailsHtml += '<h4>Description</h4>';
|
||||
detailsHtml += `<p class="description-text">${node.description || 'No description available.'}</p>`;
|
||||
detailsHtml += '</div>';
|
||||
|
||||
|
||||
// Section for Metadata
|
||||
detailsHtml += '<div class="modal-section">';
|
||||
detailsHtml += '<h4>Metadata</h4>';
|
||||
detailsHtml += this.formatObjectToHtml(node.metadata);
|
||||
detailsHtml += '</div>';
|
||||
|
||||
|
||||
detailsHtml += '</div>';
|
||||
return detailsHtml;
|
||||
}
|
||||
|
||||
/**
|
||||
* Recursively formats a JavaScript object into an HTML unordered list.
|
||||
* Recursively formats a JavaScript object into an HTML unordered list with collapsible sections.
|
||||
* @param {Object} obj - The object to format.
|
||||
* @returns {string} - An HTML string representing the object.
|
||||
*/
|
||||
@ -833,22 +855,20 @@ class DNSReconApp {
|
||||
if (!obj || Object.keys(obj).length === 0) {
|
||||
return '<p class="no-data">No data available.</p>';
|
||||
}
|
||||
|
||||
|
||||
let html = '<ul>';
|
||||
for (const key in obj) {
|
||||
if (Object.hasOwnProperty.call(obj, key)) {
|
||||
const value = obj[key];
|
||||
const formattedKey = key.replace(/_/g, ' ').replace(/\b\w/g, l => l.toUpperCase());
|
||||
html += `<li><strong>${formattedKey}:</strong>`;
|
||||
|
||||
if (Array.isArray(value)) {
|
||||
html += `<ul>${value.map(item => `<li>${this.formatValue(item)}</li>`).join('')}</ul>`;
|
||||
} else if (typeof value === 'object' && value !== null) {
|
||||
|
||||
if (typeof value === 'object' && value !== null) {
|
||||
html += `<li><details><summary><strong>${formattedKey}</strong></summary>`;
|
||||
html += this.formatObjectToHtml(value);
|
||||
html += `</details></li>`;
|
||||
} else {
|
||||
html += ` ${this.formatValue(value)}`;
|
||||
html += `<li><strong>${formattedKey}:</strong> ${this.formatValue(value)}</li>`;
|
||||
}
|
||||
html += '</li>';
|
||||
}
|
||||
}
|
||||
html += '</ul>';
|
||||
@ -889,6 +909,17 @@ class DNSReconApp {
|
||||
|
||||
if (this.elements.modalDetails) {
|
||||
this.elements.modalDetails.innerHTML = detailsHtml;
|
||||
this.elements.modalDetails.querySelectorAll('.node-link').forEach(link => {
|
||||
link.addEventListener('click', (e) => {
|
||||
e.preventDefault();
|
||||
const nodeId = e.target.dataset.nodeId;
|
||||
const nextNode = this.graphManager.nodes.get(nodeId);
|
||||
if (nextNode) {
|
||||
this.hideModal();
|
||||
this.showNodeModal(nextNode);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
this.elements.nodeModal.style.display = 'block';
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user