工作台左侧客户端列表按 sim / live 分组,没有对应模式则不显示该组标题。

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
dekun
2026-10-04 17:48:45 +08:00
parent 6bc69ab371
commit 39ee3a9376
3 changed files with 126 additions and 64 deletions
+7
View File
@@ -782,6 +782,13 @@ button, .btn {
} }
.desk-list { list-style: none; padding: 0; margin: 0; } .desk-list { list-style: none; padding: 0; margin: 0; }
.desk-list li { margin: 6px 0; } .desk-list li { margin: 6px 0; }
.desk-list .desk-group-label {
margin: 10px 0 4px;
padding: 0 2px;
list-style: none;
}
.desk-list .desk-group-label:first-child { margin-top: 0; }
.desk.is-side-collapsed .desk-group-label { display: none; }
.desk-list li a { .desk-list li a {
display: block; display: block;
padding: 7px 9px; padding: 7px 9px;
+1 -1
View File
@@ -4,7 +4,7 @@
<meta charset="utf-8"> <meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1"> <meta name="viewport" content="width=device-width, initial-scale=1">
<title>{% block title %}期权中控{% endblock %}</title> <title>{% block title %}期权中控{% endblock %}</title>
<link rel="stylesheet" href="{{ url_for('static', filename='hub.css') }}?v=16"> <link rel="stylesheet" href="{{ url_for('static', filename='hub.css') }}?v=17">
</head> </head>
<body class="{% if request.path.startswith('/login') %}page-login{% elif request.path.startswith('/desk') %}page-desk{% elif request.path.startswith('/stats') %}page-stats{% elif request.path.startswith('/instances') %}page-instances{% elif request.path == '/' %}page-dashboard{% endif %}"> <body class="{% if request.path.startswith('/login') %}page-login{% elif request.path.startswith('/desk') %}page-desk{% elif request.path.startswith('/stats') %}page-stats{% elif request.path.startswith('/instances') %}page-instances{% elif request.path == '/' %}page-dashboard{% endif %}">
{% if session.get('logged_in') %} {% if session.get('logged_in') %}
+57 -2
View File
@@ -7,9 +7,9 @@
<h2 class="desk-side-title">客户端</h2> <h2 class="desk-side-title">客户端</h2>
<button type="button" class="desk-side-toggle" id="desk-side-toggle" title="折叠/展开" aria-label="折叠客户端列表">‹</button> <button type="button" class="desk-side-toggle" id="desk-side-toggle" title="折叠/展开" aria-label="折叠客户端列表">‹</button>
</div> </div>
<ul class="desk-list"> <ul class="desk-list" id="desk-list">
{% for inst in instances %} {% for inst in instances %}
<li class="{% if current and current.id == inst.id %}active{% endif %}" title="{{ inst.name }}"> <li class="desk-list-item{% if current and current.id == inst.id %} active{% endif %}" data-id="{{ inst.id }}" title="{{ inst.name }}">
<a href="/desk?id={{ inst.id }}"> <a href="/desk?id={{ inst.id }}">
<span class="desk-list-name">{{ inst.name }}</span> <span class="desk-list-name">{{ inst.name }}</span>
</a> </a>
@@ -58,6 +58,61 @@
var saved = false; var saved = false;
try { saved = localStorage.getItem(KEY) === "1"; } catch (e) {} try { saved = localStorage.getItem(KEY) === "1"; } catch (e) {}
apply(saved); apply(saved);
var list = document.getElementById("desk-list");
if (!list) return;
var items = Array.prototype.slice.call(list.querySelectorAll("li.desk-list-item[data-id]"));
if (!items.length) return;
function groupLabel(mode) {
var li = document.createElement("li");
li.className = "desk-group-label";
li.setAttribute("aria-hidden", "true");
var span = document.createElement("span");
span.className = "overview-mode-tag overview-mode-tag--" + mode;
span.textContent = mode;
li.appendChild(span);
return li;
}
function regroup(modeById) {
var sim = [];
var live = [];
var other = [];
items.forEach(function (li) {
var m = String(modeById[li.getAttribute("data-id")] || "").toLowerCase();
if (m === "sim") sim.push(li);
else if (m === "live") live.push(li);
else other.push(li);
});
list.innerHTML = "";
if (sim.length) {
list.appendChild(groupLabel("sim"));
sim.forEach(function (li) { list.appendChild(li); });
}
if (live.length) {
list.appendChild(groupLabel("live"));
live.forEach(function (li) { list.appendChild(li); });
}
other.forEach(function (li) { list.appendChild(li); });
}
Promise.all(
items.map(function (li) {
var iid = li.getAttribute("data-id");
return fetch("/api/instances/" + iid + "/version", {
credentials: "same-origin",
headers: { Accept: "application/json" },
})
.then(function (r) { return r.json().catch(function () { return {}; }); })
.then(function (v) { return { id: iid, mode: (v && v.mode) || "" }; })
.catch(function () { return { id: iid, mode: "" }; });
})
).then(function (rows) {
var map = {};
rows.forEach(function (row) { map[row.id] = row.mode; });
regroup(map);
});
})(); })();
</script> </script>
{% endblock %} {% endblock %}