Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: implement BFS to get path between two nodes #23

Merged
merged 12 commits into from
Nov 9, 2024
62 changes: 31 additions & 31 deletions src/index.ejs
Original file line number Diff line number Diff line change
@@ -1,31 +1,31 @@
<!DOCTYPE html>
<html>
<head>
<title>
<%= htmlWebpackPlugin.options.title %>
</title>
</head>
<body>
<div id="top-bar">
<button id="save-button" class="save-button" title="Save">Save</button>
<button id="load-button" class="load-button" title="Load">Load</button>
<div id="app-title">GEduNet</div>
</div>
<div id="bottom-screen" class="row container">
<div id="left-bar" class="left-bar"></div>
<div class="canvas-container">
<canvas id="canvas"></canvas>
<select id="layer-select" class="dropdown-menu">
<option value="application">App Layer</option>
<option value="transport">Transport Layer</option>
<option value="network">Network Layer</option>
<option value="link">Link Layer</option>
</select>
</div>
<div id="right-bar" class="right-bar"></div>
</div>
</body>
</html>
<!DOCTYPE html>
<html>

<head>
<title>
<%= htmlWebpackPlugin.options.title %>
</title>
</head>

<body>
<div id="top-bar">
<button id="save-button" class="save-button" title="Save">Save</button>
<button id="load-button" class="load-button" title="Load">Load</button>
<div id="app-title">GEduNet</div>
</div>
<div id="bottom-screen" class="row container">
<div id="left-bar" class="left-bar"></div>
<div class="canvas-container">
<canvas id="canvas"></canvas>
<select id="layer-select" class="dropdown-menu">
<option value="application">App Layer</option>
<option value="transport">Transport Layer</option>
<option value="network">Network Layer</option>
<option value="link">Link Layer</option>
</select>
</div>
<div id="right-bar" class="right-bar"></div>
</div>
</body>

</html>
36 changes: 35 additions & 1 deletion src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -198,7 +198,7 @@ export class RightBar {
}
}

// Adds a specific button to the right-bar
// Adds a standard button to the right-bar
addButton(
text: string,
onClick: () => void,
Expand All @@ -216,6 +216,40 @@ export class RightBar {
};
this.rightBar.appendChild(button);
}

// Adds a select dropdown to the right-bar
addDropdown(
label: string,
options: { value: string; text: string }[],
onChange: (selectedValue: string) => void,
selectId?: string,
) {
const container = document.createElement("div");
container.classList.add("dropdown-container");

const labelElement = document.createElement("label");
labelElement.textContent = label;
labelElement.classList.add("right-bar-label");

const select = document.createElement("select");
select.classList.add("right-bar-select");
if (selectId) select.id = selectId; // Assigns ID if provided

options.forEach((optionData) => {
const option = document.createElement("option");
option.value = optionData.value;
option.textContent = optionData.text;
select.appendChild(option);
});

select.onchange = () => {
onChange(select.value);
};

container.appendChild(labelElement);
container.appendChild(select);
this.rightBar.appendChild(container);
}
}

// > index.ts
Expand Down
105 changes: 72 additions & 33 deletions src/style.css
Original file line number Diff line number Diff line change
Expand Up @@ -76,31 +76,6 @@ body {
object-fit: contain; /* Maintains image proportion without distortion */
}

/* Style for the right sidebar */
.right-bar {
flex: 0 0 250px; /* Fixed width of 250px for the right bar */
background-color: #f1f1f1; /* Light background for the bar */
box-shadow: -2px 0px 5px rgba(0, 0, 0, 0.2); /* Left shadow to highlight the bar */
padding: 20px; /* Internal space around content */
}

/* Title of the information section in the right bar */
.right-bar h2 {
text-align: center; /* Center the title horizontally */
margin: 0; /* Remove default margins */
padding-bottom: 15px; /* Space below the title */
font-size: 22px; /* Font size of the title */
font-weight: bold; /* Makes the title text thicker */
color: #333333; /* Dark gray text color */
}

/* Style for the information content in the right bar */
.info-content {
font-size: 15px; /* Adjust font size */
font-weight: bold; /* Makes the text thicker */
color: #333333; /* Dark gray text color */
}

/* Container for the canvas (central graphic) */
.canvas-container {
flex: 1; /* Canvas takes up the remaining space between bars */
Expand Down Expand Up @@ -146,27 +121,91 @@ canvas {
background-color: #357abd; /* Darker background on hover */
}

/* Style for the right sidebar */
.right-bar {
flex: 0 0 250px; /* Fixed width of 250px for the right bar */
background-color: #f1f1f1; /* Light background for the bar */
box-shadow: -2px 0px 5px rgba(0, 0, 0, 0.2); /* Left shadow to highlight the bar */
padding: 20px; /* Internal space around content */
}

/* Title of the information section in the right bar */
.right-bar h2 {
text-align: center; /* Center the title horizontally */
margin: 0; /* Remove default margins */
padding-bottom: 15px; /* Space below the title */
font-size: 22px; /* Font size of the title */
font-weight: bold; /* Makes the title text thicker */
color: #333333; /* Dark gray text color */
}

/* Style for the information content in the right bar */
.info-content {
font-size: 15px; /* Adjust font size */
font-weight: bold; /* Makes the text thicker */
color: #333333; /* Dark gray text color */
}

/* Style for buttons in the right bar */
.right-bar-button {
background-color: #4caf50; /* Background color */
background-color: #4caf50;
border: none;
color: white;
padding: 10px 20px;
padding: 6px 12px; /* Reduce padding */
text-align: center;
text-decoration: none;
display: inline-block;
font-size: 16px;
margin: 4px 2px;
font-size: 14px; /* Reduce font size */
margin: 3px 1px; /* Reduce margin */
cursor: pointer;
border-radius: 5px;
width: 200px; /* Fixed width */
border-radius: 4px;
width: 180px; /* Reduce width slightly */
}

.right-bar-button:hover {
background-color: #45a049; /* Color when hovering */
background-color: #45a049;
}

.right-bar-button.selected-button {
background-color: #007bff; /* Blue or your preferred color */
background-color: #007bff;
color: white;
}

/* Container for packet options */
.packet-options-container {
display: flex;
flex-direction: column;
gap: 8px; /* Reduce gap */
width: 100%;
margin-top: 8px; /* Reduce top margin */
}

/* Style for labels in the right bar */
.right-bar-label {
font-weight: bold;
margin-bottom: 2px; /* Reduce bottom margin */
font-size: 12px; /* Reduce font size */
color: #333333;
}

/* Style for dropdowns (selectors) */
.right-bar-select {
width: 100%;
padding: 6px; /* Reduce padding */
font-size: 14px; /* Reduce font size */
border-radius: 4px;
border: 1px solid #cccccc;
background-color: #f1f1f1;
cursor: pointer;
}

.right-bar-select:focus {
outline: none;
border-color: #007bff;
box-shadow: 0 0 4px rgba(0, 123, 255, 0.4); /* Slightly reduce shadow */
}

/* Optional: Style to make the entire dropdown area compact */
.dropdown-container {
margin-bottom: 8px; /* Reduce bottom margin */
}
91 changes: 77 additions & 14 deletions src/types/device.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { Texture, Sprite, FederatedPointerEvent, Graphics } from "pixi.js";
import RouterImage from "../assets/router.svg";
import ServerImage from "../assets/server.svg";
import PcImage from "../assets/pc.svg";
import { Packet } from "./packet";
import { ViewGraph } from "./graphs/viewgraph";
import {
deselectElement,
Expand Down Expand Up @@ -82,11 +83,40 @@ export class Device extends Sprite {
}

resize(sprite: Sprite): void {
// Setup the size of the new element
sprite.width = sprite.width / 70;
sprite.height = sprite.height / DEVICE_SIZE;
}

sendPacket(packetType: string, destinationId: number): void {
console.log(
`Sending ${packetType} packet from ${this.id} to ${destinationId}`,
);

const packetColors: Record<string, number> = {
IP: 0x0000ff, // Verde para paquetes IP
ICMP: 0xff0000, // Rojo para paquetes ICMP
};

const color = packetColors[packetType] || 0xffffff; // Color por defecto blanco
const speed = 200; // Velocidad en píxeles por segundo

const pathEdgeIds = this.viewgraph.getPathBetween(this.id, destinationId);

if (pathEdgeIds.length === 0) {
console.warn(
`No se encontró un camino entre ${this.id} y ${destinationId}.`,
);
return;
}

const pathEdges = pathEdgeIds.map((id) => this.viewgraph.getEdge(id));

const packet = new Packet(color, speed);
const stage = this.viewgraph.getViewport();
stage.addChild(packet);
packet.animateAlongPath(pathEdges, this.id);
}

deleteDevice(): void {
this.viewgraph.removeDevice(this.id);
// Clear connections
Expand Down Expand Up @@ -223,6 +253,52 @@ export class Device extends Sprite {
true,
);
this.rightbar.addButton("Delete device", () => this.deleteDevice());

// Dropdown for selecting packet type
this.rightbar.addDropdown(
"Packet Type",
[
{ value: "IP", text: "IP" },
{ value: "ICMP", text: "ICMP" },
],
(selectedValue) => {
console.log("Selected Packet Type:", selectedValue);
},
"packet-type",
);

// Dropdown for selecting destination
const adjacentDevices = this.viewgraph
.getDeviceIds()
.filter((id) => id !== this.id)
.map((id) => ({ value: id.toString(), text: `Device ${id}` }));

this.rightbar.addDropdown(
"Destination",
adjacentDevices,
(selectedValue) => {
console.log("Selected Destination:", selectedValue);
},
"destination",
);

// Button to send the packet
this.rightbar.addButton("Send Packet", () => {
// Get the selected packet type and destination ID
const packetType = (
document.getElementById("packet-type") as HTMLSelectElement
)?.value;
const destinationId = Number(
(document.getElementById("destination") as HTMLSelectElement)?.value,
);

// Call the sendPacket method with the selected values
if (packetType && !isNaN(destinationId)) {
this.sendPacket(packetType, destinationId);
} else {
console.warn("Please select both a packet type and a destination.");
}
});
}

showInfo() {
Expand Down Expand Up @@ -261,10 +337,6 @@ export class Router extends Device {
? "[" + Array.from(this.connections.values()).join(", ") + "]"
: "None",
},
{ label: "Model", value: "TP-Link AX6000" },
{ label: "IP Address", value: "192.168.1.1" },
{ label: "Firmware Version", value: "1.2.3" },
{ label: "Uptime", value: "5 days, 4 hours, 23 minutes" },
]);

this.addCommonButtons();
Expand Down Expand Up @@ -292,11 +364,6 @@ export class Server extends Device {
? "[" + Array.from(this.connections.values()).join(", ") + "]"
: "None",
},
{ label: "Operating System", value: "Ubuntu 20.04 LTS" },
{ label: "CPU Usage", value: "42%" },
{ label: "Memory Usage", value: "8 GB / 16 GB" },
{ label: "Disk Space", value: "500 GB / 1 TB" },
{ label: "Last Backup", value: "2024-11-01 02:30 AM" },
]);

this.addCommonButtons();
Expand Down Expand Up @@ -324,10 +391,6 @@ export class Pc extends Device {
? "[" + Array.from(this.connections.values()).join(", ") + "]"
: "None",
},
{ label: "Operating System", value: "Windows 10 Pro" },
{ label: "Antivirus Status", value: "Active" },
{ label: "IP Address", value: "192.168.1.100" },
{ label: "Storage Available", value: "250 GB / 512 GB" },
]);

this.addCommonButtons();
Expand Down
Loading