toggle for wifi and switch-router on openwrt page
This commit is contained in:
@@ -77,6 +77,10 @@ const showConnectForm = ref(false)
|
||||
const connecting = ref(false)
|
||||
const connectedParams = ref<Record<string, string> | null>(null)
|
||||
|
||||
const detecting = ref(false)
|
||||
const detectError = ref('')
|
||||
const detectedCandidates = ref<string[]>([])
|
||||
|
||||
const provisioning = ref(false)
|
||||
const provisionError = ref('')
|
||||
const provisionSuccess = ref(false)
|
||||
@@ -138,6 +142,61 @@ async function connect() {
|
||||
}
|
||||
}
|
||||
|
||||
interface WiredInterface { name: string; type: string; state: string; ipv4: string[] }
|
||||
|
||||
async function detectRouter() {
|
||||
detecting.value = true
|
||||
detectError.value = ''
|
||||
detectedCandidates.value = []
|
||||
try {
|
||||
const { interfaces } = await rpcClient.call<{ interfaces: WiredInterface[] }>({
|
||||
method: 'network.list-interfaces',
|
||||
timeout: 10000,
|
||||
})
|
||||
const wired = interfaces.find(i => i.type === 'ethernet' && i.state === 'up' && i.ipv4.length > 0)
|
||||
if (!wired) {
|
||||
detectError.value = 'No active wired ethernet connection found on this node.'
|
||||
return
|
||||
}
|
||||
const [ip, prefixStr] = wired.ipv4[0]!.split('/')
|
||||
const prefix = Number(prefixStr) || 24
|
||||
|
||||
const { routers } = await rpcClient.call<{ routers: string[] }>({
|
||||
method: 'openwrt.scan',
|
||||
params: { subnet: ip, prefix, ssh_user: sshUser.value, ssh_password: sshPassword.value },
|
||||
timeout: 120000,
|
||||
})
|
||||
|
||||
if (routers.length === 0) {
|
||||
detectError.value = `No OpenWrt router found on ${wired.name}'s network (/${prefix}).`
|
||||
} else if (routers.length === 1) {
|
||||
host.value = routers[0]!
|
||||
} else {
|
||||
detectedCandidates.value = routers
|
||||
}
|
||||
} catch (e) {
|
||||
detectError.value = e instanceof Error ? e.message : String(e)
|
||||
} finally {
|
||||
detecting.value = false
|
||||
}
|
||||
}
|
||||
|
||||
function pickDetectedRouter(ip: string) {
|
||||
host.value = ip
|
||||
detectedCandidates.value = []
|
||||
}
|
||||
|
||||
// The router config now persists server-side (see handle_openwrt_get_status),
|
||||
// so onMounted's no-args load() always reconnects automatically — without this,
|
||||
// there'd be no way back to the connect form (and its Detect button) at all.
|
||||
function disconnectRouter() {
|
||||
host.value = status.value?.host ?? host.value
|
||||
connectedParams.value = null
|
||||
detectError.value = ''
|
||||
detectedCandidates.value = []
|
||||
showConnectForm.value = true
|
||||
}
|
||||
|
||||
async function provisionTollgate() {
|
||||
provisioning.value = true
|
||||
provisionError.value = ''
|
||||
@@ -314,12 +373,34 @@ onMounted(() => load())
|
||||
<div class="space-y-3">
|
||||
<div>
|
||||
<label class="block text-xs text-white/40 mb-1">Router IP</label>
|
||||
<input
|
||||
v-model="host"
|
||||
type="text"
|
||||
placeholder="192.168.1.1"
|
||||
class="w-full px-4 py-3 bg-transparent border border-white/20 rounded-lg text-white placeholder-white/30 focus:outline-none focus:border-white/40 focus:ring-1 focus:ring-white/20 transition-colors"
|
||||
/>
|
||||
<div class="flex items-center gap-2">
|
||||
<input
|
||||
v-model="host"
|
||||
type="text"
|
||||
placeholder="192.168.1.1"
|
||||
class="w-full px-4 py-3 bg-transparent border border-white/20 rounded-lg text-white placeholder-white/30 focus:outline-none focus:border-white/40 focus:ring-1 focus:ring-white/20 transition-colors"
|
||||
/>
|
||||
<button
|
||||
:disabled="detecting"
|
||||
class="glass-button px-4 py-3 text-sm font-medium whitespace-nowrap flex-shrink-0"
|
||||
:class="detecting ? 'opacity-40 cursor-not-allowed' : ''"
|
||||
@click="detectRouter"
|
||||
>
|
||||
{{ detecting ? 'Detecting…' : 'Detect' }}
|
||||
</button>
|
||||
</div>
|
||||
<p v-if="detectError" class="mt-2 text-xs text-red-400">{{ detectError }}</p>
|
||||
<div v-if="detectedCandidates.length > 0" class="mt-2 space-y-1">
|
||||
<p class="text-xs text-white/40">Multiple routers found — pick one:</p>
|
||||
<button
|
||||
v-for="ip in detectedCandidates"
|
||||
:key="ip"
|
||||
class="w-full text-left px-3 py-2 bg-white/5 hover:bg-white/10 rounded-lg text-sm text-white font-mono transition-colors"
|
||||
@click="pickDetectedRouter(ip)"
|
||||
>
|
||||
{{ ip }}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="grid grid-cols-2 gap-3">
|
||||
<div>
|
||||
@@ -403,9 +484,14 @@ onMounted(() => load())
|
||||
<dd class="text-white/70">{{ formatUptime(status.uptime_secs) }}</dd>
|
||||
</div>
|
||||
</dl>
|
||||
<button class="mt-4 text-xs text-white/40 hover:text-white/70 transition-colors" @click="load()">
|
||||
↻ Refresh
|
||||
</button>
|
||||
<div class="mt-4 flex items-center gap-4">
|
||||
<button class="text-xs text-white/40 hover:text-white/70 transition-colors" @click="load()">
|
||||
↻ Refresh
|
||||
</button>
|
||||
<button class="text-xs text-white/40 hover:text-white/70 transition-colors" @click="disconnectRouter">
|
||||
Switch router →
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- WAN / Uplink -->
|
||||
|
||||
Reference in New Issue
Block a user