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 && (