diff --git a/web/src/containers/Studio/internal/components/log/logChunk.tsx b/web/src/containers/Studio/internal/components/log/logChunk.tsx index 37c59da..cc84c17 100644 --- a/web/src/containers/Studio/internal/components/log/logChunk.tsx +++ b/web/src/containers/Studio/internal/components/log/logChunk.tsx @@ -5,12 +5,14 @@ import { ErrorOutline, Warning } from '@mui/icons-material' import ContentCopyIcon from '@mui/icons-material/ContentCopy' import ExpandMoreIcon from '@mui/icons-material/ExpandMore' import CheckIcon from '@mui/icons-material/Check' +import FileDownloadIcon from '@mui/icons-material/FileDownload' import { makeStyles } from '@mui/styles' import { defaultChunkSize, parseErrorsAndWarnings, LogInstance, - clearErrorsAndWarningsHtmlWrapping + clearErrorsAndWarningsHtmlWrapping, + download } from '../../../../../utils' const useStyles: any = makeStyles((theme: any) => ({ @@ -44,7 +46,11 @@ interface LogChunkProps { } const LogChunk = (props: LogChunkProps) => { - const { id, text, logLineCount, scrollToLogInstance } = props + const { id, text, logLineCount } = props + const [scrollToLogInstance, setScrollToLogInstance] = useState( + props.scrollToLogInstance + ) + const rowText = clearErrorsAndWarningsHtmlWrapping(text) const classes = useStyles() const [expanded, setExpanded] = useState(props.expanded) const [copied, setCopied] = useState(false) @@ -78,6 +84,13 @@ const LogChunk = (props: LogChunkProps) => { const { errors, warnings } = parseErrorsAndWarnings(text) + const getLineRange = (separator = ' ... ') => + `${id * defaultChunkSize}${separator}${ + (id + 1) * defaultChunkSize < logLineCount + ? (id + 1) * defaultChunkSize + : logLineCount + }` + return (
props.onClick(evt, id)}>
- {Array.isArray(logChunks) ? ( - logChunks.map((chunk: string, id: number) => ( - { - setLogChunksState((prevState) => { - const newState = [...prevState] - const expand = !newState[chunkNumber] +
+ {Array.isArray(logChunks) ? ( + logChunks.map((chunk: string, id: number) => ( + { + setLogChunksState((prevState) => { + const newState = [...prevState] + const expand = !newState[chunkNumber] - newState[chunkNumber] = expand + newState[chunkNumber] = expand - if (expand) { - const chunkToCollapse = getChunkToAutoCollapse() + if (expand) { + const chunkToCollapse = getChunkToAutoCollapse() - if (chunkToCollapse !== undefined) { - newState[chunkToCollapse] = false + if (chunkToCollapse !== undefined) { + newState[chunkToCollapse] = false + } } - } - return newState - }) + return newState + }) - setScrollToLogInstance(undefined) - }} - /> - )) - ) : ( - - - {logChunks} - - - )} + setScrollToLogInstance(undefined) + }} + /> + )) + ) : ( + + + {logChunks} + + + )} +
) : (
@@ -254,10 +261,29 @@ const LogComponent = (props: LogComponentProps) => { id="log" style={{ overflow: 'auto', height: 'calc(100vh - 220px)' }} > - {typeof log === 'string' ? log : log.body} + {logBody}
)} +
+ +
) } diff --git a/web/src/utils/log.ts b/web/src/utils/log.ts index 1130184..52b6034 100644 --- a/web/src/utils/log.ts +++ b/web/src/utils/log.ts @@ -1,3 +1,4 @@ +import { SyntheticEvent } from 'react' import { LogInstance } from './' export const parseErrorsAndWarnings = (log: string) => { @@ -100,3 +101,25 @@ export const splitIntoChunks = (log: string, chunkSize = defaultChunkSize) => { export const clearErrorsAndWarningsHtmlWrapping = (log: string) => log.replace(/^]*>/gm, '').replace(/<\/font>/gm, '') + +export const download = ( + evt: SyntheticEvent, + log: string, + fileName = 'log' +) => { + evt.stopPropagation() + + const file = new Blob([log]) + const url = URL.createObjectURL(file) + + const a = document.createElement('a') + a.href = url + a.download = `${fileName}.log` + document.body.appendChild(a) + a.click() + + setTimeout(() => { + document.body.removeChild(a) + window.URL.revokeObjectURL(url) + }, 0) +}