diff --git a/frontend/src/hooks/api.tsx b/frontend/src/hooks/api.tsx
index 9dd74362..e7f067e3 100644
--- a/frontend/src/hooks/api.tsx
+++ b/frontend/src/hooks/api.tsx
@@ -119,6 +119,17 @@ export class api {
});
}
+ public async getListingsBatch(
+ ids: string[]
+ ): Promise
{
+ return this.callWrapper(async () => {
+ const response = await this.api.get("/listings/batch", {
+ params: { ids: ids.join(",") },
+ });
+ return response.data;
+ });
+ }
+
public async dumpListings(): Promise {
return this.callWrapper(async () => {
const response = await this.api.get("/listings/dump");
diff --git a/frontend/src/pages/ListingDetails.tsx b/frontend/src/pages/ListingDetails.tsx
index 491227ee..88f88cde 100644
--- a/frontend/src/pages/ListingDetails.tsx
+++ b/frontend/src/pages/ListingDetails.tsx
@@ -16,7 +16,7 @@ import {
Spinner,
} from "react-bootstrap";
import Markdown from "react-markdown";
-import { useNavigate, useParams } from "react-router-dom";
+import { Link, useNavigate, useParams } from "react-router-dom";
interface ListingDetailsResponse {
name: string;
@@ -26,6 +26,11 @@ interface ListingDetailsResponse {
child_ids: string[];
}
+interface Child {
+ id: string;
+ name: string;
+}
+
const RenderListing = ({
listing,
id,
@@ -44,6 +49,7 @@ const RenderListing = ({
const [ownerEmail, setOwnerEmail] = useState(null);
const [imageIndex, setArtifactIndex] = useState(0);
const [showDelete, setShowDelete] = useState(false);
+ const [children, setChildren] = useState(null);
const handleClose = () => setShow(false);
const handleShow = () => setShow(true);
@@ -78,6 +84,20 @@ const RenderListing = ({
fetchListing();
}, [user_id]);
+ useEffect(() => {
+ const fetchChildren = async () => {
+ try {
+ const children = await auth_api.getListingsBatch(listing.child_ids)
+ setChildren(children.map((child) => ({ id: child.id, name: child.name })))
+ } catch (err) {
+ addAlert(humanReadableError(err), "error");
+ }
+ }
+ if (listing.child_ids.length > 0) {
+ fetchChildren();
+ }
+ }, [])
+
return (
<>
@@ -92,7 +112,16 @@ const RenderListing = ({
{ownerEmail}.
+
+ {children &&
+ This listing depends on the following listings:
+
+ {children.map((child) => -
+ {child.name}
+
)}
+
+
}
diff --git a/store/app/routers/listings.py b/store/app/routers/listings.py
index 322e6950..da1fbf00 100644
--- a/store/app/routers/listings.py
+++ b/store/app/routers/listings.py
@@ -35,6 +35,14 @@ async def list_listings(
return await crud.get_listings(page, search_query=search_query)
+@listings_router.get("/batch")
+async def batch(
+ crud: Annotated[Crud, Depends(Crud.get)],
+ ids: list[str] = Query(description="List of part ids"),
+) -> list[Listing]:
+ return await crud._get_item_batch(ids, Listing)
+
+
@listings_router.get("/dump")
async def dump_listings(
crud: Annotated[Crud, Depends(Crud.get)],