From 3826b30cb25c2a1cb22729981412f091a8443076 Mon Sep 17 00:00:00 2001 From: Lucas Di Pentima Date: Tue, 22 Mar 2022 10:59:27 -0300 Subject: [PATCH] 16672: Implements 'auto-follow' mode when log view is scrolled all the way down Restored the CodeSnippet component as it was needing too much customization for the log viewer use case. Arvados-DCO-1.1-Signed-off-by: Lucas Di Pentima --- src/components/code-snippet/code-snippet.tsx | 23 +++---- .../process-log-code-snippet.tsx | 66 ++++++++++++++----- 2 files changed, 58 insertions(+), 31 deletions(-) diff --git a/src/components/code-snippet/code-snippet.tsx b/src/components/code-snippet/code-snippet.tsx index fd44b5fc..f0a2b213 100644 --- a/src/components/code-snippet/code-snippet.tsx +++ b/src/components/code-snippet/code-snippet.tsx @@ -24,24 +24,19 @@ export interface CodeSnippetDataProps { lines: string[]; className?: string; apiResponse?: boolean; - containerClassName?: string; - fontSize?: number; - customRenderer?: (line: string) => React.ReactNode; } type CodeSnippetProps = CodeSnippetDataProps & WithStyles; export const CodeSnippet = withStyles(styles)( - ({ classes, lines, className, containerClassName, - apiResponse, fontSize, customRenderer }: CodeSnippetProps) => - - { lines.map((line: string, index: number) => { - return - {customRenderer ? customRenderer(line) : line} - ; - }) } + ({ classes, lines, className, apiResponse }: CodeSnippetProps) => + + { + lines.map((line: string, index: number) => { + return {line}; + }) + } ); \ No newline at end of file diff --git a/src/views/process-panel/process-log-code-snippet.tsx b/src/views/process-panel/process-log-code-snippet.tsx index 4f19f917..6ea628e6 100644 --- a/src/views/process-panel/process-log-code-snippet.tsx +++ b/src/views/process-panel/process-log-code-snippet.tsx @@ -2,25 +2,37 @@ // // SPDX-License-Identifier: AGPL-3.0 -import React from 'react'; -import { MuiThemeProvider, createMuiTheme, StyleRulesCallback, withStyles, WithStyles } from '@material-ui/core/styles'; -import { CodeSnippet } from 'components/code-snippet/code-snippet'; +import React, { useEffect, useRef, useState } from 'react'; +import { + MuiThemeProvider, + createMuiTheme, + StyleRulesCallback, + withStyles, + WithStyles +} from '@material-ui/core/styles'; import grey from '@material-ui/core/colors/grey'; import { ArvadosTheme } from 'common/custom-theme'; import { Link, Typography } from '@material-ui/core'; import { navigateTo } from 'store/navigation/navigation-action'; import { Dispatch } from 'redux'; import { connect, DispatchProp } from 'react-redux'; +import classNames from 'classnames'; -type CssRules = 'wordWrap' | 'codeSnippetContainer'; +type CssRules = 'root' | 'wordWrap' | 'logText'; const styles: StyleRulesCallback = (theme: ArvadosTheme) => ({ + root: { + boxSizing: 'border-box', + overflow: 'auto', + backgroundColor: '#000', + height: `calc(100% - ${theme.spacing.unit * 4}px)`, // so that horizontal scollbar is visible + }, + logText: { + padding: theme.spacing.unit * 0.5, + }, wordWrap: { whiteSpace: 'pre-wrap', }, - codeSnippetContainer: { - height: `calc(100% - ${theme.spacing.unit * 4}px)`, // so that horizontal scollbar is visible - }, }); const theme = createMuiTheme({ @@ -28,9 +40,6 @@ const theme = createMuiTheme({ MuiTypography: { body2: { color: grey["200"] - }, - root: { - backgroundColor: '#000' } } }, @@ -68,10 +77,33 @@ const renderLinks = (fontSize: number, dispatch: Dispatch) => (text: string) => }; export const ProcessLogCodeSnippet = withStyles(styles)(connect()( - (props: ProcessLogCodeSnippetProps & WithStyles & DispatchProp) => - - - )); \ No newline at end of file + ({classes, lines, fontSize, dispatch, wordWrap}: ProcessLogCodeSnippetProps & WithStyles & DispatchProp) => { + const [followMode, setFollowMode] = useState(false); + const scrollRef = useRef(null); + + useEffect(() => { + if (followMode && scrollRef.current && lines.length > 0) { + // Scroll to bottom + scrollRef.current.scrollTop = scrollRef.current.scrollHeight; + } + }, [followMode, lines, scrollRef]); + + return +
{ + const elem = e.target as HTMLDivElement; + if (elem.scrollTop + elem.clientHeight >= elem.scrollHeight) { + setFollowMode(true); + } else { + setFollowMode(false); + } + }}> + { lines.map((line: string, index: number) => + + {renderLinks(fontSize, dispatch)(line)} + + ) } +
+
+ })); \ No newline at end of file -- 2.30.2