1- import { CircularProgress } from '@mui/material' ;
1+ import { ExpandCircleDown } from '@mui/icons-material' ;
2+ import { Button , CircularProgress } from '@mui/material' ;
23import { useEffect , useRef } from 'react' ;
34import { ErrorBoundary } from 'react-error-boundary' ;
45
@@ -9,19 +10,55 @@ import { SystemLogsErrorFallback } from '@/components/Service/SystemLog/SystemLo
910import { SomethingWentWrong } from '@/components/SomethingWentWrong/SomethingWentWrong' ;
1011import { Line } from '@/components/Text' ;
1112import { ServiceNames } from '@/constants/service' ;
13+ import { useBoolState } from '@/hooks/useEasyState' ;
1214import { useSystemLogs } from '@/hooks/useSystemLogs' ;
1315import { parseLogLine } from '@/utils/logFormatter' ;
1416
17+ import { MotionBox } from '../../components/MotionComponents' ;
18+
1519export const SystemLogs = ( { serviceName } : { serviceName ?: ServiceNames } ) => {
1620 const { services, loading, logs } = useSystemLogs ( { serviceName } ) ;
17-
21+ const showScrollDownButton = useBoolState ( false ) ;
1822 const containerRef = useRef < HTMLDivElement > ( null ) ;
1923
24+ const scrollDown = ( ) => {
25+ containerRef . current . scrollIntoView ( { behavior : 'smooth' } ) ;
26+ } ;
27+
2028 useEffect ( ( ) => {
29+ const observer = new IntersectionObserver (
30+ ( entries ) => {
31+ entries . forEach ( ( entry ) => {
32+ if ( entry . isIntersecting ) {
33+ showScrollDownButton . false ( ) ;
34+ } else {
35+ showScrollDownButton . true ( ) ;
36+ }
37+ } ) ;
38+ } ,
39+ {
40+ threshold : 0
41+ }
42+ ) ;
43+
44+ const containerElement = containerRef . current ;
45+
2146 if ( containerRef . current ) {
22- containerRef . current . scrollIntoView ( { behavior : 'smooth' } ) ;
47+ observer . observe ( containerElement ) ;
2348 }
24- } , [ logs ] ) ;
49+
50+ return ( ) => {
51+ if ( containerElement ) {
52+ observer . unobserve ( containerElement ) ;
53+ }
54+ } ;
55+ } , [ showScrollDownButton ] ) ;
56+
57+ useEffect ( ( ) => {
58+ if ( containerRef . current && ! showScrollDownButton . value ) {
59+ scrollDown ( ) ;
60+ }
61+ } , [ logs , showScrollDownButton . value ] ) ;
2562
2663 if ( ! serviceName )
2764 return (
@@ -51,6 +88,29 @@ export const SystemLogs = ({ serviceName }: { serviceName?: ServiceNames }) => {
5188 } )
5289 ) }
5390 < FlexBox ref = { containerRef } />
91+
92+ { showScrollDownButton . value && (
93+ < Button
94+ onClick = { scrollDown }
95+ component = { MotionBox }
96+ initial = { { opacity : 0 , scale : 0.7 } }
97+ animate = { { opacity : 1 , scale : 1 } }
98+ transition = { {
99+ ease : 'easeOut'
100+ } }
101+ bottom = { 20 }
102+ sx = { {
103+ position : 'fixed' ,
104+ marginLeft : `calc(${
105+ containerRef . current
106+ ? containerRef . current . clientWidth / 2 - 67
107+ : 0
108+ } px)`
109+ } }
110+ >
111+ < ExpandCircleDown fontSize = "large" color = "secondary" />
112+ </ Button >
113+ ) }
54114 </ FlexBox >
55115 </ ErrorBoundary >
56116 ) ;
0 commit comments