mirror of
https://github.com/fatedier/frp.git
synced 2025-07-27 07:35:07 +00:00
proxy supports configuring annotations, which will be displayed in the frps dashboard (#4000)
This commit is contained in:
4
web/frps/components.d.ts
vendored
4
web/frps/components.d.ts
vendored
@@ -9,19 +9,21 @@ declare module 'vue' {
|
||||
export interface GlobalComponents {
|
||||
ElButton: typeof import('element-plus/es')['ElButton']
|
||||
ElCol: typeof import('element-plus/es')['ElCol']
|
||||
ElDialog: typeof import('element-plus/es')['ElDialog']
|
||||
ElDivider: typeof import('element-plus/es')['ElDivider']
|
||||
ElForm: typeof import('element-plus/es')['ElForm']
|
||||
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']
|
||||
ElSwitch: typeof import('element-plus/es')['ElSwitch']
|
||||
ElTable: typeof import('element-plus/es')['ElTable']
|
||||
ElTableColumn: typeof import('element-plus/es')['ElTableColumn']
|
||||
ElTag: typeof import('element-plus/es')['ElTag']
|
||||
ElText: typeof import('element-plus/es')['ElText']
|
||||
ElTooltip: typeof import('element-plus/es')['ElTooltip']
|
||||
LongSpan: typeof import('./src/components/LongSpan.vue')['default']
|
||||
ProxiesHTTP: typeof import('./src/components/ProxiesHTTP.vue')['default']
|
||||
|
@@ -30,27 +30,6 @@
|
||||
>
|
||||
<el-table-column type="expand">
|
||||
<template #default="props">
|
||||
<el-popover
|
||||
placement="right"
|
||||
width="600"
|
||||
style="margin-left: 0px"
|
||||
trigger="click"
|
||||
>
|
||||
<template #default>
|
||||
<Traffic :proxyName="props.row.name" />
|
||||
</template>
|
||||
|
||||
<template #reference>
|
||||
<el-button
|
||||
type="primary"
|
||||
size="large"
|
||||
:name="props.row.name"
|
||||
style="margin-bottom: 10px"
|
||||
>Traffic Statistics
|
||||
</el-button>
|
||||
</template>
|
||||
</el-popover>
|
||||
|
||||
<ProxyViewExpand :row="props.row" :proxyType="proxyType" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
@@ -82,8 +61,27 @@
|
||||
<el-tag v-else type="danger">{{ scope.row.status }}</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="Operations">
|
||||
<template #default="scope">
|
||||
<el-button
|
||||
type="primary"
|
||||
:name="scope.row.name"
|
||||
style="margin-bottom: 10px"
|
||||
@click="dialogVisibleName = scope.row.name; dialogVisible = true"
|
||||
>Traffic
|
||||
</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</div>
|
||||
|
||||
<el-dialog
|
||||
v-model="dialogVisible"
|
||||
destroy-on-close="true"
|
||||
:title="dialogVisibleName"
|
||||
width="700px">
|
||||
<Traffic :proxyName="dialogVisibleName" />
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
@@ -92,6 +90,7 @@ import type { TableColumnCtx } from 'element-plus'
|
||||
import type { BaseProxy } from '../utils/proxy.js'
|
||||
import { ElMessage } from 'element-plus'
|
||||
import ProxyViewExpand from './ProxyViewExpand.vue'
|
||||
import { ref } from 'vue'
|
||||
|
||||
defineProps<{
|
||||
proxies: BaseProxy[]
|
||||
@@ -100,6 +99,9 @@ defineProps<{
|
||||
|
||||
const emit = defineEmits(['refresh'])
|
||||
|
||||
const dialogVisible = ref(false)
|
||||
const dialogVisibleName = ref("")
|
||||
|
||||
const formatTrafficIn = (row: BaseProxy, _: TableColumnCtx<BaseProxy>) => {
|
||||
return Humanize.fileSize(row.trafficIn)
|
||||
}
|
||||
|
@@ -60,11 +60,56 @@
|
||||
<span>{{ row.lastCloseTime }}</span>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
|
||||
<div v-if="row.annotations && row.annotations.size > 0">
|
||||
<el-divider />
|
||||
<el-text class="title-text" size="large">Annotations</el-text>
|
||||
<ul>
|
||||
<li v-for="item in annotationsArray()">
|
||||
<span class="annotation-key">{{ item.key }}</span>
|
||||
<span>{{ item.value }}</span>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
defineProps<{
|
||||
|
||||
const props = defineProps<{
|
||||
row: any
|
||||
proxyType: string
|
||||
}>()
|
||||
|
||||
// annotationsArray returns an array of key-value pairs from the annotations map.
|
||||
const annotationsArray = (): Array<{ key: string; value: string }> => {
|
||||
const array: Array<{ key: string; value: any }> = [];
|
||||
if (props.row.annotations) {
|
||||
props.row.annotations.forEach((value: any, key: string) => {
|
||||
array.push({ key, value });
|
||||
});
|
||||
}
|
||||
return array;
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
ul {
|
||||
list-style-type: none;
|
||||
padding: 5px;
|
||||
}
|
||||
|
||||
ul li {
|
||||
justify-content: space-between;
|
||||
padding: 5px;
|
||||
}
|
||||
|
||||
ul .annotation-key {
|
||||
width: 300px;
|
||||
display: inline-block;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.title-text {
|
||||
color: #99a9bf;
|
||||
}
|
||||
</style>
|
||||
|
@@ -1,6 +1,7 @@
|
||||
class BaseProxy {
|
||||
name: string
|
||||
type: string
|
||||
annotations: Map<string, string>
|
||||
encryption: boolean
|
||||
compression: boolean
|
||||
conns: number
|
||||
@@ -21,6 +22,13 @@ class BaseProxy {
|
||||
constructor(proxyStats: any) {
|
||||
this.name = proxyStats.name
|
||||
this.type = ''
|
||||
this.annotations = new Map<string, string>()
|
||||
if (proxyStats.conf?.annotations) {
|
||||
for (const key in proxyStats.conf.annotations) {
|
||||
this.annotations.set(key, proxyStats.conf.annotations[key])
|
||||
}
|
||||
}
|
||||
|
||||
this.encryption = false
|
||||
this.compression = false
|
||||
this.encryption =
|
||||
|
Reference in New Issue
Block a user