feature: Add scroll detection for NodeDescription overflow and remove feature flag (#3676)
* feat: Add scroll detection for NodeDescription overflow * style: update CSS to hide non-selected note nodes * remove feature flag * [autofix.ci] apply automated fixes * refactor: update feature flags and test IDs - Update ENABLE_MVPS flag to false in feature-flags.ts - Update testId from "extended-disclosure" to "bundle-extended-disclosure" in extraSidebarComponent/index.tsx --------- Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
This commit is contained in:
parent
7f6b3873ee
commit
ed3306fb7e
6 changed files with 79 additions and 59 deletions
|
|
@ -3,7 +3,7 @@ import useFlowsManagerStore from "@/stores/flowsManagerStore";
|
||||||
import useFlowStore from "@/stores/flowStore";
|
import useFlowStore from "@/stores/flowStore";
|
||||||
import { handleKeyDown } from "@/utils/reactflowUtils";
|
import { handleKeyDown } from "@/utils/reactflowUtils";
|
||||||
import { cn } from "@/utils/utils";
|
import { cn } from "@/utils/utils";
|
||||||
import { useEffect, useState } from "react";
|
import { useEffect, useRef, useState } from "react";
|
||||||
import Markdown from "react-markdown";
|
import Markdown from "react-markdown";
|
||||||
|
|
||||||
export default function NodeDescription({
|
export default function NodeDescription({
|
||||||
|
|
@ -29,6 +29,27 @@ export default function NodeDescription({
|
||||||
const [nodeDescription, setNodeDescription] = useState(description);
|
const [nodeDescription, setNodeDescription] = useState(description);
|
||||||
const takeSnapshot = useFlowsManagerStore((state) => state.takeSnapshot);
|
const takeSnapshot = useFlowsManagerStore((state) => state.takeSnapshot);
|
||||||
const setNode = useFlowStore((state) => state.setNode);
|
const setNode = useFlowStore((state) => state.setNode);
|
||||||
|
const overflowRef = useRef<HTMLDivElement>(null);
|
||||||
|
const [hasScroll, sethasScroll] = useState(false);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
//timeout to wait for the dom to update
|
||||||
|
setTimeout(() => {
|
||||||
|
if (overflowRef.current) {
|
||||||
|
console.log(
|
||||||
|
overflowRef.current.clientHeight,
|
||||||
|
overflowRef.current.scrollHeight,
|
||||||
|
);
|
||||||
|
if (
|
||||||
|
overflowRef.current.clientHeight < overflowRef.current.scrollHeight
|
||||||
|
) {
|
||||||
|
sethasScroll(true);
|
||||||
|
} else {
|
||||||
|
sethasScroll(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, 200);
|
||||||
|
}, [inputDescription]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!selected) {
|
if (!selected) {
|
||||||
|
|
@ -45,6 +66,7 @@ export default function NodeDescription({
|
||||||
className={cn(
|
className={cn(
|
||||||
"generic-node-desc",
|
"generic-node-desc",
|
||||||
!inputDescription ? "overflow-auto" : "",
|
!inputDescription ? "overflow-auto" : "",
|
||||||
|
hasScroll ? "nowheel" : "",
|
||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
{inputDescription ? (
|
{inputDescription ? (
|
||||||
|
|
@ -109,6 +131,7 @@ export default function NodeDescription({
|
||||||
</>
|
</>
|
||||||
) : (
|
) : (
|
||||||
<div
|
<div
|
||||||
|
ref={overflowRef}
|
||||||
className={cn(
|
className={cn(
|
||||||
"nodoubleclick generic-node-desc-text h-full cursor-text word-break-break-word dark:text-note-placeholder",
|
"nodoubleclick generic-node-desc-text h-full cursor-text word-break-break-word dark:text-note-placeholder",
|
||||||
description === "" || !description ? "font-light italic" : "",
|
description === "" || !description ? "font-light italic" : "",
|
||||||
|
|
|
||||||
|
|
@ -33,7 +33,6 @@ function NoteNode({
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
const MemoNoteToolbarComponent = useMemo(
|
const MemoNoteToolbarComponent = useMemo(
|
||||||
() => (
|
() => (
|
||||||
<NodeToolbar>
|
<NodeToolbar>
|
||||||
|
|
@ -69,7 +68,7 @@ function NoteNode({
|
||||||
ref={nodeDiv}
|
ref={nodeDiv}
|
||||||
className={cn(
|
className={cn(
|
||||||
"flex h-full w-full flex-col gap-3 rounded-md border border-b p-5 transition-all",
|
"flex h-full w-full flex-col gap-3 rounded-md border border-b p-5 transition-all",
|
||||||
selected ? "" : "shadow-sm",
|
selected ? "" : "-z-50 shadow-sm",
|
||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
<div className="flex h-fit w-full items-center align-middle">
|
<div className="flex h-fit w-full items-center align-middle">
|
||||||
|
|
@ -92,7 +91,6 @@ function NoteNode({
|
||||||
width: size.width,
|
width: size.width,
|
||||||
height: size.height,
|
height: size.height,
|
||||||
}}
|
}}
|
||||||
className="nowheel overflow-auto"
|
|
||||||
>
|
>
|
||||||
<NodeDescription
|
<NodeDescription
|
||||||
inputClassName="border-0 ring-transparent resize-none rounded-none shadow-none h-full w-full"
|
inputClassName="border-0 ring-transparent resize-none rounded-none shadow-none h-full w-full"
|
||||||
|
|
|
||||||
|
|
@ -475,59 +475,58 @@ export default function Page({ view }: { view?: boolean }): JSX.Element {
|
||||||
<Background className="" />
|
<Background className="" />
|
||||||
{!view && (
|
{!view && (
|
||||||
<Controls className="fill-foreground stroke-foreground text-primary [&>button]:border-b-border [&>button]:bg-muted hover:[&>button]:bg-border">
|
<Controls className="fill-foreground stroke-foreground text-primary [&>button]:border-b-border [&>button]:bg-muted hover:[&>button]:bg-border">
|
||||||
{ENABLE_MVPS && (
|
<ControlButton
|
||||||
<ControlButton
|
data-testid="add_note"
|
||||||
data-testid="add_note"
|
onClick={() => {
|
||||||
onClick={() => {
|
const wrapper = reactFlowWrapper.current!;
|
||||||
const wrapper = reactFlowWrapper.current!;
|
const viewport = reactFlowInstance?.getViewport();
|
||||||
const x = wrapper.getBoundingClientRect().width / 2;
|
const x = wrapper.getBoundingClientRect().width / 2;
|
||||||
const y = wrapper.getBoundingClientRect().height / 2;
|
const y = wrapper.getBoundingClientRect().height / 2;
|
||||||
const nodePosition =
|
const nodePosition =
|
||||||
reactFlowInstance?.screenToFlowPosition({ x, y })!;
|
reactFlowInstance?.screenToFlowPosition({ x, y })!;
|
||||||
|
|
||||||
const data = {
|
const data = {
|
||||||
node: {
|
node: {
|
||||||
description: "",
|
description: "",
|
||||||
display_name: "",
|
display_name: "",
|
||||||
documentation: "",
|
documentation: "",
|
||||||
template: {},
|
template: {},
|
||||||
},
|
},
|
||||||
type: "note",
|
type: "note",
|
||||||
};
|
};
|
||||||
const newId = getNodeId(data.type);
|
const newId = getNodeId(data.type);
|
||||||
|
|
||||||
const newNode: NodeType = {
|
const newNode: NodeType = {
|
||||||
|
id: newId,
|
||||||
|
type: "noteNode",
|
||||||
|
position: { x: 0, y: 0 },
|
||||||
|
data: {
|
||||||
|
...data,
|
||||||
id: newId,
|
id: newId,
|
||||||
type: "noteNode",
|
},
|
||||||
position: { x: 0, y: 0 },
|
};
|
||||||
data: {
|
paste(
|
||||||
...data,
|
{ nodes: [newNode], edges: [] },
|
||||||
id: newId,
|
{
|
||||||
},
|
x: nodePosition.x,
|
||||||
};
|
y: nodePosition?.y,
|
||||||
paste(
|
paneX: wrapper.getBoundingClientRect().x,
|
||||||
{ nodes: [newNode], edges: [] },
|
paneY: wrapper.getBoundingClientRect().y,
|
||||||
{
|
},
|
||||||
x: nodePosition.x,
|
);
|
||||||
y: nodePosition?.y,
|
}}
|
||||||
paneX: wrapper.getBoundingClientRect().x,
|
className="postion absolute -top-10 rounded-sm"
|
||||||
paneY: wrapper.getBoundingClientRect().y,
|
>
|
||||||
},
|
<ShadTooltip content="Add note">
|
||||||
);
|
<div>
|
||||||
}}
|
<IconComponent
|
||||||
className="postion absolute -top-10 rounded-sm"
|
name="SquarePen"
|
||||||
>
|
aria-hidden="true"
|
||||||
<ShadTooltip content="Add note">
|
className="scale-125"
|
||||||
<div>
|
/>
|
||||||
<IconComponent
|
</div>
|
||||||
name="SquarePen"
|
</ShadTooltip>
|
||||||
aria-hidden="true"
|
</ControlButton>
|
||||||
className="scale-125"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</ShadTooltip>
|
|
||||||
</ControlButton>
|
|
||||||
)}
|
|
||||||
</Controls>
|
</Controls>
|
||||||
)}
|
)}
|
||||||
<SelectionMenu
|
<SelectionMenu
|
||||||
|
|
|
||||||
|
|
@ -316,7 +316,7 @@ export default function ExtraSidebar(): JSX.Element {
|
||||||
title: "Bundles",
|
title: "Bundles",
|
||||||
Icon: nodeIconsLucide.unknown,
|
Icon: nodeIconsLucide.unknown,
|
||||||
}}
|
}}
|
||||||
testId="extended-disclosure"
|
testId="bundle-extended-disclosure"
|
||||||
>
|
>
|
||||||
{Object.keys(dataFilter)
|
{Object.keys(dataFilter)
|
||||||
.sort(sortKeys)
|
.sort(sortKeys)
|
||||||
|
|
|
||||||
|
|
@ -162,3 +162,7 @@ textarea[class^="ag-"]:focus {
|
||||||
.react-flow__node.dragging * {
|
.react-flow__node.dragging * {
|
||||||
cursor: grabbing !important;
|
cursor: grabbing !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.react-flow__node-noteNode:not(.selected){
|
||||||
|
z-index: -1 !important;
|
||||||
|
}
|
||||||
|
|
@ -3,10 +3,6 @@ import { expect, test } from "@playwright/test";
|
||||||
import uaParser from "ua-parser-js";
|
import uaParser from "ua-parser-js";
|
||||||
|
|
||||||
test("user should be able to interact with sticky notes", async ({ page }) => {
|
test("user should be able to interact with sticky notes", async ({ page }) => {
|
||||||
// prevent test from failing if feature flag is disabled
|
|
||||||
if (!ENABLE_MVPS) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
await page.goto("/");
|
await page.goto("/");
|
||||||
await page.waitForSelector('[data-testid="mainpage_title"]', {
|
await page.waitForSelector('[data-testid="mainpage_title"]', {
|
||||||
timeout: 30000,
|
timeout: 30000,
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue