mirror of
https://github.com/Kong/insomnia
synced 2024-11-07 22:30:15 +00:00
Add virtualization to the collection list (#6461)
* add virtualization to the collection list * remove logs
This commit is contained in:
parent
f5d26085c5
commit
86b139d296
@ -24,7 +24,7 @@ test.describe('Environment Editor', async () => {
|
||||
await page.getByRole('button', { name: 'Close' }).click();
|
||||
|
||||
// Send a request check variables defaulted to base env since new env is empty
|
||||
await page.getByLabel('Request Collection').getByRole('row', { name: 'GET New Request' }).click();
|
||||
await page.getByLabel('Request Collection').getByRole('row', { name: 'New Request' }).click();
|
||||
await page.getByRole('button', { name: 'Send' }).click();
|
||||
await page.getByRole('tab', { name: 'Timeline' }).click();
|
||||
await page.getByText('baseenv0').click();
|
||||
@ -41,7 +41,7 @@ test.describe('Environment Editor', async () => {
|
||||
await page.getByRole('button', { name: 'Close' }).click();
|
||||
|
||||
// Send a request check variables defaulted to base env since new env is empty
|
||||
await page.getByLabel('Request Collection').getByRole('row', { name: 'GET New Request' }).click();
|
||||
await page.getByLabel('Request Collection').getByRole('row', { name: 'New Request' }).click();
|
||||
await page.getByRole('button', { name: 'Send' }).click();
|
||||
await page.getByRole('tab', { name: 'Timeline' }).click();
|
||||
await page.getByText('subenvB0').click();
|
||||
@ -61,7 +61,7 @@ test.describe('Environment Editor', async () => {
|
||||
|
||||
// Open request
|
||||
await page.getByRole('button', { name: 'Close' }).click();
|
||||
await page.getByLabel('Request Collection').getByRole('row', { name: 'GET New Request' }).click();
|
||||
await page.getByLabel('Request Collection').getByRole('row', { name: 'New Request' }).click();
|
||||
|
||||
// Add number variable to request body
|
||||
await page.locator('pre').filter({ hasText: '_.exampleObject.anotherNumber' }).click();
|
||||
|
@ -1,6 +1,7 @@
|
||||
import { IconName } from '@fortawesome/fontawesome-svg-core';
|
||||
import { ServiceError, StatusObject } from '@grpc/grpc-js';
|
||||
import React, { FC, Fragment, useEffect, useState } from 'react';
|
||||
import { useVirtualizer } from '@tanstack/react-virtual';
|
||||
import React, { FC, Fragment, useEffect, useRef, useState } from 'react';
|
||||
import {
|
||||
Button,
|
||||
DropIndicator,
|
||||
@ -84,7 +85,7 @@ import {
|
||||
WebSocketRequestLoaderData,
|
||||
} from './request';
|
||||
import { RootLoaderData } from './root';
|
||||
import { WorkspaceLoaderData } from './workspace';
|
||||
import { Child, WorkspaceLoaderData } from './workspace';
|
||||
|
||||
export interface GrpcMessage {
|
||||
id: string;
|
||||
@ -489,12 +490,25 @@ export const Debug: FC = () => {
|
||||
}
|
||||
},
|
||||
renderDropIndicator(target) {
|
||||
return (
|
||||
<DropIndicator
|
||||
target={target}
|
||||
className="outline-[--color-surprise] outline-1 outline"
|
||||
/>
|
||||
);
|
||||
if (target.type === 'item') {
|
||||
const item = virtualizer.getVirtualItems().find(i => i.key === target.key);
|
||||
if (item) {
|
||||
return (
|
||||
<DropIndicator
|
||||
target={target}
|
||||
className="absolute w-full z-10 outline-[--color-surprise] left-0 top-0 outline-1 outline"
|
||||
style={{
|
||||
transform: `translateY(${target.dropPosition === 'before' ? item?.start : item.end}px)`,
|
||||
}}
|
||||
/>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return <DropIndicator
|
||||
target={target}
|
||||
className="absolute outline-[--color-surprise] left-0 top-0 outline-1 outline"
|
||||
/>;
|
||||
},
|
||||
});
|
||||
|
||||
@ -591,6 +605,17 @@ export const Debug: FC = () => {
|
||||
color: e.color,
|
||||
}));
|
||||
|
||||
const visibleCollection = collection.filter(item => !item.hidden);
|
||||
|
||||
const parentRef = useRef<HTMLDivElement>(null);
|
||||
const virtualizer = useVirtualizer<HTMLDivElement | null, Child>({
|
||||
getScrollElement: () => parentRef.current,
|
||||
count: visibleCollection.length,
|
||||
estimateSize: React.useCallback(() => 32, []),
|
||||
overscan: 30,
|
||||
getItemKey: index => visibleCollection[index].doc._id,
|
||||
});
|
||||
|
||||
return (
|
||||
<SidebarLayout
|
||||
className="new-sidebar"
|
||||
@ -877,90 +902,98 @@ export const Debug: FC = () => {
|
||||
}}
|
||||
</GridList>
|
||||
|
||||
<GridList
|
||||
className="flex-1 overflow-y-auto"
|
||||
items={collection.filter(item => !item.hidden)}
|
||||
aria-label="Request Collection"
|
||||
disallowEmptySelection
|
||||
key={sortOrder}
|
||||
dragAndDropHooks={sortOrder === 'type-manual' ? collectionDragAndDrop.dragAndDropHooks : undefined}
|
||||
selectedKeys={[requestId]}
|
||||
selectionMode="single"
|
||||
onSelectionChange={keys => {
|
||||
if (keys !== 'all') {
|
||||
const value = keys.values().next().value;
|
||||
<div className='flex-1 overflow-y-auto' ref={parentRef}>
|
||||
<GridList
|
||||
style={{ height: virtualizer.getTotalSize() }}
|
||||
items={virtualizer.getVirtualItems()}
|
||||
className="relative"
|
||||
aria-label="Request Collection"
|
||||
disallowEmptySelection
|
||||
key={sortOrder}
|
||||
dragAndDropHooks={sortOrder === 'type-manual' ? collectionDragAndDrop.dragAndDropHooks : undefined}
|
||||
selectedKeys={[requestId]}
|
||||
selectionMode="single"
|
||||
onSelectionChange={keys => {
|
||||
if (keys !== 'all') {
|
||||
const value = keys.values().next().value;
|
||||
|
||||
const item = collection.find(
|
||||
item => item.doc._id === value
|
||||
);
|
||||
if (item && isRequestGroup(item.doc)) {
|
||||
groupMetaPatcher(value, { collapsed: !item.collapsed });
|
||||
} else {
|
||||
navigate(
|
||||
`/organization/${organizationId}/project/${projectId}/workspace/${workspaceId}/debug/request/${value}?${searchParams.toString()}`
|
||||
const item = collection.find(
|
||||
item => item.doc._id === value
|
||||
);
|
||||
if (item && isRequestGroup(item.doc)) {
|
||||
groupMetaPatcher(value, { collapsed: !item.collapsed });
|
||||
} else {
|
||||
navigate(
|
||||
`/organization/${organizationId}/project/${projectId}/workspace/${workspaceId}/debug/request/${value}?${searchParams.toString()}`
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}}
|
||||
>
|
||||
{item => {
|
||||
return (
|
||||
<Item
|
||||
key={item.doc._id}
|
||||
id={item.doc._id}
|
||||
className="group outline-none select-none"
|
||||
>
|
||||
<div
|
||||
className="flex select-none outline-none group-aria-selected:text-[--color-font] relative group-hover:bg-[--hl-xs] group-focus:bg-[--hl-sm] transition-colors gap-2 px-4 items-center h-[--line-height-xs] w-full overflow-hidden text-[--hl]"
|
||||
}}
|
||||
>
|
||||
{virtualItem => {
|
||||
const item = visibleCollection[virtualItem.index];
|
||||
return (
|
||||
<Item
|
||||
className="group outline-none absolute top-0 left-0 select-none w-full"
|
||||
textValue={item.doc.name}
|
||||
style={{
|
||||
paddingLeft: `${item.level + 1}rem`,
|
||||
height: `${virtualItem.size}`,
|
||||
transform: `translateY(${virtualItem.start}px)`,
|
||||
}}
|
||||
>
|
||||
<span className="group-aria-selected:bg-[--color-surprise] transition-colors top-0 left-0 absolute h-full w-[2px] bg-transparent" />
|
||||
{isRequest(item.doc) && (
|
||||
<span className={`w-10 flex-shrink-0 flex text-[0.65rem] rounded-sm border border-solid border-[--hl-sm] items-center justify-center http-method-${item.doc.method}`}>
|
||||
{getMethodShortHand(item.doc)}
|
||||
</span>
|
||||
)}
|
||||
{isWebSocketRequest(item.doc) && (
|
||||
<span className="w-10 flex-shrink-0 flex text-[0.65rem] rounded-sm border border-solid border-[--hl-sm] items-center info justify-center">
|
||||
WS
|
||||
</span>
|
||||
)}
|
||||
{isGrpcRequest(item.doc) && (
|
||||
<span className="w-10 flex-shrink-0 flex text-[0.65rem] rounded-sm border border-solid border-[--hl-sm] items-center method-grpc justify-center">
|
||||
gRPC
|
||||
</span>
|
||||
)}
|
||||
{isRequestGroup(item.doc) && (
|
||||
<Icon
|
||||
className="w-6"
|
||||
icon={item.collapsed ? 'folder' : 'folder-open'}
|
||||
/>
|
||||
)}
|
||||
<span className="truncate">{item.doc.name}</span>
|
||||
<span className="flex-1" />
|
||||
{isWebSocketRequest(item.doc) && <WebSocketSpinner requestId={item.doc._id} />}
|
||||
{isEventStreamRequest(item.doc) && <EventStreamSpinner requestId={item.doc._id} />}
|
||||
{item.pinned && (
|
||||
<Icon className='text-[--font-size-sm]' icon="thumb-tack" />
|
||||
)}
|
||||
{isRequestGroup(item.doc) ? (
|
||||
<RequestGroupActionsDropdown
|
||||
requestGroup={item.doc}
|
||||
/>
|
||||
) : (
|
||||
<RequestActionsDropdown
|
||||
activeProject={activeProject}
|
||||
request={item.doc}
|
||||
isPinned={item.pinned}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
</Item>
|
||||
);
|
||||
}}
|
||||
</GridList>
|
||||
<div
|
||||
className="flex select-none outline-none group-aria-selected:text-[--color-font] relative group-hover:bg-[--hl-xs] group-focus:bg-[--hl-sm] transition-colors gap-2 px-4 items-center h-[--line-height-xs] w-full overflow-hidden text-[--hl]"
|
||||
style={{
|
||||
paddingLeft: `${item.level + 1}rem`,
|
||||
}}
|
||||
>
|
||||
<span className="group-aria-selected:bg-[--color-surprise] transition-colors top-0 left-0 absolute h-full w-[2px] bg-transparent" />
|
||||
<Button slot="drag" className="hidden" />
|
||||
{isRequest(item.doc) && (
|
||||
<span className={`w-10 flex-shrink-0 flex text-[0.65rem] rounded-sm border border-solid border-[--hl-sm] items-center justify-center http-method-${item.doc.method}`}>
|
||||
{getMethodShortHand(item.doc)}
|
||||
</span>
|
||||
)}
|
||||
{isWebSocketRequest(item.doc) && (
|
||||
<span className="w-10 flex-shrink-0 flex text-[0.65rem] rounded-sm border border-solid border-[--hl-sm] items-center info justify-center">
|
||||
WS
|
||||
</span>
|
||||
)}
|
||||
{isGrpcRequest(item.doc) && (
|
||||
<span className="w-10 flex-shrink-0 flex text-[0.65rem] rounded-sm border border-solid border-[--hl-sm] items-center method-grpc justify-center">
|
||||
gRPC
|
||||
</span>
|
||||
)}
|
||||
{isRequestGroup(item.doc) && (
|
||||
<Icon
|
||||
className="w-6"
|
||||
icon={item.collapsed ? 'folder' : 'folder-open'}
|
||||
/>
|
||||
)}
|
||||
<span className="truncate">{item.doc.name}</span>
|
||||
<span className="flex-1" />
|
||||
{isWebSocketRequest(item.doc) && <WebSocketSpinner requestId={item.doc._id} />}
|
||||
{isEventStreamRequest(item.doc) && <EventStreamSpinner requestId={item.doc._id} />}
|
||||
{item.pinned && (
|
||||
<Icon className='text-[--font-size-sm]' icon="thumb-tack" />
|
||||
)}
|
||||
{isRequestGroup(item.doc) ? (
|
||||
<RequestGroupActionsDropdown
|
||||
requestGroup={item.doc}
|
||||
/>
|
||||
) : (
|
||||
<RequestActionsDropdown
|
||||
activeProject={activeProject}
|
||||
request={item.doc}
|
||||
isPinned={item.pinned}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
</Item>
|
||||
);
|
||||
}}
|
||||
</GridList>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<WorkspaceSyncDropdown />
|
||||
|
Loading…
Reference in New Issue
Block a user