mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 01:38:56 -04:00
[ObsUX][APM] Replace react-syntax-highlighter
with EuiCodeBlock
(#204902)
## Summary Removes `react-syntax-highlighter` from APM errors, in favour of `EuiCodeBlock` for read-only code syntax highlighting. This in turn removes a bunch of custom styling to bring things more inline with the design system as well. Closes #204049 ## How to test * Go to Applications - Service Inventory * Find a service with errors * Go to Errors tab for service * Select an error that is an exception * View details for the exception and see the syntax highlighted block for the stack trace.
This commit is contained in:
parent
5323067906
commit
2a7a53aaf3
6 changed files with 28 additions and 177 deletions
|
@ -1253,7 +1253,6 @@
|
|||
"react-router-dom": "^5.3.4",
|
||||
"react-router-dom-v5-compat": "^6.12.0",
|
||||
"react-shortcuts": "^2.1.0",
|
||||
"react-syntax-highlighter": "^15.3.1",
|
||||
"react-use": "^15.3.8",
|
||||
"react-virtualized": "^9.22.5",
|
||||
"react-window": "^1.8.10",
|
||||
|
@ -1651,7 +1650,6 @@
|
|||
"@types/react-router": "^5.1.20",
|
||||
"@types/react-router-config": "^5.0.7",
|
||||
"@types/react-router-dom": "^5.3.3",
|
||||
"@types/react-syntax-highlighter": "^15.4.0",
|
||||
"@types/react-test-renderer": "^17.0.2",
|
||||
"@types/react-virtualized": "^9.21.30",
|
||||
"@types/react-window": "^1.8.8",
|
||||
|
|
|
@ -189,10 +189,7 @@ module.exports = {
|
|||
exclude: /node_modules/,
|
||||
},
|
||||
{
|
||||
test: [
|
||||
require.resolve('@elastic/eui/es/components/drag_and_drop'),
|
||||
require.resolve('highlight.js'),
|
||||
],
|
||||
test: [require.resolve('@elastic/eui/es/components/drag_and_drop')],
|
||||
use: require.resolve('null-loader'),
|
||||
},
|
||||
{
|
||||
|
|
|
@ -5,143 +5,47 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import { size } from 'lodash';
|
||||
import { tint } from 'polished';
|
||||
import React from 'react';
|
||||
import { Light as SyntaxHighlighter } from 'react-syntax-highlighter';
|
||||
import javascript from 'react-syntax-highlighter/dist/cjs/languages/hljs/javascript';
|
||||
import python from 'react-syntax-highlighter/dist/cjs/languages/hljs/python';
|
||||
import ruby from 'react-syntax-highlighter/dist/cjs/languages/hljs/ruby';
|
||||
import xcode from 'react-syntax-highlighter/dist/cjs/styles/hljs/xcode';
|
||||
import styled from '@emotion/styled';
|
||||
import { EuiCodeBlock } from '@elastic/eui';
|
||||
import type { StackframeWithLineContext } from '../../../../typings/es_schemas/raw/fields/stackframe';
|
||||
|
||||
SyntaxHighlighter.registerLanguage('javascript', javascript);
|
||||
SyntaxHighlighter.registerLanguage('python', python);
|
||||
SyntaxHighlighter.registerLanguage('ruby', ruby);
|
||||
|
||||
const ContextContainer = styled.div`
|
||||
position: relative;
|
||||
border-radius: ${({ theme }) => theme.euiTheme.border.radius.small};
|
||||
`;
|
||||
|
||||
const LINE_HEIGHT = 18;
|
||||
const LineHighlight = styled.div<{ lineNumber: number }>`
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
height: ${LINE_HEIGHT}px;
|
||||
top: ${(props) => props.lineNumber * LINE_HEIGHT}px;
|
||||
pointer-events: none;
|
||||
background-color: ${({ theme }) => tint(0.9, theme.euiTheme.colors.warning)};
|
||||
`;
|
||||
|
||||
const LineNumberContainer = styled.div<{ isLibraryFrame: boolean }>`
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
border-radius: ${({ theme }) => theme.euiTheme.border.radius.small};
|
||||
background: ${({ isLibraryFrame, theme }) =>
|
||||
isLibraryFrame ? theme.euiTheme.colors.emptyShade : theme.euiTheme.colors.lightestShade};
|
||||
`;
|
||||
|
||||
const LineNumber = styled.div<{ highlight: boolean }>`
|
||||
position: relative;
|
||||
min-width: 42px;
|
||||
padding-left: ${({ theme }) => theme.euiTheme.size.s};
|
||||
padding-right: ${({ theme }) => theme.euiTheme.size.xs};
|
||||
color: ${({ theme }) => theme.euiTheme.colors.mediumShade};
|
||||
line-height: ${LINE_HEIGHT}px;
|
||||
text-align: right;
|
||||
border-right: ${({ theme }) => theme.euiTheme.border.thin};
|
||||
background-color: ${({ highlight, theme }) =>
|
||||
highlight ? tint(0.9, theme.euiTheme.colors.warning) : null};
|
||||
|
||||
&:last-of-type {
|
||||
border-radius: 0 0 0 ${({ theme }) => theme.euiTheme.border.radius.small};
|
||||
}
|
||||
`;
|
||||
|
||||
const LineContainer = styled.div`
|
||||
overflow: auto;
|
||||
margin: 0 0 0 42px;
|
||||
padding: 0;
|
||||
background-color: ${({ theme }) => theme.euiTheme.colors.emptyShade};
|
||||
|
||||
&:last-of-type {
|
||||
border-radius: 0 0 ${({ theme }) => theme.euiTheme.border.radius.small} 0;
|
||||
}
|
||||
`;
|
||||
|
||||
const Line = styled.pre`
|
||||
// Override all styles
|
||||
margin: 0;
|
||||
color: inherit;
|
||||
background: inherit;
|
||||
border: 0;
|
||||
border-radius: 0;
|
||||
overflow: initial;
|
||||
padding: 0 ${LINE_HEIGHT}px;
|
||||
line-height: ${LINE_HEIGHT}px;
|
||||
`;
|
||||
|
||||
const Code = styled.code`
|
||||
position: relative;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
white-space: pre;
|
||||
z-index: 2;
|
||||
`;
|
||||
|
||||
function getStackframeLines(stackframe: StackframeWithLineContext) {
|
||||
const line = stackframe.line.context;
|
||||
const preLines = stackframe.context?.pre || [];
|
||||
const postLines = stackframe.context?.post || [];
|
||||
return [...preLines, line, ...postLines].map(
|
||||
(x) => (x.endsWith('\n') ? x.slice(0, -1) : x) || ' '
|
||||
);
|
||||
return [...preLines, line, ...postLines]
|
||||
.map((x) => (x.endsWith('\n') ? x.slice(0, -1) : x) || ' ')
|
||||
.join('\n');
|
||||
}
|
||||
|
||||
function getStartLineNumber(stackframe: StackframeWithLineContext) {
|
||||
const preLines = size(stackframe.context?.pre || []);
|
||||
const preLines = (stackframe.context?.pre || []).length;
|
||||
return stackframe.line.number - preLines;
|
||||
}
|
||||
|
||||
interface Props {
|
||||
stackframe: StackframeWithLineContext;
|
||||
codeLanguage?: string;
|
||||
isLibraryFrame: boolean;
|
||||
}
|
||||
|
||||
export function Context({ stackframe, codeLanguage, isLibraryFrame }: Props) {
|
||||
export function Context({ stackframe, codeLanguage }: Props) {
|
||||
const lines = getStackframeLines(stackframe);
|
||||
const startLineNumber = getStartLineNumber(stackframe);
|
||||
const highlightedLineIndex = size(stackframe.context?.pre || []);
|
||||
const start = getStartLineNumber(stackframe);
|
||||
const highlightedLine = start + (stackframe.context?.pre || []).length;
|
||||
const language = codeLanguage || 'javascript'; // TODO: Add support for more languages
|
||||
|
||||
return (
|
||||
<ContextContainer>
|
||||
<LineHighlight lineNumber={highlightedLineIndex} />
|
||||
<LineNumberContainer isLibraryFrame={isLibraryFrame}>
|
||||
{lines.map((line, i) => (
|
||||
<LineNumber key={line + i} highlight={highlightedLineIndex === i}>
|
||||
{i + startLineNumber}.
|
||||
</LineNumber>
|
||||
))}
|
||||
</LineNumberContainer>
|
||||
<LineContainer>
|
||||
{lines.map((line, i) => (
|
||||
<SyntaxHighlighter
|
||||
key={line + i}
|
||||
language={language}
|
||||
style={xcode}
|
||||
PreTag={Line}
|
||||
CodeTag={Code}
|
||||
customStyle={{ padding: undefined, overflowX: undefined }}
|
||||
>
|
||||
{line}
|
||||
</SyntaxHighlighter>
|
||||
))}
|
||||
</LineContainer>
|
||||
</ContextContainer>
|
||||
<EuiCodeBlock
|
||||
language={language}
|
||||
whiteSpace="pre"
|
||||
paddingSize="s"
|
||||
lineNumbers={{
|
||||
start,
|
||||
highlight: `${highlightedLine}`,
|
||||
}}
|
||||
transparentBackground
|
||||
>
|
||||
{lines}
|
||||
</EuiCodeBlock>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -34,7 +34,7 @@ describe('Stackframe', () => {
|
|||
});
|
||||
|
||||
it('should have isLibraryFrame=false as default', () => {
|
||||
expect(wrapper.find('Context').prop('isLibraryFrame')).toBe(false);
|
||||
expect(wrapper.find('FrameHeading').prop('isLibraryFrame')).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
|
|
|
@ -16,14 +16,13 @@ import { Context } from './context';
|
|||
import { FrameHeading } from './frame_heading';
|
||||
import { Variables } from './variables';
|
||||
|
||||
const ContextContainer = styled.div<{ isLibraryFrame: boolean }>`
|
||||
const ContextContainer = styled.div`
|
||||
position: relative;
|
||||
font-family: ${({ theme }) => theme.euiTheme.font.familyCode};
|
||||
font-size: ${() => useEuiFontSize('s').fontSize};
|
||||
border: ${({ theme }) => theme.euiTheme.border.thin};
|
||||
border-radius: ${({ theme }) => theme.euiTheme.border.radius.small};
|
||||
background: ${({ isLibraryFrame, theme }) =>
|
||||
isLibraryFrame ? theme.euiTheme.colors.emptyShade : theme.euiTheme.colors.lightestShade};
|
||||
background: ${({ theme }) => theme.euiTheme.colors.emptyShade};
|
||||
`;
|
||||
|
||||
// Indent the non-context frames the same amount as the accordion control
|
||||
|
@ -72,12 +71,8 @@ export function Stackframe({
|
|||
id={id}
|
||||
initialIsOpen={initialIsOpen}
|
||||
>
|
||||
<ContextContainer isLibraryFrame={isLibraryFrame}>
|
||||
<Context
|
||||
stackframe={stackframe}
|
||||
codeLanguage={codeLanguage}
|
||||
isLibraryFrame={isLibraryFrame}
|
||||
/>
|
||||
<ContextContainer>
|
||||
<Context stackframe={stackframe} codeLanguage={codeLanguage} />
|
||||
</ContextContainer>
|
||||
<Variables vars={stackframe.vars} />
|
||||
</EuiAccordion>
|
||||
|
|
47
yarn.lock
47
yarn.lock
|
@ -12291,13 +12291,6 @@
|
|||
"@types/history" "^4.7.11"
|
||||
"@types/react" "*"
|
||||
|
||||
"@types/react-syntax-highlighter@^15.4.0":
|
||||
version "15.5.5"
|
||||
resolved "https://registry.yarnpkg.com/@types/react-syntax-highlighter/-/react-syntax-highlighter-15.5.5.tgz#4d3b51f8956195f1f63360ff03f8822c5d74c516"
|
||||
integrity sha512-QH3JZQXa2usAvJvSsdSUJ4Yu4j8ReuZpgRrEW+XP+Rmosbn425YshW9iGEb/pAARm8496axHhHUPRH3UmTiB6A==
|
||||
dependencies:
|
||||
"@types/react" "*"
|
||||
|
||||
"@types/react-test-renderer@^17.0.2":
|
||||
version "17.0.2"
|
||||
resolved "https://registry.yarnpkg.com/@types/react-test-renderer/-/react-test-renderer-17.0.2.tgz#5f800a39b12ac8d2a2149e7e1885215bcf4edbbf"
|
||||
|
@ -19110,13 +19103,6 @@ fastq@^1.13.0, fastq@^1.6.0:
|
|||
dependencies:
|
||||
reusify "^1.0.4"
|
||||
|
||||
fault@^1.0.0:
|
||||
version "1.0.4"
|
||||
resolved "https://registry.yarnpkg.com/fault/-/fault-1.0.4.tgz#eafcfc0a6d214fc94601e170df29954a4f842f13"
|
||||
integrity sha512-CJ0HCB5tL5fYTEA7ToAq5+kTwd++Borf1/bifxd9iT70QcXr4MRrO3Llf8Ifs70q+SJcGHFtnIE/Nw6giCtECA==
|
||||
dependencies:
|
||||
format "^0.2.0"
|
||||
|
||||
faye-websocket@^0.11.3:
|
||||
version "0.11.3"
|
||||
resolved "https://registry.yarnpkg.com/faye-websocket/-/faye-websocket-0.11.3.tgz#5c0e9a8968e8912c286639fde977a8b209f2508e"
|
||||
|
@ -19537,11 +19523,6 @@ form-data@^4.0.0, form-data@~4.0.0:
|
|||
combined-stream "^1.0.8"
|
||||
mime-types "^2.1.12"
|
||||
|
||||
format@^0.2.0:
|
||||
version "0.2.2"
|
||||
resolved "https://registry.yarnpkg.com/format/-/format-0.2.2.tgz#d6170107e9efdc4ed30c9dc39016df942b5cb58b"
|
||||
integrity sha1-1hcBB+nv3E7TDJ3DkBbflCtctYs=
|
||||
|
||||
formdata-node@^4.3.2:
|
||||
version "4.4.1"
|
||||
resolved "https://registry.yarnpkg.com/formdata-node/-/formdata-node-4.4.1.tgz#23f6a5cb9cb55315912cbec4ff7b0f59bbd191e2"
|
||||
|
@ -20707,11 +20688,6 @@ hexoid@^2.0.0:
|
|||
resolved "https://registry.yarnpkg.com/hexoid/-/hexoid-2.0.0.tgz#fb36c740ebbf364403fa1ec0c7efd268460ec5b9"
|
||||
integrity sha512-qlspKUK7IlSQv2o+5I7yhUd7TxlOG2Vr5LTa3ve2XSNVKAL/n/u/7KLvKmFNimomDIKvZFXWHv0T12mv7rT8Aw==
|
||||
|
||||
highlight.js@^10.1.1, highlight.js@~10.4.0:
|
||||
version "10.4.1"
|
||||
resolved "https://registry.yarnpkg.com/highlight.js/-/highlight.js-10.4.1.tgz#d48fbcf4a9971c4361b3f95f302747afe19dbad0"
|
||||
integrity sha512-yR5lWvNz7c85OhVAEAeFhVCc/GV4C30Fjzc/rCP0aCWzc1UUOPUk55dK/qdwTZHBvMZo+eZ2jpk62ndX/xMFlg==
|
||||
|
||||
history@^4.9.0:
|
||||
version "4.9.0"
|
||||
resolved "https://registry.yarnpkg.com/history/-/history-4.9.0.tgz#84587c2068039ead8af769e9d6a6860a14fa1bca"
|
||||
|
@ -23730,14 +23706,6 @@ lowercase-keys@^2.0.0:
|
|||
resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-2.0.0.tgz#2603e78b7b4b0006cbca2fbcc8a3202558ac9479"
|
||||
integrity sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==
|
||||
|
||||
lowlight@^1.14.0:
|
||||
version "1.17.0"
|
||||
resolved "https://registry.yarnpkg.com/lowlight/-/lowlight-1.17.0.tgz#a1143b2fba8239df8cd5893f9fe97aaf8465af4a"
|
||||
integrity sha512-vmtBgYKD+QVNy7tIa7ulz5d//Il9R4MooOVh4nkOf9R9Cb/Dk5TXMSTieg/vDulkBkIWj59/BIlyFQxT9X1oAQ==
|
||||
dependencies:
|
||||
fault "^1.0.0"
|
||||
highlight.js "~10.4.0"
|
||||
|
||||
lru-cache@10.2.0:
|
||||
version "10.2.0"
|
||||
resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-10.2.0.tgz#0bd445ca57363465900f4d1f9bd8db343a4d95c3"
|
||||
|
@ -27036,7 +27004,7 @@ printj@~1.1.0:
|
|||
resolved "https://registry.yarnpkg.com/printj/-/printj-1.1.2.tgz#d90deb2975a8b9f600fb3a1c94e3f4c53c78a222"
|
||||
integrity sha512-zA2SmoLaxZyArQTOPj5LXecR+RagfPSU5Kw1qP+jkWeNlrq+eJZyY2oS68SU1Z/7/myXM4lo9716laOFAVStCQ==
|
||||
|
||||
prismjs@^1.22.0, prismjs@^1.29.0:
|
||||
prismjs@^1.29.0:
|
||||
version "1.29.0"
|
||||
resolved "https://registry.yarnpkg.com/prismjs/-/prismjs-1.29.0.tgz#f113555a8fa9b57c35e637bba27509dcf802dd12"
|
||||
integrity sha512-Kx/1w86q/epKcmte75LNrEoT+lX8pBpavuAbvJWRXar7Hz8jrtF+e3vY751p0R8H9HdArwaCTNDDzHg/ScJK1Q==
|
||||
|
@ -27973,17 +27941,6 @@ react-style-singleton@^2.2.0, react-style-singleton@^2.2.1:
|
|||
invariant "^2.2.4"
|
||||
tslib "^2.0.0"
|
||||
|
||||
react-syntax-highlighter@^15.3.1:
|
||||
version "15.3.1"
|
||||
resolved "https://registry.yarnpkg.com/react-syntax-highlighter/-/react-syntax-highlighter-15.3.1.tgz#ba16ae8705f191956b73d0e11ae938fd255f2579"
|
||||
integrity sha512-XVQuug7kQ4/cWxiYE0XfGXvbDqLLqRsMK/GpmD3v1WOLzb6REcgkL59cJo0m3Y2LB0eoRCNhV62jqQe9/Z0p9w==
|
||||
dependencies:
|
||||
"@babel/runtime" "^7.3.1"
|
||||
highlight.js "^10.1.1"
|
||||
lowlight "^1.14.0"
|
||||
prismjs "^1.22.0"
|
||||
refractor "^3.2.0"
|
||||
|
||||
react-tabs@^6.0.2:
|
||||
version "6.0.2"
|
||||
resolved "https://registry.yarnpkg.com/react-tabs/-/react-tabs-6.0.2.tgz#bc1065c3828561fee285a8fd045f22e0fcdde1eb"
|
||||
|
@ -28356,7 +28313,7 @@ reflect-metadata@^0.2.2:
|
|||
resolved "https://registry.yarnpkg.com/reflect-metadata/-/reflect-metadata-0.2.2.tgz#400c845b6cba87a21f2c65c4aeb158f4fa4d9c5b"
|
||||
integrity sha512-urBwgfrvVP/eAyXx4hluJivBKzuEbSQs9rKWCrCkbSxNv8mxPcUZKeuoF3Uy4mJl3Lwprp6yy5/39VWigZ4K6Q==
|
||||
|
||||
refractor@^3.2.0, refractor@^3.6.0:
|
||||
refractor@^3.6.0:
|
||||
version "3.6.0"
|
||||
resolved "https://registry.yarnpkg.com/refractor/-/refractor-3.6.0.tgz#ac318f5a0715ead790fcfb0c71f4dd83d977935a"
|
||||
integrity sha512-MY9W41IOWxxk31o+YvFCNyNzdkc9M20NoZK5vq6jkv4I/uh2zkWcfudj0Q1fovjUQJrNewS9NMzeTtqPf+n5EA==
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue