feat: run content

This commit is contained in:
karishmas6
2024-06-24 22:38:29 +05:30
parent 5fbc1beaaf
commit 0a63e802a9

View File

@@ -0,0 +1,170 @@
import { Box, Tabs, Typography, Tab } from "@mui/material";
import Highlight from "react-highlight";
import Button from "@mui/material/Button";
import * as React from "react";
import { Data } from "./RunsTable";
import { TabPanel, TabContext } from "@mui/lab";
import SettingsIcon from '@mui/icons-material/Settings';
import ImageIcon from '@mui/icons-material/Image';
import ArticleIcon from '@mui/icons-material/Article';
import {Buffer} from 'buffer';
import { useEffect } from "react";
import AssignmentIcon from '@mui/icons-material/Assignment';
interface RunContentProps {
row: Data,
currentLog: string,
interpretationInProgress: boolean,
logEndRef: React.RefObject<HTMLDivElement>,
abortRunHandler: () => void,
}
export const RunContent = ({row, currentLog, interpretationInProgress, logEndRef, abortRunHandler}: RunContentProps) => {
const [tab, setTab] = React.useState<string>('log');
useEffect(() => {
setTab(tab);
}, [interpretationInProgress])
return (
<Box sx={{ width: '100%' }}>
<TabContext value={tab}>
<Box sx={{ borderBottom: 1, borderColor: 'divider' }}>
<Tabs value={tab} onChange={(e, newTab) => setTab(newTab)} aria-label="run-content-tabs">
<Tab label="Log" value='log' />
<Tab label="Input" value='input' />
<Tab label="Output" value='output' />
</Tabs>
</Box>
<TabPanel value='log'>
<Box sx={{ margin: 1,
background: '#19171c',
overflowY: 'scroll',
overflowX: 'scroll',
width: '700px',
height: 'fit-content',
maxHeight: '450px',
}}>
<div>
<Highlight className="javascript">
{interpretationInProgress ? currentLog : row.log}
</Highlight>
<div style={{ float:"left", clear: "both" }}
ref={logEndRef}/>
</div>
</Box>
{interpretationInProgress ? <Button
color="error"
onClick={abortRunHandler}
>
Stop
</Button> : null}
</TabPanel>
<TabPanel value='input' sx={{width: '700px'}}>
<Typography variant='h6' sx={{display:'flex', alignItems:'center'}}>
<SettingsIcon sx={{marginRight: '15px'}}/>
Interpreter settings
</Typography>
{
Object.keys(row.interpreterSettings).map((setting, index) => {
if (setting === 'params') {
return (
<div key={`settings-${setting}-${index}`}>
<Typography variant='h6' sx={{display:'flex', alignItems:'center'}} key={`setting-${index}`}>
<AssignmentIcon sx={{marginRight: '15px'}}/>
Recording parameters
</Typography>
{
Object.keys(row.interpreterSettings.params).map((param, index) => {
return (
<Typography key={`recording-params-item-${index}`} sx={{margin: '10px'}}>
{/*@ts-ignore*/}
{param}: {row.interpreterSettings.params[param].toString()}
</Typography>
)
})
}
</div>
)
}
return (
<Typography key={`interpreter-settings-item-${index}`} sx={{margin: '10px'}}>
{/*@ts-ignore*/}
{setting}: {row.interpreterSettings[setting].toString()}
</Typography>
)
})
}
</TabPanel>
<TabPanel value='output' sx={{width: '700px'}}>
{ !row || !row.serializableOutput || !row.binaryOutput
|| (Object.keys(row.serializableOutput).length === 0 && Object.keys(row.binaryOutput).length === 0)
? <Typography>The output is empty.</Typography> : null }
{row.serializableOutput &&
Object.keys(row.serializableOutput).length !== 0 &&
<div>
<Typography variant='h6' sx={{display:'flex', alignItems:'center'}}>
<ArticleIcon sx={{marginRight: '15px'}}/>
Serializable output</Typography>
{ Object.keys(row.serializableOutput).map((key) => {
return (
<div key={`number-of-serializable-output-${key}`}>
<Typography>
{key}:
<a href={`data:application/json;utf8,${JSON.stringify(row.serializableOutput[key], null, 2)}`}
download={key} style={{margin:'10px'}}>Download</a>
</Typography>
<Box sx={{
width: 'fit-content',
background: 'rgba(0,0,0,0.06)',
maxHeight: '300px',
overflow: 'scroll',
}}>
<pre key={`serializable-output-${key}`}>
{row.serializableOutput[key] ? JSON.stringify(row.serializableOutput[key], null, 2)
: 'The output is empty.'}
</pre>
</Box>
</div>
)
})}
</div>
}
{row.binaryOutput
&& Object.keys(row.binaryOutput).length !== 0 &&
<div>
<Typography variant='h6' sx={{display:'flex', alignItems:'center'}}>
<ImageIcon sx={{marginRight:'15px'}}/>
Binary output</Typography>
{ Object.keys(row.binaryOutput).map((key) => {
try {
const binaryBuffer = JSON.parse(row.binaryOutput[key].data);
const b64 = Buffer.from(binaryBuffer.data).toString('base64');
return (
<Box key={`number-of-binary-output-${key}`} sx={{
width: 'max-content',
}}>
<Typography key={`binary-output-key-${key}`}>
{key}:
<a href={`data:${row.binaryOutput[key].mimetype};base64,${b64}`}
download={key} style={{margin:'10px'}}>Download</a>
</Typography>
<img key={`image-${key}`} src={`data:${row.binaryOutput[key].mimetype};base64,${b64}`}
alt={key} height='auto' width='700px'/>
</Box>
)
} catch (e) {
console.log(e)
return <Typography key={`number-of-binary-output-${key}`}>
{key}: The image failed to render
</Typography>
}
})}
</div>
}
</TabPanel>
</TabContext>
</Box>
);
}