Fonte publicada
Transferir fonte ZIP
CH-J Tools
Navegue por diretórios e arquivos para uma versão específica do aplicativo.
CH-J / Server Manager
872 arquivos
core-20261030T220507Z-61e4558d889f
Adicionado: · Construído:
1
/** Read-only view of the Core SSH sessions (permission `session.read`). */2
import { call } from "../transport";3
import type { SessionStatus } from "../types";5
export function displayName(session: SessionStatus): string {6
return (session.adhoc ? session.label : `${session.label} — ${session.username}@${session.host}`)7
+ (session.slot ? ` · T${session.slot}` : "")8
+ (session.jump?.length ? ` ⇢ ${session.jump[0].host}` : "");9
}11
export function reconcile(previousId: string, list: readonly SessionStatus[]): { id: string; reason: "keep" | "gone" | "auto" | "choose" } {12
const connected = list.filter((session) => session.state === "connected");13
if (previousId) return connected.some((session) => session.sessionId === previousId)14
? { id: previousId, reason: "keep" } : { id: "", reason: "gone" };15
return connected.length === 1 ? { id: connected[0].sessionId, reason: "auto" } : { id: "", reason: "choose" };16
}18
let askedFor = "";20
/**21
* Several connections and none chosen: asks once which one the module should use.22
* Asks again only when the set of connections changes; closing the dialog leaves the menu as it is.23
*/24
export function offerChoice(select: HTMLSelectElement, list: readonly SessionStatus[], title: string): void {25
const connected = list.filter((session) => session.state === "connected");26
const key = connected.map((session) => session.sessionId).sort().join("|");27
if (connected.length < 2 || select.value || key === askedFor || document.querySelector("dialog[open]")) return;28
askedFor = key;29
const dialog = document.createElement("dialog");30
dialog.style.cssText = "min-width:340px;max-width:560px;padding:18px;border:1px solid rgba(151,183,218,.25);border-radius:12px;color:#edf6ff;background:#0c1a2a";31
const heading = document.createElement("div");32
heading.textContent = title;33
heading.style.cssText = "margin-bottom:12px;font-size:14px;font-weight:600";34
dialog.append(heading);35
for (const session of connected) {36
const button = document.createElement("button");37
button.type = "button";38
button.textContent = displayName(session);39
button.style.cssText = "display:block;width:100%;margin-top:6px;padding:10px 12px;border:1px solid rgba(151,183,218,.25);border-radius:8px;color:inherit;background:rgba(255,255,255,.04);text-align:start;font:inherit;cursor:pointer";40
button.addEventListener("click", () => {41
dialog.close();42
if (!select.value && [...select.options].some((option) => option.value === session.sessionId)) {43
select.value = session.sessionId;44
select.dispatchEvent(new Event("change", { bubbles: true }));45
}46
});47
dialog.append(button);48
}49
dialog.addEventListener("close", () => dialog.remove());50
document.body.append(dialog);51
dialog.showModal();52
}54
export const sessions = Object.freeze({55
list: () => call<SessionStatus[]>("module_sessions_list", "plugin:sessions:list"),56
displayName,57
reconcile,58
offerChoice59
});SHA-256
215cc995a49109085297dc57f0220bfb1abc1e5007374085eceabdab9a902793CH-J Proprietary Software License 1.14 · A fonte é fornecida sob o CH-J Proprietary Software License 1.14. A sua disponibilidade não altera os termos licença nem concede direitos adicionais.
Ficheiro SHA-256
77380d4805485ffa4027fbe7858b5836f197a4aa9d52358a43e2d12d018744df