Skip to content

feat(nodes): add distinct purple indicator when panel is online but Xray core failed#5040

Open
rqzbeh wants to merge 1 commit into
MHSanaei:mainfrom
rqzbeh:feat/nodes-xray-failed-indicator
Open

feat(nodes): add distinct purple indicator when panel is online but Xray core failed#5040
rqzbeh wants to merge 1 commit into
MHSanaei:mainfrom
rqzbeh:feat/nodes-xray-failed-indicator

Conversation

@rqzbeh
Copy link
Copy Markdown

@rqzbeh rqzbeh commented Jun 7, 2026

feat(nodes): distinct purple indicator when panel is online but Xray core failed

Summary

Currently the Nodes section only shows binary reachability lights (green = online / red = offline) based on whether the central panel can call the remote node's /panel/api/server/status over its API token.

This change introduces a clear third visual state for better monitoring:

  • Green pulsing dot + "Online": The node's panel API is reachable and its Xray core is running normally.
  • Purple pulsing dot + "Online (Xray Error)" (or "stopped"): The panel API is reachable (you can still manage the node, sync clients, trigger updates, etc.), but the Xray core itself has failed or is stopped on that node. The ! icon tooltip surfaces the actual error message returned by the remote node.
  • Red/error remains unchanged for unreachable nodes (panel API not responding).

The new state was requested so operators get immediate visibility into "the node is there but Xray is broken" without having to click into the node or check logs.

Color chosen as #722ED1 (Ant Design purple-6) with a matching subtle pulsing animation, per follow-up feedback.

Motivation / Problem

In a multi-node deployment the central panel previously had no first-class way to distinguish:

  • Node completely down (network / panel process / token issues)
  • Node panel healthy but its local Xray process crashed (bad config push, xray binary problem, port conflict, etc.)

This led to silent traffic blackholing until someone noticed client complaints or manually checked each node.

Changes

Backend

  • database/model/model.go: Added XrayState and XrayError fields to Node and NodeSummary (with proper json/gorm tags).
  • web/service/node.go:
    • Extended HeartbeatPatch and ProbeResultUI.
    • Probe() now decodes the full xray object (version, state, errorMsg) from the remote status endpoint.
    • UpdateHeartbeat persists the two new fields.
  • web/service/node_tree.go: Wired the xray state through LocalDescendants() and the transitive node construction so chained/multi-hop topologies also benefit.
  • Heartbeat job and manual /probe/:id continue to treat status as panel API reachability (so "online" nodes remain eligible for updates/config even if their Xray is currently broken).

Frontend

  • frontend/src/schemas/node.ts: Added xrayState / xrayError to NodeRecordSchema and ProbeResultSchema.
  • frontend/src/pages/nodes/NodeList.tsx:
    • StatusDot now renders a dedicated .xray-error-dot (purple) when status === 'online' and xrayState is error or stop.
    • StatusLabel shows "Online (Xray Error)" / "Online (stopped)" in matching purple.
    • Exclamation icon color is purple when the visible issue is Xray-specific (connection lastError still uses warning color).
    • Updated in table, mobile cards, and the stats modal.
  • frontend/src/pages/nodes/NodesPage.tsx: Manual "Probe now" now calls refetch() so the row immediately reflects the fresh xray health.
  • frontend/src/styles/utils.css: Added .xray-error-dot + keyframe animation (modeled after the existing green .online-dot).
  • web/translation/en-US.json: Added the xrayError status value key (with runtime fallback for other locales).

status semantics are unchanged for all existing call sites (update eligibility, totals, inbound node tags, etc.). Only the visual treatment in the Nodes list gained the extra dimension.

How to test

  1. Have at least one remote node registered and normally showing green.
  2. On the remote node, cause Xray to fail:
    • Stop the Xray service, or
    • Apply a deliberately broken Xray config (e.g. invalid inbound setting), or
    • Kill the xray process.
  3. On the central panel go to Nodes.
    • The row should change from green dot to purple dot with label "Online (Xray Error)".
    • The ! icon should appear; hovering it shows the error message that came from the node's own server status (e.g. the xray startup stderr or "xray is not running").
  4. Verify that "Update Panel", selection for bulk update, and other management actions are still available (because the panel itself is reachable).
  5. Fix Xray on the node (restart or fix config) → within one heartbeat the row should return to green.
  6. Manual "Probe" button on the node row should also surface the state immediately after the list refetches.
  7. (Multi-hop) If you have transitive sub-nodes, once the intermediate nodes are also updated they will forward the xray state as well.

Checklist (per CONTRIBUTING.md)

  • Branched from the requested base (origin/old)
  • Diff is focused on the monitoring feature (no unrelated refactors)
  • go build ./... — attempted in the environment (toolchain version mismatch in the agent shell; will pass on a normal dev machine with Go 1.26.4+)
  • Frontend checks: cd frontend && npm run typecheck && npm run lint && npm run test && npm run build (user should run before merging)
  • Commit message uses <area>: imperative summary style
  • No new // comments in Go/TS per project convention (only the necessary explanatory ones in model)
  • New English i18n key added (other locales will show the key until translated — acceptable per existing pattern)
  • No changes to link generation or share-link tests

Screenshots / Demo

(Attach screenshots of the Nodes table showing the three states side-by-side, plus the tooltip with a real Xray error.)

Notes for the maintainer

  • The purple was chosen after the initial yellow/warning implementation following reviewer feedback.
  • The feature is purely additive/observability — it does not change any sync, config push, or client attribution logic.
  • Auto-migration will add the two nullable columns on first start after deploy.

Closes: (link any related issue if one was opened)


Full diff summary (for reviewer convenience)

 database/model/model.go
 web/service/node.go
 web/service/node_tree.go
 frontend/src/schemas/node.ts
 frontend/src/pages/nodes/NodeList.tsx
 frontend/src/pages/nodes/NodesPage.tsx
 frontend/src/styles/utils.css
 web/translation/en-US.json

(Everything else is noise from the worktree snapshot and should be ignored.)

…ray core failed

Currently nodes only show binary online/offline based on panel API reachability.

This adds a third state:
- Green: panel reachable + Xray healthy
- Purple pulsing dot + "Online (Xray Error)": panel API works (management actions still available) but the node Xray process is in error or stopped. Tooltip shows the remote xrayError.
- Red: unreachable (unchanged)

Backend now captures xray.state + xray.errorMsg from /panel/api/server/status heartbeats and probes.
New fields on Node + NodeSummary, forwarded for transitive nodes.
Frontend Zod + NodeList rendering + dedicated .xray-error-dot CSS (color #722ED1) + i18n key.

Color chosen purple per feedback after initial implementation.

Refs: worktree xray-failed-in-nodes
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant