1
0
Fork 0
mirror of https://github.com/postmannen/ctrl.git synced 2025-03-31 01:24:31 +00:00
ctrl/webui/index.html
postmannen 5d99554c3b Initial Web UI, and TUI implementations :
NB: Breaking change, since the message format have changed.
Uses nats to communicate with ctrl, and nkeys for auth.
Supports the use of files as templates for scripts to run. The main source for the templates are the ./files directory on the node named central.
webUI: Settings are stored locally using Javascript localStorage.
shortcut ctrl+t to open the template menu for webui
2025-02-14 06:43:52 +01:00

228 lines
6.7 KiB
HTML

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Command Dashboard</title>
<link rel="stylesheet" href="styles.css" />
<style>
.popup {
display: none;
position: fixed;
z-index: 1000;
left: 0;
top: 0;
width: 100%;
height: 100%;
background-color: rgba(0, 0, 0, 0.5);
}
.popup-content {
background-color: #fefefe;
margin: 15% auto;
padding: 20px;
border: 1px solid #888;
width: 80%;
max-width: 600px;
position: relative;
}
.close-popup {
color: #aaa;
float: right;
font-size: 28px;
font-weight: bold;
cursor: pointer;
}
.close-popup:hover,
.close-popup:focus {
color: black;
text-decoration: none;
cursor: pointer;
}
</style>
</head>
<body>
<div class="hamburger-menu">
<div class="hamburger-icon">
<span></span>
<span></span>
<span></span>
</div>
</div>
<nav class="side-menu">
<a href="index.html" class="active">Command</a>
<a href="#" id="fileTemplatesLink">File Templates</a>
<a href="settings.html">Settings</a>
</nav>
<div class="split-container">
<div class="left-panel">
<form id="commandForm">
<div class="form-group">
<label for="toNodes">To Nodes (comma-separated):</label>
<input
type="text"
id="toNodes"
placeholder="btdev1, btdev2..."
value="btdev1"
/>
</div>
<div class="form-group">
<label for="jetstreamToNode">Jetstream To Node:</label>
<input type="text" id="jetstreamToNode" placeholder="btdev1" />
</div>
<div class="form-group">
<label for="useDetectedShell">Use Detected Shell:</label>
<select id="useDetectedShell">
<option value="false">false</option>
<option value="true">true</option>
</select>
</div>
<div class="form-group">
<label for="method">Method:</label>
<input type="text" id="method" value="cliCommand" />
</div>
<div class="form-group method-args">
<label>Method Arguments:</label>
<input
type="text"
class="method-arg"
placeholder="/bin/bash"
value="/bin/bash"
/>
<input type="text" class="method-arg" placeholder="-c" value="-c" />
<textarea
class="method-arg"
placeholder="Enter command here..."
value="ls -l"
></textarea>
</div>
<div class="form-group">
<label for="methodTimeout">Method Timeout (seconds):</label>
<input type="number" id="methodTimeout" value="3" />
</div>
<div class="form-group">
<label for="replyMethod">Reply Method:</label>
<input type="text" id="replyMethod" value="webUI" />
</div>
<div class="form-group">
<label for="ackTimeout">ACK Timeout:</label>
<input type="number" id="ackTimeout" value="0" />
</div>
<div class="button-group">
<button type="submit" id="sendBtn">Send</button>
<button type="submit" id="writeFileBtn">Write File</button>
<button type="button" id="generateBtn">Generate Command</button>
</div>
</form>
</div>
<div class="right-panel">
<textarea
id="outputArea"
readonly
placeholder="Command output will appear here..."
></textarea>
</div>
</div>
<div id="fileTemplatesPopup" class="popup">
<div class="popup-content">
<span class="close-popup">&times;</span>
<!-- Content will go here later -->
</div>
</div>
<script
src="https://cdn.jsdelivr.net/npm/nats@2.29.1/index.min.js"
type="module"
></script>
<script type="module" src="script.js"></script>
<script>
// Function to close menu
function closeMenu() {
document.body.classList.remove("menu-open");
}
// Toggle menu on hamburger click
document
.querySelector(".hamburger-menu")
.addEventListener("click", function (e) {
e.stopPropagation(); // Prevent click from immediately bubbling to document
document.body.classList.toggle("menu-open");
});
// Close menu when clicking outside
document.addEventListener("click", function (e) {
// If menu is open and click is outside the side-menu and hamburger-menu
if (
document.body.classList.contains("menu-open") &&
!e.target.closest(".side-menu") &&
!e.target.closest(".hamburger-menu")
) {
closeMenu();
}
});
// Close menu on Escape key
document.addEventListener("keydown", function (e) {
if (
e.key === "Escape" &&
document.body.classList.contains("menu-open")
) {
closeMenu();
}
});
// Prevent clicks on the menu itself from closing it
document
.querySelector(".side-menu")
.addEventListener("click", function (e) {
e.stopPropagation();
});
// File Templates popup functionality
const fileTemplatesLink = document.getElementById("fileTemplatesLink");
const fileTemplatesPopup = document.getElementById("fileTemplatesPopup");
const closePopup = document.querySelector(".close-popup");
fileTemplatesLink.addEventListener("click", function (e) {
e.preventDefault();
fileTemplatesPopup.style.display = "block";
closeMenu(); // Close the side menu when opening popup
});
closePopup.addEventListener("click", function () {
fileTemplatesPopup.style.display = "none";
});
// Close popup when clicking outside
window.addEventListener("click", function (e) {
if (e.target == fileTemplatesPopup) {
fileTemplatesPopup.style.display = "none";
}
});
// Add Escape key handler for popup
document.addEventListener("keydown", function (e) {
if (e.key === "Escape") {
if (fileTemplatesPopup.style.display === "block") {
fileTemplatesPopup.style.display = "none";
} else if (document.body.classList.contains("menu-open")) {
closeMenu();
}
}
});
</script>
</body>
</html>