import { makePersisted } from '@solid-primitives/storage' import { IconSettings, IconSortAscending, IconSortDescending, } from '@tabler/icons-solidjs' import { rankItem } from '@tanstack/match-sorter-utils' import { ColumnDef, FilterFn, SortingState, createSolidTable, flexRender, getCoreRowModel, getFilteredRowModel, getSortedRowModel, } from '@tanstack/solid-table' import { For, Index, createEffect, createSignal } from 'solid-js' import { twMerge } from 'tailwind-merge' import { Button, LogsSettingsModal } from '~/components' import { LOG_LEVEL } from '~/constants' import { useI18n } from '~/i18n' import { logsTableSize, tableSizeClassName, useWsRequest } from '~/signals' import { logLevel, logMaxRows } from '~/signals/config' import { Log } from '~/types' type LogWithSeq = Log & { seq: number } const fuzzyFilter: FilterFn = (row, columnId, value, addMeta) => { // Rank the item const itemRank = rankItem(row.getValue(columnId), value) // Store the itemRank info addMeta({ itemRank, }) // Return if the item should be filtered in/out return itemRank.passed } export default () => { let logsSettingsModalRef: HTMLDialogElement | undefined const [t] = useI18n() let seq = 1 const [logs, setLogs] = createSignal([]) const logsData = useWsRequest('logs', { level: logLevel() }) createEffect(() => { const data = logsData() if (!data) { return } setLogs((logs) => [{ ...data, seq }, ...logs].slice(0, logMaxRows())) seq++ }) const [globalFilter, setGlobalFilter] = createSignal('') const [sorting, setSorting] = makePersisted(createSignal([]), { name: 'logsTableSorting', storage: localStorage, }) const columns: ColumnDef[] = [ { header: t('sequence'), accessorFn: (row) => row.seq, }, { header: t('type'), accessorFn: (row) => row.type, cell: ({ row }) => { const type = row.original.type as LOG_LEVEL let className = '' switch (type) { case LOG_LEVEL.Error: className = 'text-error' break case LOG_LEVEL.Warning: className = 'text-warning' break case LOG_LEVEL.Info: className = 'text-info' break case LOG_LEVEL.Debug: className = 'text-success' break } return {`[${row.original.type}]`} }, }, { header: t('payload'), accessorFn: (row) => row.payload, }, ] const table = createSolidTable({ filterFns: { fuzzy: fuzzyFilter, }, state: { get globalFilter() { return globalFilter() }, get sorting() { return sorting() }, }, get data() { return logs() }, sortDescFirst: true, columns, onGlobalFilterChange: setGlobalFilter, onSortingChange: setSorting, globalFilterFn: fuzzyFilter, getFilteredRowModel: getFilteredRowModel(), getSortedRowModel: getSortedRowModel(), getCoreRowModel: getCoreRowModel(), }) return (
setGlobalFilter(e.target.value)} />
{(keyedHeaderGroup) => { const headerGroup = keyedHeaderGroup() return ( {(keyedHeader) => { const header = keyedHeader() return ( ) }} ) }} {(row) => ( {(cell) => ( )} )}
{flexRender( header.column.columnDef.header, header.getContext(), )}
{{ asc: , desc: , }[header.column.getIsSorted() as string] ?? null}
{flexRender( cell.column.columnDef.cell, cell.getContext(), )}
(logsSettingsModalRef = el)} />
) }