chore: hide timeline bars and stack from ui mode (#21590)

This commit is contained in:
Pavel Feldman 2023-03-10 22:52:31 -08:00 committed by GitHub
parent ea8aa63f1a
commit 428ea66578
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 27 additions and 26 deletions

View File

@ -19,6 +19,7 @@
display: flex;
flex-direction: column;
position: relative;
min-height: 50px;
}
.film-strip-lane {

View File

@ -30,7 +30,8 @@ type StackInfo = {
export const SourceTab: React.FunctionComponent<{
action: ActionTraceEvent | undefined,
}> = ({ action }) => {
hideStackFrames?: boolean,
}> = ({ action, hideStackFrames }) => {
const [lastAction, setLastAction] = React.useState<ActionTraceEvent | undefined>();
const [selectedFrame, setSelectedFrame] = React.useState<number>(0);
@ -69,7 +70,7 @@ export const SourceTab: React.FunctionComponent<{
const targetLine = stackInfo.frames[selectedFrame]?.line || 0;
const error = action?.error?.message;
return <SplitView sidebarSize={200} orientation='horizontal'>
return <SplitView sidebarSize={200} orientation='horizontal' sidebarHidden={hideStackFrames}>
<CodeMirrorWrapper text={content} language='javascript' highlight={[{ line: targetLine, type: error ? 'error' : 'running', message: error }]} revealLine={targetLine} readOnly={true} lineNumbers={true}></CodeMirrorWrapper>
<StackTraceView action={action} selectedFrame={selectedFrame} setSelectedFrame={setSelectedFrame}></StackTraceView>
</SplitView>;

View File

@ -41,7 +41,8 @@ export const Timeline: React.FunctionComponent<{
model: MultiTraceModel | undefined,
selectedAction: ActionTraceEvent | undefined,
onSelected: (action: ActionTraceEvent) => void,
}> = ({ model, selectedAction, onSelected }) => {
hideTimelineBars?: boolean,
}> = ({ model, selectedAction, onSelected, hideTimelineBars }) => {
const [measure, ref] = useMeasure<HTMLDivElement>();
const barsRef = React.useRef<HTMLDivElement | null>(null);
@ -50,6 +51,10 @@ export const Timeline: React.FunctionComponent<{
const { boundaries, offsets } = React.useMemo(() => {
const boundaries = { minimum: model?.startTime || 0, maximum: model?.endTime || 30000 };
if (boundaries.minimum > boundaries.maximum) {
boundaries.minimum = 0;
boundaries.maximum = 30000;
}
// Leave some nice free space on the right hand side.
boundaries.maximum += (boundaries.maximum - boundaries.minimum) / 20;
return { boundaries, offsets: calculateDividerOffsets(measure.width, boundaries) };
@ -95,41 +100,34 @@ export const Timeline: React.FunctionComponent<{
let targetBar: TimelineBar | undefined = bars.find(bar => bar.action === selectedAction);
targetBar = hoveredBar || targetBar;
const findHoveredBarIndex = (x: number, y: number) => {
const findHoveredBarIndex = (x: number) => {
const time = positionToTime(measure.width, boundaries, x);
const time1 = positionToTime(measure.width, boundaries, x - 5);
const time2 = positionToTime(measure.width, boundaries, x + 5);
let index: number | undefined;
let yDistance: number | undefined;
let xDistance: number | undefined;
for (let i = 0; i < bars.length; i++) {
const bar = bars[i];
const yMiddle = kBarHeight / 2 + barTop(bar);
const left = Math.max(bar.leftTime, time1);
const right = Math.min(bar.rightTime, time2);
const xMiddle = (bar.leftTime + bar.rightTime) / 2;
const xd = Math.abs(time - xMiddle);
const yd = Math.abs(y - yMiddle);
if (left > right)
continue;
// Prefer closest yDistance (the same bar), among those prefer the closest xDistance.
if (index === undefined ||
(yd < yDistance!) ||
(Math.abs(yd - yDistance!) < 1e-2 && xd < xDistance!)) {
if (index === undefined || xd < xDistance!) {
index = i;
xDistance = xd;
yDistance = yd;
}
}
return index;
};
const onMouseMove = (event: React.MouseEvent) => {
if (!ref.current || !barsRef.current)
if (!ref.current)
return;
const x = event.clientX - ref.current.getBoundingClientRect().left;
const y = event.clientY - barsRef.current.getBoundingClientRect().top;
const index = findHoveredBarIndex(x, y);
const index = findHoveredBarIndex(x);
setPreviewPoint({ x, clientY: event.clientY });
setHoveredBarIndex(index);
};
@ -141,11 +139,10 @@ export const Timeline: React.FunctionComponent<{
const onClick = (event: React.MouseEvent) => {
setPreviewPoint(undefined);
if (!ref.current || !barsRef.current)
if (!ref.current)
return;
const x = event.clientX - ref.current.getBoundingClientRect().left;
const y = event.clientY - barsRef.current.getBoundingClientRect().top;
const index = findHoveredBarIndex(x, y);
const index = findHoveredBarIndex(x);
if (index === undefined)
return;
const entry = bars[index].action;
@ -162,7 +159,7 @@ export const Timeline: React.FunctionComponent<{
</div>;
})
}</div>
<div className='timeline-lane timeline-labels'>{
{!hideTimelineBars && <div className='timeline-lane timeline-labels'>{
bars.map((bar, index) => {
return <div key={index}
className={'timeline-label ' + bar.className + (targetBar === bar ? ' selected' : '')}
@ -174,8 +171,8 @@ export const Timeline: React.FunctionComponent<{
{bar.label}
</div>;
})
}</div>
<div className='timeline-lane timeline-bars' ref={barsRef}>{
}</div>}
{!hideTimelineBars && <div className='timeline-lane timeline-bars' ref={barsRef}>{
bars.map((bar, index) => {
return <div key={index}
className={'timeline-bar ' + (bar.action ? 'action ' : '') + (bar.event ? 'event ' : '') + bar.className + (targetBar === bar ? ' selected' : '')}
@ -187,7 +184,7 @@ export const Timeline: React.FunctionComponent<{
title={bar.title}
></div>;
})
}</div>
}</div>}
<FilmStrip model={model} boundaries={boundaries} previewPoint={previewPoint} />
<div className='timeline-marker timeline-marker-hover' style={{
display: (previewPoint !== undefined) ? 'block' : 'none',
@ -239,7 +236,6 @@ function trimRight(s: string, maxLength: number): string {
return s.length <= maxLength ? s : s.substring(0, maxLength - 1) + '\u2026';
}
const kBarHeight = 11;
function barTop(bar: TimelineBar): number {
return bar.event ? 22 : (bar.action?.method === 'waitForEventInfo' ? 0 : 11);
}

View File

@ -346,7 +346,7 @@ export const TraceView: React.FC<{
const xterm = <XtermWrapper source={xtermDataSource}></XtermWrapper>;
return <Workbench model={model} output={xterm} rightToolbar={[
<ToolbarButton icon='trash' title='Clear output' onClick={() => xtermDataSource.clear()}></ToolbarButton>,
]}/>;
]} hideTimelineBars={true} hideStackFrames={true} />;
};
declare global {

View File

@ -35,7 +35,9 @@ export const Workbench: React.FunctionComponent<{
model?: MultiTraceModel,
output?: React.ReactElement,
rightToolbar?: React.ReactElement[],
}> = ({ model, output, rightToolbar }) => {
hideTimelineBars?: boolean,
hideStackFrames?: boolean,
}> = ({ model, output, rightToolbar, hideTimelineBars, hideStackFrames }) => {
const [selectedAction, setSelectedAction] = React.useState<ActionTraceEvent | undefined>(undefined);
const [highlightedAction, setHighlightedAction] = React.useState<ActionTraceEvent | undefined>();
const [selectedNavigatorTab, setSelectedNavigatorTab] = React.useState<string>('actions');
@ -49,7 +51,7 @@ export const Workbench: React.FunctionComponent<{
if (failedAction)
setSelectedAction(failedAction);
// In the UI mode, selecting the first error should reveal source.
if (output)
if (failedAction && output)
setSelectedPropertiesTab('source');
}, [model, output, selectedAction, setSelectedAction, setSelectedPropertiesTab]);
@ -60,7 +62,7 @@ export const Workbench: React.FunctionComponent<{
const tabs: TabbedPaneTabModel[] = [
{ id: 'call', title: 'Call', render: () => <CallTab action={activeAction} sdkLanguage={sdkLanguage} /> },
{ id: 'source', title: 'Source', count: 0, render: () => <SourceTab action={activeAction} /> },
{ id: 'source', title: 'Source', count: 0, render: () => <SourceTab action={activeAction} hideStackFrames={hideStackFrames}/> },
{ id: 'console', title: 'Console', count: consoleCount, render: () => <ConsoleTab action={activeAction} /> },
{ id: 'network', title: 'Network', count: networkCount, render: () => <NetworkTab action={activeAction} /> },
];
@ -73,6 +75,7 @@ export const Workbench: React.FunctionComponent<{
model={model}
selectedAction={activeAction}
onSelected={action => setSelectedAction(action)}
hideTimelineBars={hideTimelineBars}
/>
<SplitView sidebarSize={output ? 250 : 350} orientation={output ? 'vertical' : 'horizontal'}>
<SplitView sidebarSize={250} orientation='horizontal' sidebarIsFirst={true}>