-
Notifications
You must be signed in to change notification settings - Fork 40
/
Log.js
130 lines (122 loc) · 4.75 KB
/
Log.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
import React, {useEffect, useRef, useState} from "react";
import useWindowDimensions from "../../utils/windowDimension";
import {Box, Flex, Spacer, Text, Tooltip, useClipboard} from "@chakra-ui/react";
import parse from 'html-react-parser';
import hasAnsi from 'has-ansi';
import stripAnsi from 'strip-ansi';
import {saveTextAsFile} from "../../utils/download";
import {Virtuoso} from "react-virtuoso";
import {DownloadIcon, TriangleDownIcon} from '@chakra-ui/icons'
var os = require('os-browserify/browser')
const Convert = require('ansi-to-html');
const convert = new Convert();
const Row = ({log}) => {
if (log !== undefined && log.length !== 0) {
let txt = log
if (hasAnsi(txt)) {
const parsedAnsi = convert.toHtml(txt)
txt = parse(parsedAnsi)
}
return (
<Box style={styles.row}>{txt}</Box>
);
}
return <></>;
};
export const Log = ({logs, fileName, currentExecutionStatus, executionStatusText}) => {
const [displayLogs, setDisplayLogs] = useState(logs)
const virtuosoRef = useRef(null)
const {height: windowHeight} = useWindowDimensions();
const {onCopy, setValue: setCopyValue, hasCopied} = useClipboard("");
useEffect(() => {
setDisplayLogs(logs);
const logsWithoutAnsi = logs.map((log) => {
return stripAnsi(log)
})
setCopyValue(logsWithoutAnsi.join(os.EOL))
}, [logs]);
const handleDownload = () => {
const logsWithoutAnsi = logs.map((log) => {
return stripAnsi(log)
})
const logsAsText = logsWithoutAnsi.join(os.EOL)
saveTextAsFile(logsAsText, fileName)
}
const handleScrollToBottom = () => {
virtuosoRef.current.scrollToIndex({
index: displayLogs.length - 1,
behavior: 'auto',
align: "end",
});
}
return (
<div className="flex flex-col bg-black">
<Virtuoso
style={{height: (windowHeight - 100) * 0.8, backgroundColor: "black"}}
ref={virtuosoRef}
data={displayLogs}
totalCount={displayLogs.length - 1}
itemContent={(index, log) => {
return (<Row index={index} log={log}/>);
}}
followOutput={"smooth"}
/>
<Flex className="bg-black" style={{height: `80px`}}>
<Spacer/>
<Box
p='2'
m="4"
height={"40px"}
>
<Text fontSize={"sm"}>{executionStatusText}</Text>
</Box>
<Box p='2' m="4"
height={"40px"}
>
{currentExecutionStatus}
</Box>
<Tooltip label={`${hasCopied ? "Copied!" : "Copy to clipboard"}`}
placement='top-end'
closeOnClick={false}
>
<Box p='2' m="4" onClick={onCopy} height={"40px"}>
<svg className="w-6 h-6 text-gray-800 dark:text-white" aria-hidden="true"
xmlns="http://www.w3.org/2000/svg" fill="currentColor" viewBox="0 0 18 20">
<path
d="M5 9V4.13a2.96 2.96 0 0 0-1.293.749L.879 7.707A2.96 2.96 0 0 0 .13 9H5Zm11.066-9H9.829a2.98 2.98 0 0 0-2.122.879L7 1.584A.987.987 0 0 0 6.766 2h4.3A3.972 3.972 0 0 1 15 6v10h1.066A1.97 1.97 0 0 0 18 14V2a1.97 1.97 0 0 0-1.934-2Z"/>
<path
d="M11.066 4H7v5a2 2 0 0 1-2 2H0v7a1.969 1.969 0 0 0 1.933 2h9.133A1.97 1.97 0 0 0 13 18V6a1.97 1.97 0 0 0-1.934-2Z"/>
</svg>
</Box>
</Tooltip>
<Tooltip label={"Download to file"}
placement='top'
>
<Box p='2' m="4" onClick={handleDownload} height={"40px"}>
<DownloadIcon textColor={"white"}/>
</Box>
</Tooltip>
<Tooltip label={"Autoscroll to bottom"}
placement='top'
>
<Box p='2' m="4"
height={"40px"}
onClick={handleScrollToBottom}
>
<TriangleDownIcon textColor={"white"}/>
</Box>
</Tooltip>
</Flex>
</div>
)
}
const styles = {
row: {
fontSize: "10pt",
fontFamily: "Menlo, Monaco, Inconsolata, Consolas, Courier, monospace",
boxSizing: "border-box",
borderBottom: "1px solid #222",
padding: "1em",
color: "white"
}
};