Brings Balancers to full parity with the legacy panel and adds a
DNS tab placeholder that exposes the full dns/fakedns trees as JSON
so users can edit them without falling through to Advanced.
- BalancerFormModal.vue: tag (with duplicate-tag warning across
other balancers), strategy (random/roundRobin/leastLoad/leastPing),
selector tag-mode multi-select sourced from existing outbound
tags + free-form additions, fallback. Disable-on-invalid is
driven by the duplicateTag + emptySelector computed flags.
- BalancersTab.vue: empty state with a single "Add balancer" CTA;
populated state shows the legacy 4-column table (action / tag /
strategy / selector / fallback) with per-row edit + delete in a
dropdown. On submit the wire shape preserves the
`strategy: { type }` nesting only when the strategy is non-default,
matching the legacy emit. Tag renames also chase across
routing.rules.balancerTag references so existing rules don't dangle.
- DnsTab.vue: master enable switch + raw JSON for `dns` and
`fakedns`. Legacy had a dedicated server-by-server editor + a
fakedns row editor; both are big enough to deserve their own
commits, and the JSON path supports every field today.
WARP / NordVPN provisioning modals still toast as "coming soon" —
those are third-party API integrations worth their own commits.
The xray page now has structured editors for Basics / Routing /
Outbounds / Balancers and JSON editors for DNS / Advanced — every
xray tab the legacy panel offered is functional.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>