Skip to content

Commit 9c8eb6b

Browse files
committed
fix: qp to show full node details (include condition and skip in fetch), modal to disable move canvas when open
1 parent ca3cf53 commit 9c8eb6b

File tree

4 files changed

+53
-15
lines changed

4 files changed

+53
-15
lines changed

packages/libraries/laboratory/src/components/flow.tsx

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -199,13 +199,32 @@ export const Flow = (props: {
199199

200200
const handleMouseDown = useCallback(
201201
(event: MouseEvent<HTMLDivElement>) => {
202+
if (!containerRef.current) {
203+
return;
204+
}
205+
206+
if (!event.nativeEvent.composedPath().includes(containerRef.current)) {
207+
return;
208+
}
209+
202210
if (props.disableGestures) {
203211
return;
204212
}
205213

206214
event.preventDefault();
207215
setIsPanning(true);
208216
panStartRef.current = { x: event.clientX, y: event.clientY };
217+
218+
function handleMouseUp() {
219+
stopPanning();
220+
setIsCanvasActive(false);
221+
}
222+
223+
document.addEventListener('mouseup', handleMouseUp);
224+
225+
return () => {
226+
document.removeEventListener('mouseup', handleMouseUp);
227+
};
209228
},
210229
[props.disableGestures],
211230
);
@@ -312,7 +331,6 @@ export const Flow = (props: {
312331
onWheel={handleWheel}
313332
onMouseDown={handleMouseDown}
314333
onMouseMove={handleMouseMove}
315-
onMouseUp={stopPanning}
316334
onMouseLeave={() => {
317335
stopPanning();
318336
setIsCanvasActive(false);

packages/libraries/laboratory/src/components/laboratory/laboratory.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -623,7 +623,7 @@ export const Laboratory = (
623623
[],
624624
);
625625

626-
const containerRef = useRef<HTMLDivElement>(null);
626+
const [container, setContainer] = useState<HTMLDivElement | null>(null);
627627

628628
const [isFullScreen, setIsFullScreen] = useState(false);
629629

@@ -642,7 +642,7 @@ export const Laboratory = (
642642
className={cn('hive-laboratory bg-background size-full', props.theme, {
643643
'fixed inset-0 z-50': isFullScreen,
644644
})}
645-
ref={containerRef}
645+
ref={setContainer}
646646
>
647647
<Toaster richColors closeButton position="top-right" theme={props.theme} />
648648
<Dialog open={isUpdateEndpointDialogOpen} onOpenChange={setIsUpdateEndpointDialogOpen}>
@@ -809,7 +809,7 @@ export const Laboratory = (
809809
{...collectionsApi}
810810
{...operationsApi}
811811
{...historyApi}
812-
container={containerRef.current}
812+
container={container}
813813
openAddCollectionDialog={openAddCollectionDialog}
814814
openUpdateEndpointDialog={openUpdateEndpointDialog}
815815
openAddTestDialog={openAddTestDialog}

packages/libraries/laboratory/src/components/ui/dialog.tsx

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ function DialogTrigger({ ...props }: React.ComponentProps<typeof DialogPrimitive
1313

1414
function DialogPortal({ ...props }: React.ComponentProps<typeof DialogPrimitive.Portal>) {
1515
const { container } = useLaboratory();
16+
1617
return <DialogPrimitive.Portal data-slot="dialog-portal" {...props} container={container} />;
1718
}
1819

@@ -44,8 +45,10 @@ function DialogContent({
4445
}: React.ComponentProps<typeof DialogPrimitive.Content> & {
4546
showCloseButton?: boolean;
4647
}) {
48+
const { container } = useLaboratory();
49+
4750
return (
48-
<DialogPortal data-slot="dialog-portal">
51+
<DialogPortal data-slot="dialog-portal" container={container}>
4952
<DialogOverlay />
5053
<DialogPrimitive.Content
5154
data-slot="dialog-content"

packages/libraries/laboratory/src/lib/query-plan/utils.tsx

Lines changed: 27 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -165,7 +165,7 @@ export function renderFetchNode(node: FetchNodePlan, depth = 0): string {
165165
lines.push(`${indent(depth)}Fetch(service: "${node.serviceName}") {`);
166166

167167
if (node.requires) {
168-
lines.push(`${indent(depth + 1)} {`);
168+
lines.push(`${indent(depth + 1)}{`);
169169
const requires = renderSelectionSet(node.requires, depth + 2);
170170
if (requires) lines.push(requires);
171171
lines.push(`${indent(depth + 1)}} =>`);
@@ -181,14 +181,16 @@ export function renderFetchNode(node: FetchNodePlan, depth = 0): string {
181181
.split('\n')
182182
.slice(slice, slice * -1)
183183
.join('\n'),
184-
depth + 1,
184+
depth + 2 - slice,
185185
),
186186
`${indent(depth + 1)}}`,
187187
);
188188
} catch {
189189
lines.push(`${indent(depth + 1)}${node.operation}`);
190190
}
191191

192+
lines.push(`${indent(depth)}}`);
193+
192194
return lines.join('\n');
193195
}
194196

@@ -464,6 +466,7 @@ function visitNode(
464466
parentNode: QueryPlanNode | null,
465467
nodes: QueryPlanNode[],
466468
contentPrefix?: React.ReactNode,
469+
detailsContent?: string,
467470
): QueryPlanNode {
468471
let result: QueryPlanNode | null = {
469472
id: uuidv4(),
@@ -475,7 +478,6 @@ function visitNode(
475478
case 'Fetch':
476479
result.content = () => {
477480
const entity = (node.requires?.[0] as SelectionInlineFragment)?.typeCondition;
478-
479481
return (
480482
<div className="flex flex-col gap-2">
481483
{contentPrefix}
@@ -505,7 +507,7 @@ function visitNode(
505507
<DialogTitle>Fetch</DialogTitle>
506508
</DialogHeader>
507509
<div className="h-full overflow-hidden rounded-sm border">
508-
<Editor value={renderFetchNode(node)} language="graphql" />
510+
<Editor value={detailsContent ?? renderFetchNode(node)} language="graphql" />
509511
</div>
510512
</DialogContent>
511513
</Dialog>
@@ -585,7 +587,13 @@ function visitNode(
585587
Show details
586588
</Button>
587589
</DialogTrigger>
588-
<DialogContent className="max-w-2xl! max-h-150 h-full w-full">
590+
<DialogContent
591+
className="max-w-2xl! max-h-150 h-full w-full"
592+
onMouseDown={e => {
593+
e.preventDefault();
594+
e.stopPropagation();
595+
}}
596+
>
589597
<DialogHeader>
590598
<DialogTitle>BatchFetch</DialogTitle>
591599
</DialogHeader>
@@ -622,6 +630,7 @@ function visitNode(
622630
</Tooltip>
623631
</div>
624632
</>,
633+
detailsContent ?? renderFlattenNode(node),
625634
);
626635
break;
627636

@@ -633,7 +642,13 @@ function visitNode(
633642
for (let i = 0; i < node.nodes.length; i++) {
634643
const child = node.nodes[i];
635644

636-
const childNode = visitNode(child, prevChild, i === 0 ? [] : nodes);
645+
const childNode = visitNode(
646+
child,
647+
prevChild,
648+
i === 0 ? [] : nodes,
649+
contentPrefix,
650+
detailsContent,
651+
);
637652

638653
if (i === 0) {
639654
result = childNode;
@@ -653,7 +668,7 @@ function visitNode(
653668
result.children = [];
654669

655670
for (const child of node.nodes) {
656-
visitNode(child, result, result.children);
671+
visitNode(child, result, result.children, contentPrefix, detailsContent);
657672
}
658673

659674
break;
@@ -672,6 +687,7 @@ function visitNode(
672687
if: ${node.condition}
673688
</span>
674689
</div>,
690+
renderConditionNode(node),
675691
);
676692
}
677693
if (node.elseClause) {
@@ -685,21 +701,22 @@ function visitNode(
685701
if: ${node.condition}
686702
</span>
687703
</div>,
704+
renderConditionNode(node),
688705
);
689706
}
690707
break;
691708

692709
case 'Subscription':
693-
visitNode(node.primary, result, nodes);
710+
visitNode(node.primary, result, nodes, contentPrefix, detailsContent);
694711
break;
695712

696713
case 'Defer':
697714
if (node.primary.node) {
698-
visitNode(node.primary.node, result, nodes);
715+
visitNode(node.primary.node, result, nodes, contentPrefix, detailsContent);
699716
}
700717
for (const deferred of node.deferred) {
701718
if (deferred.node) {
702-
visitNode(deferred.node, result, nodes);
719+
visitNode(deferred.node, result, nodes, contentPrefix, detailsContent);
703720
}
704721
}
705722
break;

0 commit comments

Comments
 (0)