mirror of
https://github.com/EasyTier/EasyTier.git
synced 2025-10-08 10:10:33 +08:00
@@ -15,9 +15,9 @@ const props = defineProps<{
|
|||||||
defineEmits(['runNetwork'])
|
defineEmits(['runNetwork'])
|
||||||
|
|
||||||
const networking_methods = ref([
|
const networking_methods = ref([
|
||||||
{ value: NetworkingMethod.PublicServer, label: t('public_server') },
|
{ value: NetworkingMethod.PublicServer, label: () => t('public_server') },
|
||||||
{ value: NetworkingMethod.Manual, label: t('manual') },
|
{ value: NetworkingMethod.Manual, label: () => t('manual') },
|
||||||
{ value: NetworkingMethod.Standalone, label: t('standalone') },
|
{ value: NetworkingMethod.Standalone, label: () => t('standalone') },
|
||||||
])
|
])
|
||||||
|
|
||||||
const networkStore = useNetworkStore()
|
const networkStore = useNetworkStore()
|
||||||
@@ -32,9 +32,78 @@ const curNetwork = computed(() => {
|
|||||||
return networkStore.curNetwork
|
return networkStore.curNetwork
|
||||||
})
|
})
|
||||||
|
|
||||||
const presetPublicServers = [
|
const protos:{ [proto: string] : number; } = {'tcp': 11010, 'udp': 11010, 'wg':11011, 'ws': 11011, 'wss': 11012}
|
||||||
'tcp://easytier.public.kkrainbow.top:11010',
|
|
||||||
]
|
function searchUrlSuggestions(e: { query: string }): string[] {
|
||||||
|
const query = e.query
|
||||||
|
let ret = []
|
||||||
|
// if query match "^\w+:.*", then no proto prefix
|
||||||
|
if (query.match(/^\w+:.*/)) {
|
||||||
|
// if query is a valid url, then add to suggestions
|
||||||
|
try {
|
||||||
|
new URL(query)
|
||||||
|
ret.push(query)
|
||||||
|
} catch (e) {}
|
||||||
|
} else {
|
||||||
|
for (let proto in protos) {
|
||||||
|
let item = proto + '://' + query
|
||||||
|
// if query match ":\d+$", then no port suffix
|
||||||
|
if (!query.match(/:\d+$/)) {
|
||||||
|
item += ':' + protos[proto]
|
||||||
|
}
|
||||||
|
ret.push(item)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const publicServerSuggestions = ref([''])
|
||||||
|
|
||||||
|
const searchPresetPublicServers = (e: { query: string }) => {
|
||||||
|
const presetPublicServers = [
|
||||||
|
'tcp://easytier.public.kkrainbow.top:11010',
|
||||||
|
]
|
||||||
|
|
||||||
|
let query = e.query
|
||||||
|
// if query is sub string of presetPublicServers, add to suggestions
|
||||||
|
let ret = presetPublicServers.filter((item) => item.includes(query))
|
||||||
|
// add additional suggestions
|
||||||
|
if (query.length > 0) {
|
||||||
|
ret = ret.concat(searchUrlSuggestions(e))
|
||||||
|
}
|
||||||
|
|
||||||
|
publicServerSuggestions.value = ret
|
||||||
|
}
|
||||||
|
|
||||||
|
const peerSuggestions = ref([''])
|
||||||
|
|
||||||
|
const searchPeerSuggestions = (e: { query: string }) => {
|
||||||
|
peerSuggestions.value = searchUrlSuggestions(e)
|
||||||
|
}
|
||||||
|
|
||||||
|
const listenerSuggestions = ref([''])
|
||||||
|
|
||||||
|
const searchListenerSuggestiong = (e: { query: string }) => {
|
||||||
|
let ret = []
|
||||||
|
|
||||||
|
for (let proto in protos) {
|
||||||
|
let item = proto + '://0.0.0.0:';
|
||||||
|
// if query is a number, use it as port
|
||||||
|
if (e.query.match(/^\d+$/)) {
|
||||||
|
item += e.query
|
||||||
|
} else {
|
||||||
|
item += protos[proto]
|
||||||
|
}
|
||||||
|
|
||||||
|
if (item.includes(e.query)) {
|
||||||
|
ret.push(item)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
listenerSuggestions.value = ret
|
||||||
|
}
|
||||||
|
|
||||||
function validateHostname() {
|
function validateHostname() {
|
||||||
if (curNetwork.value.hostname) {
|
if (curNetwork.value.hostname) {
|
||||||
@@ -102,16 +171,15 @@ onMounted(async () => {
|
|||||||
<div class="flex flex-row gap-x-9 flex-wrap">
|
<div class="flex flex-row gap-x-9 flex-wrap">
|
||||||
<div class="flex flex-column gap-2 basis-5/12 grow">
|
<div class="flex flex-column gap-2 basis-5/12 grow">
|
||||||
<label for="nm">{{ t('networking_method') }}</label>
|
<label for="nm">{{ t('networking_method') }}</label>
|
||||||
|
<SelectButton v-model="curNetwork.networking_method" :options="networking_methods" :option-label="(v) => v.label()" option-value="value"></SelectButton>
|
||||||
<div class="items-center flex flex-row p-fluid gap-x-1">
|
<div class="items-center flex flex-row p-fluid gap-x-1">
|
||||||
<Dropdown v-model="curNetwork.networking_method" :options="networking_methods" option-label="label"
|
<AutoComplete v-if="curNetwork.networking_method === NetworkingMethod.Manual" id="chips"
|
||||||
option-value="value" placeholder="Select Method" class="" />
|
|
||||||
<Chips v-if="curNetwork.networking_method === NetworkingMethod.Manual" id="chips"
|
|
||||||
v-model="curNetwork.peer_urls" :placeholder="t('chips_placeholder', ['tcp://8.8.8.8:11010'])"
|
v-model="curNetwork.peer_urls" :placeholder="t('chips_placeholder', ['tcp://8.8.8.8:11010'])"
|
||||||
separator=" " class="grow" />
|
class="grow" multiple fluid :suggestions="peerSuggestions" @complete="searchPeerSuggestions"/>
|
||||||
|
|
||||||
<Dropdown v-if="curNetwork.networking_method === NetworkingMethod.PublicServer"
|
<AutoComplete v-if="curNetwork.networking_method === NetworkingMethod.PublicServer" :suggestions="publicServerSuggestions"
|
||||||
v-model="curNetwork.public_server_url" :editable="true" class="grow"
|
:virtualScrollerOptions="{ itemSize: 38 }" class="grow" dropdown @complete="searchPresetPublicServers" :completeOnFocus="true"
|
||||||
:options="presetPublicServers" />
|
v-model="curNetwork.public_server_url"/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -141,29 +209,32 @@ onMounted(async () => {
|
|||||||
<div class="flex flex-row gap-x-9 flex-wrap ">
|
<div class="flex flex-row gap-x-9 flex-wrap ">
|
||||||
<div class="flex flex-column gap-2 grow">
|
<div class="flex flex-column gap-2 grow">
|
||||||
<label for="username">VPN Portal</label>
|
<label for="username">VPN Portal</label>
|
||||||
<div class="items-center flex flex-row gap-x-4">
|
|
||||||
<ToggleButton v-model="curNetwork.enable_vpn_portal" on-icon="pi pi-check" off-icon="pi pi-times"
|
<ToggleButton v-model="curNetwork.enable_vpn_portal" on-icon="pi pi-check" off-icon="pi pi-times"
|
||||||
:on-label="t('off_text')" :off-label="t('on_text')" />
|
:on-label="t('off_text')" :off-label="t('on_text')" class="w-48"/>
|
||||||
<div v-if="curNetwork.enable_vpn_portal" class="grow">
|
<div class="items-center flex flex-row gap-x-4" v-if="curNetwork.enable_vpn_portal">
|
||||||
<InputGroup>
|
<div class="min-w-64">
|
||||||
<InputText v-model="curNetwork.vpn_portal_client_network_addr"
|
<InputGroup>
|
||||||
:placeholder="t('vpn_portal_client_network')" />
|
<InputText v-model="curNetwork.vpn_portal_client_network_addr"
|
||||||
<InputGroupAddon>
|
:placeholder="t('vpn_portal_client_network')" />
|
||||||
<span>/{{ curNetwork.vpn_portal_client_network_len }}</span>
|
<InputGroupAddon>
|
||||||
</InputGroupAddon>
|
<span>/{{ curNetwork.vpn_portal_client_network_len }}</span>
|
||||||
</InputGroup>
|
</InputGroupAddon>
|
||||||
|
</InputGroup>
|
||||||
|
|
||||||
|
<InputNumber v-model="curNetwork.vpn_portal_listen_port" :allow-empty="false"
|
||||||
|
:format="false" :min="0" :max="65535" class="w-8" fluid/>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<InputNumber v-if="curNetwork.enable_vpn_portal" v-model="curNetwork.vpn_portal_listen_port"
|
|
||||||
:placeholder="t('vpn_portal_listen_port')" class="" :format="false" :min="0" :max="65535" />
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="flex flex-row gap-x-9 flex-wrap">
|
<div class="flex flex-row gap-x-9 flex-wrap">
|
||||||
<div class="flex flex-column gap-2 grow p-fluid">
|
<div class="flex flex-column gap-2 grow p-fluid">
|
||||||
<label for="listener_urls">{{ t('listener_urls') }}</label>
|
<label for="listener_urls">{{ t('listener_urls') }}</label>
|
||||||
<Chips id="listener_urls" v-model="curNetwork.listener_urls"
|
<AutoComplete id="listener_urls" :suggestions="listenerSuggestions"
|
||||||
:placeholder="t('chips_placeholder', ['tcp://1.1.1.1:11010'])" separator=" " class="w-full" />
|
class="w-full" dropdown @complete="searchListenerSuggestiong" :completeOnFocus="true"
|
||||||
|
:placeholder="t('chips_placeholder', ['tcp://1.1.1.1:11010'])"
|
||||||
|
v-model="curNetwork.listener_urls" multiple/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@@ -343,10 +343,10 @@ function showEventLogs() {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="flex flex-row align-items-center flex-wrap w-full">
|
<div class="flex flex-row align-items-center flex-wrap w-full max-h-40 overflow-scroll">
|
||||||
<Chip
|
<Chip
|
||||||
v-for="(chip, i) in myNodeInfoChips" :key="i" :label="chip.label" :icon="chip.icon"
|
v-for="(chip, i) in myNodeInfoChips" :key="i" :label="chip.label" :icon="chip.icon"
|
||||||
class="mr-2 mt-2"
|
class="mr-2 mt-2 text-sm"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@@ -256,14 +256,8 @@ function isRunning(id: string) {
|
|||||||
:placeholder="t('select_network')" class="w-full">
|
:placeholder="t('select_network')" class="w-full">
|
||||||
<template #value="slotProps">
|
<template #value="slotProps">
|
||||||
<div class="flex items-start content-center">
|
<div class="flex items-start content-center">
|
||||||
<div class="mr-3">
|
<div class="mr-3 flex-column">
|
||||||
<span>{{ slotProps.value.network_name }}</span>
|
<span>{{ slotProps.value.network_name }}</span>
|
||||||
<span
|
|
||||||
v-if="isRunning(slotProps.value.instance_id) && networkStore.instances[slotProps.value.instance_id].detail && (networkStore.instances[slotProps.value.instance_id].detail?.my_node_info.virtual_ipv4 !== '')"
|
|
||||||
class="ml-3">
|
|
||||||
{{ networkStore.instances[slotProps.value.instance_id].detail
|
|
||||||
? networkStore.instances[slotProps.value.instance_id].detail?.my_node_info.virtual_ipv4 : '' }}
|
|
||||||
</span>
|
|
||||||
</div>
|
</div>
|
||||||
<Tag class="my-auto" :severity="isRunning(slotProps.value.instance_id) ? 'success' : 'info'"
|
<Tag class="my-auto" :severity="isRunning(slotProps.value.instance_id) ? 'success' : 'info'"
|
||||||
:value="t(isRunning(slotProps.value.instance_id) ? 'network_running' : 'network_stopped')" />
|
:value="t(isRunning(slotProps.value.instance_id) ? 'network_running' : 'network_stopped')" />
|
||||||
@@ -279,6 +273,11 @@ function isRunning(id: string) {
|
|||||||
:value="t(isRunning(slotProps.option.instance_id) ? 'network_running' : 'network_stopped')" />
|
:value="t(isRunning(slotProps.option.instance_id) ? 'network_running' : 'network_stopped')" />
|
||||||
</div>
|
</div>
|
||||||
<div>{{ slotProps.option.public_server_url }}</div>
|
<div>{{ slotProps.option.public_server_url }}</div>
|
||||||
|
<div
|
||||||
|
v-if="isRunning(slotProps.option.instance_id) && networkStore.instances[slotProps.option.instance_id].detail && (networkStore.instances[slotProps.option.instance_id].detail?.my_node_info.virtual_ipv4 !== '')">
|
||||||
|
{{ networkStore.instances[slotProps.option.instance_id].detail
|
||||||
|
? networkStore.instances[slotProps.option.instance_id].detail?.my_node_info.virtual_ipv4 : '' }}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
</Dropdown>
|
</Dropdown>
|
||||||
|
Reference in New Issue
Block a user