Skip to content

Commit 62c5492

Browse files
committed
Device uplink, UI cleanup
1 parent cc3eb49 commit 62c5492

File tree

3 files changed

+139
-93
lines changed

3 files changed

+139
-93
lines changed

Protest/Front/grid.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -286,7 +286,7 @@ class Grid extends Window {
286286
dialog.cancelButton.disabled = true;
287287

288288
const url = (this instanceof DevicesGrid) ? "db/device/grid" : "db/user/grid";
289-
289+
290290
try {
291291
const response = await fetch(url, {
292292
method: "POST",

Protest/Front/topology.js

Lines changed: 108 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,8 @@ class Topology extends Window {
5050
this.SetupToolbar();
5151

5252
this.startButton = this.AddToolbarButton("Start discovery", "mono/play.svg?light");
53+
this.syncButton = this.AddToolbarButton("Save uplinks to Devices", "mono/upload.svg?light");
54+
this.syncButton.disabled = true;
5355
this.AddToolbarSeparator();
5456

5557
this.findButton = this.AddToolbarButton("Find", "mono/search.svg?light");
@@ -128,6 +130,7 @@ class Topology extends Window {
128130
this.content.onmouseup = event=> this.Topology_onmouseup(event);
129131

130132
this.startButton.onclick = ()=> this.StartDialog();
133+
this.syncButton.onclick = ()=> this.UpdateDeviceUplink();
131134
this.findButton.onclick = ()=> this.FindMode();
132135
this.vlanButton.onclick = ()=> this.VlanMode();
133136
this.trafficButton.onclick = ()=> this.TrafficMode();
@@ -492,6 +495,7 @@ class Topology extends Window {
492495
this.ws = new WebSocket(`${KEEP.isSecure ? "wss://" : "ws://"}${server}/ws/topology`);
493496

494497
this.ws.onopen = ()=> {
498+
this.syncButton.disabled = true;
495499
this.startButton.disabled = true;
496500
this.vlanButton.disabled = true;
497501
this.trafficButton.disabled = true;
@@ -500,6 +504,7 @@ class Topology extends Window {
500504
};
501505

502506
this.ws.onclose = ()=> {
507+
this.syncButton.disabled = false;
503508
this.startButton.disabled = false;
504509
this.startButton.setAttribute("tip-below", "Re-discover");
505510
this.startButton.style.backgroundImage = "url(mono/restart.svg?light)";
@@ -601,6 +606,7 @@ class Topology extends Window {
601606

602607
this.ws.onerror = ()=> {
603608
this.startButton.disabled = false;
609+
this.syncButton.disabled = false;
604610
};
605611
}
606612

@@ -2691,8 +2697,8 @@ class Topology extends Window {
26912697
updateDbButton.style.backgroundRepeat = "no-repeat";
26922698
updateDbButton.style.backgroundImage = "url(mono/upload.svg)";
26932699
optionsBox.appendChild(updateDbButton);
2694-
2695-
updateDbButton.onclick = ()=> this.UpdateDatabaseDialog(file);
2700+
2701+
updateDbButton.onclick = ()=> this.UpdateDeviceUplink(file);
26962702
}
26972703

26982704
const overwriteProtocol = {};
@@ -2894,97 +2900,126 @@ class Topology extends Window {
28942900
}
28952901
}
28962902

2897-
UpdateDatabaseDialog(file) {
2898-
const dialog = this.DialogBox("640px");
2903+
UpdateDeviceUplink(target="*") {
2904+
const dialog = this.DialogBox("calc(100% - 40px)");
28992905
if (dialog === null) return;
29002906

29012907
const {okButton, innerBox} = dialog;
29022908
okButton.value = "Sync database uplinks";
29032909

2904-
innerBox.parentElement.style.maxWidth = "640px";
2905-
2906-
innerBox.style.padding = "16px 32px";
2910+
innerBox.parentElement.style.maxWidth = "720px";
29072911

2908-
const device = this.devices[file];
2912+
innerBox.style.border = "2px solid var(--clr-control)";
2913+
innerBox.style.borderRadius = "4px";
2914+
innerBox.style.margin = "20px 20px 8px 20px";
29092915

29102916
const list = [];
2917+
2918+
for (const file in this.devices) {
2919+
if (target !== "*" && file !== target) continue;
29112920

2912-
for (const portIndex in device.lldp.localPortName) {
2913-
const portName = device.lldp.localPortName[portIndex] || portIndex;
2914-
2915-
const entry = device.lldp.entry[portIndex] || [device?.dot1tp?.entry[portIndex]];
2916-
if (!entry || entry.length === 0) continue;
2917-
2918-
for (let i=0; i<entry.length; i++) {
2919-
if (!entry[i]) continue;
2920-
2921-
const dbEntry = LOADER.devices.data[entry[i]];
2922-
2923-
let checked = true;
2924-
if ("type" in dbEntry && dbEntry.type.v.toLowerCase() === "switch") {
2925-
checked = false;
2926-
}
2927-
2928-
const newItem = document.createElement("div");
2929-
newItem.className = "topology-find-listitem";
2930-
newItem.style.paddingLeft = "4px";
2931-
newItem.style.overflow = "hidden";
2932-
innerBox.appendChild(newItem);
2933-
2934-
const toggle = this.CreateToggle(portName, checked, newItem);
2935-
toggle.label.style.marginRight = "12px";
2936-
toggle.label.style.marginTop = "4px";
2937-
toggle.label.style.width = "128px";
2938-
2939-
const deviceLabel = document.createElement("div");
2940-
deviceLabel.style.display = "inline-block";
2941-
deviceLabel.style.transform = "translateY(4px)";
2942-
deviceLabel.style.width = "calc(100% - 225px)";
2943-
deviceLabel.style.backgroundImage = "url(mono/gear.svg)";
2944-
deviceLabel.style.backgroundSize = "20px 20px";
2945-
deviceLabel.style.backgroundPosition = "2px 50%";
2946-
deviceLabel.style.backgroundRepeat = "no-repeat";
2947-
deviceLabel.style.paddingLeft = "28px";
2948-
deviceLabel.style.overflow = "hidden";
2949-
deviceLabel.style.textOverflow = "ellipsis";
2950-
deviceLabel.style.whiteSpace = "nowrap";
2951-
newItem.appendChild(deviceLabel);
2921+
const device = this.devices[file];
29522922

2953-
if ("hostname" in dbEntry && dbEntry.hostname.v.length > 0) {
2954-
deviceLabel.textContent = dbEntry.hostname.v;
2955-
}
2956-
else if ("name" in dbEntry && dbEntry.name.v.length > 0) {
2957-
deviceLabel.textContent = dbEntry.name.v;
2958-
}
2959-
else if ("mac address" in dbEntry && dbEntry["mac address"].v.length > 0) {
2960-
deviceLabel.textContent = dbEntry["mac address"].v;
2961-
}
2962-
else if ("ip" in dbEntry && dbEntry.ip.v.length > 0) {
2963-
deviceLabel.textContent = dbEntry.ip.v;
2964-
}
2923+
if (device.isUnmanaged) continue;
2924+
if (!device.lldp || device.lldp.localPortName === 0) continue;
29652925

2966-
if ("type" in dbEntry) {
2967-
const type = dbEntry.type.v.toLowerCase();
2968-
deviceLabel.style.backgroundImage = `url(${type in LOADER.deviceIcons ? LOADER.deviceIcons[type] : "mono/gear.svg"})`;
2969-
}
2926+
const switchBox = document.createElement("div");
2927+
switchBox.style.border = "2px solid var(--clr-control)";
2928+
switchBox.style.borderRadius = "4px";
2929+
switchBox.style.margin = "20px";
29702930

2971-
list.push({
2972-
toggle: toggle,
2973-
file : entry[i],
2974-
port : portName
2975-
});
2931+
const titleBox = document.createElement("div");
2932+
titleBox.textContent = device.initial.hostname;
2933+
titleBox.style.fontWeight = "bold";
2934+
titleBox.style.backgroundColor = "var(--clr-control)";
2935+
titleBox.style.padding = "4px";
29762936

2977-
newItem.onclick = ()=> {
2978-
toggle.checkbox.checked = !toggle.checkbox.checked;
2979-
};
2937+
const contentBox = document.createElement("div");
2938+
2939+
switchBox.append(titleBox, contentBox);
2940+
2941+
for (const portIndex in device.lldp.localPortName) {
2942+
const portName = device.lldp.localPortName[portIndex] || portIndex;
2943+
2944+
const entry = device.lldp.entry[portIndex] || [device?.dot1tp?.entry[portIndex]];
2945+
if (!entry || entry.length === 0) continue;
2946+
2947+
for (let i=0; i<entry.length; i++) {
2948+
if (!entry[i]) continue;
2949+
2950+
const dbEntry = LOADER.devices.data[entry[i]];
2951+
if (!dbEntry) continue;
2952+
2953+
let checked = true;
2954+
if ("type" in dbEntry && dbEntry.type.v.toLowerCase() === "switch") {
2955+
checked = false;
2956+
}
2957+
2958+
const newItem = document.createElement("div");
2959+
newItem.className = "topology-find-listitem";
2960+
newItem.style.paddingLeft = "4px";
2961+
newItem.style.overflow = "hidden";
2962+
contentBox.appendChild(newItem);
2963+
2964+
const toggle = this.CreateToggle(portName, checked, newItem);
2965+
toggle.label.style.marginRight = "12px";
2966+
toggle.label.style.marginTop = "4px";
2967+
toggle.label.style.width = "128px";
2968+
2969+
const deviceLabel = document.createElement("div");
2970+
deviceLabel.style.display = "inline-block";
2971+
deviceLabel.style.transform = "translateY(4px)";
2972+
deviceLabel.style.width = "calc(100% - 225px)";
2973+
deviceLabel.style.backgroundImage = "url(mono/gear.svg)";
2974+
deviceLabel.style.backgroundSize = "20px 20px";
2975+
deviceLabel.style.backgroundPosition = "2px 50%";
2976+
deviceLabel.style.backgroundRepeat = "no-repeat";
2977+
deviceLabel.style.paddingLeft = "28px";
2978+
deviceLabel.style.overflow = "hidden";
2979+
deviceLabel.style.textOverflow = "ellipsis";
2980+
deviceLabel.style.whiteSpace = "nowrap";
2981+
newItem.appendChild(deviceLabel);
2982+
2983+
if ("hostname" in dbEntry && dbEntry.hostname.v.length > 0) {
2984+
deviceLabel.textContent = dbEntry.hostname.v;
2985+
}
2986+
else if ("name" in dbEntry && dbEntry.name.v.length > 0) {
2987+
deviceLabel.textContent = dbEntry.name.v;
2988+
}
2989+
else if ("mac address" in dbEntry && dbEntry["mac address"].v.length > 0) {
2990+
deviceLabel.textContent = dbEntry["mac address"].v;
2991+
}
2992+
else if ("ip" in dbEntry && dbEntry.ip.v.length > 0) {
2993+
deviceLabel.textContent = dbEntry.ip.v;
2994+
}
2995+
2996+
if ("type" in dbEntry) {
2997+
const type = dbEntry.type.v.toLowerCase();
2998+
deviceLabel.style.backgroundImage = `url(${type in LOADER.deviceIcons ? LOADER.deviceIcons[type] : "mono/gear.svg"})`;
2999+
}
3000+
3001+
list.push({
3002+
toggle: toggle,
3003+
file : entry[i],
3004+
port : portName
3005+
});
3006+
3007+
newItem.onclick = ()=> {
3008+
toggle.checkbox.checked = !toggle.checkbox.checked;
3009+
};
3010+
}
3011+
}
3012+
3013+
if (contentBox.childNodes.length > 0) {
3014+
innerBox.appendChild(switchBox);
29803015
}
29813016
}
29823017

29833018
okButton.onclick = async ()=> {
29843019
const mods = {};
29853020
for (let i=0; i<list.length; i++) {
29863021
if (!list[i].toggle.checkbox.checked) continue;
2987-
3022+
29883023
mods[list[i].file] = {
29893024
uplink: JSON.stringify({
29903025
device: file,

Protest/Front/view.js

Lines changed: 30 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -324,37 +324,48 @@ class View extends Window {
324324

325325
valueBox.style.display = "none";
326326

327-
const deviceButton = document.createElement("input");
328-
deviceButton.type = "button";
329-
deviceButton.className = "with-icon";
330-
deviceButton.style.backgroundImage = "url(mono/switch.svg?light)";
327+
const deviceButton = document.createElement("button");
328+
deviceButton.style.height = "40px";
329+
deviceButton.style.paddingLeft = "4px";
330+
deviceButton.style.paddingRight = "4px";
331+
deviceButton.style.color = "var(--clr-dark)";
332+
deviceButton.style.backgroundColor = "transparent";
333+
deviceButton.style.whiteSpace = "nowrap";
331334
valueContainer.appendChild(deviceButton);
332335

336+
deviceButton.onclick = ()=> LOADER.OpenDeviceByFile(json.device);
337+
338+
const deviceBox = document.createElement("div");
339+
const portBox = document.createElement("div");
340+
deviceBox.style.marginRight = "4px";
341+
deviceBox.style.padding = portBox.style.padding = "6px 4px 6px 32px";
342+
deviceBox.style.display = portBox.style.display = "inline-block";
343+
deviceBox.style.backgroundSize = portBox.style.backgroundSize = "24px 24px";
344+
deviceBox.style.backgroundPosition = portBox.style.backgroundPosition = "4px 50%";
345+
deviceBox.style.backgroundRepeat = portBox.style.backgroundRepeat = "no-repeat";
346+
deviceBox.style.border = portBox.style.border = "1px solid var(--clr-dark)";
347+
deviceBox.style.borderRadius = portBox.style.borderRadius = "4px";
348+
349+
deviceButton.append(deviceBox, portBox);
350+
351+
deviceBox.style.backgroundImage = "url(mono/switch.svg)";
352+
333353
if (device.name && device.name.v.length > 0) {
334-
deviceButton.value = device.name.v;
354+
deviceBox.textContent = device.name.v;
335355
}
336356
else if (device.hostname && device.hostname.v.length > 0) {
337-
deviceButton.value = device.hostname.v;
357+
deviceBox.textContent = device.hostname.v;
338358
}
339359
else if (device.ip && device.ip.v.length > 0) {
340-
deviceButton.value = device.ip.v;
360+
deviceBox.textContent = device.ip.v;
341361
}
342362
else {
343-
deviceButton.value = "Device";
363+
deviceBox.textContent = "Device";
344364
}
345365

346-
const portButton = document.createElement("input");
347-
portButton.type = "button";
348-
portButton.className = "with-icon";
349-
portButton.style.backgroundImage = "url(mono/ethernetport.svg?light)";
350-
valueContainer.appendChild(portButton);
351-
352-
portButton.value = port;
366+
portBox.textContent = port;
367+
portBox.style.backgroundImage = "url(mono/ethernetport.svg)";
353368

354-
deviceButton.onclick = portButton.onclick = ()=> {
355-
const win = LOADER.OpenDeviceByFile(json.device);
356-
357-
};
358369
}
359370
catch (ex) {
360371
console.error(`uplink parse error: ${ex}`);

0 commit comments

Comments
 (0)