feat(connections): add closed connections tab

This commit is contained in:
kunish 2023-09-06 01:19:37 +08:00
parent b91332c53d
commit f0e32d93f6
No known key found for this signature in database
GPG Key ID: 647A12B4F782C430
3 changed files with 66 additions and 23 deletions

View File

@ -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',
} }

View File

@ -67,4 +67,5 @@ export default {
switchEndpoint: '切换后端', switchEndpoint: '切换后端',
switchLanguage: '切换语言', switchLanguage: '切换语言',
requestTimeoutDuration: '请求超时时间', requestTimeoutDuration: '请求超时时间',
closedConnections: '已关闭连接',
} }

View File

@ -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">