feat(trace viewer): fix UI issues (#6890)

This commit is contained in:
Dmitry Gozman 2021-06-03 21:52:29 -07:00 committed by GitHub
parent cfcf6a8899
commit 85786b1a11
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 58 additions and 30 deletions

View file

@ -69,6 +69,7 @@
color: red;
position: relative;
margin-right: 2px;
flex: none;
}
.action-selector {

View file

@ -37,7 +37,6 @@ export const FilmStrip: React.FunctionComponent<{
}
const screencastFrames = context.pages[pageIndex]?.screencastFrames;
// TODO: pick file from the Y position.
let previewImage = undefined;
if (previewPoint !== undefined && screencastFrames) {
const previewTime = boundaries.minimum + (boundaries.maximum - boundaries.minimum) * previewPoint.x / measure.width;

View file

@ -23,6 +23,18 @@
user-select: text;
}
.logs-error {
border-bottom: 1px solid var(--background);
padding: 3px 0 3px 12px;
}
.logs-error .codicon {
color: red;
position: relative;
top: 2px;
margin-right: 2px;
}
.log-line {
flex: none;
padding: 3px 0 3px 12px;

View file

@ -21,13 +21,13 @@ import { ActionTraceEvent } from '../../../server/trace/common/traceEvents';
export const LogsTab: React.FunctionComponent<{
action: ActionTraceEvent | undefined,
}> = ({ action }) => {
let logs: string[] = [];
if (action) {
logs = action.metadata.log || [];
if (action.metadata.error)
logs = [action.metadata.error, ...logs];
}
const logs = action?.metadata.log || [];
const error = action?.metadata.error;
return <div className='logs-tab'>{
<div className='logs-error' key='error' hidden={!error}>
<div className='codicon codicon-issues'/>
{error}
</div>}{
logs.map((logLine, index) => {
return <div key={index} className='log-line'>
{logLine}

View file

@ -70,7 +70,6 @@
.timeline-bar {
position: absolute;
height: 9px;
top: 11px;
border-radius: 2px;
min-width: 3px;
--action-color: gray;
@ -125,13 +124,8 @@
--action-color: var(--blue);
}
.timeline-bar.event {
top: 22px;
}
.timeline-bar.frame_waitforeventinfo {
bottom: inherit;
top: 0;
.timeline-bar.frame_waitforeventinfo,
.timeline-bar.page_waitforeventinfo {
--action-color: var(--gray);
}

View file

@ -45,6 +45,8 @@ export const Timeline: React.FunctionComponent<{
onHighlighted: (action: ActionTraceEvent | undefined) => void,
}> = ({ context, boundaries, selectedAction, highlightedAction, onSelected, onHighlighted }) => {
const [measure, ref] = useMeasure<HTMLDivElement>();
const barsRef = React.useRef<HTMLDivElement | null>(null);
const [previewPoint, setPreviewPoint] = React.useState<{ x: number, clientY: number } | undefined>();
const [hoveredBarIndex, setHoveredBarIndex] = React.useState<number | undefined>();
@ -58,9 +60,9 @@ export const Timeline: React.FunctionComponent<{
for (const entry of page.actions) {
if (!entry.metadata.params)
console.log(entry);
let detail = entry.metadata.params.selector || '';
let detail = trimRight(entry.metadata.params.selector || '', 50);
if (entry.metadata.method === 'goto')
detail = entry.metadata.params.url || '';
detail = trimRight(entry.metadata.params.url || '', 50);
bars.push({
action: entry,
leftTime: entry.metadata.startTime,
@ -94,32 +96,41 @@ export const Timeline: React.FunctionComponent<{
let targetBar: TimelineBar | undefined = bars.find(bar => bar.action === (highlightedAction || selectedAction));
targetBar = hoveredBar || targetBar;
const findHoveredBarIndex = (x: number) => {
const findHoveredBarIndex = (x: number, y: 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 distance: 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 middle = (bar.leftTime + bar.rightTime) / 2;
const d = Math.abs(time - middle);
if (left <= right && (index === undefined || d < distance!)) {
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!)) {
index = i;
distance = d;
xDistance = xd;
yDistance = yd;
}
}
return index;
};
const onMouseMove = (event: React.MouseEvent) => {
if (!ref.current)
if (!ref.current || !barsRef.current)
return;
const bounds = ref.current.getBoundingClientRect();
const x = event.clientX - bounds.left;
const index = findHoveredBarIndex(x);
const x = event.clientX - ref.current.getBoundingClientRect().left;
const y = event.clientY - barsRef.current.getBoundingClientRect().top;
const index = findHoveredBarIndex(x, y);
setPreviewPoint({ x, clientY: event.clientY });
setHoveredBarIndex(index);
if (typeof index === 'number')
@ -134,10 +145,11 @@ export const Timeline: React.FunctionComponent<{
const onClick = (event: React.MouseEvent) => {
setPreviewPoint(undefined);
if (!ref.current)
if (!ref.current || !barsRef.current)
return;
const x = event.clientX - ref.current.getBoundingClientRect().left;
const index = findHoveredBarIndex(x);
const y = event.clientY - barsRef.current.getBoundingClientRect().top;
const index = findHoveredBarIndex(x, y);
if (index === undefined)
return;
const entry = bars[index].action;
@ -166,13 +178,14 @@ export const Timeline: React.FunctionComponent<{
</div>;
})
}</div>
<div className='timeline-lane timeline-bars'>{
<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' : '')}
style={{
left: bar.leftPosition + 'px',
width: Math.max(1, bar.rightPosition - bar.leftPosition) + 'px',
top: barTop(bar) + 'px',
}}
></div>;
})
@ -222,3 +235,12 @@ function timeToPosition(clientWidth: number, boundaries: Boundaries, time: numbe
function positionToTime(clientWidth: number, boundaries: Boundaries, x: number): number {
return x / clientWidth * (boundaries.maximum - boundaries.minimum) + boundaries.minimum;
}
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?.metadata.method === 'waitForEventInfo' ? 0 : 11);
}