mirror of
https://github.com/MHSanaei/3x-ui.git
synced 2026-08-16 00:01:02 +00:00
feat(nodes): bulk panel self-update with live online indicator
Adds the ability to update node panels to the latest release from the Nodes page: select online, enabled nodes (checkboxes) and trigger their official self-updater, or use the per-row Update action. A node whose reported panel version trails the latest GitHub release is flagged with an 'update available' tag (compared via lib/panel-version, mirroring the Go isNewerVersion). Backend: Remote.UpdatePanel calls the node's existing POST /panel/api/server/updatePanel; NodeService.UpdatePanels fans out over the selected ids, skipping disabled/offline nodes with a per-node reason; exposed as POST /panel/api/nodes/updatePanel (documented in endpoints.ts + openapi.json). The bulk request sends a JSON body, so it sets Content-Type: application/json explicitly — axios defaults POST to form-urlencoded, which made ShouldBindJSON fail with 'invalid character i'. Also reuses the clients-page online cue on the Nodes page: a pulsing green dot plus green label for an online node. The .online-dot style moved to the shared styles/utils.css so both pages load it. Translations for all new node keys added across every language file.
This commit is contained in:
@@ -4244,6 +4244,69 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"/panel/api/nodes/updatePanel": {
|
||||
"post": {
|
||||
"tags": [
|
||||
"Nodes"
|
||||
],
|
||||
"summary": "Trigger the official panel self-updater on each given node (downloads the latest release and restarts). Only enabled, online nodes are updated; offline/disabled ones are reported as skipped. Returns a per-node result list.",
|
||||
"operationId": "post_panel_api_nodes_updatePanel",
|
||||
"requestBody": {
|
||||
"required": true,
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"type": "object"
|
||||
},
|
||||
"example": {
|
||||
"ids": [
|
||||
1,
|
||||
2,
|
||||
3
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "Successful response",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"success": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"msg": {
|
||||
"type": "string"
|
||||
},
|
||||
"obj": {}
|
||||
}
|
||||
},
|
||||
"example": {
|
||||
"success": true,
|
||||
"obj": [
|
||||
{
|
||||
"id": 1,
|
||||
"name": "de-1",
|
||||
"ok": true
|
||||
},
|
||||
{
|
||||
"id": 2,
|
||||
"name": "fr-1",
|
||||
"ok": false,
|
||||
"error": "node is offline"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/panel/api/nodes/history/{id}/{metric}/{bucket}": {
|
||||
"get": {
|
||||
"tags": [
|
||||
|
||||
Reference in New Issue
Block a user