mirror of
https://github.com/fatedier/frp.git
synced 2025-07-27 07:35:07 +00:00
web: support to clear offline proxies data on dashboard (#3963)
This commit is contained in:
6
web/frps/auto-imports.d.ts
vendored
6
web/frps/auto-imports.d.ts
vendored
@@ -1,4 +1,8 @@
|
||||
// Generated by 'unplugin-auto-import'
|
||||
/* eslint-disable */
|
||||
/* prettier-ignore */
|
||||
// @ts-nocheck
|
||||
// noinspection JSUnusedGlobalSymbols
|
||||
// Generated by unplugin-auto-import
|
||||
export {}
|
||||
declare global {
|
||||
|
||||
|
12
web/frps/components.d.ts
vendored
12
web/frps/components.d.ts
vendored
@@ -1,11 +1,11 @@
|
||||
// generated by unplugin-vue-components
|
||||
// We suggest you to commit this file into source control
|
||||
/* eslint-disable */
|
||||
/* prettier-ignore */
|
||||
// @ts-nocheck
|
||||
// Generated by unplugin-vue-components
|
||||
// Read more: https://github.com/vuejs/core/pull/3399
|
||||
import '@vue/runtime-core'
|
||||
|
||||
export {}
|
||||
|
||||
declare module '@vue/runtime-core' {
|
||||
declare module 'vue' {
|
||||
export interface GlobalComponents {
|
||||
ElButton: typeof import('element-plus/es')['ElButton']
|
||||
ElCol: typeof import('element-plus/es')['ElCol']
|
||||
@@ -13,6 +13,8 @@ declare module '@vue/runtime-core' {
|
||||
ElFormItem: typeof import('element-plus/es')['ElFormItem']
|
||||
ElMenu: typeof import('element-plus/es')['ElMenu']
|
||||
ElMenuItem: typeof import('element-plus/es')['ElMenuItem']
|
||||
ElPageHeader: typeof import('element-plus/es')['ElPageHeader']
|
||||
ElPopconfirm: typeof import('element-plus/es')['ElPopconfirm']
|
||||
ElPopover: typeof import('element-plus/es')['ElPopover']
|
||||
ElRow: typeof import('element-plus/es')['ElRow']
|
||||
ElSubMenu: typeof import('element-plus/es')['ElSubMenu']
|
||||
|
@@ -12,27 +12,27 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@types/humanize-plus": "^1.8.0",
|
||||
"echarts": "^5.4.1",
|
||||
"element-plus": "^2.3.3",
|
||||
"echarts": "^5.4.3",
|
||||
"element-plus": "^2.5.3",
|
||||
"humanize-plus": "^1.8.2",
|
||||
"vue": "^3.2.47",
|
||||
"vue-router": "^4.1.6"
|
||||
"vue": "^3.4.15",
|
||||
"vue-router": "^4.2.5"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@rushstack/eslint-patch": "^1.1.4",
|
||||
"@rushstack/eslint-patch": "^1.7.2",
|
||||
"@types/node": "^18.11.12",
|
||||
"@vitejs/plugin-vue": "^4.0.0",
|
||||
"@vue/eslint-config-prettier": "^7.0.0",
|
||||
"@vue/eslint-config-typescript": "^11.0.0",
|
||||
"@vue/tsconfig": "^0.1.3",
|
||||
"eslint": "^8.22.0",
|
||||
"eslint-plugin-vue": "^9.3.0",
|
||||
"@vitejs/plugin-vue": "^5.0.3",
|
||||
"@vue/eslint-config-prettier": "^9.0.0",
|
||||
"@vue/eslint-config-typescript": "^12.0.0",
|
||||
"@vue/tsconfig": "^0.5.1",
|
||||
"eslint": "^8.56.0",
|
||||
"eslint-plugin-vue": "^9.21.0",
|
||||
"npm-run-all": "^4.1.5",
|
||||
"prettier": "^2.7.1",
|
||||
"typescript": "~4.7.4",
|
||||
"unplugin-auto-import": "^0.13.0",
|
||||
"unplugin-vue-components": "^0.23.0",
|
||||
"vite": "^4.0.4",
|
||||
"vue-tsc": "^1.0.12"
|
||||
"prettier": "^3.2.4",
|
||||
"typescript": "~5.3.3",
|
||||
"unplugin-auto-import": "^0.17.5",
|
||||
"unplugin-vue-components": "^0.26.0",
|
||||
"vite": "^5.0.12",
|
||||
"vue-tsc": "^1.8.27"
|
||||
}
|
||||
}
|
||||
|
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<ProxyView :proxies="proxies" proxyType="http" />
|
||||
<ProxyView :proxies="proxies" proxyType="http" @refresh="fetchData"/>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
@@ -27,6 +27,7 @@ const fetchData = () => {
|
||||
return res.json()
|
||||
})
|
||||
.then((json) => {
|
||||
proxies.value = []
|
||||
for (let proxyStats of json.proxies) {
|
||||
proxies.value.push(
|
||||
new HTTPProxy(proxyStats, vhostHTTPPort, subdomainHost)
|
||||
|
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<ProxyView :proxies="proxies" proxyType="https" />
|
||||
<ProxyView :proxies="proxies" proxyType="https" @refresh="fetchData"/>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
@@ -27,6 +27,7 @@ const fetchData = () => {
|
||||
return res.json()
|
||||
})
|
||||
.then((json) => {
|
||||
proxies.value = []
|
||||
for (let proxyStats of json.proxies) {
|
||||
proxies.value.push(
|
||||
new HTTPSProxy(proxyStats, vhostHTTPSPort, subdomainHost)
|
||||
|
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<ProxyView :proxies="proxies" proxyType="stcp" />
|
||||
<ProxyView :proxies="proxies" proxyType="stcp" @refresh="fetchData"/>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
@@ -15,6 +15,7 @@ const fetchData = () => {
|
||||
return res.json()
|
||||
})
|
||||
.then((json) => {
|
||||
proxies.value = []
|
||||
for (let proxyStats of json.proxies) {
|
||||
proxies.value.push(new STCPProxy(proxyStats))
|
||||
}
|
||||
|
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<ProxyView :proxies="proxies" proxyType="sudp" />
|
||||
<ProxyView :proxies="proxies" proxyType="sudp" @refresh="fetchData"/>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
@@ -15,6 +15,7 @@ const fetchData = () => {
|
||||
return res.json()
|
||||
})
|
||||
.then((json) => {
|
||||
proxies.value = []
|
||||
for (let proxyStats of json.proxies) {
|
||||
proxies.value.push(new SUDPProxy(proxyStats))
|
||||
}
|
||||
|
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<ProxyView :proxies="proxies" proxyType="tcp" />
|
||||
<ProxyView :proxies="proxies" proxyType="tcp" @refresh="fetchData" />
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
@@ -15,6 +15,7 @@ const fetchData = () => {
|
||||
return res.json()
|
||||
})
|
||||
.then((json) => {
|
||||
proxies.value = []
|
||||
for (let proxyStats of json.proxies) {
|
||||
proxies.value.push(new TCPProxy(proxyStats))
|
||||
}
|
||||
|
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<ProxyView :proxies="proxies" proxyType="udp" />
|
||||
<ProxyView :proxies="proxies" proxyType="udp" @refresh="fetchData"/>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
@@ -15,12 +15,12 @@ const fetchData = () => {
|
||||
return res.json()
|
||||
})
|
||||
.then((json) => {
|
||||
proxies.value = []
|
||||
for (let proxyStats of json.proxies) {
|
||||
proxies.value.push(new UDPProxy(proxyStats))
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
fetchData()
|
||||
</script>
|
||||
|
||||
|
@@ -1,5 +1,28 @@
|
||||
<template>
|
||||
<div>
|
||||
<el-page-header
|
||||
:icon="null"
|
||||
style="width: 100%; margin-left: 30px; margin-bottom: 20px"
|
||||
>
|
||||
<template #title>
|
||||
<span>{{ proxyType }}</span>
|
||||
</template>
|
||||
<template #content> </template>
|
||||
<template #extra>
|
||||
<div class="flex items-center" style="margin-right: 30px">
|
||||
<el-popconfirm
|
||||
title="Are you sure to clear all data of offline proxies?"
|
||||
@confirm="clearOfflineProxies"
|
||||
>
|
||||
<template #reference>
|
||||
<el-button>ClearOfflineProxies</el-button>
|
||||
</template>
|
||||
</el-popconfirm>
|
||||
<el-button @click="$emit('refresh')">Refresh</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-page-header>
|
||||
|
||||
<el-table
|
||||
:data="proxies"
|
||||
:default-sort="{ prop: 'name', order: 'ascending' }"
|
||||
@@ -67,6 +90,7 @@
|
||||
import * as Humanize from 'humanize-plus'
|
||||
import type { TableColumnCtx } from 'element-plus'
|
||||
import type { BaseProxy } from '../utils/proxy.js'
|
||||
import { ElMessage } from 'element-plus'
|
||||
import ProxyViewExpand from './ProxyViewExpand.vue'
|
||||
|
||||
defineProps<{
|
||||
@@ -74,6 +98,8 @@ defineProps<{
|
||||
proxyType: string
|
||||
}>()
|
||||
|
||||
const emit = defineEmits(['refresh'])
|
||||
|
||||
const formatTrafficIn = (row: BaseProxy, _: TableColumnCtx<BaseProxy>) => {
|
||||
return Humanize.fileSize(row.trafficIn)
|
||||
}
|
||||
@@ -81,4 +107,37 @@ const formatTrafficIn = (row: BaseProxy, _: TableColumnCtx<BaseProxy>) => {
|
||||
const formatTrafficOut = (row: BaseProxy, _: TableColumnCtx<BaseProxy>) => {
|
||||
return Humanize.fileSize(row.trafficOut)
|
||||
}
|
||||
|
||||
const clearOfflineProxies = () => {
|
||||
fetch('/api/proxies?status=offline', {
|
||||
method: 'DELETE',
|
||||
credentials: 'include',
|
||||
})
|
||||
.then((res) => {
|
||||
if (res.ok) {
|
||||
ElMessage({
|
||||
message: 'Successfully cleared offline proxies',
|
||||
type: 'success',
|
||||
})
|
||||
emit('refresh')
|
||||
} else {
|
||||
ElMessage({
|
||||
message: 'Failed to clear offline proxies: ' + res.status + ' ' + res.statusText,
|
||||
type: 'warning',
|
||||
})
|
||||
}
|
||||
})
|
||||
.catch((err) => {
|
||||
ElMessage({
|
||||
message: 'Failed to clear offline proxies: ' + err.message,
|
||||
type: 'warning',
|
||||
})
|
||||
})
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.el-page-header__title {
|
||||
font-size: 20px;
|
||||
}
|
||||
</style>
|
||||
|
@@ -17,10 +17,7 @@
|
||||
<el-form-item label="KCP Bind Port" v-if="data.kcpBindPort != 0">
|
||||
<span>{{ data.kcpBindPort }}</span>
|
||||
</el-form-item>
|
||||
<el-form-item
|
||||
label="QUIC Bind Port"
|
||||
v-if="data.quicBindPort != 0"
|
||||
>
|
||||
<el-form-item label="QUIC Bind Port" v-if="data.quicBindPort != 0">
|
||||
<span>{{ data.quicBindPort }}</span>
|
||||
</el-form-item>
|
||||
<el-form-item label="Http Port" v-if="data.vhostHTTPPort != 0">
|
||||
|
@@ -23,8 +23,10 @@ class BaseProxy {
|
||||
this.type = ''
|
||||
this.encryption = false
|
||||
this.compression = false
|
||||
this.encryption = (proxyStats.conf?.transport?.useEncryption) || this.encryption;
|
||||
this.compression = (proxyStats.conf?.transport?.useCompression) || this.compression;
|
||||
this.encryption =
|
||||
proxyStats.conf?.transport?.useEncryption || this.encryption
|
||||
this.compression =
|
||||
proxyStats.conf?.transport?.useCompression || this.compression
|
||||
this.conns = proxyStats.curConns
|
||||
this.trafficIn = proxyStats.todayTrafficIn
|
||||
this.trafficOut = proxyStats.todayTrafficOut
|
||||
@@ -76,12 +78,12 @@ class HTTPProxy extends BaseProxy {
|
||||
this.type = 'http'
|
||||
this.port = port
|
||||
if (proxyStats.conf) {
|
||||
this.customDomains = proxyStats.conf.customDomains || this.customDomains;
|
||||
this.customDomains = proxyStats.conf.customDomains || this.customDomains
|
||||
this.hostHeaderRewrite = proxyStats.conf.hostHeaderRewrite
|
||||
this.locations = proxyStats.conf.locations
|
||||
if (proxyStats.conf.subdomain) {
|
||||
this.subdomain = `${proxyStats.conf.subdomain}.${subdomainHost}`
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -92,7 +94,7 @@ class HTTPSProxy extends BaseProxy {
|
||||
this.type = 'https'
|
||||
this.port = port
|
||||
if (proxyStats.conf != null) {
|
||||
this.customDomains = proxyStats.conf.customDomains || this.customDomains;
|
||||
this.customDomains = proxyStats.conf.customDomains || this.customDomains
|
||||
if (proxyStats.conf.subdomain) {
|
||||
this.subdomain = `${proxyStats.conf.subdomain}.${subdomainHost}`
|
||||
}
|
||||
|
@@ -1,8 +0,0 @@
|
||||
{
|
||||
"extends": "@vue/tsconfig/tsconfig.node.json",
|
||||
"include": ["vite.config.*", "vitest.config.*", "cypress.config.*", "playwright.config.*"],
|
||||
"compilerOptions": {
|
||||
"composite": true,
|
||||
"types": ["node"]
|
||||
}
|
||||
}
|
@@ -1,16 +1,25 @@
|
||||
{
|
||||
"extends": "@vue/tsconfig/tsconfig.web.json",
|
||||
"include": ["env.d.ts", "src/**/*", "src/**/*.vue"],
|
||||
"compilerOptions": {
|
||||
"baseUrl": ".",
|
||||
"paths": {
|
||||
"@/*": ["./src/*"]
|
||||
}
|
||||
},
|
||||
"target": "ES2020",
|
||||
"useDefineForClassFields": true,
|
||||
"module": "ESNext",
|
||||
"lib": ["ES2020", "DOM", "DOM.Iterable"],
|
||||
"skipLibCheck": true,
|
||||
|
||||
"references": [
|
||||
{
|
||||
"path": "./tsconfig.config.json"
|
||||
}
|
||||
]
|
||||
/* Bundler mode */
|
||||
"moduleResolution": "bundler",
|
||||
"allowImportingTsExtensions": true,
|
||||
"resolveJsonModule": true,
|
||||
"isolatedModules": true,
|
||||
"noEmit": true,
|
||||
"jsx": "preserve",
|
||||
|
||||
/* Linting */
|
||||
"strict": true,
|
||||
"noUnusedLocals": true,
|
||||
"noUnusedParameters": true,
|
||||
"noFallthroughCasesInSwitch": true
|
||||
},
|
||||
"include": ["src/**/*.ts", "src/**/*.tsx", "src/**/*.vue"],
|
||||
"references": [{ "path": "./tsconfig.node.json" }]
|
||||
}
|
||||
|
10
web/frps/tsconfig.node.json
Normal file
10
web/frps/tsconfig.node.json
Normal file
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"composite": true,
|
||||
"skipLibCheck": true,
|
||||
"module": "ESNext",
|
||||
"moduleResolution": "bundler",
|
||||
"allowSyntheticDefaultImports": true
|
||||
},
|
||||
"include": ["vite.config.ts"]
|
||||
}
|
2225
web/frps/yarn.lock
2225
web/frps/yarn.lock
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user