X-Git-Url: https://git.arvados.org/arvados-workbench2.git/blobdiff_plain/cfe5ff035578ede95613b0c545708466da78cbea..cc6952cee5f114b62b851adcbc667ed20a3946ce:/src/views/process-panel/process-log-code-snippet.tsx diff --git a/src/views/process-panel/process-log-code-snippet.tsx b/src/views/process-panel/process-log-code-snippet.tsx index 1ea83912..2b7391c2 100644 --- a/src/views/process-panel/process-log-code-snippet.tsx +++ b/src/views/process-panel/process-log-code-snippet.tsx @@ -2,21 +2,42 @@ // // 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 { navigationNotAvailable } from 'store/navigation/navigation-action'; +import { Dispatch } from 'redux'; +import { connect, DispatchProp } from 'react-redux'; +import classNames from 'classnames'; +import { FederationConfig, getNavUrl } from 'routes/routes'; +import { RootState } from 'store/store'; -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 + "& a": { + color: theme.palette.primary.main, + }, + }, + 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({ @@ -24,9 +45,6 @@ const theme = createMuiTheme({ MuiTypography: { body2: { color: grey["200"] - }, - root: { - backgroundColor: '#000' } } }, @@ -42,10 +60,70 @@ interface ProcessLogCodeSnippetProps { wordWrap?: boolean; } -export const ProcessLogCodeSnippet = withStyles(styles)( - (props: ProcessLogCodeSnippetProps & WithStyles) => - - - ); \ No newline at end of file +interface ProcessLogCodeSnippetAuthProps { + auth: FederationConfig; +} + +const renderLinks = (fontSize: number, auth: FederationConfig, dispatch: Dispatch) => (text: string) => { + // Matches UUIDs & PDHs + const REGEX = /[a-z0-9]{5}-[a-z0-9]{5}-[a-z0-9]{15}|[0-9a-f]{32}\+\d+/g; + const links = text.match(REGEX); + if (!links) { + return {text}; + } + return + {text.split(REGEX).map((part, index) => + + {part} + {links[index] && + { + const url = getNavUrl(links[index], auth) + if (url) { + window.open(`${window.location.origin}${url}`, '_blank'); + } else { + dispatch(navigationNotAvailable(links[index])); + } + }} + style={ {cursor: 'pointer'} }> + {links[index]} + } + + )} + ; +}; + +const mapStateToProps = (state: RootState): ProcessLogCodeSnippetAuthProps => ({ + auth: state.auth, +}); + +export const ProcessLogCodeSnippet = withStyles(styles)(connect(mapStateToProps)( + ({classes, lines, fontSize, auth, dispatch, wordWrap}: ProcessLogCodeSnippetProps & WithStyles & ProcessLogCodeSnippetAuthProps & DispatchProp) => { + const [followMode, setFollowMode] = useState(true); + 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*1.1) >= elem.scrollHeight) { + setFollowMode(true); + } else { + setFollowMode(false); + } + }}> + { lines.map((line: string, index: number) => + + {renderLinks(fontSize, auth, dispatch)(line)} + + ) } +
+
+ })); \ No newline at end of file