diff --git a/src/client/components/LogsNext.tsx b/src/client/components/LogsNext.tsx index 7be8dd4f..dc666b12 100644 --- a/src/client/components/LogsNext.tsx +++ b/src/client/components/LogsNext.tsx @@ -1,12 +1,13 @@ import React, {PropsWithChildren, useState, useEffect} from 'react'; import * as AnsiImport from "ansi-to-react"; -import { Text, Box } from '@chakra-ui/react'; +import { Text, Box, SegmentGroup, Separator, HStack, Stack, Span } from '@chakra-ui/react'; import {FixedSizeList} from "fixed-size-list"; import {useSSE} from "@flamefrontend/sse-runtime-react"; -import { useQueryClient, QueryFunctionContext, useQuery } from '@tanstack/react-query' +import { useQueryClient, QueryFunctionContext, useQuery, useMutation } from '@tanstack/react-query' import { LogOutputConfig } from '../../core/Atomic'; import ky from 'ky'; import { baseUrl } from '../utils'; +import { LogLevel } from '@foxxmd/logging'; // @ts-expect-error Ansi export is built incorrectly const Ansi = AnsiImport.default.default as typeof AnsiImport.default; @@ -49,12 +50,15 @@ export const LogsFetchable = (props: {settings?: LogOutputConfig, streamable?: b streamable = true } = props; + const client = useQueryClient(); const [logLevel, setLogLevel] = useState(level); + const [logLimit, setLogLimit] = useState(limit); const [logList, setLogList] = useState([]); const { isPending, isError, data, error } = useQuery({ - queryKey: ['logs', { level: logLevel }], - queryFn: queryFn + queryKey: ['logs', { level: logLevel, limit: logLimit }], + queryFn: queryFn, + staleTime: Infinity }); const connection = useSSE<{stream: MinLogInfo}>({ @@ -71,18 +75,62 @@ export const LogsFetchable = (props: {settings?: LogOutputConfig, streamable?: b } }); + const mutateLogSettings = useMutation({ + mutationFn: (settings: Partial) => ky.put('/api/logs', {json: settings}), + onSuccess: (sentData, variables) => { + if(variables.level !== undefined) { + setLogLevel(variables.level); + } + if(variables.limit !== undefined) { + setLogLimit(variables.limit); + } + client.invalidateQueries({ + queryKey: ['logs', { level: variables.level ?? logLevel, limit: variables.limit ?? logLimit }], + refetchType: 'all' + }) + } + }); + + const levelGroup = { + mutateLogSettings.mutate({level: val.value as LogLevel}); + }}> + + + + + const limitGroup = { + mutateLogSettings.mutate({limit: Number.parseInt(val.value)}); + }}> + + + + useEffect(() => { if(data !== undefined) { - list = createFixedList(limit, data.data.map((x, index) => ({...x, message: x.line, id: x.time.toString(), levelLabel: x.levelLabel, level: x.level}))); + list = createFixedList(logLimit, data.data.map((x, index) => ({...x, message: x.line, id: x.time.toString(), levelLabel: x.levelLabel, level: x.level}))); setLogList(Array.from(list.data)); } }, [data, limit,setLogList]); - return + return ( + Level: {levelGroup}Limit: {limitGroup} + + ); } -type LogsQueryKey = ['logs', {level: string}]; +type LogsQueryKey = ['logs', {level: string, limit: number}]; const queryFn = async (context: QueryFunctionContext) => { return await ky.get(`logs`, { baseUrl: baseUrl }).json() as {data: {line: string, time: number, levelLabel: string, level: number}[]}; } \ No newline at end of file