mirror of
https://github.com/MetaCubeX/metacubexd.git
synced 2024-11-10 05:15:35 +08:00
feat(logs): render logs in table
This commit is contained in:
parent
4a16271bb0
commit
7eee024cdc
@ -7,7 +7,6 @@ mode: rule
|
|||||||
log-level: info
|
log-level: info
|
||||||
ipv6: true
|
ipv6: true
|
||||||
external-controller: 0.0.0.0:9090
|
external-controller: 0.0.0.0:9090
|
||||||
external-ui: ui
|
|
||||||
global-client-fingerprint: random
|
global-client-fingerprint: random
|
||||||
|
|
||||||
profile:
|
profile:
|
||||||
|
@ -1,11 +1,21 @@
|
|||||||
import { createEventSignal } from '@solid-primitives/event-listener'
|
import { createEventSignal } from '@solid-primitives/event-listener'
|
||||||
import { createReconnectingWS } from '@solid-primitives/websocket'
|
import { createReconnectingWS } from '@solid-primitives/websocket'
|
||||||
|
import {
|
||||||
|
ColumnDef,
|
||||||
|
createSolidTable,
|
||||||
|
flexRender,
|
||||||
|
getCoreRowModel,
|
||||||
|
} from '@tanstack/solid-table'
|
||||||
import { For, createEffect, createSignal } from 'solid-js'
|
import { For, createEffect, createSignal } from 'solid-js'
|
||||||
import { secret, wsEndpointURL } from '~/signals'
|
import { secret, wsEndpointURL } from '~/signals'
|
||||||
|
import { Log } from '~/types'
|
||||||
|
|
||||||
|
type LogWithSeq = Log & { seq: number }
|
||||||
|
|
||||||
export default () => {
|
export default () => {
|
||||||
|
let seq = 0
|
||||||
const [search, setSearch] = createSignal('')
|
const [search, setSearch] = createSignal('')
|
||||||
const [logs, setLogs] = createSignal<string[]>([])
|
const [logs, setLogs] = createSignal<LogWithSeq[]>([])
|
||||||
|
|
||||||
const ws = createReconnectingWS(`${wsEndpointURL()}/logs?token=${secret()}`)
|
const ws = createReconnectingWS(`${wsEndpointURL()}/logs?token=${secret()}`)
|
||||||
|
|
||||||
@ -21,11 +31,37 @@ export default () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
setLogs((logs) =>
|
setLogs((logs) =>
|
||||||
[
|
[{ ...(JSON.parse(data) as Log), seq }, ...logs].slice(0, 100),
|
||||||
...logs,
|
|
||||||
(JSON.parse(data) as { type: string; payload: string }).payload,
|
|
||||||
].slice(-100),
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
seq++
|
||||||
|
})
|
||||||
|
|
||||||
|
const columns: ColumnDef<LogWithSeq>[] = [
|
||||||
|
{
|
||||||
|
accessorKey: 'Sequence',
|
||||||
|
accessorFn: (row) => row.seq,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
accessorKey: 'Type',
|
||||||
|
accessorFn: (row) => row.type,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
accessorKey: 'Payload',
|
||||||
|
accessorFn: (row) => row.payload,
|
||||||
|
},
|
||||||
|
]
|
||||||
|
|
||||||
|
const table = createSolidTable({
|
||||||
|
get data() {
|
||||||
|
return search()
|
||||||
|
? logs().filter((log) =>
|
||||||
|
log.payload.toLowerCase().includes(search().toLowerCase()),
|
||||||
|
)
|
||||||
|
: logs()
|
||||||
|
},
|
||||||
|
columns,
|
||||||
|
getCoreRowModel: getCoreRowModel(),
|
||||||
})
|
})
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@ -37,21 +73,49 @@ export default () => {
|
|||||||
/>
|
/>
|
||||||
|
|
||||||
<div class="overflow-x-auto whitespace-nowrap">
|
<div class="overflow-x-auto whitespace-nowrap">
|
||||||
<For
|
<table class="table table-zebra-zebra table-xs bg-base-200">
|
||||||
each={
|
<thead>
|
||||||
search()
|
<For each={table.getHeaderGroups()}>
|
||||||
? logs().filter((log) =>
|
{(headerGroup) => (
|
||||||
log.toLowerCase().includes(search().toLowerCase()),
|
<tr>
|
||||||
)
|
<For each={headerGroup.headers}>
|
||||||
: logs()
|
{(header) => (
|
||||||
}
|
<th class="bg-base-300">
|
||||||
>
|
<div>
|
||||||
{(log) => (
|
{header.isPlaceholder
|
||||||
<div class="flex gap-4">
|
? null
|
||||||
<div class="flex-shrink-0">{log}</div>
|
: flexRender(
|
||||||
|
header.column.columnDef.header,
|
||||||
|
header.getContext(),
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
</th>
|
||||||
)}
|
)}
|
||||||
</For>
|
</For>
|
||||||
|
</tr>
|
||||||
|
)}
|
||||||
|
</For>
|
||||||
|
</thead>
|
||||||
|
|
||||||
|
<tbody>
|
||||||
|
<For each={table.getRowModel().rows}>
|
||||||
|
{(row) => (
|
||||||
|
<tr>
|
||||||
|
<For each={row.getVisibleCells()}>
|
||||||
|
{(cell) => (
|
||||||
|
<td>
|
||||||
|
{flexRender(
|
||||||
|
cell.column.columnDef.cell,
|
||||||
|
cell.getContext(),
|
||||||
|
)}
|
||||||
|
</td>
|
||||||
|
)}
|
||||||
|
</For>
|
||||||
|
</tr>
|
||||||
|
)}
|
||||||
|
</For>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
|
@ -195,7 +195,7 @@ export default () => {
|
|||||||
</TrafficWidget>
|
</TrafficWidget>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="mx-auto grid w-full max-w-screen-lg grid-cols-1 gap-4">
|
<div class="mx-auto grid h-full w-full max-w-screen-xl grid-cols-1 gap-4">
|
||||||
<SolidApexCharts
|
<SolidApexCharts
|
||||||
type="area"
|
type="area"
|
||||||
options={trafficChartOptions()}
|
options={trafficChartOptions()}
|
||||||
|
5
src/types.d.ts
vendored
5
src/types.d.ts
vendored
@ -100,6 +100,11 @@ export type Connection = {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export type Log = {
|
||||||
|
type: string
|
||||||
|
payload: string
|
||||||
|
}
|
||||||
|
|
||||||
export type Config = {
|
export type Config = {
|
||||||
port: number
|
port: number
|
||||||
'socks-port': number
|
'socks-port': number
|
||||||
|
Loading…
Reference in New Issue
Block a user