mirror of
https://github.com/MHSanaei/3x-ui.git
synced 2026-06-05 20:54:14 +00:00
Step 4 of the planned vue->react migration. The nodes entry brings in
the largest shared-infrastructure batch so far — every authenticated
react page from here on can lean on these.
New shared pieces (live alongside their .vue counterparts during
coexistence):
* hooks/useMediaQuery.ts — useState + resize listener
* hooks/useWebSocket.ts — wraps WebSocketClient, subscribes on mount
and unsubscribes on unmount. The underlying client is a single
module-level instance so multiple components on the same page
share one socket.
* hooks/useNodes.ts — node list state + CRUD + probe/test, including
the totals memo (online/offline/avgLatency) used by the summary card.
applyNodesEvent is the entry point for the heartbeat-pushed list.
* components/CustomStatistic.tsx — thin Statistic wrapper, prefix +
suffix slots become props.
* components/Sparkline.tsx — the SVG line chart with measured-width
axis scaling, gradient fill, tooltip overlay, and per-instance
gradient id from React.useId. ResizeObserver lifecycle is in
useEffect; the math is unchanged.
Pages:
* NodesPage — wires hooks + WebSocket together, renders summary card
+ NodeList, hosts the form modal. Uses Modal.useModal() for the
delete confirm so the dialog inherits ConfigProvider theming.
* NodeList — desktop renders a Table with expandable history rows;
mobile flips to a vertical card list whose actions live in a
bottom-right Dropdown. The IP-blur eye toggle persists across both.
* NodeFormModal — controlled form (useState object, single setForm
per change). The reset-on-open effect computes the next state
once and applies it with eslint-disable to satisfy the new
react-hooks/set-state-in-effect rule on a legitimate pattern.
* NodeHistoryPanel — polls /panel/api/nodes/history/{id}/{metric}/
{bucket} every 15s, renders cpu+mem sparklines side-by-side.
|
||
|---|---|---|
| .. | ||
| AppSidebar.css | ||
| AppSidebar.tsx | ||
| AppSidebar.vue | ||
| CustomStatistic.css | ||
| CustomStatistic.tsx | ||
| CustomStatistic.vue | ||
| DateTimePicker.vue | ||
| FinalMaskForm.vue | ||
| InfinityIcon.vue | ||
| JsonEditor.vue | ||
| PromptModal.vue | ||
| SettingListItem.vue | ||
| Sparkline.css | ||
| Sparkline.tsx | ||
| Sparkline.vue | ||
| TableSortable.vue | ||
| TextModal.vue | ||