chore: trace timeline ux (#26797)

This commit is contained in:
Pavel Feldman 2023-08-30 15:48:51 -07:00 committed by GitHub
parent fd31f5bc50
commit 123ee9ddc1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 30 additions and 17 deletions

View File

@ -35,7 +35,7 @@ test.describe('New Todo', () => {
// Make sure the list now has two todo items. // Make sure the list now has two todo items.
await expect(page.getByTestId('todo-title')).toHaveText([ await expect(page.getByTestId('todo-title')).toHaveText([
TODO_ITEMS[0], TODO_ITEMS[0],
TODO_ITEMS[1] TODO_ITEMS[1],
]); ]);
await checkNumberOfTodosInLocalStorage(page, 2); await checkNumberOfTodosInLocalStorage(page, 2);

View File

@ -88,6 +88,7 @@
align-items: center; align-items: center;
white-space: nowrap; white-space: nowrap;
height: 100%; height: 100%;
overflow: hidden;
} }
.network-request-header.filter-start.positive .network-request-start .codicon-triangle-down { .network-request-header.filter-start.positive .network-request-start .codicon-triangle-down {

View File

@ -82,6 +82,11 @@
} }
.timeline-bar.action { .timeline-bar.action {
--action-color: var(--vscode-charts-orange);
--action-background-color: #d1861633;
}
.timeline-bar.action.error {
--action-color: var(--vscode-charts-red); --action-color: var(--vscode-charts-red);
--action-background-color: #e5140033; --action-background-color: #e5140033;
} }
@ -91,6 +96,11 @@
--action-background-color: #1a85ff33; --action-background-color: #1a85ff33;
} }
body.dark-mode .timeline-bar.action.error {
--action-color: var(--vscode-errorForeground);
--action-background-color: #f4877133;
}
.timeline-label { .timeline-label {
position: absolute; position: absolute;
top: 0; top: 0;
@ -144,17 +154,13 @@ body.dark-mode .timeline-window-curtain {
background-color: #161718bf; background-color: #161718bf;
} }
.timeline-window-curtain.left {
border-right: 1px solid var(--vscode-panel-border);
}
.timeline-window-curtain.right {
border-left: 1px solid var(--vscode-panel-border);
}
.timeline-window-resizer { .timeline-window-resizer {
flex: none; flex: none;
width: 6px; width: 10px;
cursor: ew-resize; cursor: ew-resize;
pointer-events: all; pointer-events: all;
position: relative;
background-color: var(--vscode-panel-border);
border-left: 1px solid var(--vscode-panel-border);
border-right: 1px solid var(--vscode-panel-border);
} }

View File

@ -33,6 +33,7 @@ type TimelineBar = {
leftTime: number; leftTime: number;
rightTime: number; rightTime: number;
active: boolean; active: boolean;
error: boolean;
}; };
export const Timeline: React.FunctionComponent<{ export const Timeline: React.FunctionComponent<{
@ -74,6 +75,7 @@ export const Timeline: React.FunctionComponent<{
leftPosition: timeToPosition(measure.width, boundaries, entry.startTime), leftPosition: timeToPosition(measure.width, boundaries, entry.startTime),
rightPosition: timeToPosition(measure.width, boundaries, entry.endTime || boundaries.maximum), rightPosition: timeToPosition(measure.width, boundaries, entry.endTime || boundaries.maximum),
active: false, active: false,
error: !!entry.error,
}); });
} }
@ -87,6 +89,7 @@ export const Timeline: React.FunctionComponent<{
leftPosition: timeToPosition(measure.width, boundaries, startTime), leftPosition: timeToPosition(measure.width, boundaries, startTime),
rightPosition: timeToPosition(measure.width, boundaries, endTime), rightPosition: timeToPosition(measure.width, boundaries, endTime),
active: false, active: false,
error: false,
}); });
} }
return bars; return bars;
@ -230,7 +233,10 @@ export const Timeline: React.FunctionComponent<{
<div className='timeline-bars'>{ <div className='timeline-bars'>{
bars.map((bar, index) => { bars.map((bar, index) => {
return <div key={index} return <div key={index}
className={'timeline-bar' + (bar.action ? ' action' : '') + (bar.resource ? ' network' : '') + (bar.active ? ' active' : '')} className={'timeline-bar' + (bar.action ? ' action' : '')
+ (bar.resource ? ' network' : '')
+ (bar.active ? ' active' : '')
+ (bar.error ? ' error' : '')}
style={{ style={{
left: bar.leftPosition, left: bar.leftPosition,
width: Math.max(1, bar.rightPosition - bar.leftPosition), width: Math.max(1, bar.rightPosition - bar.leftPosition),
@ -246,11 +252,11 @@ export const Timeline: React.FunctionComponent<{
}} /> }} />
{selectedTime && <div className='timeline-window'> {selectedTime && <div className='timeline-window'>
<div className='timeline-window-curtain left' style={{ width: curtainLeft }}></div> <div className='timeline-window-curtain left' style={{ width: curtainLeft }}></div>
<div className='timeline-window-resizer'></div> <div className='timeline-window-resizer' style={{ left: -5 }}></div>
<div className='timeline-window-center'> <div className='timeline-window-center'>
<div className='timeline-window-drag'></div> <div className='timeline-window-drag'></div>
</div> </div>
<div className='timeline-window-resizer'></div> <div className='timeline-window-resizer' style={{ left: 5 }}></div>
<div className='timeline-window-curtain right' style={{ width: curtainRight }}></div> <div className='timeline-window-curtain right' style={{ width: curtainRight }}></div>
</div>} </div>}
</div> </div>

View File

@ -159,15 +159,15 @@ type TreeItemData = {
function flattenTree<T extends TreeItem>(rootItem: T, selectedItem: T | undefined, expandedItems: Map<string, boolean | undefined>, autoExpandDepth: number): Map<T, TreeItemData> { function flattenTree<T extends TreeItem>(rootItem: T, selectedItem: T | undefined, expandedItems: Map<string, boolean | undefined>, autoExpandDepth: number): Map<T, TreeItemData> {
const result = new Map<T, TreeItemData>(); const result = new Map<T, TreeItemData>();
const temporaryExpanded = new Map<string, boolean | undefined>(); const temporaryExpanded = new Set<string>();
for (let item: TreeItem | undefined = selectedItem?.parent; item; item = item.parent) for (let item: TreeItem | undefined = selectedItem?.parent; item; item = item.parent)
temporaryExpanded.set(item.id, true); temporaryExpanded.add(item.id);
const appendChildren = (parent: T, depth: number) => { const appendChildren = (parent: T, depth: number) => {
for (const item of parent.children as T[]) { for (const item of parent.children as T[]) {
const expandState = expandedItems.get(item.id) ?? temporaryExpanded.get(item.id); const expandState = temporaryExpanded.has(item.id) || expandedItems.get(item.id);
const autoExpandMatches = autoExpandDepth > depth && result.size < 25 && expandState !== false; const autoExpandMatches = autoExpandDepth > depth && result.size < 25 && expandState !== false;
const expanded = item.children.length ? expandState || autoExpandMatches : undefined; const expanded = item.children.length ? expandState ?? autoExpandMatches : undefined;
result.set(item, { depth, expanded, parent: rootItem === parent ? null : parent }); result.set(item, { depth, expanded, parent: rootItem === parent ? null : parent });
if (expanded) if (expanded)
appendChildren(item, depth + 1); appendChildren(item, depth + 1);