mirror of
https://github.com/Significant-Gravitas/AutoGPT.git
synced 2026-04-08 03:00:28 -04:00
chore: improvements
This commit is contained in:
@@ -54,6 +54,7 @@
|
||||
"@supabase/supabase-js": "2.50.3",
|
||||
"@tanstack/react-query": "5.81.5",
|
||||
"@tanstack/react-table": "8.21.3",
|
||||
"@tanstack/react-virtual": "3.13.12",
|
||||
"@types/jaro-winkler": "0.2.4",
|
||||
"@xyflow/react": "12.8.1",
|
||||
"ajv": "8.17.1",
|
||||
|
||||
36
autogpt_platform/frontend/pnpm-lock.yaml
generated
36
autogpt_platform/frontend/pnpm-lock.yaml
generated
@@ -92,6 +92,9 @@ importers:
|
||||
'@tanstack/react-table':
|
||||
specifier: 8.21.3
|
||||
version: 8.21.3(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
|
||||
'@tanstack/react-virtual':
|
||||
specifier: 3.13.12
|
||||
version: 3.13.12(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
|
||||
'@types/jaro-winkler':
|
||||
specifier: 0.2.4
|
||||
version: 0.2.4
|
||||
@@ -2748,10 +2751,19 @@ packages:
|
||||
react: '>=16.8'
|
||||
react-dom: '>=16.8'
|
||||
|
||||
'@tanstack/react-virtual@3.13.12':
|
||||
resolution: {integrity: sha512-Gd13QdxPSukP8ZrkbgS2RwoZseTTbQPLnQEn7HY/rqtM+8Zt95f7xKC7N0EsKs7aoz0WzZ+fditZux+F8EzYxA==}
|
||||
peerDependencies:
|
||||
react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0
|
||||
react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0
|
||||
|
||||
'@tanstack/table-core@8.21.3':
|
||||
resolution: {integrity: sha512-ldZXEhOBb8Is7xLs01fR3YEc3DERiz5silj8tnGkFZytt1abEvl/GhUmCE0PMLaMPTa3Jk4HbKmRlHmu+gCftg==}
|
||||
engines: {node: '>=12'}
|
||||
|
||||
'@tanstack/virtual-core@3.13.12':
|
||||
resolution: {integrity: sha512-1YBOJfRHV4sXUmWsFSf5rQor4Ss82G8dQWLRbnk3GA4jeP8hQt1hxXh0tmflpC0dz3VgEv/1+qwPyLeWkQuPFA==}
|
||||
|
||||
'@testing-library/dom@10.4.0':
|
||||
resolution: {integrity: sha512-pemlzrSESWbdAloYml3bAJMEfNh1Z7EduzqPKprCH5S341frlpYnUEW0H72dLxa6IsYr+mPno20GiSm+h9dEdQ==}
|
||||
engines: {node: '>=18'}
|
||||
@@ -9982,8 +9994,16 @@ snapshots:
|
||||
react: 18.3.1
|
||||
react-dom: 18.3.1(react@18.3.1)
|
||||
|
||||
'@tanstack/react-virtual@3.13.12(react-dom@18.3.1(react@18.3.1))(react@18.3.1)':
|
||||
dependencies:
|
||||
'@tanstack/virtual-core': 3.13.12
|
||||
react: 18.3.1
|
||||
react-dom: 18.3.1(react@18.3.1)
|
||||
|
||||
'@tanstack/table-core@8.21.3': {}
|
||||
|
||||
'@tanstack/virtual-core@3.13.12': {}
|
||||
|
||||
'@testing-library/dom@10.4.0':
|
||||
dependencies:
|
||||
'@babel/code-frame': 7.27.1
|
||||
@@ -11633,8 +11653,8 @@ snapshots:
|
||||
'@typescript-eslint/parser': 8.36.0(eslint@8.57.1)(typescript@5.8.3)
|
||||
eslint: 8.57.1
|
||||
eslint-import-resolver-node: 0.3.9
|
||||
eslint-import-resolver-typescript: 3.10.1(eslint-plugin-import@2.32.0)(eslint@8.57.1)
|
||||
eslint-plugin-import: 2.32.0(@typescript-eslint/parser@8.36.0(eslint@8.57.1)(typescript@5.8.3))(eslint-import-resolver-typescript@3.10.1)(eslint@8.57.1)
|
||||
eslint-import-resolver-typescript: 3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.36.0(eslint@8.57.1)(typescript@5.8.3))(eslint@8.57.1))(eslint@8.57.1)
|
||||
eslint-plugin-import: 2.32.0(@typescript-eslint/parser@8.36.0(eslint@8.57.1)(typescript@5.8.3))(eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.36.0(eslint@8.57.1)(typescript@5.8.3))(eslint@8.57.1))(eslint@8.57.1))(eslint@8.57.1)
|
||||
eslint-plugin-jsx-a11y: 6.10.2(eslint@8.57.1)
|
||||
eslint-plugin-react: 7.37.5(eslint@8.57.1)
|
||||
eslint-plugin-react-hooks: 5.2.0(eslint@8.57.1)
|
||||
@@ -11653,7 +11673,7 @@ snapshots:
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.32.0)(eslint@8.57.1):
|
||||
eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.36.0(eslint@8.57.1)(typescript@5.8.3))(eslint@8.57.1))(eslint@8.57.1):
|
||||
dependencies:
|
||||
'@nolyfill/is-core-module': 1.0.39
|
||||
debug: 4.4.1
|
||||
@@ -11664,22 +11684,22 @@ snapshots:
|
||||
tinyglobby: 0.2.14
|
||||
unrs-resolver: 1.11.0
|
||||
optionalDependencies:
|
||||
eslint-plugin-import: 2.32.0(@typescript-eslint/parser@8.36.0(eslint@8.57.1)(typescript@5.8.3))(eslint-import-resolver-typescript@3.10.1)(eslint@8.57.1)
|
||||
eslint-plugin-import: 2.32.0(@typescript-eslint/parser@8.36.0(eslint@8.57.1)(typescript@5.8.3))(eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.36.0(eslint@8.57.1)(typescript@5.8.3))(eslint@8.57.1))(eslint@8.57.1))(eslint@8.57.1)
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
eslint-module-utils@2.12.1(@typescript-eslint/parser@8.36.0(eslint@8.57.1)(typescript@5.8.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.10.1)(eslint@8.57.1):
|
||||
eslint-module-utils@2.12.1(@typescript-eslint/parser@8.36.0(eslint@8.57.1)(typescript@5.8.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.36.0(eslint@8.57.1)(typescript@5.8.3))(eslint@8.57.1))(eslint@8.57.1))(eslint@8.57.1):
|
||||
dependencies:
|
||||
debug: 3.2.7
|
||||
optionalDependencies:
|
||||
'@typescript-eslint/parser': 8.36.0(eslint@8.57.1)(typescript@5.8.3)
|
||||
eslint: 8.57.1
|
||||
eslint-import-resolver-node: 0.3.9
|
||||
eslint-import-resolver-typescript: 3.10.1(eslint-plugin-import@2.32.0)(eslint@8.57.1)
|
||||
eslint-import-resolver-typescript: 3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.36.0(eslint@8.57.1)(typescript@5.8.3))(eslint@8.57.1))(eslint@8.57.1)
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.36.0(eslint@8.57.1)(typescript@5.8.3))(eslint-import-resolver-typescript@3.10.1)(eslint@8.57.1):
|
||||
eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.36.0(eslint@8.57.1)(typescript@5.8.3))(eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.36.0(eslint@8.57.1)(typescript@5.8.3))(eslint@8.57.1))(eslint@8.57.1))(eslint@8.57.1):
|
||||
dependencies:
|
||||
'@rtsao/scc': 1.1.0
|
||||
array-includes: 3.1.9
|
||||
@@ -11690,7 +11710,7 @@ snapshots:
|
||||
doctrine: 2.1.0
|
||||
eslint: 8.57.1
|
||||
eslint-import-resolver-node: 0.3.9
|
||||
eslint-module-utils: 2.12.1(@typescript-eslint/parser@8.36.0(eslint@8.57.1)(typescript@5.8.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.10.1)(eslint@8.57.1)
|
||||
eslint-module-utils: 2.12.1(@typescript-eslint/parser@8.36.0(eslint@8.57.1)(typescript@5.8.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.36.0(eslint@8.57.1)(typescript@5.8.3))(eslint@8.57.1))(eslint@8.57.1))(eslint@8.57.1)
|
||||
hasown: 2.0.2
|
||||
is-core-module: 2.16.1
|
||||
is-glob: 4.0.3
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
import React from "react";
|
||||
import React, { useRef } from "react";
|
||||
import { useVirtualizer, VirtualItem } from "@tanstack/react-virtual";
|
||||
import { Card, CardContent, CardHeader } from "@/components/ui/card";
|
||||
import { Label } from "@/components/ui/label";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { Input } from "@/components/ui/input";
|
||||
import { TextRenderer } from "@/components/ui/render";
|
||||
import { ScrollArea } from "@/components/ui/scroll-area";
|
||||
import {
|
||||
Popover,
|
||||
PopoverContent,
|
||||
@@ -34,10 +34,6 @@ interface Props {
|
||||
nodes: CustomNode[];
|
||||
}
|
||||
|
||||
/**
|
||||
* A React functional component that displays a control for managing blocks.
|
||||
* Optimized for performance with debounced search, memoized data, and separated concerns.
|
||||
*/
|
||||
function BlocksControlComponent({
|
||||
blocks,
|
||||
addBlock,
|
||||
@@ -61,6 +57,15 @@ function BlocksControlComponent({
|
||||
addBlock,
|
||||
});
|
||||
|
||||
const parentRef = useRef<HTMLDivElement>(null);
|
||||
|
||||
const virtualizer = useVirtualizer({
|
||||
count: filteredAvailableBlocks.length,
|
||||
getScrollElement: () => parentRef.current,
|
||||
estimateSize: () => 96, // 80px height + 16px margin (my-4)
|
||||
overscan: 5,
|
||||
});
|
||||
|
||||
return (
|
||||
<Popover
|
||||
open={pinBlocksPopover ? true : undefined}
|
||||
@@ -133,64 +138,90 @@ function BlocksControlComponent({
|
||||
})}
|
||||
</div>
|
||||
</CardHeader>
|
||||
<CardContent className="overflow-scroll border-t border-t-gray-200 p-0 dark:border-t-slate-700">
|
||||
<ScrollArea
|
||||
className="h-[60vh] w-full"
|
||||
<CardContent className="border-t border-t-gray-200 p-0 dark:border-t-slate-700">
|
||||
<div
|
||||
ref={parentRef}
|
||||
className="h-[60vh] w-full overflow-auto"
|
||||
data-id="blocks-control-scroll-area"
|
||||
>
|
||||
{filteredAvailableBlocks.map((block) => (
|
||||
<Card
|
||||
key={block.uiKey || block.id}
|
||||
className={`m-2 my-4 flex h-20 shadow-none dark:border-slate-700 dark:bg-slate-800 dark:text-slate-100 dark:hover:bg-slate-700 ${
|
||||
block.notAvailable
|
||||
? "cursor-not-allowed opacity-50"
|
||||
: "cursor-pointer hover:shadow-lg"
|
||||
}`}
|
||||
data-id={`block-card-${block.id}`}
|
||||
onClick={() => handleAddBlock(block)}
|
||||
title={block.notAvailable ?? undefined}
|
||||
>
|
||||
<div
|
||||
className={`-ml-px h-full w-3 rounded-l-xl ${getPrimaryCategoryColor(block.categories)}`}
|
||||
></div>
|
||||
<div
|
||||
style={{
|
||||
height: `${virtualizer.getTotalSize()}px`,
|
||||
width: "100%",
|
||||
position: "relative",
|
||||
}}
|
||||
>
|
||||
{virtualizer
|
||||
.getVirtualItems()
|
||||
.map((virtualItem: VirtualItem) => {
|
||||
const block = filteredAvailableBlocks[virtualItem.index];
|
||||
|
||||
<div className="mx-3 flex flex-1 items-center justify-between">
|
||||
<div className="mr-2 min-w-0">
|
||||
<span
|
||||
className="block truncate pb-1 text-sm font-semibold dark:text-white"
|
||||
data-id={`block-name-${block.id}`}
|
||||
data-type={block.uiType}
|
||||
data-testid={`block-name-${block.id}`}
|
||||
return (
|
||||
<div
|
||||
key={virtualItem.key}
|
||||
style={{
|
||||
position: "absolute",
|
||||
top: 0,
|
||||
left: 0,
|
||||
width: "100%",
|
||||
height: `${virtualItem.size}px`,
|
||||
transform: `translateY(${virtualItem.start}px)`,
|
||||
}}
|
||||
>
|
||||
<TextRenderer
|
||||
value={beautifyString(block.name).replace(
|
||||
/ Block$/,
|
||||
"",
|
||||
)}
|
||||
truncateLengthLimit={45}
|
||||
/>
|
||||
</span>
|
||||
<span
|
||||
className="block break-all text-xs font-normal text-gray-500 dark:text-gray-400"
|
||||
data-testid={`block-description-${block.id}`}
|
||||
>
|
||||
<TextRenderer
|
||||
value={block.description}
|
||||
truncateLengthLimit={165}
|
||||
/>
|
||||
</span>
|
||||
</div>
|
||||
<div
|
||||
className="flex flex-shrink-0 items-center gap-1"
|
||||
data-id={`block-tooltip-${block.id}`}
|
||||
data-testid={`block-add`}
|
||||
>
|
||||
<PlusIcon className="h-6 w-6 rounded-lg bg-gray-200 stroke-black stroke-[0.5px] p-1 dark:bg-gray-700 dark:stroke-white" />
|
||||
</div>
|
||||
</div>
|
||||
</Card>
|
||||
))}
|
||||
</ScrollArea>
|
||||
<Card
|
||||
className={`m-2 my-4 flex h-20 shadow-none dark:border-slate-700 dark:bg-slate-800 dark:text-slate-100 dark:hover:bg-slate-700 ${
|
||||
block.notAvailable
|
||||
? "cursor-not-allowed opacity-50"
|
||||
: "cursor-pointer hover:shadow-lg"
|
||||
}`}
|
||||
data-id={`block-card-${block.id}`}
|
||||
onClick={() => handleAddBlock(block)}
|
||||
title={block.notAvailable ?? undefined}
|
||||
>
|
||||
<div
|
||||
className={`-ml-px h-full w-3 rounded-l-xl ${getPrimaryCategoryColor(block.categories)}`}
|
||||
></div>
|
||||
|
||||
<div className="mx-3 flex flex-1 items-center justify-between">
|
||||
<div className="mr-2 min-w-0">
|
||||
<span
|
||||
className="block truncate pb-1 text-sm font-semibold dark:text-white"
|
||||
data-id={`block-name-${block.id}`}
|
||||
data-type={block.uiType}
|
||||
data-testid={`block-name-${block.id}`}
|
||||
>
|
||||
<TextRenderer
|
||||
value={beautifyString(block.name).replace(
|
||||
/ Block$/,
|
||||
"",
|
||||
)}
|
||||
truncateLengthLimit={45}
|
||||
/>
|
||||
</span>
|
||||
<span
|
||||
className="block break-all text-xs font-normal text-gray-500 dark:text-gray-400"
|
||||
data-testid={`block-description-${block.id}`}
|
||||
>
|
||||
<TextRenderer
|
||||
value={block.description}
|
||||
truncateLengthLimit={165}
|
||||
/>
|
||||
</span>
|
||||
</div>
|
||||
<div
|
||||
className="flex flex-shrink-0 items-center gap-1"
|
||||
data-id={`block-tooltip-${block.id}`}
|
||||
data-testid={`block-add`}
|
||||
>
|
||||
<PlusIcon className="h-6 w-6 rounded-lg bg-gray-200 stroke-black stroke-[0.5px] p-1 dark:bg-gray-700 dark:stroke-white" />
|
||||
</div>
|
||||
</div>
|
||||
</Card>
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
</PopoverContent>
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import { useState, useMemo } from "react";
|
||||
import debounce from "lodash/debounce";
|
||||
import { useState, useMemo, useRef, useCallback } from "react";
|
||||
import {
|
||||
Block,
|
||||
BlockUIType,
|
||||
@@ -31,6 +30,7 @@ interface Args {
|
||||
export function useBlocksControl({ blocks, flows, nodes, addBlock }: Args) {
|
||||
const [searchQuery, setSearchQuery] = useState("");
|
||||
const [selectedCategory, setSelectedCategory] = useState<string | null>(null);
|
||||
const animationFrameRef = useRef<number | null>(null);
|
||||
|
||||
// Memoize graph state checks to avoid recalculating on every render
|
||||
const graphState = useMemo(
|
||||
@@ -113,11 +113,15 @@ export function useBlocksControl({ blocks, flows, nodes, addBlock }: Args) {
|
||||
|
||||
const categories = useMemo(() => extractCategories(blocks), [blocks]);
|
||||
|
||||
// Create debounced version of setSearchQuery
|
||||
const debouncedSetSearchQuery = useMemo(
|
||||
() => debounce(setSearchQuery, 200),
|
||||
[],
|
||||
);
|
||||
// Create requestAnimationFrame-based search query setter
|
||||
const debouncedSetSearchQuery = useCallback((value: string) => {
|
||||
if (animationFrameRef.current) {
|
||||
cancelAnimationFrame(animationFrameRef.current);
|
||||
}
|
||||
animationFrameRef.current = requestAnimationFrame(() => {
|
||||
setSearchQuery(value);
|
||||
});
|
||||
}, []);
|
||||
|
||||
function resetFilters() {
|
||||
setSearchQuery("");
|
||||
|
||||
Reference in New Issue
Block a user