-export const ProcessLogCodeSnippet = withStyles(styles)(
- (props: ProcessLogCodeSnippetProps & WithStyles<CssRules>) =>
- <MuiThemeProvider theme={theme}>
- <CodeSnippet lines={props.lines} fontSize={props.fontSize}
- className={props.wordWrap ? props.classes.wordWrap : undefined}
- containerClassName={props.classes.codeSnippetContainer} />
- </MuiThemeProvider>);
\ 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 <Typography style={{ fontSize: fontSize }}>{text}</Typography>;
+ }
+ return <Typography style={{ fontSize: fontSize }}>
+ {text.split(REGEX).map((part, index) =>
+ <React.Fragment key={index}>
+ {part}
+ {links[index] &&
+ <Link onClick={() => {
+ 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]}
+ </Link>}
+ </React.Fragment>
+ )}
+ </Typography>;
+};
+
+const mapStateToProps = (state: RootState): ProcessLogCodeSnippetAuthProps => ({
+ auth: state.auth,
+});
+
+export const ProcessLogCodeSnippet = withStyles(styles)(connect(mapStateToProps)(
+ ({classes, lines, fontSize, auth, dispatch, wordWrap}: ProcessLogCodeSnippetProps & WithStyles<CssRules> & ProcessLogCodeSnippetAuthProps & DispatchProp) => {
+ const [followMode, setFollowMode] = useState<boolean>(true);
+ const scrollRef = useRef<HTMLDivElement>(null);
+
+ useEffect(() => {
+ if (followMode && scrollRef.current && lines.length > 0) {
+ // Scroll to bottom
+ scrollRef.current.scrollTop = scrollRef.current.scrollHeight;
+ }
+ }, [followMode, lines, scrollRef]);
+
+ return <MuiThemeProvider theme={theme}>
+ <div ref={scrollRef} className={classes.root}
+ onScroll={(e) => {
+ 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) =>
+ <Typography key={index} component="pre"
+ className={classNames(classes.logText, wordWrap ? classes.wordWrap : undefined)}>
+ {renderLinks(fontSize, auth, dispatch)(line)}
+ </Typography>
+ ) }
+ </div>
+ </MuiThemeProvider>
+ }));
\ No newline at end of file