1
0
mirror of https://github.com/sasjs/server.git synced 2025-12-10 19:34:34 +00:00

feat(log): added logComponent and LogTabWithIcons

This commit is contained in:
Yury Shkoda
2023-04-10 16:21:32 +03:00
parent 7c1c1e2410
commit 3a887dec55
3 changed files with 185 additions and 11 deletions

View File

@@ -1,4 +1,4 @@
import React, { Dispatch, SetStateAction } from 'react'
import { Dispatch, SetStateAction } from 'react'
import {
Backdrop,
@@ -17,6 +17,8 @@ import { TabContext, TabList, TabPanel } from '@mui/lab'
import FilePathInputModal from '../../components/filePathInputModal'
import FileMenu from './internal/components/fileMenu'
import RunMenu from './internal/components/runMenu'
import LogComponent from './internal/components/log/logComponent'
import LogTabWithIcons from './internal/components/log/logTabWithIcons'
import { usePrompt } from '../../utils/hooks'
import { getLanguageFromExtension } from './internal/helper'
@@ -108,6 +110,8 @@ const SASjsEditor = ({
/>
)
const logWithErrorsOrWarnings = log?.errors.length || log?.warnings.length
return (
<Box sx={{ width: '100%', typography: 'body1', marginTop: '50px' }}>
<Backdrop
@@ -145,7 +149,13 @@ const SASjsEditor = ({
>
<TabList onChange={handleTabChange} centered>
<StyledTab label="Code" value="code" />
<StyledTab label="Log" value="log" />
<StyledTab
label={logWithErrorsOrWarnings ? '' : 'log'}
value="log"
icon={
logWithErrorsOrWarnings ? <LogTabWithIcons log={log} /> : ''
}
/>
<StyledTab
label={
<Tooltip title="Displays content from the _webout fileref">
@@ -195,15 +205,7 @@ const SASjsEditor = ({
</Paper>
</StyledTabPanel>
<StyledTabPanel value="log">
<div>
<h2>Log</h2>
<pre
id="log"
style={{ overflow: 'auto', height: 'calc(100vh - 220px)' }}
>
{log}
</pre>
</div>
{log && <LogComponent log={log} />}
</StyledTabPanel>
<StyledTabPanel value="webout">
<div>

View File

@@ -0,0 +1,140 @@
import TreeView from '@mui/lab/TreeView'
import TreeItem from '@mui/lab/TreeItem'
import { ChevronRight, ExpandMore } from '@mui/icons-material'
import { Typography } from '@mui/material'
import { ListItemText } from '@mui/material'
import { makeStyles } from '@mui/styles'
import Highlight from 'react-highlight'
import { LogObject } from '../../../../../utils'
const useStyles: any = makeStyles((theme: any) => ({
expansionDescription: {
backgroundColor: '#fbfbfb',
border: '1px solid #e2e2e2',
borderRadius: '3px',
minHeight: '50px',
padding: '10px',
boxSizing: 'border-box',
whiteSpace: 'pre-wrap',
fontFamily: 'Monaco, Courier, monospace',
position: 'relative',
width: '100%',
[theme.breakpoints.down('sm')]: {
fontSize: theme.typography.pxToRem(12)
},
[theme.breakpoints.up('md')]: {
fontSize: theme.typography.pxToRem(16)
}
}
}))
interface LogComponentProps {
log: LogObject
}
const LogComponent = (props: LogComponentProps) => {
const { log } = props
const classes = useStyles()
const goToLogLine = (type: 'error' | 'warning', ind: number) => {
const line = document.getElementById(`${type}_${ind}`)
const logWrapper: HTMLDivElement | null =
document.querySelector(`#logWrapper`)
const logContainer: HTMLHeadElement | null =
document.querySelector(`#log_container`)
if (line && logWrapper && logContainer) {
line.style.backgroundColor = '#f6e30599'
logWrapper.scrollTop =
line.offsetTop - logWrapper.offsetTop + logContainer.offsetTop
setTimeout(() => {
line.setAttribute('style', '')
}, 3000)
}
}
const decodeHtml = (encodedString: string) => {
const tempElement = document.createElement('textarea')
tempElement.innerHTML = encodedString
return tempElement.value
}
return (
<div
id="logWrapper"
style={{ overflowY: 'auto', maxHeight: 'calc(100vh - 130px)' }}
>
<div style={{ backgroundColor: 'white' }}>
<div
style={{
display: 'flex',
flexDirection: 'row',
justifyContent: 'center',
alignItems: 'center',
gap: 10
}}
></div>
<div style={{ paddingBottom: 10 }}>
<TreeView
defaultCollapseIcon={<ExpandMore />}
defaultExpandIcon={<ChevronRight />}
>
{log?.errors.length && (
<TreeItem
nodeId="errors"
label={
<Typography color="error">
{`Errors (${log.errors.length})`}
</Typography>
}
>
{log.errors &&
log.errors.map((error, ind) => (
<TreeItem
nodeId={`error_${ind}`}
label={<ListItemText primary={error} />}
key={`error_${ind}`}
onClick={() => goToLogLine('error', ind)}
/>
))}
</TreeItem>
)}
{log?.warnings.length && (
<TreeItem
nodeId="warnings"
label={
<Typography>{`Warnings (${log.warnings.length})`}</Typography>
}
>
{log.warnings &&
log.warnings.map((warning, ind) => (
<TreeItem
nodeId={`warning_${ind}`}
label={<ListItemText primary={warning} />}
key={`warning_${ind}`}
onClick={() => goToLogLine('warning', ind)}
/>
))}
</TreeItem>
)}
</TreeView>
</div>
</div>
<Typography
id={`log_container`}
variant="h5"
className={classes.expansionDescription}
>
<Highlight className={'html'} innerHTML={true}>
{decodeHtml(log?.body || '')}
</Highlight>
</Typography>
</div>
)
}
export default LogComponent

View File

@@ -0,0 +1,32 @@
import { ErrorOutline, Warning } from '@mui/icons-material'
import { LogObject } from '../../../../../utils'
interface LogTabProps {
log: LogObject
}
const LogTabWithIcons = (props: LogTabProps) => {
const { errors, warnings } = props.log
return (
<div
style={{
display: 'flex',
flexDirection: 'row',
gap: 6,
alignItems: 'center'
}}
onClick={() => {
const logWrapper = document.querySelector(`#logWrapper`)
if (logWrapper) logWrapper.scrollTop = 0
}}
>
<span>log</span>
{errors.length && <ErrorOutline color="error" style={{ fontSize: 20 }} />}
{warnings.length && <Warning style={{ fontSize: 20 }} />}{' '}
</div>
)
}
export default LogTabWithIcons