feat(trace-viewer) add copy to clipboard on the Source > Stacktrace tab

This commit is contained in:
Ryan Rosello 2024-06-20 20:13:02 +10:00
parent 251028ff10
commit 0e8fdcecd9
3 changed files with 29 additions and 5 deletions

View file

@ -18,7 +18,8 @@ import * as React from 'react';
export const CopyToClipboard: React.FunctionComponent<{ export const CopyToClipboard: React.FunctionComponent<{
value: string, value: string,
}> = ({ value }) => { description?: string,
}> = ({ value, description }) => {
const [iconClassName, setIconClassName] = React.useState('codicon-clippy'); const [iconClassName, setIconClassName] = React.useState('codicon-clippy');
const handleCopy = React.useCallback(() => { const handleCopy = React.useCallback(() => {
@ -32,5 +33,5 @@ export const CopyToClipboard: React.FunctionComponent<{
}); });
}, [value]); }, [value]);
return <span className={`copy-icon codicon ${iconClassName}`} onClick={handleCopy}/>; return <span title={description ? description : 'Copy'} className={`copy-icon codicon ${iconClassName}`} onClick={handleCopy}/>;
}; };

View file

@ -30,3 +30,17 @@
.stack-trace-frame-line { .stack-trace-frame-line {
flex: none; flex: none;
} }
.stack-trace-copy-to-clipboard {
padding: 0 5px;
}
.copy-icon {
display: none;
margin-right: 4px;
}
.list-view-entry:hover .copy-icon {
display: block;
cursor: pointer;
}

View file

@ -18,6 +18,7 @@ import * as React from 'react';
import './stackTrace.css'; import './stackTrace.css';
import { ListView } from '@web/components/listView'; import { ListView } from '@web/components/listView';
import type { StackFrame } from '@protocol/channels'; import type { StackFrame } from '@protocol/channels';
import { CopyToClipboard } from './copyToClipboard';
const StackFrameListView = ListView<StackFrame>; const StackFrameListView = ListView<StackFrame>;
@ -27,23 +28,31 @@ export const StackTraceView: React.FunctionComponent<{
setSelectedFrame: (index: number) => void setSelectedFrame: (index: number) => void
}> = ({ stack, setSelectedFrame, selectedFrame }) => { }> = ({ stack, setSelectedFrame, selectedFrame }) => {
const frames = stack || []; const frames = stack || [];
const getFileName = (frame: StackFrame) => {
const pathSep = frame.file[1] === ':' ? '\\' : '/';
const fileName = frame.file.split(pathSep).pop();
return fileName;
};
return <StackFrameListView return <StackFrameListView
name='stack-trace' name='stack-trace'
items={frames} items={frames}
selectedItem={frames[selectedFrame]} selectedItem={frames[selectedFrame]}
render={frame => { render={frame => {
const pathSep = frame.file[1] === ':' ? '\\' : '/';
return <> return <>
<span className='stack-trace-frame-function'> <span className='stack-trace-frame-function'>
{frame.function || '(anonymous)'} {frame.function || '(anonymous)'}
</span> </span>
<span className='stack-trace-frame-location'> <span className='stack-trace-frame-location'>
{frame.file.split(pathSep).pop()} {getFileName(frame)}
</span> </span>
<span className='stack-trace-frame-line'> <span className='stack-trace-frame-line'>
{':' + frame.line} {':' + frame.line}
</span> </span>
<span className='stack-trace-copy-to-clipboard'>
<CopyToClipboard description='Copy filename' value={`${getFileName(frame)}:${frame.line}`}/>
</span>
</>; </>;
}} }}
onSelected={frame => setSelectedFrame(frames.indexOf(frame))} />; onSelected={frame => setSelectedFrame(frames.indexOf(frame))} />;
}; };