CH-J Server ManagerSerververwaltung über SSH
Menü
Veröffentlichte Quellen

CH-J Server Manager

Durchsuchen Sie Verzeichnisse und Dateien einer bestimmten Anwendungsausgabe.

Quellen als ZIP herunterladen
CH-J / Server Manager 339 Dateien
core-20261014T184258Z-3fbed0b93fdf Hinzugefügt: Datum nicht erfasst · Erstellt:
Dateien
index.js Hinzugefügt: Datum nicht erfasst 3,8 KB · 73 Zeilen
Datei herunterladen
1"use strict";
3const api = window.chjPlugin;
4const elements = Object.fromEntries(["pluginVersion", "closeButton", "levelFilter", "searchInput", "refreshButton", "autoRefresh", "status", "visibleCount", "readTime", "fileSize", "logList", "recordTemplate"].map((id) => [id, document.querySelector(`#${id}`)]));
5let records = [];
6let busy = false;
8function bytes(value) {
9 const units = ["B", "KB", "MB", "GB"]; let amount = Number(value || 0); let unit = 0;
10 while (amount >= 1024 && unit < units.length - 1) { amount /= 1024; unit += 1; }
11 return `${amount.toLocaleString("cs-CZ", { maximumFractionDigits: 1 })} ${units[unit]}`;
14function parseLines(text) {
15 return String(text || "").split("\n").filter(Boolean).map((line) => {
16 try {
17 const value = JSON.parse(line);
18 return { timestamp: String(value.timestamp || ""), level: String(value.level || "info").toLowerCase(), message: String(value.message || ""), data: value.data ?? {} };
19 } catch { return { timestamp: "", level: "raw", message: line, data: null }; }
20 });
23function render() {
24 const level = elements.levelFilter.value;
25 const query = elements.searchInput.value.trim().toLocaleLowerCase("cs-CZ");
26 const visible = records.filter((record) => {
27 if (level !== "all" && record.level !== level) return false;
28 return !query || `${record.message} ${JSON.stringify(record.data)}`.toLocaleLowerCase("cs-CZ").includes(query);
29 });
30 const fragment = document.createDocumentFragment();
31 for (const record of visible) {
32 const node = elements.recordTemplate.content.cloneNode(true);
33 const article = node.querySelector(".record");
34 article.dataset.level = record.level;
35 node.querySelector(".level").textContent = record.level.toUpperCase();
36 node.querySelector("time").textContent = record.timestamp ? new Date(record.timestamp).toLocaleString("cs-CZ") : "bez času";
37 node.querySelector(".message").textContent = record.message;
38 const data = node.querySelector(".data");
39 const hasData = record.data && typeof record.data === "object" && Object.keys(record.data).length;
40 data.hidden = !hasData; data.textContent = hasData ? JSON.stringify(record.data, null, 2) : "";
41 fragment.append(node);
42 }
43 elements.logList.replaceChildren(fragment);
44 elements.visibleCount.textContent = String(visible.length);
45 if (!visible.length) elements.logList.textContent = records.length ? "Filtru neodpovídá žádný záznam." : "Log zatím neobsahuje žádné záznamy.";
48async function refresh() {
49 if (busy) return;
50 busy = true; elements.refreshButton.disabled = true; elements.status.textContent = "Načítám diagnostický log…"; elements.status.classList.remove("error");
51 try {
52 const result = await api.logs.read({ maxBytes: 1024 * 1024 });
53 records = parseLines(result.text);
54 elements.readTime.textContent = `Načteno ${new Date(result.readAt).toLocaleTimeString("cs-CZ")}`;
55 elements.fileSize.textContent = bytes(result.size);
56 elements.status.textContent = result.truncated ? "Zobrazen je poslední 1 MB logu." : "Log byl načten.";
57 render();
58 } catch (error) {
59 elements.status.textContent = error?.message || String(error); elements.status.classList.add("error");
60 } finally { busy = false; elements.refreshButton.disabled = false; }
63elements.closeButton.addEventListener("click", () => api.close());
64elements.refreshButton.addEventListener("click", refresh);
65elements.levelFilter.addEventListener("change", render);
66elements.searchInput.addEventListener("input", render);
67setInterval(() => { if (elements.autoRefresh.checked && !document.hidden) void refresh(); }, 5000);
69(async () => {
70 const info = await api.getInfo();
71 elements.pluginVersion.textContent = `${info.name} v${info.version} · ${info.publisher}`;
72 await refresh();
73})().catch((error) => { elements.status.textContent = error?.message || String(error); elements.status.classList.add("error"); });
SHA-256275532769bcea215cb7138eaec6ca7d9e8dd6e41906a16ca2d33d6ff3586c33f

CH-J Proprietary Software License 1.14 · Die Quellen werden unter der CH-J Proprietary Software License 1.14 bereitgestellt. Ihre Verfügbarkeit ändert die Lizenzbedingungen nicht und gewährt keine zusätzlichen Rechte.

SHA-256 des Archivs3df08cf5e899262a6ce92d7ec2caf5c42b683f1f2b57055662b845ff7dde67a8