From 4213326fe8f14ec3d19646e048a68ea84e89487d Mon Sep 17 00:00:00 2001 From: Rares Stefan Date: Thu, 16 Mar 2023 15:41:39 +0100 Subject: [PATCH] feat(admin-ui): Add location names to fulfilment rows and timeline events (#3481) Adds location information to fulfilment rows and timeline events ![image](https://user-images.githubusercontent.com/948623/225306827-ebd08517-41c5-426e-88f2-43192b337995.png) ![image](https://user-images.githubusercontent.com/948623/225306876-7f77cbb8-6583-4082-b141-21b84fc2c79e.png) Resolves CORE-1234 --- .changeset/stale-colts-thank.md | 5 +++ .../timeline-events/event-container.tsx | 3 ++ .../timeline-events/event-item-container.tsx | 40 +++++++++++-------- .../timeline-events/items-fulfilled.tsx | 6 +++ .../timeline-events/items-shipped.tsx | 5 +++ .../orders/details/templates/fulfillment.tsx | 19 ++++++++- .../ui/src/hooks/use-build-timeline.tsx | 26 +++++++++++- .../ui/src/hooks/use-stock-locations.ts | 13 ++++++ 8 files changed, 98 insertions(+), 19 deletions(-) create mode 100644 .changeset/stale-colts-thank.md create mode 100644 packages/admin-ui/ui/src/hooks/use-stock-locations.ts diff --git a/.changeset/stale-colts-thank.md b/.changeset/stale-colts-thank.md new file mode 100644 index 0000000000..a815ef7d03 --- /dev/null +++ b/.changeset/stale-colts-thank.md @@ -0,0 +1,5 @@ +--- +"@medusajs/admin-ui": patch +--- + +feat(admin-ui): Add location names to fulfilment rows and timeline events diff --git a/packages/admin-ui/ui/src/components/molecules/timeline-events/event-container.tsx b/packages/admin-ui/ui/src/components/molecules/timeline-events/event-container.tsx index d56a82d167..96c849788e 100644 --- a/packages/admin-ui/ui/src/components/molecules/timeline-events/event-container.tsx +++ b/packages/admin-ui/ui/src/components/molecules/timeline-events/event-container.tsx @@ -25,6 +25,7 @@ export type EventContainerProps = { isFirst?: boolean expandable?: boolean children: ReactNode + detail?: string | React.ReactNode } const EventContainer: React.FC = ({ @@ -38,6 +39,7 @@ const EventContainer: React.FC = ({ isFirst = false, expandable = false, children, + detail, }) => { const [isExpanded, setIsExpanded] = useState(!expandable) @@ -92,6 +94,7 @@ const EventContainer: React.FC = ({ {children && isExpanded && (
{children}
)} +
{detail}
diff --git a/packages/admin-ui/ui/src/components/molecules/timeline-events/event-item-container.tsx b/packages/admin-ui/ui/src/components/molecules/timeline-events/event-item-container.tsx index 840597a93d..5355c4026f 100644 --- a/packages/admin-ui/ui/src/components/molecules/timeline-events/event-item-container.tsx +++ b/packages/admin-ui/ui/src/components/molecules/timeline-events/event-item-container.tsx @@ -9,30 +9,38 @@ type EventItemContainerProps = { title: string } } + detail?: string } -const EventItemContainer: React.FC = ({ item }) => { +const EventItemContainer: React.FC = ({ + item, + detail, +}) => { if (!item) { return null } + return ( -
- {item.thumbnail && ( -
- {`Thumbnail +
+
+ {item.thumbnail && ( +
+ {`Thumbnail +
+ )} +
+
+

{item.title}

+ {`x${item.quantity}`} +
+

{item.variant.title}

- )} -
-
-

{item.title}

- {`x${item.quantity}`} -
-

{item.variant.title}

+ {detail &&
{detail}
}
) } diff --git a/packages/admin-ui/ui/src/components/molecules/timeline-events/items-fulfilled.tsx b/packages/admin-ui/ui/src/components/molecules/timeline-events/items-fulfilled.tsx index affa047d15..86186a3485 100644 --- a/packages/admin-ui/ui/src/components/molecules/timeline-events/items-fulfilled.tsx +++ b/packages/admin-ui/ui/src/components/molecules/timeline-events/items-fulfilled.tsx @@ -16,6 +16,10 @@ const ItemsFulfilled: React.FC = ({ event }) => { ? "Exchange Items Fulfilled" : "Items Fulfilled" + const detail = event.locationName + ? `Shipping from ${event.locationName}` + : undefined + const args = { icon: , time: event.time, @@ -25,7 +29,9 @@ const ItemsFulfilled: React.FC = ({ event }) => { )), noNotification: event.noNotification, isFirst: event.first, + detail, } + return } diff --git a/packages/admin-ui/ui/src/components/molecules/timeline-events/items-shipped.tsx b/packages/admin-ui/ui/src/components/molecules/timeline-events/items-shipped.tsx index 3ed6fbc5c8..892deeb5db 100644 --- a/packages/admin-ui/ui/src/components/molecules/timeline-events/items-shipped.tsx +++ b/packages/admin-ui/ui/src/components/molecules/timeline-events/items-shipped.tsx @@ -16,6 +16,10 @@ const ItemsShipped: React.FC = ({ event }) => { ? "Exchange Items Shipped" : "Items Shipped" + const detail = event.locationName + ? `Shipped from ${event.locationName}` + : undefined + const args = { icon: , time: event.time, @@ -25,6 +29,7 @@ const ItemsShipped: React.FC = ({ event }) => { )), noNotification: event.noNotification, isFirst: event.first, + detail, } return } diff --git a/packages/admin-ui/ui/src/domain/orders/details/templates/fulfillment.tsx b/packages/admin-ui/ui/src/domain/orders/details/templates/fulfillment.tsx index dc7138bc70..422f55347c 100644 --- a/packages/admin-ui/ui/src/domain/orders/details/templates/fulfillment.tsx +++ b/packages/admin-ui/ui/src/domain/orders/details/templates/fulfillment.tsx @@ -4,11 +4,14 @@ import { useAdminCancelFulfillment, useAdminCancelSwapFulfillment, } from "medusa-react" +import IconBadge from "../../../../components/fundamentals/icon-badge" +import BuildingsIcon from "../../../../components/fundamentals/icons/buildings-icon" import CancelIcon from "../../../../components/fundamentals/icons/cancel-icon" import PackageIcon from "../../../../components/fundamentals/icons/package-icon" import Actionables from "../../../../components/molecules/actionables" import useImperativeDialog from "../../../../hooks/use-imperative-dialog" import useNotification from "../../../../hooks/use-notification" +import useStockLocations from "../../../../hooks/use-stock-locations" import { getErrorMessage } from "../../../../utils/error-messages" import { TrackingLink } from "./tracking-link" @@ -23,6 +26,7 @@ export const FormattedFulfillment = ({ const cancelFulfillment = useAdminCancelFulfillment(order.id) const cancelSwapFulfillment = useAdminCancelSwapFulfillment(order.id) const cancelClaimFulfillment = useAdminCancelClaimFulfillment(order.id) + const { getLocationNameById } = useStockLocations() const { fulfillment } = fulfillmentObj const hasLinks = !!fulfillment.tracking_links?.length @@ -89,7 +93,7 @@ export const FormattedFulfillment = ({ return (
-
+
{fulfillment.canceled_at ? "Fulfillment has been canceled" @@ -104,6 +108,19 @@ export const FormattedFulfillment = ({ ))}
+ {!fulfillment.canceled_at && fulfillment.location_id && ( +
+
+ {fulfillment.shipped_at ? "Shipped" : "Shipping"} from{" "} +
+
+ + + + {getLocationNameById(fulfillment.location_id)} +
+
+ )}
{!fulfillment.canceled_at && !fulfillment.shipped_at && (
diff --git a/packages/admin-ui/ui/src/hooks/use-build-timeline.tsx b/packages/admin-ui/ui/src/hooks/use-build-timeline.tsx index 73de7bd5d5..4710a6215b 100644 --- a/packages/admin-ui/ui/src/hooks/use-build-timeline.tsx +++ b/packages/admin-ui/ui/src/hooks/use-build-timeline.tsx @@ -15,6 +15,7 @@ import { import { useMemo } from "react" import useOrdersExpandParam from "../domain/orders/details/utils/use-admin-expand-paramter" import { useFeatureFlag } from "../providers/feature-flag-provider" +import useStockLocations from "./use-stock-locations" export interface TimelineEvent { id: string @@ -92,10 +93,12 @@ interface FulfillmentEvent extends TimelineEvent { export interface ItemsFulfilledEvent extends FulfillmentEvent { items: OrderItem[] + locationName?: string } export interface ItemsShippedEvent extends FulfillmentEvent { items: OrderItem[] + locationName?: string } export interface RefundEvent extends TimelineEvent { @@ -175,6 +178,8 @@ export const useBuildTimeline = (orderId: string) => { const { notifications } = useAdminNotifications({ resource_id: orderId }) + const { getLocationNameById } = useStockLocations() + const events: TimelineEvent[] | undefined = useMemo(() => { if (!order) { return undefined @@ -318,9 +323,10 @@ export const useBuildTimeline = (orderId: string) => { id: event.id, time: event.created_at, type: "fulfilled", - items: event.items.map((item) => getLineItem(allItems, item.item_id)), + items: event.items.map((item) => getFulfilmentItem(allItems, item)), noNotification: event.no_notification, orderId: order.id, + locationName: getLocationNameById(event.location_id), } as ItemsFulfilledEvent) if (event.shipped_at) { @@ -328,9 +334,10 @@ export const useBuildTimeline = (orderId: string) => { id: event.id, time: event.shipped_at, type: "shipped", - items: event.items.map((item) => getLineItem(allItems, item.item_id)), + items: event.items.map((item) => getFulfilmentItem(allItems, item)), noNotification: event.no_notification, orderId: order.id, + locationName: getLocationNameById(event.location_id), } as ItemsShippedEvent) } } @@ -592,3 +599,18 @@ function getWasRefundClaim(claimId, order) { return claim.type === "refund" } + +function getFulfilmentItem(allItems, item) { + const line = allItems.find((line) => line.id === item.item_id) + + if (!line) { + return + } + + return { + title: line.title, + quantity: item.quantity, + thumbnail: line.thumbnail, + variant: { title: line?.variant?.title || "-" }, + } +} diff --git a/packages/admin-ui/ui/src/hooks/use-stock-locations.ts b/packages/admin-ui/ui/src/hooks/use-stock-locations.ts new file mode 100644 index 0000000000..2569c6e1f6 --- /dev/null +++ b/packages/admin-ui/ui/src/hooks/use-stock-locations.ts @@ -0,0 +1,13 @@ +import { useAdminStockLocations } from "medusa-react" + +const useStockLocations = () => { + const { stock_locations } = useAdminStockLocations() + + const getLocationNameById = (locationId: string | null) => + stock_locations?.find((stock_location) => stock_location.id === locationId) + ?.name + + return { stock_locations, getLocationNameById } +} + +export default useStockLocations