11import Collapse from "@/assets/icons/collapse-text.svg?react" ;
22import Expand from "@/assets/icons/expand-full.svg?react" ;
3- import { LogEntry as LogEntryType } from "@/types/logs" ; // Assuming types are in src/types/logs.ts
4- import { Button } from "@zenml-io/react-component-library/components/server" ;
5- import React , { useState } from "react" ;
3+ import { LogEntryInternal } from "@/types/logs" ; // Assuming types are in src/types/logs.ts
4+ import { Button , Input } from "@zenml-io/react-component-library/components/server" ;
5+ import React , { useCallback , useState } from "react" ;
6+ import { EmptyStateLogs } from "./empty-state-logs" ;
67import LogLine from "./log-line" ; // Import the LogLine component
78import { LogToolbar } from "./toolbar" ;
89import { useLogSearch } from "./use-log-search" ;
9- import { EmptyStateLogs } from "./empty-state-logs" ;
10+ import { useLogLevelFilter } from "./use-loglevel-filter" ;
11+ import { useLogPageInput } from "./use-logpage-input" ;
1012
1113interface EnhancedLogsViewerProps {
12- logs : LogEntryType [ ] ;
14+ logs : LogEntryInternal [ ] ;
1315 itemsPerPage ?: number ; // Optional prop for items per page
1416}
1517
@@ -19,10 +21,15 @@ export function EnhancedLogsViewer({
1921 logs,
2022 itemsPerPage = DEFAULT_ITEMS_PER_PAGE
2123} : EnhancedLogsViewerProps ) {
22- const [ currentPage , setCurrentPage ] = useState ( 1 ) ;
24+ const [ currentPage , setCurrentPageState ] = useState ( 1 ) ;
2325 const [ textWrapEnabled , setTextWrapEnabled ] = useState ( true ) ;
2426
25- // Initialize search functionality on filtered logs
27+ const {
28+ filteredLogs : filteredLogsByLogLevel ,
29+ selectedLogLevel,
30+ setSelectedLogLevel
31+ } = useLogLevelFilter ( logs ) ;
32+
2633 const {
2734 searchQuery,
2835 setSearchQuery,
@@ -32,27 +39,42 @@ export function EnhancedLogsViewer({
3239 goToNextMatch,
3340 goToPreviousMatch,
3441 highlightText
35- } = useLogSearch ( logs ) ;
42+ } = useLogSearch ( filteredLogsByLogLevel ) ;
3643
3744 // Use search + filtered logs for pagination
3845 const logsToDisplay = searchAndFilteredLogs ;
3946
4047 // Reset to first page when search or filters change
41- React . useEffect ( ( ) => {
42- setCurrentPage ( 1 ) ;
43- } , [ searchQuery ] ) ;
4448
4549 const totalPages = Math . ceil ( logsToDisplay . length / itemsPerPage ) ;
4650 const startIndex = ( currentPage - 1 ) * itemsPerPage ;
4751 const endIndex = startIndex + itemsPerPage ;
4852 const currentLogs = logsToDisplay . slice ( startIndex , endIndex ) ;
4953
54+ const { form } = useLogPageInput ( currentPage , totalPages ) ;
55+
56+ const setCurrentPage = useCallback (
57+ ( page : number ) => {
58+ setCurrentPageState ( page ) ;
59+ form . setValue ( "page" , page ) ;
60+ } ,
61+ [ form ]
62+ ) ;
63+
64+ function handlePageSubmit ( data : { page : number } ) {
65+ setCurrentPage ( data . page ) ;
66+ }
67+
68+ React . useEffect ( ( ) => {
69+ setCurrentPage ( 1 ) ;
70+ } , [ searchQuery ] ) ;
71+
5072 const handlePreviousPage = ( ) => {
51- setCurrentPage ( ( prev ) => Math . max ( prev - 1 , 1 ) ) ;
73+ setCurrentPage ( Math . max ( currentPage - 1 , 1 ) ) ;
5274 } ;
5375
5476 const handleNextPage = ( ) => {
55- setCurrentPage ( ( prev ) => Math . min ( prev + 1 , totalPages ) ) ;
77+ setCurrentPage ( Math . min ( currentPage + 1 , totalPages ) ) ;
5678 } ;
5779
5880 const handleFirstPage = ( ) => {
@@ -64,15 +86,14 @@ export function EnhancedLogsViewer({
6486 } ;
6587
6688 const handleCopyAllLogs = ( ) => {
67- const logText = getOriginalLogText ( logsToDisplay ) ;
68-
89+ const logText = getOriginalLogText ( logs ) ;
6990 navigator . clipboard . writeText ( logText ) . catch ( ( err ) => {
7091 console . error ( "Failed to copy logs:" , err ) ;
7192 } ) ;
7293 } ;
7394
7495 const handleDownloadLogs = ( ) => {
75- const logText = getOriginalLogText ( logsToDisplay ) ;
96+ const logText = getOriginalLogText ( logs ) ;
7697 const blob = new Blob ( [ logText ] , { type : "text/plain" } ) ;
7798 const url = URL . createObjectURL ( blob ) ;
7899 const a = document . createElement ( "a" ) ;
@@ -89,10 +110,12 @@ export function EnhancedLogsViewer({
89110 } ;
90111
91112 // Empty state - no logs at all
92- if ( ! logs ) {
113+ if ( ! logs || searchAndFilteredLogs . length === 0 ) {
93114 return (
94115 < div className = "flex h-full flex-col space-y-5" >
95116 < LogToolbar
117+ logLevel = { selectedLogLevel }
118+ setLogLevel = { setSelectedLogLevel }
96119 onSearchChange = { setSearchQuery }
97120 onCopyAll = { handleCopyAllLogs }
98121 onDownload = { handleDownloadLogs }
@@ -113,6 +136,8 @@ export function EnhancedLogsViewer({
113136 return (
114137 < div className = "flex h-full flex-col space-y-5" >
115138 < LogToolbar
139+ logLevel = { selectedLogLevel }
140+ setLogLevel = { setSelectedLogLevel }
116141 onSearchChange = { setSearchQuery }
117142 onCopyAll = { handleCopyAllLogs }
118143 onDownload = { handleDownloadLogs }
@@ -129,7 +154,7 @@ export function EnhancedLogsViewer({
129154 { /* Table-style header with fixed structure */ }
130155 < div className = "flex w-full min-w-[600px] space-x-3 bg-theme-surface-tertiary px-4 py-1 font-medium text-theme-text-secondary" >
131156 { /* Type column header - match LogLine badge area */ }
132- < div className = "flex w-8 flex-shrink-0 items-center" >
157+ < div className = "flex w-12 flex-shrink-0 items-center" >
133158 < span className = "text-text-sm font-semibold" > Type</ span >
134159 </ div >
135160
@@ -216,9 +241,14 @@ export function EnhancedLogsViewer({
216241 >
217242 Previous
218243 </ Button >
219- < span className = "text-sm text-theme-text-secondary" >
220- Page { currentPage } of { totalPages }
221- </ span >
244+ < form
245+ onSubmit = { form . handleSubmit ( handlePageSubmit ) }
246+ className = "text-sm flex items-center gap-1 text-theme-text-secondary"
247+ >
248+ Page
249+ < Input { ...form . register ( "page" ) } className = "w-10" />
250+ of { totalPages }
251+ </ form >
222252 < Button
223253 className = "bg-theme-surface-primary"
224254 size = "md"
@@ -248,6 +278,6 @@ export function EnhancedLogsViewer({
248278 ) ;
249279}
250280
251- function getOriginalLogText ( logs : LogEntryType [ ] ) {
281+ function getOriginalLogText ( logs : LogEntryInternal [ ] ) {
252282 return logs . map ( ( log ) => log . originalEntry ) . join ( "\n" ) ;
253283}
0 commit comments