Skip to content

Commit c6232c2

Browse files
MegaRedHandV-SANTpgallino
authored
feat: implement BFS to get path between two nodes (#23)
Closes #18 --------- Co-authored-by: V-SANT <[email protected]> Co-authored-by: pgallino <[email protected]>
1 parent ed52dc3 commit c6232c2

File tree

13 files changed

+780
-93
lines changed

13 files changed

+780
-93
lines changed

src/index.ejs

Lines changed: 31 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,31 @@
1-
<!DOCTYPE html>
2-
<html>
3-
4-
<head>
5-
<title>
6-
<%= htmlWebpackPlugin.options.title %>
7-
</title>
8-
</head>
9-
10-
<body>
11-
<div id="top-bar">
12-
<button id="save-button" class="save-button" title="Save">Save</button>
13-
<button id="load-button" class="load-button" title="Load">Load</button>
14-
<div id="app-title">GEduNet</div>
15-
</div>
16-
<div id="bottom-screen" class="row container">
17-
<div id="left-bar" class="left-bar"></div>
18-
<div class="canvas-container">
19-
<canvas id="canvas"></canvas>
20-
<select id="layer-select" class="dropdown-menu">
21-
<option value="application">App Layer</option>
22-
<option value="transport">Transport Layer</option>
23-
<option value="network">Network Layer</option>
24-
<option value="link">Link Layer</option>
25-
</select>
26-
</div>
27-
<div id="right-bar" class="right-bar"></div>
28-
</div>
29-
</body>
30-
31-
</html>
1+
<!DOCTYPE html>
2+
<html>
3+
4+
<head>
5+
<title>
6+
<%= htmlWebpackPlugin.options.title %>
7+
</title>
8+
</head>
9+
10+
<body>
11+
<div id="top-bar">
12+
<button id="save-button" class="save-button" title="Save">Save</button>
13+
<button id="load-button" class="load-button" title="Load">Load</button>
14+
<div id="app-title">GEduNet</div>
15+
</div>
16+
<div id="bottom-screen" class="row container">
17+
<div id="left-bar" class="left-bar"></div>
18+
<div class="canvas-container">
19+
<canvas id="canvas"></canvas>
20+
<select id="layer-select" class="dropdown-menu">
21+
<option value="application">App Layer</option>
22+
<option value="transport">Transport Layer</option>
23+
<option value="network">Network Layer</option>
24+
<option value="link">Link Layer</option>
25+
</select>
26+
</div>
27+
<div id="right-bar" class="right-bar"></div>
28+
</div>
29+
</body>
30+
31+
</html>

src/index.ts

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -198,7 +198,7 @@ export class RightBar {
198198
}
199199
}
200200

201-
// Adds a specific button to the right-bar
201+
// Adds a standard button to the right-bar
202202
addButton(
203203
text: string,
204204
onClick: () => void,
@@ -216,6 +216,40 @@ export class RightBar {
216216
};
217217
this.rightBar.appendChild(button);
218218
}
219+
220+
// Adds a select dropdown to the right-bar
221+
addDropdown(
222+
label: string,
223+
options: { value: string; text: string }[],
224+
onChange: (selectedValue: string) => void,
225+
selectId?: string,
226+
) {
227+
const container = document.createElement("div");
228+
container.classList.add("dropdown-container");
229+
230+
const labelElement = document.createElement("label");
231+
labelElement.textContent = label;
232+
labelElement.classList.add("right-bar-label");
233+
234+
const select = document.createElement("select");
235+
select.classList.add("right-bar-select");
236+
if (selectId) select.id = selectId; // Assigns ID if provided
237+
238+
options.forEach((optionData) => {
239+
const option = document.createElement("option");
240+
option.value = optionData.value;
241+
option.textContent = optionData.text;
242+
select.appendChild(option);
243+
});
244+
245+
select.onchange = () => {
246+
onChange(select.value);
247+
};
248+
249+
container.appendChild(labelElement);
250+
container.appendChild(select);
251+
this.rightBar.appendChild(container);
252+
}
219253
}
220254

221255
// > index.ts

src/style.css

Lines changed: 72 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -76,31 +76,6 @@ body {
7676
object-fit: contain; /* Maintains image proportion without distortion */
7777
}
7878

79-
/* Style for the right sidebar */
80-
.right-bar {
81-
flex: 0 0 250px; /* Fixed width of 250px for the right bar */
82-
background-color: #f1f1f1; /* Light background for the bar */
83-
box-shadow: -2px 0px 5px rgba(0, 0, 0, 0.2); /* Left shadow to highlight the bar */
84-
padding: 20px; /* Internal space around content */
85-
}
86-
87-
/* Title of the information section in the right bar */
88-
.right-bar h2 {
89-
text-align: center; /* Center the title horizontally */
90-
margin: 0; /* Remove default margins */
91-
padding-bottom: 15px; /* Space below the title */
92-
font-size: 22px; /* Font size of the title */
93-
font-weight: bold; /* Makes the title text thicker */
94-
color: #333333; /* Dark gray text color */
95-
}
96-
97-
/* Style for the information content in the right bar */
98-
.info-content {
99-
font-size: 15px; /* Adjust font size */
100-
font-weight: bold; /* Makes the text thicker */
101-
color: #333333; /* Dark gray text color */
102-
}
103-
10479
/* Container for the canvas (central graphic) */
10580
.canvas-container {
10681
flex: 1; /* Canvas takes up the remaining space between bars */
@@ -146,27 +121,91 @@ canvas {
146121
background-color: #357abd; /* Darker background on hover */
147122
}
148123

124+
/* Style for the right sidebar */
125+
.right-bar {
126+
flex: 0 0 250px; /* Fixed width of 250px for the right bar */
127+
background-color: #f1f1f1; /* Light background for the bar */
128+
box-shadow: -2px 0px 5px rgba(0, 0, 0, 0.2); /* Left shadow to highlight the bar */
129+
padding: 20px; /* Internal space around content */
130+
}
131+
132+
/* Title of the information section in the right bar */
133+
.right-bar h2 {
134+
text-align: center; /* Center the title horizontally */
135+
margin: 0; /* Remove default margins */
136+
padding-bottom: 15px; /* Space below the title */
137+
font-size: 22px; /* Font size of the title */
138+
font-weight: bold; /* Makes the title text thicker */
139+
color: #333333; /* Dark gray text color */
140+
}
141+
142+
/* Style for the information content in the right bar */
143+
.info-content {
144+
font-size: 15px; /* Adjust font size */
145+
font-weight: bold; /* Makes the text thicker */
146+
color: #333333; /* Dark gray text color */
147+
}
148+
149149
/* Style for buttons in the right bar */
150150
.right-bar-button {
151-
background-color: #4caf50; /* Background color */
151+
background-color: #4caf50;
152152
border: none;
153153
color: white;
154-
padding: 10px 20px;
154+
padding: 6px 12px; /* Reduce padding */
155155
text-align: center;
156156
text-decoration: none;
157157
display: inline-block;
158-
font-size: 16px;
159-
margin: 4px 2px;
158+
font-size: 14px; /* Reduce font size */
159+
margin: 3px 1px; /* Reduce margin */
160160
cursor: pointer;
161-
border-radius: 5px;
162-
width: 200px; /* Fixed width */
161+
border-radius: 4px;
162+
width: 180px; /* Reduce width slightly */
163163
}
164164

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

169169
.right-bar-button.selected-button {
170-
background-color: #007bff; /* Blue or your preferred color */
170+
background-color: #007bff;
171171
color: white;
172172
}
173+
174+
/* Container for packet options */
175+
.packet-options-container {
176+
display: flex;
177+
flex-direction: column;
178+
gap: 8px; /* Reduce gap */
179+
width: 100%;
180+
margin-top: 8px; /* Reduce top margin */
181+
}
182+
183+
/* Style for labels in the right bar */
184+
.right-bar-label {
185+
font-weight: bold;
186+
margin-bottom: 2px; /* Reduce bottom margin */
187+
font-size: 12px; /* Reduce font size */
188+
color: #333333;
189+
}
190+
191+
/* Style for dropdowns (selectors) */
192+
.right-bar-select {
193+
width: 100%;
194+
padding: 6px; /* Reduce padding */
195+
font-size: 14px; /* Reduce font size */
196+
border-radius: 4px;
197+
border: 1px solid #cccccc;
198+
background-color: #f1f1f1;
199+
cursor: pointer;
200+
}
201+
202+
.right-bar-select:focus {
203+
outline: none;
204+
border-color: #007bff;
205+
box-shadow: 0 0 4px rgba(0, 123, 255, 0.4); /* Slightly reduce shadow */
206+
}
207+
208+
/* Optional: Style to make the entire dropdown area compact */
209+
.dropdown-container {
210+
margin-bottom: 8px; /* Reduce bottom margin */
211+
}

src/types/device.ts

Lines changed: 77 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { Texture, Sprite, FederatedPointerEvent, Graphics } from "pixi.js";
22
import RouterImage from "../assets/router.svg";
33
import ServerImage from "../assets/server.svg";
44
import PcImage from "../assets/pc.svg";
5+
import { Packet } from "./packet";
56
import { ViewGraph } from "./graphs/viewgraph";
67
import {
78
deselectElement,
@@ -82,11 +83,40 @@ export class Device extends Sprite {
8283
}
8384

8485
resize(sprite: Sprite): void {
85-
// Setup the size of the new element
8686
sprite.width = sprite.width / 70;
8787
sprite.height = sprite.height / DEVICE_SIZE;
8888
}
8989

90+
sendPacket(packetType: string, destinationId: number): void {
91+
console.log(
92+
`Sending ${packetType} packet from ${this.id} to ${destinationId}`,
93+
);
94+
95+
const packetColors: Record<string, number> = {
96+
IP: 0x0000ff, // Verde para paquetes IP
97+
ICMP: 0xff0000, // Rojo para paquetes ICMP
98+
};
99+
100+
const color = packetColors[packetType] || 0xffffff; // Color por defecto blanco
101+
const speed = 200; // Velocidad en píxeles por segundo
102+
103+
const pathEdgeIds = this.viewgraph.getPathBetween(this.id, destinationId);
104+
105+
if (pathEdgeIds.length === 0) {
106+
console.warn(
107+
`No se encontró un camino entre ${this.id} y ${destinationId}.`,
108+
);
109+
return;
110+
}
111+
112+
const pathEdges = pathEdgeIds.map((id) => this.viewgraph.getEdge(id));
113+
114+
const packet = new Packet(color, speed);
115+
const stage = this.viewgraph.getViewport();
116+
stage.addChild(packet);
117+
packet.animateAlongPath(pathEdges, this.id);
118+
}
119+
90120
deleteDevice(): void {
91121
this.viewgraph.removeDevice(this.id);
92122
// Clear connections
@@ -223,6 +253,52 @@ export class Device extends Sprite {
223253
true,
224254
);
225255
this.rightbar.addButton("Delete device", () => this.deleteDevice());
256+
257+
// Dropdown for selecting packet type
258+
this.rightbar.addDropdown(
259+
"Packet Type",
260+
[
261+
{ value: "IP", text: "IP" },
262+
{ value: "ICMP", text: "ICMP" },
263+
],
264+
(selectedValue) => {
265+
console.log("Selected Packet Type:", selectedValue);
266+
},
267+
"packet-type",
268+
);
269+
270+
// Dropdown for selecting destination
271+
const adjacentDevices = this.viewgraph
272+
.getDeviceIds()
273+
.filter((id) => id !== this.id)
274+
.map((id) => ({ value: id.toString(), text: `Device ${id}` }));
275+
276+
this.rightbar.addDropdown(
277+
"Destination",
278+
adjacentDevices,
279+
(selectedValue) => {
280+
console.log("Selected Destination:", selectedValue);
281+
},
282+
"destination",
283+
);
284+
285+
// Button to send the packet
286+
this.rightbar.addButton("Send Packet", () => {
287+
// Get the selected packet type and destination ID
288+
const packetType = (
289+
document.getElementById("packet-type") as HTMLSelectElement
290+
)?.value;
291+
const destinationId = Number(
292+
(document.getElementById("destination") as HTMLSelectElement)?.value,
293+
);
294+
295+
// Call the sendPacket method with the selected values
296+
if (packetType && !isNaN(destinationId)) {
297+
this.sendPacket(packetType, destinationId);
298+
} else {
299+
console.warn("Please select both a packet type and a destination.");
300+
}
301+
});
226302
}
227303

228304
showInfo() {
@@ -261,10 +337,6 @@ export class Router extends Device {
261337
? "[" + Array.from(this.connections.values()).join(", ") + "]"
262338
: "None",
263339
},
264-
{ label: "Model", value: "TP-Link AX6000" },
265-
{ label: "IP Address", value: "192.168.1.1" },
266-
{ label: "Firmware Version", value: "1.2.3" },
267-
{ label: "Uptime", value: "5 days, 4 hours, 23 minutes" },
268340
]);
269341

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

302369
this.addCommonButtons();
@@ -324,10 +391,6 @@ export class Pc extends Device {
324391
? "[" + Array.from(this.connections.values()).join(", ") + "]"
325392
: "None",
326393
},
327-
{ label: "Operating System", value: "Windows 10 Pro" },
328-
{ label: "Antivirus Status", value: "Active" },
329-
{ label: "IP Address", value: "192.168.1.100" },
330-
{ label: "Storage Available", value: "250 GB / 512 GB" },
331394
]);
332395

333396
this.addCommonButtons();

0 commit comments

Comments
 (0)