chore(trace-viewer): preserve column widths after showing resource details
This commit is contained in:
parent
6e9c31f93b
commit
684159728f
|
|
@ -76,6 +76,10 @@ export const NetworkTab: React.FunctionComponent<{
|
|||
return { renderedEntries };
|
||||
}, [networkModel.resources, networkModel.contextIdMap, sorting, boundaries]);
|
||||
|
||||
const [widths, setWidths] = React.useState<Map<ColumnName, number>>(() => {
|
||||
return new Map(allColumns().map(column => [column, columnWidth(column)]));
|
||||
});
|
||||
|
||||
if (!networkModel.resources.length)
|
||||
return <PlaceholderPanel text='No network calls' />;
|
||||
|
||||
|
|
@ -87,7 +91,8 @@ export const NetworkTab: React.FunctionComponent<{
|
|||
onHighlighted={item => onEntryHovered(item?.resource)}
|
||||
columns={visibleColumns(!!selectedEntry, renderedEntries)}
|
||||
columnTitle={columnTitle}
|
||||
columnWidth={columnWidth}
|
||||
columnWidths={widths}
|
||||
setColumnWidths={setWidths}
|
||||
isError={item => item.status.code >= 400}
|
||||
isInfo={item => !!item.route}
|
||||
render={(item, column) => renderCell(item, column)}
|
||||
|
|
@ -96,7 +101,7 @@ export const NetworkTab: React.FunctionComponent<{
|
|||
/>;
|
||||
return <>
|
||||
{!selectedEntry && grid}
|
||||
{selectedEntry && <SplitView sidebarSize={200} sidebarIsFirst={true} orientation='horizontal'>
|
||||
{selectedEntry && <SplitView sidebarSize={widths.get('name')!} sidebarIsFirst={true} orientation='horizontal' settingName='networkResourceDetails'>
|
||||
<NetworkResourceDetails resource={selectedEntry.resource} onClose={() => setSelectedEntry(undefined)} />
|
||||
{grid}
|
||||
</SplitView>}
|
||||
|
|
@ -142,13 +147,16 @@ const columnWidth = (column: ColumnName) => {
|
|||
function visibleColumns(entrySelected: boolean, renderedEntries: RenderedEntry[]): (keyof RenderedEntry)[] {
|
||||
if (entrySelected)
|
||||
return ['name'];
|
||||
const columns: (keyof RenderedEntry)[] = [];
|
||||
if (hasMultipleContexts(renderedEntries))
|
||||
columns.push('contextId');
|
||||
columns.push('name', 'method', 'status', 'contentType', 'duration', 'size', 'start', 'route');
|
||||
let columns: (keyof RenderedEntry)[] = allColumns();
|
||||
if (!hasMultipleContexts(renderedEntries))
|
||||
columns = columns.filter(name => name !== 'contextId');
|
||||
return columns;
|
||||
}
|
||||
|
||||
function allColumns(): (keyof RenderedEntry)[] {
|
||||
return ['contextId', 'name', 'method', 'status', 'contentType', 'duration', 'size', 'start', 'route'];
|
||||
}
|
||||
|
||||
const renderCell = (entry: RenderedEntry, column: ColumnName): RenderedGridCell => {
|
||||
if (column === 'contextId') {
|
||||
return {
|
||||
|
|
|
|||
|
|
@ -30,19 +30,33 @@ export type RenderedGridCell = {
|
|||
export type GridViewProps<T> = Omit<ListViewProps<T>, 'render'> & {
|
||||
columns: (keyof T)[],
|
||||
columnTitle: (column: keyof T) => string,
|
||||
columnWidth: (column: keyof T) => number,
|
||||
columnWidths: Map<keyof T, number>,
|
||||
setColumnWidths: (widths: Map<keyof T, number>) => void,
|
||||
render: (item: T, column: keyof T, index: number) => RenderedGridCell,
|
||||
sorting?: Sorting<T>,
|
||||
setSorting?: (sorting: Sorting<T> | undefined) => void,
|
||||
};
|
||||
|
||||
export function GridView<T>(model: GridViewProps<T>) {
|
||||
const initialOffsets: number[] = [];
|
||||
for (let i = 0; i < model.columns.length - 1; ++i) {
|
||||
const column = model.columns[i];
|
||||
initialOffsets[i] = (initialOffsets[i - 1] || 0) + model.columnWidth(column);
|
||||
function offsets() {
|
||||
const offsets: number[] = [];
|
||||
for (let i = 0; i < model.columns.length - 1; ++i) {
|
||||
const column = model.columns[i];
|
||||
offsets[i] = (offsets[i - 1] || 0) + model.columnWidths.get(column)!;
|
||||
}
|
||||
console.log('offsets', offsets, model.columns);
|
||||
return offsets;
|
||||
}
|
||||
function setOffsets(offsets: number[]) {
|
||||
const widths = new Map<keyof T, number>(model.columnWidths.entries());
|
||||
for (let i = 0; i < offsets.length; ++i) {
|
||||
const width = offsets[i] - (offsets[i - 1] || 0);
|
||||
const column = model.columns[i];
|
||||
widths.set(column, width);
|
||||
}
|
||||
console.log('setOffsets', offsets);
|
||||
model.setColumnWidths(widths);
|
||||
}
|
||||
const [offsets, setOffsets] = React.useState<number[]>(initialOffsets);
|
||||
|
||||
const toggleSorting = React.useCallback((f: keyof T) => {
|
||||
model.setSorting?.({ by: f, negate: model.sorting?.by === f ? !model.sorting.negate : false });
|
||||
|
|
@ -51,7 +65,7 @@ export function GridView<T>(model: GridViewProps<T>) {
|
|||
return <div className={`grid-view ${model.name}-grid-view`}>
|
||||
<ResizeView
|
||||
orientation={'horizontal'}
|
||||
offsets={offsets}
|
||||
offsets={offsets()}
|
||||
setOffsets={setOffsets}
|
||||
resizerColor='var(--vscode-panel-border)'
|
||||
resizerWidth={1}
|
||||
|
|
@ -63,7 +77,7 @@ export function GridView<T>(model: GridViewProps<T>) {
|
|||
return <div
|
||||
className={'grid-view-header-cell ' + sortingHeader(column, model.sorting)}
|
||||
style={{
|
||||
width: offsets[i] - (offsets[i - 1] || 0),
|
||||
width: i < model.columns.length - 1 ? model.columnWidths.get(column) : undefined,
|
||||
}}
|
||||
onClick={() => model.setSorting && toggleSorting(column)}
|
||||
>
|
||||
|
|
@ -84,7 +98,9 @@ export function GridView<T>(model: GridViewProps<T>) {
|
|||
return <div
|
||||
className={`grid-view-cell grid-view-column-${String(column)}`}
|
||||
title={title}
|
||||
style={{ width: offsets[i] - (offsets[i - 1] || 0) }}>
|
||||
style={{
|
||||
width: i < model.columns.length - 1 ? model.columnWidths.get(column) : undefined,
|
||||
}}>
|
||||
{body}
|
||||
</div>;
|
||||
})}
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@ import { kTargetClosedErrorMessage } from '../config/errors';
|
|||
import { browserTest as it, expect } from '../config/browserTest';
|
||||
import { attachFrame, verifyViewport } from '../config/utils';
|
||||
import type { Page } from '@playwright/test';
|
||||
import { request } from '@playwright/test';
|
||||
|
||||
it('should create new context @smoke', async function({ browser }) {
|
||||
expect(browser.contexts().length).toBe(0);
|
||||
|
|
@ -31,6 +32,22 @@ it('should create new context @smoke', async function({ browser }) {
|
|||
expect(browser).toBe(context.browser());
|
||||
});
|
||||
|
||||
it('log two contexts', async function({ browser }) {
|
||||
const context1 = await browser.newContext();
|
||||
const context2 = await browser.newContext();
|
||||
const api1 = await request.newContext();
|
||||
const api2 = await request.newContext();
|
||||
const page1 = await context1.newPage();
|
||||
const page2 = await context2.newPage();
|
||||
await page1.evaluate(() => { window.open('about:blank'); });
|
||||
const promises = [];
|
||||
promises.push(page1.goto('https://playwright.dev/'));
|
||||
promises.push(page2.goto('https://theverge.com/'));
|
||||
promises.push(api1.get('https://playwright.dev/'));
|
||||
promises.push(api2.get('https://theverge.com/'));
|
||||
await Promise.all(promises);
|
||||
});
|
||||
|
||||
it('should be able to click across browser contexts', async function({ browser }) {
|
||||
it.info().annotations.push({ type: 'issue', description: 'https://github.com/microsoft/playwright/issues/29096' });
|
||||
expect(browser.contexts().length).toBe(0);
|
||||
|
|
|
|||
Loading…
Reference in a new issue