--wip-- [skip ci]

This commit is contained in:
2026-03-22 18:19:12 +01:00
parent fdf0e65e22
commit 4eb5a4d7db
11 changed files with 1200 additions and 34 deletions

View File

@@ -1,6 +1,8 @@
# -*- coding: utf-8 -*-
from __future__ import annotations
import logging as lg
import subprocess
def main() -> None:
@@ -11,6 +13,19 @@ def main() -> None:
format="%(asctime)s : [%(levelname)s] : %(threadName)s : %(name)s :: %(message)s",
)
_ = subprocess.Popen(
[
"npx",
"tailwindcss",
"-i",
"input.css",
"-o",
"../src/judas_web/static/css/dist/tailwind.css",
"--watch",
],
cwd="tailwind/",
)
web_server = WebServer("http://127.0.0.1:8000/api/v1", "supersecretkey")
web_server.run(debug=True, host="0.0.0.0", port=5000)

View File

@@ -9,27 +9,50 @@ $(document).ready(function () {
}, 3000);
};
const loadClientDetails = (clientId) => {
fetch(`/client/${clientId}`)
.then((response) => response.text())
.then((html) => {
$("#content").html(html);
})
.catch((error) => {
console.error("Error fetching client details:", error);
});
};
// load client_details for the client specified in the URL
const urlParams = new URLSearchParams(window.location.search);
const clientId = urlParams.get("client");
if (clientId) {
loadClientDetails(clientId);
// loadClientDetails(clientId);
$(`#client-list a[href="?client=${clientId}"]`).addClass("active");
}
$("#notify").hide();
// Show the correct nav item and panel by default based on GET param
const urlParamsPanel = new URLSearchParams(window.location.search);
const panelParam = urlParamsPanel.get("panel");
let navItems = $("#panel-content > nav > ul > li");
let panelToShow = panelParam;
let navToActivate = null;
if (panelToShow) {
navToActivate = navItems.filter(`[panel='${panelToShow}']`).first();
}
if (!navToActivate || navToActivate.length === 0) {
navToActivate = navItems.first();
panelToShow = navToActivate.attr("panel");
}
navItems.removeClass("bg-ctp-surface0");
navToActivate.addClass("bg-ctp-surface0");
$(".panels").addClass("hidden");
if (panelToShow) {
$(`#${panelToShow}`).removeClass("hidden");
}
navItems.on("click", function (e) {
navItems.removeClass("bg-ctp-surface0");
$(this).addClass("bg-ctp-surface0");
$(".panels").addClass("hidden");
const panelToShow = $(this).attr("panel");
$(`#${panelToShow}`).removeClass("hidden");
// Update the URL GET params with the selected panel
const urlParams = new URLSearchParams(window.location.search);
urlParams.set("panel", panelToShow);
const newUrl = `${window.location.pathname}?${urlParams.toString()}`;
window.history.pushState({ path: newUrl }, "", newUrl);
});
socket.on("connect", () => {
console.log("Connected to server");
$("#no-connection-message").hide();
@@ -159,7 +182,7 @@ $(document).ready(function () {
clientId = clientId.replace("client=", "");
loadClientDetails(clientId);
// loadClientDetails(clientId);
$("#client-list a").removeClass("bg-ctp-surface0");
$(this).addClass("bg-ctp-surface0");
e.preventDefault();
@@ -167,5 +190,17 @@ $(document).ready(function () {
let newUrl = `${window.location.pathname}?client=${clientId}`;
window.history.pushState({ path: newUrl }, "", newUrl);
});
// update client details panel
if (clientId) {
const client = data.clients[clientId];
if (client) {
$("#client-hostname").text(client.initial_telemetry.platform.node);
$("#client-status").text(client.status);
$("#client-last_seen").text(
new Date(client.last_seen * 1000).toLocaleString(),
);
}
}
});
});

View File

@@ -4,10 +4,8 @@
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>{% block title %}{% endblock %} judas</title>
<link
rel="stylesheet"
href="{{ url_for('static', filename='css/style.css') }}"
/>
<link rel="stylesheet" href="{{ url_for('static', filename='css/dist/tailwind.css') }}" />
<link rel="stylesheet" href="https://cdn-uicons.flaticon.com/2.6.0/uicons-regular-rounded/css/uicons-regular-rounded.css" />
<link rel="stylesheet" href="https://cdn-uicons.flaticon.com/2.6.0/uicons-regular-straight/css/uicons-regular-straight.css" />
<link rel="stylesheet" href="https://cdn-uicons.flaticon.com/2.6.0/uicons-solid-rounded/css/uicons-solid-rounded.css" />
@@ -29,10 +27,12 @@
});
</script>
</head>
<body>
<body class="bg-ctp-base text-ctp-text min-h-screen flex flex-col {% block body_class %}{% endblock %}">
{% include "base/header.html" %}
<!-- -->
<div id="content" class="flex flex-col grow {% block content_class %}{% endblock %}">
{% block content %}{% endblock %}
</div>
<!-- -->
{% block scripts %}{% endblock %}
</body>

View File

@@ -8,6 +8,6 @@
{% if current_user.is_authenticated %}
<a class="btn-primary" href="{{ url_for('auth.logout') }}">Logout</a>
{% else %}
<a class="button" href="{{ url_for('auth.login') }}">Login</a>
<a class="btn-primary" href="{{ url_for('auth.login') }}">Login</a>
{% endif %}
</header>

View File

@@ -2,20 +2,22 @@
{% block title %}home{% endblock %}
{% block content_class %}
text-center gap-2
{% endblock content_class %}
{% block content %}
<div id="content" class="center">
<div style="margin-top: 2rem">
<div class="mt-16">
<p>Welcome to</p>
<h2 id="typing-text" style="font-size: 3rem">judas</h2>
<h2 id="typing-text" class="my-2 text-6xl font-mono font-bold">judas</h2>
<p>a remote PC fleet management system</p>
</div>
<p style="color: var(--ctp-red)"><strong>Notice:</strong> Please use this system responsibly and in accordance with all applicable laws and organizational policies.</p>
{% if logged %}
<p><a class="button" href="{{ url_for('panel.panel') }}">Go to panel</a></p>
{% else %}
<p>Please <a href="{{ url_for('auth.login')}}" class="link">log in</a> to manage your remote PCs.</p>
{% endif %}
</div>
<p class="text-ctp-red"><strong>Notice:</strong> Please use this system responsibly and in accordance with all applicable laws and organizational policies.</p>
{% if logged %}
<p><a class="btn-primary" href="{{ url_for('panel.panel') }}">Go to panel</a></p>
{% else %}
<p>Please <a href="{{ url_for('auth.login')}}" class="link">log in</a> to manage your remote PCs.</p>
{% endif %}
{% endblock %}
{% block scripts %}

View File

@@ -4,10 +4,32 @@
{% block content %}
<main class="flex grow h-full">
<aside class="border-r-4 border-r-ctp-mantle">
<aside class="border-r-4 border-r-ctp-mantle w-80">
<ul id="client-list"></ul>
</aside>
<div id="content" class="grow"></div>
<div id="panel-content" class="flex flex-row grow">
<nav class="border-r-4 border-r-ctp-mantle">
<ul>
<li class="px-4 py-2 hover:bg-ctp-mantle cursor-pointer" panel="summary">Summary</li>
<li class="px-4 py-2 hover:bg-ctp-mantle cursor-pointer" panel="settings">Settings</li>
</ul>
</nav>
<div id="summary" class="panels hidden grow p-4">
<h1 class="text-2xl font-bold mb-4">Summary</h1>
<div class="flex grow flex-col gap-4">
<div class="flex items-center justify-between">
<h2 class="text-xl font-semibold"><span id="client-hostname"></span> (<span id="client-status"></span>)</h2>
<h2 class="text-xl font-semibold">Last seen: <span id="client-last_seen"></span></h2>
</div>
</div>
</div>
<div id="settings" class="panels hidden">
<h1 class="text-2xl font-bold mb-4">Settings</h1>
<div class="flex flex-col gap-4">
<!-- Settings content will be dynamically inserted here -->
</div>
</div>
</div>
</main>
{% endblock %}

1
tailwind/.gitignore vendored Normal file
View File

@@ -0,0 +1 @@
node_modules/

37
tailwind/input.css Normal file
View File

@@ -0,0 +1,37 @@
@import "tailwindcss";
@source "../src/judas_web/templates/**/*.html";
@source "../src/judas_web/static/js/**/*.js";
.btn-primary {
@apply px-2 py-1 rounded text-sm font-medium text-ctp-base bg-ctp-blue hover:bg-ctp-lavender active:bg-ctp-sapphire;
}
@theme {
--color-ctp-rosewater: #f5e0dc;
--color-ctp-flamingo: #f2cdcd;
--color-ctp-pink: #f5c2e7;
--color-ctp-mauve: #cba6f7;
--color-ctp-red: #f38ba8;
--color-ctp-maroon: #eba0ac;
--color-ctp-peach: #fab387;
--color-ctp-yellow: #f9e2af;
--color-ctp-green: #a6e3a1;
--color-ctp-teal: #94e2d5;
--color-ctp-sky: #89dceb;
--color-ctp-sapphire: #74c7ec;
--color-ctp-blue: #89b4fa;
--color-ctp-lavender: #b4befe;
--color-ctp-text: #cdd6f4;
--color-ctp-subtext1: #bac2de;
--color-ctp-subtext0: #a6adc8;
--color-ctp-overlay2: #9399b2;
--color-ctp-overlay1: #7f849c;
--color-ctp-overlay0: #6c7086;
--color-ctp-surface2: #585b70;
--color-ctp-surface1: #45475a;
--color-ctp-surface0: #313244;
--color-ctp-base: #1e1e2e;
--color-ctp-mantle: #181825;
--color-ctp-crust: #11111b;
}

1037
tailwind/package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

17
tailwind/package.json Normal file
View File

@@ -0,0 +1,17 @@
{
"name": "tailwind",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "",
"license": "ISC",
"type": "commonjs",
"dependencies": {
"@tailwindcss/cli": "^4.2.1",
"tailwindcss": "^4.2.1"
}
}