Adds the inbounds entry as a fourth Vite multi-page input and wires
/panel/inbounds through the dev proxy bypass. Lays down the page
chrome (sidebar, summary statistics card, refresh button) and the
fetch lifecycle composable so 5f-ii onward can drop in the table
columns and the modals without re-implementing it.
- inbounds.html + src/inbounds.js: fourth Vite entry; mounts InboundsPage.
- InboundsPage.vue: sidebar + summary card (totals over up/down,
all-time, inbound count, client tags) + a basic table with enable/
remark/port/protocol/traffic/expiry columns. Row actions, popovers,
search/filter, auto-refresh, and the WebSocket delta path are all
deferred to subsequent 5f subphases.
- useInbounds.js composable: GET /panel/api/inbounds/list +
POST /panel/api/inbounds/onlines + POST /panel/api/inbounds/lastOnline +
POST /panel/setting/defaultSettings, then computes the
per-inbound clientCount roll-ups (active/deactive/depleted/expiring/
online/comments) the table popovers consume.
- models/dbinbound.js + models/inbound.js: switched the legacy-utils
import to the @/utils alias for consistency with the rest of the
app. Semantics unchanged.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Adds the settings entry as a new Vite multi-page input. Lays down the
shared page chrome (sidebar, save bar, restart, security alert) and the
AllSetting fetch/dirty-poll lifecycle so 5d-ii through 5d-vi can drop
in tab partials without re-implementing it.
- settings.html + src/settings.js: third Vite entry; mounts SettingsPage.
- SettingsPage.vue: page chrome with the legacy two-button save/restart
bar, conf-alerts banner, and 5 a-tabs (4 always-visible + the formats
tab gated on subJsonEnable || subClashEnable). Each tab body is an
a-empty placeholder until 5d-ii…vi fill them in.
- useAllSetting.js composable: POST /panel/setting/all on mount, mirrors
the legacy 1s busy-loop dirty check via setInterval, and exposes
fetchAll/saveAll. saveDisabled flips off as soon as the user diverges
from the server snapshot.
- restartPanel rebuilds the URL (host/port/scheme/base path) from the
saved settings so users land on the new endpoint after a port or
cert change.
- models/setting.js: adopts the @/utils alias and a leading file-level
doc — semantics unchanged.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Adds the CPU / memory / swap / disk dashboard cards to IndexPage,
backed by a useStatus() composable that polls /panel/api/server/status
every 2 s and a Status / CurTotal model ported from the legacy inline
classes in index.html.
- models/status.js — Status & CurTotal classes (CurTotal exposes
reactive .percent and .color computed-style getters; Status maps
the API payload + xray state to color/message strings)
- composables/useStatus.js — 2s polling with shallowRef so each fetch
swaps the whole Status object atomically. WebSocket integration
intentionally deferred — the legacy panel falls back to this same
2s polling when its websocket drops, so we ship the proven path
first and add WS on top in a later sub-phase.
- pages/index/StatusCard.vue — four a-progress dashboard widgets in
a 2x2 grid (mobile collapses to a 1x4). CPU widget exposes a
history button; the modal it opens is part of 5c-iv.
- IndexPage now consumes both, plus useMediaQuery so the layout
responds to viewport changes.
AD-Vue 4 changes: <a-icon type="area-chart"|"history"> dropped in
favor of explicit AreaChartOutlined / HistoryOutlined imports.
<a-tooltip slot="title"> → <template #title>.
i18n strings still hardcoded English (Phase 7 wires up vue-i18n).
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Ports the framework-agnostic JS from web/assets/js/ into frontend/src/
so Vue 3 pages can import what they need without relying on script-tag
globals.
- web/assets/js/util/index.js (927 lines, 21 classes) →
frontend/src/utils/legacy.js + a barrel at utils/index.js. All
classes are now named exports.
- Vue.prototype.$message in HttpUtil → direct import of `message`
from ant-design-vue (Vue 3 has no Vue.prototype).
- RandomUtil.randomShadowsocksPassword previously defaulted to
SSMethods.BLAKE3_AES_256_GCM from inbound.js, creating a circular
import. Replaced with the literal string default.
- MediaQueryMixin (Vue 2 mixin) removed. Replaced by
composables/useMediaQuery.js — Vue 3 composable returning reactive
`isMobile`.
- axios-init.js wrapped as setupAxios(); Qs global → npm `qs`.
- websocket.js exported as WebSocketClient class; the implicit
window.wsClient global is gone — pages instantiate it themselves.
- model/{inbound,outbound,dbinbound,setting,reality_targets}.js
copied with `export` added on every top-level declaration. Imports
between models and utils are wired up explicitly.
- subscription.js deferred to Phase 5 (it's a Vue 2 mount, not a util).
- App.vue smoke test exercises SizeFormatter / RandomUtil / Wireguard /
useMediaQuery so the user can verify Phase 3 with `npm run dev`.
Run `cd frontend && npm install && npm run dev` — qs was added so a
fresh install is required.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>