diff --git a/control/frontend/src/pages/Monitor.tsx b/control/frontend/src/pages/Monitor.tsx
index f9cde56..471d604 100644
--- a/control/frontend/src/pages/Monitor.tsx
+++ b/control/frontend/src/pages/Monitor.tsx
@@ -425,8 +425,8 @@ export default function MonitorPage() {
}
}
- async function batchUpdate() {
- const ids = [...selected];
+ async function batchUpdate(idsOverride?: number[]) {
+ const ids = idsOverride ?? [...selected];
if (!ids.length) return;
const names = nodes
.filter((n) => ids.includes(n.id))
@@ -457,6 +457,29 @@ export default function MonitorPage() {
});
}
+ const updatableIds = nodes
+ .filter((n) => n.token_configured)
+ .map((n) => n.id);
+ const allSelected =
+ updatableIds.length > 0 && updatableIds.every((id) => selected.has(id));
+
+ function toggleSelectAll() {
+ setSelected((prev) => {
+ if (updatableIds.length === 0) return prev;
+ if (updatableIds.every((id) => prev.has(id))) return new Set();
+ return new Set(updatableIds);
+ });
+ }
+
+ async function updateAll() {
+ if (!updatableIds.length) {
+ setErr("没有已配对 Token 的策略机可更新");
+ return;
+ }
+ setSelected(new Set(updatableIds));
+ await batchUpdate(updatableIds);
+ }
+
const detailNode = detailId != null ? nodes.find((x) => x.id === detailId) : null;
const detail = detailNode ? pickStrategy(detailNode) : null;
const detailRunning =
@@ -497,6 +520,15 @@ export default function MonitorPage() {
+