|
1 | 1 | import * as React from 'react'; |
2 | | -import styled from 'styled-components'; |
3 | | -import { Box, Link } from '@primer/react'; |
4 | | -import { AnalysisAlert, HighlightedRegion, ResultSeverity } from '../shared/analysis-result'; |
5 | | - |
6 | | -const borderColor = 'var(--vscode-editor-snippetFinalTabstopHighlightBorder)'; |
7 | | -const warningColor = '#966C23'; |
8 | | -const highlightColor = '#534425'; |
9 | | - |
10 | | -const getSeverityColor = (severity: ResultSeverity) => { |
11 | | - switch (severity) { |
12 | | - case 'Recommendation': |
13 | | - return 'blue'; |
14 | | - case 'Warning': |
15 | | - return warningColor; |
16 | | - case 'Error': |
17 | | - return 'red'; |
18 | | - } |
19 | | -}; |
20 | | - |
21 | | -const Container = styled.div` |
22 | | - font-family: ui-monospace, SFMono-Regular, SF Mono, Menlo, Consolas, Liberation Mono, monospace; |
23 | | -`; |
24 | | - |
25 | | -const TitleContainer = styled.div` |
26 | | - border: 0.1em solid ${borderColor}; |
27 | | - border-top-left-radius: 0.2em; |
28 | | - border-top-right-radius: 0.2em; |
29 | | - padding: 0.5em; |
30 | | -`; |
31 | | - |
32 | | -const CodeContainer = styled.div` |
33 | | - font-size: x-small; |
34 | | - border-left: 0.1em solid ${borderColor}; |
35 | | - border-right: 0.1em solid ${borderColor}; |
36 | | - border-bottom: 0.1em solid ${borderColor}; |
37 | | - border-bottom-left-radius: 0.2em; |
38 | | - border-bottom-right-radius: 0.2em; |
39 | | - padding-top: 1em; |
40 | | - padding-bottom: 1em; |
41 | | -`; |
42 | | - |
43 | | -const MessageText = styled.span<{ severity: ResultSeverity }>` |
44 | | - font-size: x-small; |
45 | | - color: ${props => getSeverityColor(props.severity)}; |
46 | | - padding-left: 0.5em; |
47 | | -`; |
48 | | - |
49 | | -const MessageContainer = styled.div` |
50 | | - padding-top: 0.5em; |
51 | | - padding-bottom: 0.5em; |
52 | | -`; |
53 | | - |
54 | | -const Message = ({ alert, currentLineNumber }: { |
55 | | - alert: AnalysisAlert, |
56 | | - currentLineNumber: number |
57 | | -}) => { |
58 | | - if (alert.highlightedRegion.startLine !== currentLineNumber) { |
59 | | - return <></>; |
60 | | - } |
61 | | - return <MessageContainer> |
62 | | - <Box |
63 | | - borderColor="border.default" |
64 | | - borderWidth={1} |
65 | | - borderStyle="solid" |
66 | | - borderLeftColor={getSeverityColor(alert.severity)} |
67 | | - borderLeftWidth={3} |
68 | | - paddingTop="1em" |
69 | | - paddingBottom="1em"> |
70 | | - <MessageText severity={alert.severity}>{alert.message}</MessageText> |
71 | | - </Box> |
72 | | - |
73 | | - </MessageContainer>; |
74 | | -}; |
75 | | - |
76 | | -const replaceSpaceChar = (text: string) => text.replaceAll(' ', '\u00a0'); |
77 | | - |
78 | | -const PlainLine = ({ text }: { text: string }) => { |
79 | | - return <span>{replaceSpaceChar(text)}</span>; |
80 | | -}; |
81 | | - |
82 | | -const HighlightedLine = ({ text }: { text: string }) => { |
83 | | - return <span style={{ backgroundColor: highlightColor }}>{replaceSpaceChar(text)}</span>; |
84 | | -}; |
85 | | - |
86 | | -const shouldHighlightLine = (lineNumber: number, highlightedRegion: HighlightedRegion) => { |
87 | | - if (lineNumber < highlightedRegion.startLine) { |
88 | | - return false; |
89 | | - } |
90 | | - |
91 | | - if (highlightedRegion.endLine) { |
92 | | - return lineNumber <= highlightedRegion.endLine; |
93 | | - } |
94 | | - |
95 | | - return true; |
96 | | -}; |
97 | | - |
98 | | -const CodeLine = ({ |
99 | | - line, |
100 | | - lineNumber, |
101 | | - highlightedRegion |
102 | | -}: { |
103 | | - line: string, |
104 | | - lineNumber: number, |
105 | | - highlightedRegion: HighlightedRegion |
106 | | -}) => { |
107 | | - if (!shouldHighlightLine(lineNumber, highlightedRegion)) { |
108 | | - return <PlainLine text={line} />; |
109 | | - } |
110 | | - |
111 | | - const section1 = line.substring(0, highlightedRegion.startColumn - 1); |
112 | | - const section2 = line.substring(highlightedRegion.startColumn - 1, highlightedRegion.endColumn - 1); |
113 | | - const section3 = line.substring(highlightedRegion.endColumn - 1, line.length); |
114 | | - |
115 | | - return ( |
116 | | - <> |
117 | | - <PlainLine text={section1} /> |
118 | | - <HighlightedLine text={section2} /> |
119 | | - <PlainLine text={section3} /> |
120 | | - </> |
121 | | - ); |
122 | | -}; |
| 2 | +import { AnalysisAlert } from '../shared/analysis-result'; |
| 3 | +import FileCodeSnippet from './FileCodeSnippet'; |
123 | 4 |
|
124 | 5 | const AnalysisAlertResult = ({ alert }: { alert: AnalysisAlert }) => { |
125 | | - const code = alert.codeSnippet.text |
126 | | - .split('\n') |
127 | | - .filter(line => line.replace('\n', '').length > 0); |
128 | | - |
129 | | - const startingLine = alert.codeSnippet.startLine; |
130 | 6 |
|
131 | | - return ( |
132 | | - <Container> |
133 | | - <TitleContainer> |
134 | | - <Link>{alert.filePath}</Link> |
135 | | - </TitleContainer> |
136 | | - <CodeContainer> |
137 | | - {code.map((line, index) => ( |
138 | | - <div key={index}> |
139 | | - <Message alert={alert} currentLineNumber={startingLine + index} /> |
140 | | - <Box display="flex"> |
141 | | - <Box |
142 | | - p={2} |
143 | | - borderStyle="none" |
144 | | - paddingTop="0.01em" |
145 | | - paddingLeft="0.5em" |
146 | | - paddingRight="0.5em" |
147 | | - paddingBottom="0.2em"> |
148 | | - {startingLine + index} |
149 | | - </Box> |
150 | | - <Box |
151 | | - flexGrow={1} |
152 | | - p={2} |
153 | | - borderStyle="none" |
154 | | - paddingTop="0.01em" |
155 | | - paddingLeft="1.5em" |
156 | | - paddingRight="0.5em" |
157 | | - paddingBottom="0.2em"> |
158 | | - <CodeLine |
159 | | - line={line} |
160 | | - lineNumber={startingLine + index} |
161 | | - highlightedRegion={alert.highlightedRegion} /> |
162 | | - </Box> |
163 | | - </Box> |
164 | | - </div> |
165 | | - ))} |
166 | | - </CodeContainer> |
167 | | - </Container> |
168 | | - ); |
| 7 | + return <FileCodeSnippet |
| 8 | + filePath={alert.filePath} |
| 9 | + codeSnippet={alert.codeSnippet} |
| 10 | + highlightedRegion={alert.highlightedRegion} |
| 11 | + severity={alert.severity} |
| 12 | + message={alert.message} |
| 13 | + />; |
169 | 14 | }; |
170 | 15 |
|
171 | 16 | export default AnalysisAlertResult; |
0 commit comments