mirror of
https://github.com/Significant-Gravitas/AutoGPT.git
synced 2026-01-07 22:33:57 -05:00
When users drag and drop nodes in the new flow editor, nodes can overlap with each other, making the graph difficult to read and interact with. This PR adds an automatic collision resolution algorithm that runs when a node is dropped, ensuring nodes are automatically separated to prevent overlaps and maintain a clean, readable graph layout. ### Changes 🏗️ - **Added collision resolution algorithm** (`resolve-collision.ts`): - Implements an iterative collision detection and resolution system using Flatbush for efficient spatial indexing - Automatically resolves overlaps by moving nodes apart along the axis with the smallest overlap - Configurable options: `maxIterations`, `overlapThreshold`, and `margin` - Uses actual node dimensions (`width`, `height`, or `measured` values) when available - **Integrated collision resolution into Flow component**: - Added `onNodeDragStop` callback that triggers collision resolution after a node is dropped - Configured with `maxIterations: Infinity`, `overlapThreshold: 0.5`, and `margin: 15px` - **Enhanced node dimension handling**: - Updated `nodeStore.ts` to prioritize actual node dimensions (`node.width`, `node.measured.width`) over hardcoded defaults when calculating positions - Ensures collision detection uses accurate node sizes - **Added dependency**: - Added `flatbush@4.5.0` for efficient spatial indexing and collision detection ### Checklist 📋 #### For code changes: - [x] I have clearly listed my changes in the PR description - [x] I have made a test plan - [x] I have tested my changes according to the test plan: - [x] Drag a node and drop it on top of another node - verify nodes automatically separate - [x] Drag multiple nodes to create overlapping clusters - verify all overlaps are resolved - [x] Drag nodes with different sizes (NOTE blocks vs regular blocks) - verify collision detection uses correct dimensions - [x] Drag nodes near the edge of the canvas - verify nodes don't get pushed off-screen - [x] Test with a graph containing many nodes (20+) - verify performance is acceptable - [x] Verify nodes maintain their positions when no collisions occur - [x] Test with nodes that have custom measured dimensions - verify accurate collision detection
162 lines
5.5 KiB
JSON
162 lines
5.5 KiB
JSON
{
|
|
"name": "frontend",
|
|
"version": "0.3.4",
|
|
"private": true,
|
|
"engines": {
|
|
"node": "22.x"
|
|
},
|
|
"scripts": {
|
|
"dev": "pnpm run generate:api:force && next dev --turbo",
|
|
"build": "next build",
|
|
"start": "next start",
|
|
"start:standalone": "cd .next/standalone && node server.js",
|
|
"lint": "next lint && prettier --check .",
|
|
"format": "next lint --fix; prettier --write .",
|
|
"types": "tsc --noEmit",
|
|
"test": "NEXT_PUBLIC_PW_TEST=true next build --turbo && playwright test",
|
|
"test-ui": "NEXT_PUBLIC_PW_TEST=true next build --turbo && playwright test --ui",
|
|
"test:no-build": "playwright test",
|
|
"gentests": "playwright codegen http://localhost:3000",
|
|
"storybook": "storybook dev -p 6006",
|
|
"build-storybook": "storybook build",
|
|
"test-storybook": "test-storybook",
|
|
"test-storybook:ci": "concurrently -k -s first -n \"SB,TEST\" -c \"magenta,blue\" \"pnpm run build-storybook -- --quiet && npx http-server storybook-static --port 6006 --silent\" \"wait-on tcp:6006 && pnpm run test-storybook\"",
|
|
"generate:api": "npx --yes tsx ./scripts/generate-api-queries.ts && orval --config ./orval.config.ts",
|
|
"generate:api:force": "npx --yes tsx ./scripts/generate-api-queries.ts --force && orval --config ./orval.config.ts"
|
|
},
|
|
"browserslist": [
|
|
"defaults"
|
|
],
|
|
"dependencies": {
|
|
"@faker-js/faker": "10.0.0",
|
|
"@hookform/resolvers": "5.2.2",
|
|
"@next/third-parties": "15.4.6",
|
|
"@phosphor-icons/react": "2.1.10",
|
|
"@radix-ui/react-alert-dialog": "1.1.15",
|
|
"@radix-ui/react-avatar": "1.1.10",
|
|
"@radix-ui/react-checkbox": "1.3.3",
|
|
"@radix-ui/react-collapsible": "1.1.12",
|
|
"@radix-ui/react-context-menu": "2.2.16",
|
|
"@radix-ui/react-dialog": "1.1.15",
|
|
"@radix-ui/react-dropdown-menu": "2.1.16",
|
|
"@radix-ui/react-icons": "1.3.2",
|
|
"@radix-ui/react-label": "2.1.7",
|
|
"@radix-ui/react-popover": "1.1.15",
|
|
"@radix-ui/react-radio-group": "1.3.8",
|
|
"@radix-ui/react-scroll-area": "1.2.10",
|
|
"@radix-ui/react-select": "2.2.6",
|
|
"@radix-ui/react-separator": "1.1.7",
|
|
"@radix-ui/react-slot": "1.2.3",
|
|
"@radix-ui/react-switch": "1.2.6",
|
|
"@radix-ui/react-tabs": "1.1.13",
|
|
"@radix-ui/react-toast": "1.2.15",
|
|
"@radix-ui/react-tooltip": "1.2.8",
|
|
"@rjsf/core": "5.24.13",
|
|
"@rjsf/utils": "5.24.13",
|
|
"@rjsf/validator-ajv8": "5.24.13",
|
|
"@sentry/nextjs": "10.27.0",
|
|
"@supabase/ssr": "0.7.0",
|
|
"@supabase/supabase-js": "2.78.0",
|
|
"@tanstack/react-query": "5.90.6",
|
|
"@tanstack/react-table": "8.21.3",
|
|
"@types/jaro-winkler": "0.2.4",
|
|
"@vercel/analytics": "1.5.0",
|
|
"@vercel/speed-insights": "1.2.0",
|
|
"@xyflow/react": "12.9.2",
|
|
"boring-avatars": "1.11.2",
|
|
"class-variance-authority": "0.7.1",
|
|
"clsx": "2.1.1",
|
|
"cmdk": "1.1.1",
|
|
"cookie": "1.0.2",
|
|
"date-fns": "4.1.0",
|
|
"dotenv": "17.2.3",
|
|
"elliptic": "6.6.1",
|
|
"embla-carousel-react": "8.6.0",
|
|
"flatbush": "4.5.0",
|
|
"framer-motion": "12.23.24",
|
|
"geist": "1.5.1",
|
|
"highlight.js": "11.11.1",
|
|
"jaro-winkler": "0.2.8",
|
|
"katex": "0.16.25",
|
|
"launchdarkly-react-client-sdk": "3.9.0",
|
|
"lodash": "4.17.21",
|
|
"lucide-react": "0.552.0",
|
|
"moment": "2.30.1",
|
|
"next": "15.4.7",
|
|
"next-themes": "0.4.6",
|
|
"nuqs": "2.7.2",
|
|
"party-js": "2.2.0",
|
|
"react": "18.3.1",
|
|
"react-currency-input-field": "4.0.3",
|
|
"react-day-picker": "9.11.1",
|
|
"react-dom": "18.3.1",
|
|
"react-drag-drop-files": "2.4.0",
|
|
"react-hook-form": "7.66.0",
|
|
"react-icons": "5.5.0",
|
|
"react-markdown": "9.0.3",
|
|
"react-modal": "3.16.3",
|
|
"react-shepherd": "6.1.9",
|
|
"react-window": "1.8.11",
|
|
"recharts": "3.3.0",
|
|
"rehype-autolink-headings": "7.1.0",
|
|
"rehype-highlight": "7.0.2",
|
|
"rehype-katex": "7.0.1",
|
|
"rehype-slug": "6.0.0",
|
|
"remark-gfm": "4.0.1",
|
|
"remark-math": "6.0.0",
|
|
"shepherd.js": "14.5.1",
|
|
"sonner": "2.0.7",
|
|
"tailwind-merge": "2.6.0",
|
|
"tailwind-scrollbar": "3.1.0",
|
|
"tailwindcss-animate": "1.0.7",
|
|
"uuid": "11.1.0",
|
|
"vaul": "1.1.2",
|
|
"zod": "3.25.76",
|
|
"zustand": "5.0.8"
|
|
},
|
|
"devDependencies": {
|
|
"@chromatic-com/storybook": "4.1.2",
|
|
"@playwright/test": "1.56.1",
|
|
"@storybook/addon-a11y": "9.1.5",
|
|
"@storybook/addon-docs": "9.1.5",
|
|
"@storybook/addon-links": "9.1.5",
|
|
"@storybook/addon-onboarding": "9.1.5",
|
|
"@storybook/nextjs": "9.1.5",
|
|
"@tanstack/eslint-plugin-query": "5.91.2",
|
|
"@tanstack/react-query-devtools": "5.90.2",
|
|
"@types/canvas-confetti": "1.9.0",
|
|
"@types/lodash": "4.17.20",
|
|
"@types/negotiator": "0.6.4",
|
|
"@types/node": "24.10.0",
|
|
"@types/react": "18.3.17",
|
|
"@types/react-dom": "18.3.5",
|
|
"@types/react-modal": "3.16.3",
|
|
"@types/react-window": "1.8.8",
|
|
"axe-playwright": "2.2.2",
|
|
"chromatic": "13.3.3",
|
|
"concurrently": "9.2.1",
|
|
"cross-env": "10.1.0",
|
|
"eslint": "8.57.1",
|
|
"eslint-config-next": "15.5.2",
|
|
"eslint-plugin-storybook": "9.1.5",
|
|
"import-in-the-middle": "1.14.2",
|
|
"msw": "2.11.6",
|
|
"msw-storybook-addon": "2.0.6",
|
|
"orval": "7.13.0",
|
|
"pbkdf2": "3.1.5",
|
|
"postcss": "8.5.6",
|
|
"prettier": "3.6.2",
|
|
"prettier-plugin-tailwindcss": "0.7.1",
|
|
"require-in-the-middle": "7.5.2",
|
|
"storybook": "9.1.5",
|
|
"tailwindcss": "3.4.17",
|
|
"typescript": "5.9.3"
|
|
},
|
|
"msw": {
|
|
"workerDirectory": [
|
|
"public"
|
|
]
|
|
},
|
|
"packageManager": "pnpm@10.20.0+sha512.cf9998222162dd85864d0a8102e7892e7ba4ceadebbf5a31f9c2fce48dfce317a9c53b9f6464d1ef9042cba2e02ae02a9f7c143a2b438cd93c91840f0192b9dd"
|
|
}
|