diff --git a/src/frontend/src/pages/FlowPage/components/flowSidebarComponent/components/bundleItems/index.tsx b/src/frontend/src/pages/FlowPage/components/flowSidebarComponent/components/bundleItems/index.tsx new file mode 100644 index 00000000000..6ef924069a1 --- /dev/null +++ b/src/frontend/src/pages/FlowPage/components/flowSidebarComponent/components/bundleItems/index.tsx @@ -0,0 +1,83 @@ +import ForwardedIconComponent from "@/components/common/genericIconComponent"; +import { + Disclosure, + DisclosureContent, + DisclosureTrigger, +} from "@/components/ui/disclosure"; +import { SidebarMenuButton, SidebarMenuItem } from "@/components/ui/sidebar"; +import { memo } from "react"; +import SidebarItemsList from "../sidebarItemsList"; + +export const BundleItem = memo( + ({ + item, + isOpen, + onOpenChange, + dataFilter, + nodeColors, + chatInputAdded, + onDragStart, + sensitiveSort, + handleKeyDownInput, + }: { + item: any; + isOpen: boolean; + onOpenChange: (isOpen: boolean) => void; + dataFilter: any; + nodeColors: any; + chatInputAdded: any; + onDragStart: any; + sensitiveSort: any; + handleKeyDownInput: any; + }) => { + if ( + !dataFilter[item.name] || + Object.keys(dataFilter[item.name]).length === 0 + ) { + return null; + } + + return ( + <> + + + + +
handleKeyDownInput(e, item.name)} + className="flex cursor-pointer items-center gap-2" + data-testid={`disclosure-bundles-${item.display_name.toLowerCase()}`} + > + + + {item.display_name} + + +
+
+
+ + + +
+
+ + ); + }, +); + +BundleItem.displayName = "BundleItem"; diff --git a/src/frontend/src/pages/FlowPage/components/flowSidebarComponent/components/sidebarBundles/index.tsx b/src/frontend/src/pages/FlowPage/components/flowSidebarComponent/components/sidebarBundles/index.tsx new file mode 100644 index 00000000000..b49c061e44b --- /dev/null +++ b/src/frontend/src/pages/FlowPage/components/flowSidebarComponent/components/sidebarBundles/index.tsx @@ -0,0 +1,81 @@ +import { + SidebarGroup, + SidebarGroupContent, + SidebarGroupLabel, + SidebarMenu, +} from "@/components/ui/sidebar"; +import { memo, useMemo } from "react"; +import { BundleItem } from "../bundleItems"; + +export const MemoizedSidebarGroup = memo( + ({ + BUNDLES, + search, + sortedCategories, + dataFilter, + nodeColors, + chatInputAdded, + onDragStart, + sensitiveSort, + openCategories, + setOpenCategories, + handleKeyDownInput, + }: { + BUNDLES: any; + search: any; + sortedCategories: any; + dataFilter: any; + nodeColors: any; + chatInputAdded: any; + onDragStart: any; + sensitiveSort: any; + openCategories: any; + setOpenCategories: any; + handleKeyDownInput: any; + }) => { + // Memoize the sorted bundles calculation + const sortedBundles = useMemo(() => { + return BUNDLES.toSorted((a, b) => { + const referenceArray = search !== "" ? sortedCategories : BUNDLES; + return ( + referenceArray.findIndex((value) => value === a.name) - + referenceArray.findIndex((value) => value === b.name) + ); + }); + }, [BUNDLES, search, sortedCategories]); + + return ( + + Bundles + + + {sortedBundles.map((item) => ( + { + setOpenCategories((prev) => + isOpen + ? [...prev, item.name] + : prev.filter((cat) => cat !== item.name), + ); + }} + dataFilter={dataFilter} + nodeColors={nodeColors} + chatInputAdded={chatInputAdded} + onDragStart={onDragStart} + sensitiveSort={sensitiveSort} + handleKeyDownInput={handleKeyDownInput} + /> + ))} + + + + ); + }, +); + +MemoizedSidebarGroup.displayName = "MemoizedSidebarGroup"; + +export default MemoizedSidebarGroup; diff --git a/src/frontend/src/pages/FlowPage/components/flowSidebarComponent/index.tsx b/src/frontend/src/pages/FlowPage/components/flowSidebarComponent/index.tsx index cf2fe3bda15..51eabc1810f 100644 --- a/src/frontend/src/pages/FlowPage/components/flowSidebarComponent/index.tsx +++ b/src/frontend/src/pages/FlowPage/components/flowSidebarComponent/index.tsx @@ -36,6 +36,7 @@ import { APIClassType } from "../../../../types/api"; import sensitiveSort from "../extraSidebarComponent/utils/sensitive-sort"; import { CategoryGroup } from "./components/categoryGroup"; import NoResultsMessage from "./components/emptySearchComponent"; +import MemoizedSidebarGroup from "./components/sidebarBundles"; import SidebarMenuButtons from "./components/sidebarFooterButtons"; import { SidebarHeaderComponent } from "./components/sidebarHeader"; import SidebarItemsList from "./components/sidebarItemsList"; @@ -416,75 +417,19 @@ export function FlowSidebarComponent() { /> )} {hasBundleItems && ( - - Bundles - - - {BUNDLES.toSorted( - (a, b) => - (search !== "" ? sortedCategories : BUNDLES).findIndex( - (value) => value === a.name, - ) - - (search !== "" ? sortedCategories : BUNDLES).findIndex( - (value) => value === b.name, - ), - ).map( - (item) => - dataFilter[item.name] && - Object.keys(dataFilter[item.name]).length > 0 && ( - { - setOpenCategories((prev) => - isOpen - ? [...prev, item.name] - : prev.filter((cat) => cat !== item.name), - ); - }} - > - - - -
- handleKeyDownInput(e, item.name) - } - className="flex cursor-pointer items-center gap-2" - data-testid={`disclosure-bundles-${item.display_name.toLocaleLowerCase()}`} - > - - - {item.display_name} - - -
-
-
- - - -
-
- ), - )} -
-
-
+ )} ) : (