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)
+}