mirror of
https://github.com/MetaCubeX/metacubexd.git
synced 2024-11-24 09:45:35 +08:00
feat(connections): add closed connections tab
This commit is contained in:
parent
b91332c53d
commit
f0e32d93f6
@ -67,4 +67,5 @@ export default {
|
|||||||
switchEndpoint: 'Switch Endpoint',
|
switchEndpoint: 'Switch Endpoint',
|
||||||
switchLanguage: 'Switch Language',
|
switchLanguage: 'Switch Language',
|
||||||
requestTimeoutDuration: 'Request Timeout Duration',
|
requestTimeoutDuration: 'Request Timeout Duration',
|
||||||
|
closedConnections: 'Closed Connections',
|
||||||
}
|
}
|
||||||
|
@ -67,4 +67,5 @@ export default {
|
|||||||
switchEndpoint: '切换后端',
|
switchEndpoint: '切换后端',
|
||||||
switchLanguage: '切换语言',
|
switchLanguage: '切换语言',
|
||||||
requestTimeoutDuration: '请求超时时间',
|
requestTimeoutDuration: '请求超时时间',
|
||||||
|
closedConnections: '已关闭连接',
|
||||||
}
|
}
|
||||||
|
@ -26,6 +26,7 @@ import {
|
|||||||
import byteSize from 'byte-size'
|
import byteSize from 'byte-size'
|
||||||
import dayjs from 'dayjs'
|
import dayjs from 'dayjs'
|
||||||
import { isIPv6 } from 'is-ip'
|
import { isIPv6 } from 'is-ip'
|
||||||
|
import { differenceWith, isEqualWith } from 'lodash'
|
||||||
import { For, createEffect, createSignal } from 'solid-js'
|
import { For, createEffect, createSignal } from 'solid-js'
|
||||||
import { twMerge } from 'tailwind-merge'
|
import { twMerge } from 'tailwind-merge'
|
||||||
import { Button, ConnectionsTableOrderingModal } from '~/components'
|
import { Button, ConnectionsTableOrderingModal } from '~/components'
|
||||||
@ -47,11 +48,17 @@ type ConnectionWithSpeed = Connection & {
|
|||||||
type ColumnVisibility = Partial<Record<CONNECTIONS_TABLE_ACCESSOR_KEY, boolean>>
|
type ColumnVisibility = Partial<Record<CONNECTIONS_TABLE_ACCESSOR_KEY, boolean>>
|
||||||
type ColumnOrder = CONNECTIONS_TABLE_ACCESSOR_KEY[]
|
type ColumnOrder = CONNECTIONS_TABLE_ACCESSOR_KEY[]
|
||||||
|
|
||||||
|
enum ActiveTab {
|
||||||
|
activeConnections = 'activeConnections',
|
||||||
|
closedConnections = 'closedConnections',
|
||||||
|
}
|
||||||
|
|
||||||
export default () => {
|
export default () => {
|
||||||
const [t] = useI18n()
|
const [t] = useI18n()
|
||||||
const request = useRequest()
|
const request = useRequest()
|
||||||
|
|
||||||
const [search, setSearch] = createSignal('')
|
const [search, setSearch] = createSignal('')
|
||||||
|
const [activeTab, setActiveTab] = createSignal(ActiveTab.activeConnections)
|
||||||
|
|
||||||
const ws = createReconnectingWS(
|
const ws = createReconnectingWS(
|
||||||
`${wsEndpointURL()}/connections?token=${secret()}`,
|
`${wsEndpointURL()}/connections?token=${secret()}`,
|
||||||
@ -61,9 +68,11 @@ export default () => {
|
|||||||
message: WebSocketEventMap['message']
|
message: WebSocketEventMap['message']
|
||||||
}>(ws, 'message')
|
}>(ws, 'message')
|
||||||
|
|
||||||
const [connectionsWithSpeed, setConnectionsWithSpeed] = createSignal<
|
const [closedConnectionsWithSpeed, setClosedConnectionsWithSpeed] =
|
||||||
ConnectionWithSpeed[]
|
createSignal<ConnectionWithSpeed[]>([])
|
||||||
>([])
|
|
||||||
|
const [activeConnectionsWithSpeed, setActiveConnectionsWithSpeed] =
|
||||||
|
createSignal<ConnectionWithSpeed[]>([])
|
||||||
|
|
||||||
createEffect(() => {
|
createEffect(() => {
|
||||||
const data = messageEvent()?.data
|
const data = messageEvent()?.data
|
||||||
@ -72,7 +81,7 @@ export default () => {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
setConnectionsWithSpeed((prevConnections) => {
|
setActiveConnectionsWithSpeed((prevConnections) => {
|
||||||
const prevMap = new Map<string, Connection>()
|
const prevMap = new Map<string, Connection>()
|
||||||
prevConnections.forEach((prev) => prevMap.set(prev.id, prev))
|
prevConnections.forEach((prev) => prevMap.set(prev.id, prev))
|
||||||
|
|
||||||
@ -96,6 +105,16 @@ export default () => {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const closedConnections = differenceWith(
|
||||||
|
prevConnections,
|
||||||
|
connections,
|
||||||
|
(a, b) => isEqualWith(a, b, (a, b) => a.id === b.id),
|
||||||
|
)
|
||||||
|
|
||||||
|
setClosedConnectionsWithSpeed((prev) =>
|
||||||
|
[...prev, ...closedConnections].slice(-1000),
|
||||||
|
)
|
||||||
|
|
||||||
return connections.slice(-100)
|
return connections.slice(-100)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
@ -249,7 +268,9 @@ export default () => {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
get data() {
|
get data() {
|
||||||
return connectionsWithSpeed()
|
return activeTab() === ActiveTab.activeConnections
|
||||||
|
? activeConnectionsWithSpeed()
|
||||||
|
: closedConnectionsWithSpeed()
|
||||||
},
|
},
|
||||||
sortDescFirst: true,
|
sortDescFirst: true,
|
||||||
enableHiding: true,
|
enableHiding: true,
|
||||||
@ -266,32 +287,52 @@ export default () => {
|
|||||||
|
|
||||||
const tableSizeClassName = () => {
|
const tableSizeClassName = () => {
|
||||||
const size = tableSize()
|
const size = tableSize()
|
||||||
|
let className = 'table-xs'
|
||||||
|
|
||||||
if (size === TAILWINDCSS_SIZE.XS) {
|
switch (size) {
|
||||||
return 'table-xs'
|
case TAILWINDCSS_SIZE.XS:
|
||||||
|
className = 'table-xs'
|
||||||
|
break
|
||||||
|
case TAILWINDCSS_SIZE.SM:
|
||||||
|
className = 'table-sm'
|
||||||
|
break
|
||||||
|
case TAILWINDCSS_SIZE.MD:
|
||||||
|
className = 'table-md'
|
||||||
|
break
|
||||||
|
case TAILWINDCSS_SIZE.LG:
|
||||||
|
className = 'table-lg'
|
||||||
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
if (size === TAILWINDCSS_SIZE.SM) {
|
return className
|
||||||
return 'table-sm'
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (size === TAILWINDCSS_SIZE.MD) {
|
const tabs = () => [
|
||||||
return 'table-md'
|
{
|
||||||
}
|
type: ActiveTab.activeConnections,
|
||||||
|
name: t('activeConnections'),
|
||||||
if (size === TAILWINDCSS_SIZE.LG) {
|
count: activeConnectionsWithSpeed().length,
|
||||||
return 'table-lg'
|
},
|
||||||
}
|
{
|
||||||
|
type: ActiveTab.closedConnections,
|
||||||
return ''
|
name: t('closedConnections'),
|
||||||
}
|
count: closedConnectionsWithSpeed().length,
|
||||||
|
},
|
||||||
|
]
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div class="flex h-full flex-col gap-4 overflow-y-auto p-1">
|
<div class="flex h-full flex-col gap-4 overflow-y-auto p-1">
|
||||||
<div class="tabs-boxed tabs">
|
<div class="tabs-boxed tabs">
|
||||||
<button class="tab tab-active">
|
<For each={tabs()}>
|
||||||
{t('activeConnections')} ({connectionsWithSpeed().length})
|
{(tab) => (
|
||||||
|
<button
|
||||||
|
class={twMerge(activeTab() === tab.type && 'tab-active', 'tab')}
|
||||||
|
onClick={() => setActiveTab(tab.type)}
|
||||||
|
>
|
||||||
|
{tab.name} ({tab.count})
|
||||||
</button>
|
</button>
|
||||||
|
)}
|
||||||
|
</For>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="flex w-full items-center gap-2">
|
<div class="flex w-full items-center gap-2">
|
||||||
|
Loading…
Reference in New Issue
Block a user