CH-J Toolsadministrasi server melalui SSH
Menu
Sumber yang diterbitkan

CH-J Tools

Jelajahi direktori dan file untuk rilis aplikasi tertentu.

Unduh ZIP sumber
CH-J / Server Manager 1704 file
0.1.2-beta Ditambahkan: · Dibuat:
index.js Ditambahkan: Tanggal tidak tercatat 4,2 KB · 78 baris
Kode Unduh file
1"use strict";
3const api = window.chjPlugin;
4const i18n = window.chjPluginI18n.createI18n("cs");
5const t = i18n.t;
6const elements = Object.fromEntries(["pluginVersion", "closeButton", "levelFilter", "searchInput", "refreshButton", "autoRefresh", "status", "visibleCount", "readTime", "fileSize", "logList", "recordTemplate"].map((id) => [id, document.querySelector(`#${id}`)]));
7let records = [];
8let busy = false;
10function bytes(value) {
11 const units = ["B", "KB", "MB", "GB"]; let amount = Number(value || 0); let unit = 0;
12 while (amount >= 1024 && unit < units.length - 1) { amount /= 1024; unit += 1; }
13 return `${amount.toLocaleString(i18n.locale(), { maximumFractionDigits: 1 })} ${units[unit]}`;
16function parseLines(text) {
17 return String(text || "").split("\n").filter(Boolean).map((line) => {
18 try {
19 const value = JSON.parse(line);
20 return { timestamp: String(value.timestamp || ""), level: String(value.level || "info").toLowerCase(), message: String(value.message || ""), data: value.data ?? {} };
21 } catch { return { timestamp: "", level: "raw", message: line, data: null }; }
22 });
25function render() {
26 const level = elements.levelFilter.value;
27 const query = elements.searchInput.value.trim().toLocaleLowerCase(i18n.locale());
28 const visible = records.filter((record) => {
29 if (level !== "all" && record.level !== level) return false;
30 return !query || `${record.message} ${JSON.stringify(record.data)}`.toLocaleLowerCase(i18n.locale()).includes(query);
31 });
32 const fragment = document.createDocumentFragment();
33 for (const record of visible) {
34 const node = elements.recordTemplate.content.cloneNode(true);
35 const article = node.querySelector(".record");
36 article.dataset.level = record.level;
37 node.querySelector(".level").textContent = record.level.toUpperCase();
38 node.querySelector("time").textContent = record.timestamp ? new Date(record.timestamp).toLocaleString(i18n.locale()) : t("bez času");
39 node.querySelector(".message").textContent = record.message;
40 const data = node.querySelector(".data");
41 const hasData = record.data && typeof record.data === "object" && Object.keys(record.data).length;
42 data.hidden = !hasData; data.textContent = hasData ? JSON.stringify(record.data, null, 2) : "";
43 fragment.append(node);
44 }
45 elements.logList.replaceChildren(fragment);
46 elements.visibleCount.textContent = String(visible.length);
47 if (!visible.length) elements.logList.textContent = records.length ? t("Filtru neodpovídá žádný záznam.") : t("Log zatím neobsahuje žádné záznamy.");
50async function refresh() {
51 if (busy) return;
52 busy = true; elements.refreshButton.disabled = true; elements.status.textContent = t("Načítám diagnostický log…"); elements.status.classList.remove("error");
53 try {
54 const result = await api.logs.read({ maxBytes: 1024 * 1024 });
55 records = parseLines(result.text);
56 elements.readTime.textContent = t("Načteno {time}", { time: new Date(result.readAt).toLocaleTimeString(i18n.locale()) });
57 elements.fileSize.textContent = bytes(result.size);
58 elements.status.textContent = result.truncated ? t("Zobrazen je poslední 1 MB logu.") : t("Log byl načten.");
59 render();
60 } catch (error) {
61 elements.status.textContent = error?.message || String(error); elements.status.classList.add("error");
62 } finally { busy = false; elements.refreshButton.disabled = false; }
65elements.closeButton.addEventListener("click", () => api.close());
66elements.refreshButton.addEventListener("click", refresh);
67elements.levelFilter.addEventListener("change", render);
68elements.searchInput.addEventListener("input", render);
69setInterval(() => { if (elements.autoRefresh.checked && !document.hidden) void refresh(); }, 5000);
71(async () => {
72 try { i18n.setLanguage(await api.ui.getLanguage()); } catch {}
73 i18n.apply(document);
74 api.ui.onLanguageChanged((language) => { i18n.setLanguage(language); i18n.apply(document); void refresh(); });
75 const info = await api.getInfo();
76 elements.pluginVersion.textContent = `${info.name} v${info.version} · ${info.publisher}`;
77 await refresh();
78})().catch((error) => { elements.status.textContent = error?.message || String(error); elements.status.classList.add("error"); });
SHA-256b8df7230a6a5243bf74fa110f643cc9d43a57648b5385cb7f1ad99127df21124

CH-J Proprietary Software License 1.14 · Kode sumber disediakan berdasarkan CH-J Proprietary Software License 1.14. Ketersediaannya tidak mengubah ketentuan lisensi atau memberikan hak tambahan.

SHA-256 arsipac8fe790f4ba60fc098f8c985fc2656cfcc6cdc21fb34b30e308a2b54e62258f
File