diff --git a/src/backend/base/langflow/custom/directory_reader/directory_reader.py b/src/backend/base/langflow/custom/directory_reader/directory_reader.py index 81ac913f5..fb0388059 100644 --- a/src/backend/base/langflow/custom/directory_reader/directory_reader.py +++ b/src/backend/base/langflow/custom/directory_reader/directory_reader.py @@ -9,6 +9,8 @@ from loguru import logger from langflow.custom import Component +MAX_DEPTH = 2 + class CustomComponentPathValueError(ValueError): pass @@ -135,12 +137,11 @@ class DirectoryReader: if "deactivated" in file_path.parent.name: continue - # The other condtion is that it should be - # in the safe_path/[folder]/[file].py format - # any folders below [folder] will be ignored - # basically the parent folder of the file should be a - # folder in the safe_path - if file_path.is_file() and file_path.parent.parent == safe_path_obj and not file_path.name.startswith("__"): + # Calculate the depth of the file relative to the safe path + relative_depth = len(file_path.relative_to(safe_path_obj).parts) + + # Only include files that are one or two levels deep + if relative_depth <= MAX_DEPTH and file_path.is_file() and not file_path.name.startswith("__"): file_list.append(str(file_path)) return file_list diff --git a/src/frontend/src/pages/FlowPage/components/flowSidebarComponent/components/categoryGroup/index.tsx b/src/frontend/src/pages/FlowPage/components/flowSidebarComponent/components/categoryGroup/index.tsx index 3756e37bf..2e54e274b 100644 --- a/src/frontend/src/pages/FlowPage/components/flowSidebarComponent/components/categoryGroup/index.tsx +++ b/src/frontend/src/pages/FlowPage/components/flowSidebarComponent/components/categoryGroup/index.tsx @@ -3,6 +3,7 @@ import { SidebarGroupContent, SidebarMenu, } from "@/components/ui/sidebar"; +import { SIDEBAR_BUNDLES } from "@/utils/styleUtils"; import { memo } from "react"; import { CategoryGroupProps } from "../../types"; import { CategoryDisclosure } from "../categoryDisclouse"; @@ -23,20 +24,42 @@ export const CategoryGroup = memo(function CategoryGroup({ - {CATEGORIES.toSorted( - (a, b) => - (search !== "" ? sortedCategories : CATEGORIES).findIndex( - (value) => value === a.name, - ) - - (search !== "" ? sortedCategories : CATEGORIES).findIndex( - (value) => value === b.name, - ), - ).map( - (item) => - dataFilter[item.name] && - Object.keys(dataFilter[item.name]).length > 0 && ( + {Object.entries(dataFilter) + .filter( + ([categoryName, items]) => + // filter out bundles + !SIDEBAR_BUNDLES.some((cat) => cat.name === categoryName) && + categoryName !== "custom_component" && + Object.keys(items).length > 0, + ) + .sort(([aName], [bName]) => { + const categoryList = + search !== "" + ? sortedCategories + : CATEGORIES.map((c) => c.name); + const aIndex = categoryList.indexOf(aName); + const bIndex = categoryList.indexOf(bName); + + // If neither is in CATEGORIES, keep their relative order + if (aIndex === -1 && bIndex === -1) return 0; + // If only a is not in CATEGORIES, put it after b + if (aIndex === -1) return 1; + // If only b is not in CATEGORIES, put it after a + if (bIndex === -1) return -1; + // If both are in CATEGORIES, sort by their index + return aIndex - bIndex; + }) + .map(([categoryName]) => { + const item = CATEGORIES.find( + (cat) => cat.name === categoryName, + ) ?? { + name: categoryName, + icon: "folder", + display_name: categoryName, + }; + return ( - ), - )} + ); + })} diff --git a/src/frontend/src/pages/FlowPage/components/flowSidebarComponent/index.tsx b/src/frontend/src/pages/FlowPage/components/flowSidebarComponent/index.tsx index 32e41fb34..857430ee8 100644 --- a/src/frontend/src/pages/FlowPage/components/flowSidebarComponent/index.tsx +++ b/src/frontend/src/pages/FlowPage/components/flowSidebarComponent/index.tsx @@ -120,19 +120,12 @@ export function FlowSidebarComponent() { const sortedCategories = useMemo(() => { if (!searchResults || !searchFilteredData) return []; - return Object.keys(searchFilteredData) - .filter( - (category) => - Object.keys(searchFilteredData[category]).length > 0 && - (CATEGORIES.find((c) => c.name === category) || - BUNDLES.find((b) => b.name === category)), - ) - .toSorted((a, b) => - searchResults.fuseCategories.indexOf(b) < - searchResults.fuseCategories.indexOf(a) - ? 1 - : -1, - ); + return Object.keys(searchFilteredData).toSorted((a, b) => + searchResults.fuseCategories.indexOf(b) < + searchResults.fuseCategories.indexOf(a) + ? 1 + : -1, + ); }, [searchResults, searchFilteredData, CATEGORIES, BUNDLES]); const finalFilteredData = useMemo(() => { @@ -305,16 +298,6 @@ export function FlowSidebarComponent() { [dataFilter], ); - const hasCategoryItems = useMemo( - () => - CATEGORIES.some( - (item) => - dataFilter[item.name] && - Object.keys(dataFilter[item.name]).length > 0, - ), - [dataFilter], - ); - return ( {hasResults ? ( <> - {hasCategoryItems && ( - - )} + {hasBundleItems && (