diff --git a/src/backend/langflow/api/v1/store.py b/src/backend/langflow/api/v1/store.py index 30775f745..273ea41e4 100644 --- a/src/backend/langflow/api/v1/store.py +++ b/src/backend/langflow/api/v1/store.py @@ -102,6 +102,7 @@ async def share_component( @router.get("/components/", response_model=ListComponentResponseModel) async def get_components( + component_id: Annotated[Optional[str], Query()] = None, search: Annotated[Optional[str], Query()] = None, private: Annotated[Optional[bool], Query()] = None, is_component: Annotated[Optional[bool], Query()] = None, @@ -117,6 +118,7 @@ async def get_components( ): try: return await store_service.get_list_component_response_model( + component_id=component_id, search=search, private=private, is_component=is_component, diff --git a/src/backend/langflow/services/store/service.py b/src/backend/langflow/services/store/service.py index 3dcf3fd76..057f4d697 100644 --- a/src/backend/langflow/services/store/service.py +++ b/src/backend/langflow/services/store/service.py @@ -171,6 +171,7 @@ class StoreService(Service): def build_filter_conditions( self, + component_id: Optional[str] = None, search: Optional[str] = None, private: Optional[bool] = None, tags: Optional[List[str]] = None, @@ -191,7 +192,8 @@ class StoreService(Service): if tags: tags_filter = self.build_tags_filter(tags) filter_conditions.append(tags_filter) - + if component_id is not None: + filter_conditions.append({"id": {"_eq": component_id}}) if is_component is not None: filter_conditions.append({"is_component": {"_eq": is_component}}) if liked and store_api_Key: @@ -412,6 +414,7 @@ class StoreService(Service): async def get_list_component_response_model( self, + component_id: Optional[str] = None, search: Optional[str] = None, private: Optional[bool] = None, tags: Optional[List[str]] = None, @@ -426,6 +429,7 @@ class StoreService(Service): ): async with user_data_context(api_key=store_api_key, store_service=self): filter_conditions: List[Dict[str, Any]] = self.build_filter_conditions( + component_id=component_id, search=search, private=private, tags=tags, diff --git a/src/frontend/src/controllers/API/index.ts b/src/frontend/src/controllers/API/index.ts index da16ba531..dc5fc014e 100644 --- a/src/frontend/src/controllers/API/index.ts +++ b/src/frontend/src/controllers/API/index.ts @@ -594,6 +594,7 @@ export async function getFlowsStore(): Promise> { } export async function getStoreComponents({ + component_id = null, page = 1, limit = 9999999, is_component = null, @@ -605,6 +606,7 @@ export async function getStoreComponents({ filterByUser = null, fields = null, }: { + component_id?: string | null; page?: number; limit?: number; is_component?: boolean | null; @@ -619,6 +621,9 @@ export async function getStoreComponents({ try { let url = `${BASE_URL_API}store/components/`; const queryParams: any = []; + if (component_id !== undefined && component_id !== null) { + queryParams.push(`component_id=${component_id}`); + } if (search !== undefined && search !== null) { queryParams.push(`search=${search}`); } diff --git a/src/frontend/src/pages/StorePage/index.tsx b/src/frontend/src/pages/StorePage/index.tsx index 7c0a86369..a544d7a8b 100644 --- a/src/frontend/src/pages/StorePage/index.tsx +++ b/src/frontend/src/pages/StorePage/index.tsx @@ -9,7 +9,9 @@ import { SkeletonCardComponent } from "../../components/skeletonCardComponent"; import { Button } from "../../components/ui/button"; import { Input } from "../../components/ui/input"; +import { Link, useParams } from "react-router-dom"; import { TagsSelector } from "../../components/tagsSelectorComponent"; +import { Badge } from "../../components/ui/badge"; import { Select, SelectContent, @@ -27,6 +29,7 @@ import StoreApiKeyModal from "../../modals/StoreApiKeyModal"; import { storeComponent } from "../../types/store"; import { cn } from "../../utils/utils"; export default function StorePage(): JSX.Element { + const { id } = useParams(); const { validApiKey, setValidApiKey, hasApiKey, loadingApiKey } = useContext(StoreContext); const { apiKey } = useContext(AuthContext); @@ -85,6 +88,7 @@ export default function StorePage(): JSX.Element { apiKey, searchNow, loadingApiKey, + id, ]); function handleGetTags() { @@ -104,6 +108,7 @@ export default function StorePage(): JSX.Element { if (!hasApiKey || loadingApiKey) return; setLoading(true); getStoreComponents({ + component_id: id, page: pageIndex, limit: pageSize, is_component: @@ -275,13 +280,27 @@ export default function StorePage(): JSX.Element { - + {id === undefined ? ( + + ) : ( + + + + + {id} + + )}
diff --git a/src/frontend/src/routes.tsx b/src/frontend/src/routes.tsx index 50e2da164..b48e5147d 100644 --- a/src/frontend/src/routes.tsx +++ b/src/frontend/src/routes.tsx @@ -55,6 +55,16 @@ const Router = () => { } /> + + + + + + } + />