fix(admin-ui): Fix use of expand parameter on order page (#3383)

* Create cuddly-seahorses-thank.md

* add integration tests

* revert back from master to develop

* fix expand

* add new integration test

* add missing default relations

* add missing refunds relation

* re work

* fix tests

* init

* fix order page according to fixes to expand

* expand shipping on returns

* Create .changeset/cuddly-beers-tease.md

---------

Co-authored-by: Adrien de Peretti <adrien.deperetti@gmail.com>
Co-authored-by: Oliver Windall Juhl <59018053+olivermrbl@users.noreply.github.com>
This commit is contained in:
Kasper Fabricius Kristensen
2023-03-07 19:43:44 +01:00
committed by GitHub
co-authored by Adrien de Peretti Oliver Windall Juhl
parent 47d3440766
commit d0d11307d2
10 changed files with 54 additions and 35 deletions
+6
View File
@@ -0,0 +1,6 @@
---
"@medusajs/admin-ui": patch
"@medusajs/admin": patch
---
fix(admin-ui): Fix use of `expand` parameter on order page
@@ -6,7 +6,6 @@ import {
import { Fragment } from "react" import { Fragment } from "react"
import CreateFulfillmentModal from "../../../../domain/orders/details/create-fulfillment" import CreateFulfillmentModal from "../../../../domain/orders/details/create-fulfillment"
import { ReceiveReturnMenu } from "../../../../domain/orders/details/receive-return" import { ReceiveReturnMenu } from "../../../../domain/orders/details/receive-return"
import { orderReturnableFields } from "../../../../domain/orders/details/utils/order-returnable-fields"
import useOrdersExpandParam from "../../../../domain/orders/details/utils/use-admin-expand-paramter" import useOrdersExpandParam from "../../../../domain/orders/details/utils/use-admin-expand-paramter"
import { ClaimEvent } from "../../../../hooks/use-build-timeline" import { ClaimEvent } from "../../../../hooks/use-build-timeline"
import useNotification from "../../../../hooks/use-notification" import useNotification from "../../../../hooks/use-notification"
@@ -49,7 +48,6 @@ const Claim = ({ event }: Props) => {
const { orderRelations } = useOrdersExpandParam() const { orderRelations } = useOrdersExpandParam()
// Orders and returns aren't linked in `medusa-react` so we need to manually refetch the order // Orders and returns aren't linked in `medusa-react` so we need to manually refetch the order
const { refetch } = useAdminOrder(event.orderId, { const { refetch } = useAdminOrder(event.orderId, {
fields: orderReturnableFields,
expand: orderRelations, expand: orderRelations,
}) })
@@ -9,7 +9,6 @@ import React, { useEffect, useState } from "react"
import CreateFulfillmentModal from "../../../domain/orders/details/create-fulfillment" import CreateFulfillmentModal from "../../../domain/orders/details/create-fulfillment"
import { ReceiveReturnMenu } from "../../../domain/orders/details/receive-return" import { ReceiveReturnMenu } from "../../../domain/orders/details/receive-return"
import { orderReturnableFields } from "../../../domain/orders/details/utils/order-returnable-fields"
import useOrdersExpandParam from "../../../domain/orders/details/utils/use-admin-expand-paramter" import useOrdersExpandParam from "../../../domain/orders/details/utils/use-admin-expand-paramter"
import { ExchangeEvent } from "../../../hooks/use-build-timeline" import { ExchangeEvent } from "../../../hooks/use-build-timeline"
import useNotification from "../../../hooks/use-notification" import useNotification from "../../../hooks/use-notification"
@@ -39,21 +38,21 @@ type ExchangeStatusProps = {
} }
const ExchangeStatus: React.FC<ExchangeStatusProps> = ({ event }) => { const ExchangeStatus: React.FC<ExchangeStatusProps> = ({ event }) => {
const divider = <div className="h-11 w-px bg-grey-20" /> const divider = <div className="bg-grey-20 h-11 w-px" />
return ( return (
<div className="inter-small-regular flex items-center gap-x-base"> <div className="inter-small-regular gap-x-base flex items-center">
<div className="flex flex-col gap-y-2xsmall"> <div className="gap-y-2xsmall flex flex-col">
<span className="text-grey-50">Payment:</span> <span className="text-grey-50">Payment:</span>
<PaymentStatus paymentStatus={event.paymentStatus} /> <PaymentStatus paymentStatus={event.paymentStatus} />
</div> </div>
{divider} {divider}
<div className="flex flex-col gap-y-2xsmall"> <div className="gap-y-2xsmall flex flex-col">
<span className="text-grey-50">Return:</span> <span className="text-grey-50">Return:</span>
<ReturnStatus returnStatus={event.returnStatus} /> <ReturnStatus returnStatus={event.returnStatus} />
</div> </div>
{divider} {divider}
<div className="flex flex-col gap-y-2xsmall"> <div className="gap-y-2xsmall flex flex-col">
<span className="text-grey-50">Fulfillment:</span> <span className="text-grey-50">Fulfillment:</span>
<FulfillmentStatus fulfillmentStatus={event.fulfillmentStatus} /> <FulfillmentStatus fulfillmentStatus={event.fulfillmentStatus} />
</div> </div>
@@ -79,7 +78,6 @@ const Exchange: React.FC<ExchangeProps> = ({ event, refetch }) => {
const { orderRelations } = useOrdersExpandParam() const { orderRelations } = useOrdersExpandParam()
const { order } = useAdminOrder(event.orderId, { const { order } = useAdminOrder(event.orderId, {
expand: orderRelations, expand: orderRelations,
fields: orderReturnableFields,
}) })
const notification = useNotification() const notification = useNotification()
@@ -197,7 +195,7 @@ const Exchange: React.FC<ExchangeProps> = ({ event, refetch }) => {
noNotification: event.noNotification, noNotification: event.noNotification,
topNode: getActions(event, actions), topNode: getActions(event, actions),
children: [ children: [
<div className="flex flex-col gap-y-base" key={event.id}> <div className="gap-y-base flex flex-col" key={event.id}>
{event.canceledAt && ( {event.canceledAt && (
<div> <div>
<span className="inter-small-semibold mr-2">Requested on:</span> <span className="inter-small-semibold mr-2">Requested on:</span>
@@ -210,7 +208,7 @@ const Exchange: React.FC<ExchangeProps> = ({ event, refetch }) => {
{!event.canceledAt && paymentLink} {!event.canceledAt && paymentLink}
{returnItems} {returnItems}
{newItems} {newItems}
<div className="flex items-center gap-x-xsmall"> <div className="gap-x-xsmall flex items-center">
{event.returnStatus === "requested" && ( {event.returnStatus === "requested" && (
<Button <Button
variant="secondary" variant="secondary"
@@ -276,7 +274,7 @@ const Exchange: React.FC<ExchangeProps> = ({ event, refetch }) => {
function getNewItems(event: ExchangeEvent) { function getNewItems(event: ExchangeEvent) {
return ( return (
<div className="flex flex-col gap-y-small"> <div className="gap-y-small flex flex-col">
<span className="inter-small-regular text-grey-50">New Items</span> <span className="inter-small-regular text-grey-50">New Items</span>
<div> <div>
{event.newItems.map((i, index) => ( {event.newItems.map((i, index) => (
@@ -294,8 +292,8 @@ function getPaymentLink(
exchangeCartId: string | undefined exchangeCartId: string | undefined
) { ) {
return payable ? ( return payable ? (
<div className="inter-small-regular flex flex-col gap-y-xsmall text-grey-50"> <div className="inter-small-regular gap-y-xsmall text-grey-50 flex flex-col">
<div className="flex items-center gap-x-xsmall"> <div className="gap-x-xsmall flex items-center">
{paymentFormatWarning && <IconTooltip content={paymentFormatWarning} />} {paymentFormatWarning && <IconTooltip content={paymentFormatWarning} />}
<span>Payment link:</span> <span>Payment link:</span>
</div> </div>
@@ -311,7 +309,7 @@ function getPaymentLink(
function getReturnItems(event: ExchangeEvent) { function getReturnItems(event: ExchangeEvent) {
return ( return (
<div className="flex flex-col gap-y-small"> <div className="gap-y-small flex flex-col">
<span className="inter-small-regular text-grey-50">Return Items</span> <span className="inter-small-regular text-grey-50">Return Items</span>
<div> <div>
{event.returnItems {event.returnItems
@@ -5,7 +5,6 @@ import React, { useState } from "react"
import RegisterClaimMenu from "../../../domain/orders/details/claim/register-claim-menu" import RegisterClaimMenu from "../../../domain/orders/details/claim/register-claim-menu"
import ReturnMenu from "../../../domain/orders/details/returns" import ReturnMenu from "../../../domain/orders/details/returns"
import SwapMenu from "../../../domain/orders/details/swap/create" import SwapMenu from "../../../domain/orders/details/swap/create"
import { orderReturnableFields } from "../../../domain/orders/details/utils/order-returnable-fields"
import useOrdersExpandParam from "../../../domain/orders/details/utils/use-admin-expand-paramter" import useOrdersExpandParam from "../../../domain/orders/details/utils/use-admin-expand-paramter"
import { import {
ClaimEvent, ClaimEvent,
@@ -63,7 +62,6 @@ const Timeline: React.FC<TimelineProps> = ({ orderId }) => {
const createNote = useAdminCreateNote() const createNote = useAdminCreateNote()
const { order } = useAdminOrder(orderId, { const { order } = useAdminOrder(orderId, {
expand: orderRelations, expand: orderRelations,
fields: orderReturnableFields,
}) })
const [showRequestReturn, setShowRequestReturn] = useState(false) const [showRequestReturn, setShowRequestReturn] = useState(false)
@@ -112,8 +110,8 @@ const Timeline: React.FC<TimelineProps> = ({ orderId }) => {
return ( return (
<> <>
<div className="h-full w-5/12 rounded-rounded border border-grey-20 bg-grey-0"> <div className="rounded-rounded border-grey-20 bg-grey-0 h-full w-5/12 border">
<div className="border-b border-grey-20 py-large px-xlarge"> <div className="border-grey-20 py-large px-xlarge border-b">
<div className="flex items-center justify-between"> <div className="flex items-center justify-between">
<h3 className="inter-xlarge-semibold">Timeline</h3> <h3 className="inter-xlarge-semibold">Timeline</h3>
<div <div
@@ -2,7 +2,7 @@ import { Order, Return } from "@medusajs/medusa"
import { useMemo } from "react" import { useMemo } from "react"
import { UseFormReturn, useWatch } from "react-hook-form" import { UseFormReturn, useWatch } from "react-hook-form"
import { nestedForm } from "../../../../utils/nested-form" import { nestedForm } from "../../../../utils/nested-form"
import { ReceiveReturnFormType } from "../../details/receive-return/receive-return-menu" import { ReceiveReturnFormType } from "../../details/receive-return"
import RefundAmountForm from "../refund-amount-form" import RefundAmountForm from "../refund-amount-form"
import { SummaryLineItem } from "./summary-line-item" import { SummaryLineItem } from "./summary-line-item"
import { SummaryShippingLine } from "./summary-shipping-line" import { SummaryShippingLine } from "./summary-shipping-line"
@@ -71,11 +71,11 @@ export const ReceiveReturnSummary = ({ form, order, returnRequest }: Props) => {
return ( return (
<div className="inter-base-regular"> <div className="inter-base-regular">
<div className="flex flex-col gap-y-base border-y border-grey-20 py-large"> <div className="gap-y-base border-grey-20 py-large flex flex-col border-y">
{itemToReceive.length > 0 && ( {itemToReceive.length > 0 && (
<div> <div>
<p className="inter-base-semibold mb-small">Receiving</p> <p className="inter-base-semibold mb-small">Receiving</p>
<div className="flex flex-col gap-y-xsmall"> <div className="gap-y-xsmall flex flex-col">
{itemToReceive.map((item, index) => { {itemToReceive.map((item, index) => {
return ( return (
<SummaryLineItem <SummaryLineItem
@@ -102,7 +102,7 @@ export const ReceiveReturnSummary = ({ form, order, returnRequest }: Props) => {
</div> </div>
)} )}
</div> </div>
<div className="flex flex-col gap-y-xsmall pt-large"> <div className="gap-y-xsmall pt-large flex flex-col">
<div <div
className="inter-large-semibold flex items-center justify-between" className="inter-large-semibold flex items-center justify-between"
data-testid="refund-amount-container" data-testid="refund-amount-container"
@@ -12,7 +12,6 @@ import { ItemsToReceiveForm } from "../../components/items-to-receive-form/items
import { RefundAmountFormType } from "../../components/refund-amount-form" import { RefundAmountFormType } from "../../components/refund-amount-form"
import { ReceiveReturnSummary } from "../../components/rma-summaries/receive-return-summary" import { ReceiveReturnSummary } from "../../components/rma-summaries/receive-return-summary"
import { getDefaultReceiveReturnValues } from "../utils/get-default-values" import { getDefaultReceiveReturnValues } from "../utils/get-default-values"
import { orderReturnableFields } from "../utils/order-returnable-fields"
import useOrdersExpandParam from "../utils/use-admin-expand-paramter" import useOrdersExpandParam from "../utils/use-admin-expand-paramter"
type Props = { type Props = {
@@ -30,7 +29,6 @@ export const ReceiveReturnMenu = ({ order, returnRequest, onClose }: Props) => {
const { mutate, isLoading } = useAdminReceiveReturn(returnRequest.id) const { mutate, isLoading } = useAdminReceiveReturn(returnRequest.id)
const { orderRelations } = useOrdersExpandParam() const { orderRelations } = useOrdersExpandParam()
const { refetch } = useAdminOrder(order.id, { const { refetch } = useAdminOrder(order.id, {
fields: orderReturnableFields,
expand: orderRelations, expand: orderRelations,
}) })
@@ -146,7 +144,7 @@ export const ReceiveReturnMenu = ({ order, returnRequest, onClose }: Props) => {
</Modal.Header> </Modal.Header>
<form onSubmit={onSubmit}> <form onSubmit={onSubmit}>
<Modal.Content> <Modal.Content>
<div className="flex flex-col gap-y-large"> <div className="gap-y-large flex flex-col">
<ItemsToReceiveForm <ItemsToReceiveForm
order={order} order={order}
form={nestedForm(form, "receive_items")} form={nestedForm(form, "receive_items")}
@@ -161,7 +159,7 @@ export const ReceiveReturnMenu = ({ order, returnRequest, onClose }: Props) => {
</div> </div>
</Modal.Content> </Modal.Content>
<Modal.Footer> <Modal.Footer>
<div className="flex w-full items-center justify-end gap-x-xsmall"> <div className="gap-x-xsmall flex w-full items-center justify-end">
<Button size="small" variant="secondary"> <Button size="small" variant="secondary">
Cancel Cancel
</Button> </Button>
@@ -4,6 +4,8 @@ export const getAllReturnableItems = (
order: Omit<Order, "beforeInserts">, order: Omit<Order, "beforeInserts">,
isClaim: boolean isClaim: boolean
) => { ) => {
console.log(JSON.stringify(order, null, 2))
let orderItems = order.items.reduce( let orderItems = order.items.reduce(
(map, obj) => (map, obj) =>
map.set(obj.id, { map.set(obj.id, {
@@ -16,8 +18,10 @@ export const getAllReturnableItems = (
if (order.claims && order.claims.length) { if (order.claims && order.claims.length) {
for (const claim of order.claims) { for (const claim of order.claims) {
claim.claim_items = claim.claim_items ?? [] if (claim.return_order?.status !== "canceled") {
claimedItems = [...claimedItems, ...claim.claim_items] claim.claim_items = claim.claim_items ?? []
claimedItems = [...claimedItems, ...claim.claim_items]
}
if ( if (
claim.fulfillment_status === "not_fulfilled" && claim.fulfillment_status === "not_fulfilled" &&
@@ -41,6 +45,10 @@ export const getAllReturnableItems = (
if (!isClaim) { if (!isClaim) {
if (order.swaps && order.swaps.length) { if (order.swaps && order.swaps.length) {
for (const swap of order.swaps) { for (const swap of order.swaps) {
if (swap.fulfillment_status === "not_fulfilled") {
continue
}
orderItems = swap.additional_items.reduce( orderItems = swap.additional_items.reduce(
(map, obj) => (map, obj) =>
map.set(obj.id, { map.set(obj.id, {
@@ -1,4 +0,0 @@
/**
* Fields paramater used to retrieve an order including its returnable items
*/
export const orderReturnableFields = "returnable_items"
@@ -8,13 +8,28 @@ const orderRelations = [
"discounts.rule", "discounts.rule",
"shipping_methods", "shipping_methods",
"payments", "payments",
"items",
"fulfillments", "fulfillments",
"fulfillments.tracking_links", "fulfillments.tracking_links",
"returns", "returns",
"returns.shipping_method",
"returns.shipping_method.tax_lines",
"refunds",
"claims", "claims",
"claims.claim_items",
"claims.claim_items.item",
"claims.fulfillments",
"claims.return_order",
"claims.additional_items",
"claims.additional_items.variant",
"claims.additional_items.variant.product",
"swaps", "swaps",
"swaps.return_order", "swaps.return_order",
"swaps.additional_items", "swaps.additional_items",
"swaps.additional_items.variant",
"swaps.additional_items.variant.product",
"swaps.fulfillments",
"returnable_items",
] ]
const useOrdersExpandParam = () => { const useOrdersExpandParam = () => {
@@ -13,7 +13,7 @@ import {
useAdminOrderEdits, useAdminOrderEdits,
} from "medusa-react" } from "medusa-react"
import { useMemo } from "react" import { useMemo } from "react"
import { orderReturnableFields } from "../domain/orders/details/utils/order-returnable-fields" import useOrdersExpandParam from "../domain/orders/details/utils/use-admin-expand-paramter"
import { useFeatureFlag } from "../providers/feature-flag-provider" import { useFeatureFlag } from "../providers/feature-flag-provider"
export interface TimelineEvent { export interface TimelineEvent {
@@ -157,8 +157,10 @@ export interface NotificationEvent extends TimelineEvent {
} }
export const useBuildTimeline = (orderId: string) => { export const useBuildTimeline = (orderId: string) => {
const { orderRelations } = useOrdersExpandParam()
const { order, refetch } = useAdminOrder(orderId, { const { order, refetch } = useAdminOrder(orderId, {
fields: orderReturnableFields, expand: orderRelations,
}) })
const { order_edits: edits } = useAdminOrderEdits({ order_id: orderId }) const { order_edits: edits } = useAdminOrderEdits({ order_id: orderId })