From a9a011ed1f1daec47a9bc306f13ff91a63954e42 Mon Sep 17 00:00:00 2001 From: Stephen Smith Date: Fri, 5 Apr 2024 17:43:16 -0400 Subject: [PATCH 1/1] 21651: Add virtual code snippet, implement in cmd card Arvados-DCO-1.1-Signed-off-by: Stephen Smith --- .../components/code-snippet/code-snippet.tsx | 2 +- .../code-snippet/virtual-code-snippet.tsx | 75 +++++++++++++++++++ .../default-virtual-code-snippet.tsx | 31 ++++++++ .../views/process-panel/process-cmd-card.tsx | 11 +-- .../process-panel/process-panel-root.tsx | 1 + 5 files changed, 114 insertions(+), 6 deletions(-) create mode 100644 services/workbench2/src/components/code-snippet/virtual-code-snippet.tsx create mode 100644 services/workbench2/src/components/default-code-snippet/default-virtual-code-snippet.tsx diff --git a/services/workbench2/src/components/code-snippet/code-snippet.tsx b/services/workbench2/src/components/code-snippet/code-snippet.tsx index 47d8fe1bf0..3be1e4fc71 100644 --- a/services/workbench2/src/components/code-snippet/code-snippet.tsx +++ b/services/workbench2/src/components/code-snippet/code-snippet.tsx @@ -66,7 +66,7 @@ export const CodeSnippet = withStyles(styles)(connect(mapStateToProps)( )); -const renderLinks = (auth: FederationConfig, dispatch: Dispatch) => (text: string): JSX.Element => { +export const renderLinks = (auth: FederationConfig, dispatch: Dispatch) => (text: string): JSX.Element => { // 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); diff --git a/services/workbench2/src/components/code-snippet/virtual-code-snippet.tsx b/services/workbench2/src/components/code-snippet/virtual-code-snippet.tsx new file mode 100644 index 0000000000..bc43d5d9f2 --- /dev/null +++ b/services/workbench2/src/components/code-snippet/virtual-code-snippet.tsx @@ -0,0 +1,75 @@ +// Copyright (C) The Arvados Authors. All rights reserved. +// +// SPDX-License-Identifier: AGPL-3.0 + +import React from 'react'; +import { StyleRulesCallback, WithStyles, Typography, withStyles } from '@material-ui/core'; +import { ArvadosTheme } from 'common/custom-theme'; +import classNames from 'classnames'; +import { connect, DispatchProp } from 'react-redux'; +import { RootState } from 'store/store'; +import { FederationConfig } from 'routes/routes'; +import { renderLinks } from './code-snippet'; +import { FixedSizeList } from 'react-window'; +import AutoSizer from "react-virtualized-auto-sizer"; + +type CssRules = 'root' | 'space' | 'content' ; + +const styles: StyleRulesCallback = (theme: ArvadosTheme) => ({ + root: { + boxSizing: 'border-box', + height: '100%', + padding: theme.spacing.unit, + }, + space: { + marginLeft: '15px', + }, + content: { + maxHeight: '100%', + height: '100vh', + }, +}); + +export interface CodeSnippetDataProps { + lines: string[]; + lineTransformer?: (line: string) => string; + className?: string; + apiResponse?: boolean; + linked?: boolean; +} + +interface CodeSnippetAuthProps { + auth: FederationConfig; +} + +type CodeSnippetProps = CodeSnippetDataProps & WithStyles; + +const mapStateToProps = (state: RootState): CodeSnippetAuthProps => ({ + auth: state.auth, +}); + +export const VirtualCodeSnippet = withStyles(styles)(connect(mapStateToProps)( + ({ classes, lines, linked, className, apiResponse, dispatch, auth }: CodeSnippetProps & CodeSnippetAuthProps & DispatchProp) => { + const RenderRow = ({index, style}) => ( + {linked ? renderLinks(auth, dispatch)(lines[index]) : lines[index]} + ); + + return + + + {({ height, width }) => + + {RenderRow} + + } + + + ; +})); diff --git a/services/workbench2/src/components/default-code-snippet/default-virtual-code-snippet.tsx b/services/workbench2/src/components/default-code-snippet/default-virtual-code-snippet.tsx new file mode 100644 index 0000000000..581f0f4acc --- /dev/null +++ b/services/workbench2/src/components/default-code-snippet/default-virtual-code-snippet.tsx @@ -0,0 +1,31 @@ +// Copyright (C) The Arvados Authors. All rights reserved. +// +// SPDX-License-Identifier: AGPL-3.0 + +import React from 'react'; +import { MuiThemeProvider, createMuiTheme } from '@material-ui/core/styles'; +import { VirtualCodeSnippet, CodeSnippetDataProps } from 'components/code-snippet/virtual-code-snippet'; +import grey from '@material-ui/core/colors/grey'; +import { themeOptions } from 'common/custom-theme'; + +const theme = createMuiTheme(Object.assign({}, themeOptions, { + overrides: { + MuiTypography: { + body1: { + color: grey["900"] + }, + root: { + backgroundColor: grey["200"] + } + } + }, + typography: { + fontFamily: 'monospace', + useNextVariants: true, + } +})); + +export const DefaultVirtualCodeSnippet = (props: CodeSnippetDataProps) => + + + ; diff --git a/services/workbench2/src/views/process-panel/process-cmd-card.tsx b/services/workbench2/src/views/process-panel/process-cmd-card.tsx index 478b0bc56f..d7b47653e6 100644 --- a/services/workbench2/src/views/process-panel/process-cmd-card.tsx +++ b/services/workbench2/src/views/process-panel/process-cmd-card.tsx @@ -18,7 +18,7 @@ import { import { ArvadosTheme } from 'common/custom-theme'; import { CloseIcon, CommandIcon, CopyIcon } from 'components/icon/icon'; import { MPVPanelProps } from 'components/multi-panel-view/multi-panel-view'; -import { DefaultCodeSnippet } from 'components/default-code-snippet/default-code-snippet'; +import { DefaultVirtualCodeSnippet } from 'components/default-code-snippet/default-virtual-code-snippet'; import { Process } from 'store/processes/process'; import shellescape from 'shell-escape'; import CopyToClipboard from 'react-copy-to-clipboard'; @@ -31,7 +31,7 @@ const styles: StyleRulesCallback = (theme: ArvadosTheme) => ({ }, header: { paddingTop: theme.spacing.unit, - paddingBottom: theme.spacing.unit, + paddingBottom: 0, }, iconHeader: { fontSize: '1.875rem', @@ -42,8 +42,9 @@ const styles: StyleRulesCallback = (theme: ArvadosTheme) => ({ paddingTop: theme.spacing.unit * 0.5 }, content: { + height: `calc(100% - ${theme.spacing.unit * 6}px)`, padding: theme.spacing.unit * 1.0, - paddingTop: theme.spacing.unit * 0.5, + paddingTop: 0, '&:last-child': { paddingBottom: theme.spacing.unit * 1, } @@ -52,7 +53,7 @@ const styles: StyleRulesCallback = (theme: ArvadosTheme) => ({ overflow: 'hidden', paddingTop: theme.spacing.unit * 0.5, color: theme.customs.colors.greyD, - fontSize: '1.875rem' + fontSize: '1.875rem' }, }); @@ -127,7 +128,7 @@ export const ProcessCmdCard = withStyles(styles)( } /> - + ); diff --git a/services/workbench2/src/views/process-panel/process-panel-root.tsx b/services/workbench2/src/views/process-panel/process-panel-root.tsx index 2a9b3882e8..21f38b0938 100644 --- a/services/workbench2/src/views/process-panel/process-panel-root.tsx +++ b/services/workbench2/src/views/process-panel/process-panel-root.tsx @@ -198,6 +198,7 @@ export const ProcessPanelRoot = withStyles(styles)(