feat: multi-type server support — SQL, Redis, Grafana, Prometheus, Telnet, WinRM, RDP/VNC
Full implementation of multi-type server management across GUI and CLI: New clients: SQLClient (MariaDB/MSSQL/PostgreSQL), RedisClient, GrafanaClient, PrometheusClient, TelnetSession, WinRMClient, RemoteDesktopLauncher. New GUI tabs: QueryTab (SQL editor + Treeview), RedisTab (console + history), GrafanaTab (dashboards + alerts), PrometheusTab (PromQL + targets), PowershellTab (PS/CMD), LaunchTab (RDP/VNC external client). Infrastructure: TAB_REGISTRY for conditional tabs per server type, adaptive server_dialog fields, colored type badges in sidebar, status checker for all types (SSH/TCP/SQL/Redis/HTTP), 100+ i18n keys. CLI: ssh.py extended with --sql, --redis, --grafana-*, --prom-*, --ps, --cmd. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -6,6 +6,34 @@ import customtkinter as ctk
|
||||
from core.i18n import t
|
||||
from gui.widgets.status_badge import StatusBadge
|
||||
|
||||
TYPE_COLORS = {
|
||||
"ssh": "#22c55e",
|
||||
"telnet": "#a855f7",
|
||||
"rdp": "#3b82f6",
|
||||
"vnc": "#6366f1",
|
||||
"winrm": "#0ea5e9",
|
||||
"mariadb": "#f59e0b",
|
||||
"mssql": "#ef4444",
|
||||
"postgresql": "#3b82f6",
|
||||
"redis": "#dc2626",
|
||||
"grafana": "#f97316",
|
||||
"prometheus": "#e11d48",
|
||||
}
|
||||
|
||||
TYPE_LABELS = {
|
||||
"ssh": "SSH",
|
||||
"telnet": "TEL",
|
||||
"rdp": "RDP",
|
||||
"vnc": "VNC",
|
||||
"winrm": "PS",
|
||||
"mariadb": "MDB",
|
||||
"mssql": "SQL",
|
||||
"postgresql": "PG",
|
||||
"redis": "RDS",
|
||||
"grafana": "GRF",
|
||||
"prometheus": "PRM",
|
||||
}
|
||||
|
||||
|
||||
class Sidebar(ctk.CTkFrame):
|
||||
def __init__(self, master, store, on_select=None, session_pool=None):
|
||||
@@ -101,6 +129,17 @@ class Sidebar(ctk.CTkFrame):
|
||||
badge.pack(side="left", padx=(10, 5), pady=10)
|
||||
self._badges[alias] = badge
|
||||
|
||||
# Type badge (colored short label)
|
||||
type_color = TYPE_COLORS.get(stype, "#6b7280")
|
||||
type_label_text = TYPE_LABELS.get(stype, stype.upper()[:3])
|
||||
type_badge = ctk.CTkLabel(
|
||||
frame, text=type_label_text,
|
||||
font=ctk.CTkFont(size=9, weight="bold"),
|
||||
text_color=type_color,
|
||||
width=30
|
||||
)
|
||||
type_badge.pack(side="left", padx=(0, 2), pady=10)
|
||||
|
||||
# Active session indicator (right side)
|
||||
session_ind = ctk.CTkLabel(
|
||||
frame, text="", width=12, height=12,
|
||||
@@ -117,12 +156,11 @@ class Sidebar(ctk.CTkFrame):
|
||||
|
||||
name_label = ctk.CTkLabel(info, text=alias, font=ctk.CTkFont(size=13, weight="bold"), anchor="w")
|
||||
name_label.pack(fill="x")
|
||||
detail = f"{ip} [{stype}]"
|
||||
detail_label = ctk.CTkLabel(info, text=detail, font=ctk.CTkFont(size=10), text_color="#9ca3af", anchor="w")
|
||||
detail_label = ctk.CTkLabel(info, text=ip, font=ctk.CTkFont(size=10), text_color="#9ca3af", anchor="w")
|
||||
detail_label.pack(fill="x")
|
||||
|
||||
# Click handlers
|
||||
for widget in [frame, info, name_label, detail_label, badge, session_ind]:
|
||||
for widget in [frame, info, name_label, detail_label, badge, type_badge, session_ind]:
|
||||
widget.bind("<Button-1>", lambda e, a=alias: self._select(a))
|
||||
|
||||
self._server_frames[alias] = frame
|
||||
|
||||
Reference in New Issue
Block a user