Browse Source

add connection tls, connection modal

pull/1/head
Stephanie Gredell 7 months ago
parent
commit
32ce500588
  1. 4
      static/app.js
  2. 102
      static/connection.js
  3. 74
      static/game.html

4
static/app.js

@ -9,6 +9,7 @@ export class CanvasApp { @@ -9,6 +9,7 @@ export class CanvasApp {
this.componentSize = { width: 120, height: 40 };
this.arrowMode = false;
this.connectionStart = null;
this.pendingConnection = null;
this.activeNode = null;
this.selectedConnection = null;
@ -216,7 +217,8 @@ export class CanvasApp { @@ -216,7 +217,8 @@ export class CanvasApp {
target: c.end.id,
label: c.label || '',
direction: c.direction,
protocol: c.protocol || ''
protocol: c.protocol || '',
tls: !!c.tls
}));
return { nodes, connections };

102
static/connection.js

@ -1,22 +1,25 @@ @@ -1,22 +1,25 @@
import { generateNodeId, createSVGElement } from './utils.js';
export class Connection {
constructor(startNode, endNode, label, protocol, app) {
static _activeConnection = null;
static modalSetupDone = false;
constructor(startNode, endNode, label, protocol, app, tls) {
this.start = startNode;
this.end = endNode;
this.app = app;
this.label = label;
this.protocol = protocol;
this.direction = "forward";
this.tls = tls;
this.line = createSVGElement('line', {
stroke: '#ccc', 'stroke-width': 2, 'marker-end': 'url(#arrowhead)'
stroke: '#ccc', 'stroke-width': 2, 'marker-end': 'url(#arrowhead-end)'
});
this.hitbox = createSVGElement('circle', {
r: 12,
fill: 'transparent',
cursor: 'pointer',
});
this.app.canvas.appendChild(this.hitbox);
this.text = createSVGElement('text', {
'text-anchor': 'middle', 'font-size': 12, fill: '#ccc'
});
@ -30,6 +33,8 @@ export class Connection { @@ -30,6 +33,8 @@ export class Connection {
app.canvas.appendChild(this.line);
app.canvas.appendChild(this.text);
app.canvas.appendChild(this.protocolText)
app.canvas.appendChild(this.hitbox);
this.updatePosition();
this.selected = false;
@ -42,7 +47,17 @@ export class Connection { @@ -42,7 +47,17 @@ export class Connection {
this.line.addEventListener('dblclick', (e) => {
e.stopPropagation();
this.toggleDirection();
})
});
this.text.addEventListener('dblclick', (e) => {
e.stopPropagation();
this.openEditModal()
});
this.protocolText.addEventListener('click', (e) => {
e.stopPropagation();
this.openEditModal();
});
}
updatePosition() {
@ -114,7 +129,63 @@ export class Connection { @@ -114,7 +129,63 @@ export class Connection {
this.line.setAttribute('stroke-width', 2);
}
static setupModal(app) {
if (Connection.modalSetupDone) return;
Connection.modalSetupDone = true;
Connection.modal = document.getElementById('connection-modal');
Connection.labelInput = document.getElementById('connection-label');
Connection.tlsCheckbox = document.getElementById('connection-tls');
Connection.protocolInput = document.getElementById('connection-protocol');
Connection.saveBtn = document.getElementById('connection-save');
Connection.cancelBtn = document.getElementById('connection-cancel');
Connection.saveBtn.addEventListener('click', () => {
const label = Connection.labelInput.value.trim();
const protocol = Connection.protocolInput.value.trim();
const tls = Connection.tlsCheckbox.checked;
if (!label || !protocol) return;
if (Connection._activeConnection) {
// Editing an existing connection
const conn = Connection._activeConnection;
conn.label = label;
conn.protocol = protocol;
conn.text.textContent = label;
conn.tls = tls;
conn.protocolText.textContent = protocol;
conn.updatePosition();
} else if (app.pendingConnection) {
// Creating a new connection
const { start, end } = app.pendingConnection;
const conn = new Connection(start, end, label, protocol, app, tls);
app.connections.push(conn);
}
Connection.modal.style.display = 'none';
app.pendingConnection = null;
Connection._activeConnection = null;
if (app.connectionStart) {
app.connectionStart.group.classList.remove('selected');
app.connectionStart = null;
}
});
Connection.cancelBtn.addEventListener('click', () => {
Connection.modal.style.display = 'none';
app.pendingConnection = null;
if (app.connectionStart) {
app.connectionStart.group.classList.remove('selected');
app.connectionStart = null;
}
});
}
static handleClick(nodeObj, app) {
Connection.setupModal(app);
if (!app.connectionStart) {
app.connectionStart = nodeObj;
nodeObj.group.classList.add('selected');
@ -122,15 +193,22 @@ export class Connection { @@ -122,15 +193,22 @@ export class Connection {
app.connectionStart.group.classList.remove('selected');
app.connectionStart = null;
} else {
const defaultLabel = 'Read traffic';
const label = prompt('Enter connection label:', defaultLabel);
const protocol = prompt('Protocol (e.g. HTTP, gRPC, Kafka):', 'HTTP');
if (label && protocol) {
const conn = new Connection(app.connectionStart, nodeObj, label, protocol, app);
app.connections.push(conn);
app.pendingConnection = { start: app.connectionStart, end: nodeObj };
Connection.labelInput.value = 'Read traffic';
Connection.protocolInput.value = 'HTTP';
Connection.tlsCheckbox.checked = false;
Connection.modal.style.display = 'block';
}
app.connectionStart.group.classList.remove('selected');
app.connectionStart = null;
}
openEditModal() {
Connection.setupModal(this.app);
Connection._activeConnection = this;
Connection.labelInput.value = this.label;
Connection.protocolInput.value = this.protocol;
Connection.tlsCheckbox.checked = this.tls;
Connection.modal.style.display = 'block';
}
}

74
static/game.html

@ -483,6 +483,46 @@ @@ -483,6 +483,46 @@
position: absolute;
left: 0;
}
.modal {
position: absolute;
top: 30%;
left: 50%;
transform: translate(-50%, -30%);
background: #121212;
padding: 20px;
border-radius: 8px;
border: 1px solid #444;
z-index: 999;
color: #ccc;
}
.modal-content label {
display: block;
margin: 10px 0;
}
.modal-actions {
margin-top: 10px;
text-align: right;
}
.modal input {
width: 100%;
padding: 6px;
margin-top: 4px;
background: #222;
border: 1px solid #444;
color: #fff;
border-radius: 4px;
}
.modal select {
width: 100%;
padding: 6px;
margin-top: 4px;
background: #222;
border: 1px solid #444;
color: #fff;
border-radius: 4px;
}
</style>
</head>
<body>
@ -613,6 +653,40 @@ @@ -613,6 +653,40 @@
</div>
<div id="canvas-container">
<div id="connection-modal" style="display: none;" class="modal">
<div class="modal-content">
<h3>Create Connection</h3>
<label>
Label:
<input type="text" id="connection-label" value="Read traffic">
</label>
<label>
Protocol:
<select id="connection-protocol">
<option>HTTP</option>
<option>HTTPS</option>
<option>gRPC</option>
<option>WebSocket</option>
<option>GraphQL</option>
<option>Kafka</option>
<option>AMQP</option>
<option>MQTT</option>
<option>SQL</option>
<option>NoSQL</option>
<option>Redis</option>
<option>TLS</option>
</select>
</label>
<label style="margin-top: 10px;">
<input type="checkbox" id="connection-tls">
Enable TLS (encryption)
</label>
<div class="modal-actions">
<button id="connection-save">Save</button>
<button id="connection-cancel">Cancel</button>
</div>
</div>
</div>
<div id="canvas-toolbar">
<button id="arrow-tool-btn" class="toolbar-btn">Arrow Tool</button>
</div>

Loading…
Cancel
Save