21700: Install Bundler system-wide in Rails postinst
[arvados.git] / services / workbench2 / src / components / code-snippet / virtual-code-snippet.tsx
1 // Copyright (C) The Arvados Authors. All rights reserved.
2 //
3 // SPDX-License-Identifier: AGPL-3.0
4
5 import React from 'react';
6 import { StyleRulesCallback, WithStyles, Typography, withStyles } from '@material-ui/core';
7 import { ArvadosTheme } from 'common/custom-theme';
8 import classNames from 'classnames';
9 import { connect, DispatchProp } from 'react-redux';
10 import { RootState } from 'store/store';
11 import { FederationConfig } from 'routes/routes';
12 import { renderLinks } from './code-snippet';
13 import { FixedSizeList } from 'react-window';
14 import AutoSizer from "react-virtualized-auto-sizer";
15
16 type CssRules = 'root' | 'space' | 'content' ;
17
18 const styles: StyleRulesCallback<CssRules> = (theme: ArvadosTheme) => ({
19     root: {
20         boxSizing: 'border-box',
21         height: '100%',
22         padding: theme.spacing.unit,
23     },
24     space: {
25         marginLeft: '15px',
26     },
27     content: {
28         maxHeight: '100%',
29         height: '100vh',
30     },
31 });
32
33 export interface CodeSnippetDataProps {
34     lines: string[];
35     lineFormatter?: (lines: string[], index: number) => string;
36     className?: string;
37     apiResponse?: boolean;
38     linked?: boolean;
39 }
40
41 interface CodeSnippetAuthProps {
42     auth: FederationConfig;
43 }
44
45 type CodeSnippetProps = CodeSnippetDataProps & WithStyles<CssRules>;
46
47 const mapStateToProps = (state: RootState): CodeSnippetAuthProps => ({
48     auth: state.auth,
49 });
50
51 export const VirtualCodeSnippet = withStyles(styles)(connect(mapStateToProps)(
52     ({ classes, lines, lineFormatter, linked, className, apiResponse, dispatch, auth }: CodeSnippetProps & CodeSnippetAuthProps & DispatchProp) => {
53         const RenderRow = ({index, style}) => {
54             const lineContents = lineFormatter ? lineFormatter(lines, index) : lines[index];
55             return <span style={style}>{linked ? renderLinks(auth, dispatch)(lineContents) : lineContents}</span>
56         };
57
58         return <Typography
59             component="div"
60             className={classNames([classes.root, className])}>
61             <Typography className={classNames(classes.content, apiResponse ? classes.space : className)} component="pre">
62                 <AutoSizer>
63                     {({ height, width }) =>
64                         <FixedSizeList
65                             height={height}
66                             width={width}
67                             itemSize={21}
68                             itemCount={lines.length}
69                         >
70                             {RenderRow}
71                         </FixedSizeList>
72                     }
73                 </AutoSizer>
74             </Typography>
75         </Typography>;
76 }));