3x-ui/frontend/src/pages/xray/DnsTab.vue

112 lines
3.1 KiB
Vue
Raw Normal View History

feat(frontend): Phase 6-v — xray Balancers tab + DNS placeholder 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>
2026-05-08 12:30:48 +00:00
<script setup>
import { computed } from 'vue';
// Compact DNS editor — a master enable switch plus a JSON textarea
// for the full dns + fakedns trees. The legacy panel had a
// dedicated DNS-server modal + fakedns row editor; both are large
// enough to deserve their own commits. For now this gives users a
// working path to edit DNS settings without leaving the structured
// page.
const props = defineProps({
templateSettings: { type: Object, default: null },
});
const enableDns = computed({
get: () => !!props.templateSettings?.dns,
set: (next) => {
if (!props.templateSettings) return;
if (next) {
props.templateSettings.dns = {
servers: [],
queryStrategy: 'UseIP',
tag: 'dns_inbound',
enableParallelQuery: false,
};
props.templateSettings.fakedns = null;
} else {
delete props.templateSettings.dns;
delete props.templateSettings.fakedns;
}
},
});
const dnsJson = computed({
get: () => {
if (!props.templateSettings?.dns) return '';
try { return JSON.stringify(props.templateSettings.dns, null, 2); }
catch (_e) { return ''; }
},
set: (next) => {
if (!props.templateSettings) return;
try {
const parsed = next.trim() ? JSON.parse(next) : null;
props.templateSettings.dns = parsed;
} catch (_e) {
// wait for valid JSON — leaves the previous value untouched
}
},
});
const fakednsJson = computed({
get: () => {
if (!props.templateSettings?.fakedns) return '';
try { return JSON.stringify(props.templateSettings.fakedns, null, 2); }
catch (_e) { return ''; }
},
set: (next) => {
if (!props.templateSettings) return;
try {
const parsed = next.trim() ? JSON.parse(next) : null;
if (parsed) props.templateSettings.fakedns = parsed;
else delete props.templateSettings.fakedns;
} catch (_e) { /* wait for valid JSON */ }
},
});
</script>
<template>
<a-space direction="vertical" size="middle" :style="{ width: '100%' }">
<a-form layout="vertical">
<a-form-item label="Enable DNS">
<a-switch v-model:checked="enableDns" />
</a-form-item>
<template v-if="enableDns">
<a-alert
type="info"
show-icon
message="The full DNS tree is editable here. A dedicated server-by-server editor is coming in a future commit."
class="mb-12"
/>
<a-form-item label="dns (JSON)">
<a-textarea
v-model:value="dnsJson"
:auto-size="{ minRows: 12, maxRows: 28 }"
spellcheck="false"
class="json-editor"
/>
</a-form-item>
<a-form-item label="fakedns (JSON, optional)">
<a-textarea
v-model:value="fakednsJson"
:auto-size="{ minRows: 6, maxRows: 18 }"
spellcheck="false"
class="json-editor"
placeholder="Leave empty to omit fakedns."
/>
</a-form-item>
</template>
</a-form>
</a-space>
</template>
<style scoped>
.mb-12 { margin-bottom: 12px; }
.json-editor {
font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace;
font-size: 12px;
}
</style>