feat: run content
This commit is contained in:
@@ -7,7 +7,7 @@ import { TabPanel, TabContext } from "@mui/lab";
|
|||||||
import SettingsIcon from '@mui/icons-material/Settings';
|
import SettingsIcon from '@mui/icons-material/Settings';
|
||||||
import ImageIcon from '@mui/icons-material/Image';
|
import ImageIcon from '@mui/icons-material/Image';
|
||||||
import ArticleIcon from '@mui/icons-material/Article';
|
import ArticleIcon from '@mui/icons-material/Article';
|
||||||
import {Buffer} from 'buffer';
|
import { Buffer } from 'buffer';
|
||||||
import { useEffect } from "react";
|
import { useEffect } from "react";
|
||||||
import AssignmentIcon from '@mui/icons-material/Assignment';
|
import AssignmentIcon from '@mui/icons-material/Assignment';
|
||||||
|
|
||||||
@@ -19,7 +19,7 @@ interface RunContentProps {
|
|||||||
abortRunHandler: () => void,
|
abortRunHandler: () => void,
|
||||||
}
|
}
|
||||||
|
|
||||||
export const RunContent = ({row, currentLog, interpretationInProgress, logEndRef, abortRunHandler}: RunContentProps) => {
|
export const RunContent = ({ row, currentLog, interpretationInProgress, logEndRef, abortRunHandler }: RunContentProps) => {
|
||||||
const [tab, setTab] = React.useState<string>('log');
|
const [tab, setTab] = React.useState<string>('log');
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@@ -29,141 +29,142 @@ export const RunContent = ({row, currentLog, interpretationInProgress, logEndRef
|
|||||||
return (
|
return (
|
||||||
<Box sx={{ width: '100%' }}>
|
<Box sx={{ width: '100%' }}>
|
||||||
<TabContext value={tab}>
|
<TabContext value={tab}>
|
||||||
<Box sx={{ borderBottom: 1, borderColor: 'divider' }}>
|
<Box sx={{ borderBottom: 1, borderColor: 'divider' }}>
|
||||||
<Tabs value={tab} onChange={(e, newTab) => setTab(newTab)} aria-label="run-content-tabs">
|
<Tabs value={tab} onChange={(e, newTab) => setTab(newTab)} aria-label="run-content-tabs">
|
||||||
<Tab label="Log" value='log' />
|
<Tab label="Log" value='log' />
|
||||||
<Tab label="Input" value='input' />
|
<Tab label="Input" value='input' />
|
||||||
<Tab label="Output" value='output' />
|
<Tab label="Output" value='output' />
|
||||||
</Tabs>
|
</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>
|
</Box>
|
||||||
{interpretationInProgress ? <Button
|
<TabPanel value='log'>
|
||||||
color="error"
|
<Box sx={{
|
||||||
onClick={abortRunHandler}
|
margin: 1,
|
||||||
>
|
background: '#19171c',
|
||||||
Stop
|
overflowY: 'scroll',
|
||||||
</Button> : null}
|
overflowX: 'scroll',
|
||||||
</TabPanel>
|
width: '700px',
|
||||||
<TabPanel value='input' sx={{width: '700px'}}>
|
height: 'fit-content',
|
||||||
<Typography variant='h6' sx={{display:'flex', alignItems:'center'}}>
|
maxHeight: '450px',
|
||||||
<SettingsIcon sx={{marginRight: '15px'}}/>
|
}}>
|
||||||
Interpreter settings
|
<div>
|
||||||
</Typography>
|
<Highlight className="javascript">
|
||||||
{
|
{interpretationInProgress ? currentLog : row.log}
|
||||||
Object.keys(row.interpreterSettings).map((setting, index) => {
|
</Highlight>
|
||||||
if (setting === 'params') {
|
<div style={{ float: "left", clear: "both" }}
|
||||||
return (
|
ref={logEndRef} />
|
||||||
<div key={`settings-${setting}-${index}`}>
|
</div>
|
||||||
<Typography variant='h6' sx={{display:'flex', alignItems:'center'}} key={`setting-${index}`}>
|
</Box>
|
||||||
<AssignmentIcon sx={{marginRight: '15px'}}/>
|
{interpretationInProgress ? <Button
|
||||||
Recording parameters
|
color="error"
|
||||||
</Typography>
|
onClick={abortRunHandler}
|
||||||
{
|
>
|
||||||
Object.keys(row.interpreterSettings.params).map((param, index) => {
|
Stop
|
||||||
return (
|
</Button> : null}
|
||||||
<Typography key={`recording-params-item-${index}`} sx={{margin: '10px'}}>
|
</TabPanel>
|
||||||
{/*@ts-ignore*/}
|
<TabPanel value='input' sx={{ width: '700px' }}>
|
||||||
{param}: {row.interpreterSettings.params[param].toString()}
|
<Typography variant='h6' sx={{ display: 'flex', alignItems: 'center' }}>
|
||||||
</Typography>
|
<SettingsIcon sx={{ marginRight: '15px' }} />
|
||||||
)
|
Interpreter settings
|
||||||
})
|
</Typography>
|
||||||
}
|
{
|
||||||
</div>
|
Object.keys(row.interpreterSettings).map((setting, index) => {
|
||||||
)
|
if (setting === 'params') {
|
||||||
}
|
|
||||||
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 (
|
return (
|
||||||
<Box key={`number-of-binary-output-${key}`} sx={{
|
<div key={`settings-${setting}-${index}`}>
|
||||||
width: 'max-content',
|
<Typography variant='h6' sx={{ display: 'flex', alignItems: 'center' }} key={`setting-${index}`}>
|
||||||
}}>
|
<AssignmentIcon sx={{ marginRight: '15px' }} />
|
||||||
<Typography key={`binary-output-key-${key}`}>
|
Recording parameters
|
||||||
{key}:
|
|
||||||
<a href={`data:${row.binaryOutput[key].mimetype};base64,${b64}`}
|
|
||||||
download={key} style={{margin:'10px'}}>Download</a>
|
|
||||||
</Typography>
|
</Typography>
|
||||||
<img key={`image-${key}`} src={`data:${row.binaryOutput[key].mimetype};base64,${b64}`}
|
{
|
||||||
alt={key} height='auto' width='700px'/>
|
Object.keys(row.interpreterSettings.params).map((param, index) => {
|
||||||
</Box>
|
return (
|
||||||
|
<Typography key={`recording-params-item-${index}`} sx={{ margin: '10px' }}>
|
||||||
|
{/*@ts-ignore*/}
|
||||||
|
{param}: {row.interpreterSettings.params[param].toString()}
|
||||||
|
</Typography>
|
||||||
|
)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
</div>
|
||||||
)
|
)
|
||||||
} catch (e) {
|
|
||||||
console.log(e)
|
|
||||||
return <Typography key={`number-of-binary-output-${key}`}>
|
|
||||||
{key}: The image failed to render
|
|
||||||
</Typography>
|
|
||||||
}
|
}
|
||||||
|
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>
|
</div>
|
||||||
}
|
}
|
||||||
</TabPanel>
|
{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>
|
</TabContext>
|
||||||
</Box>
|
</Box>
|
||||||
);
|
);
|
||||||
|
|||||||
Reference in New Issue
Block a user