Skip to content

Commit c16f387

Browse files
authored
fix(admin-ui): Edit allocation update (#3447)
**What** - update the edit-allocation side-bar with the new table layout Fixes CORE-1215
1 parent ad7d7fc commit c16f387

File tree

2 files changed

+114
-23
lines changed

2 files changed

+114
-23
lines changed

.changeset/shy-poems-lie.md

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@medusajs/admin-ui": patch
3+
---
4+
5+
fix(admin-ui): update edit-allocation sidebar

packages/admin-ui/ui/src/domain/orders/details/allocations/edit-allocation-modal.tsx

+109-23
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,21 @@
1-
import {
2-
AllocationLineItem,
3-
AllocationLineItemForm,
4-
} from "./allocate-items-modal"
1+
import { AllocationLineItemForm } from "./allocate-items-modal"
52
import { Controller, useForm, useWatch } from "react-hook-form"
63
import { LineItem, ReservationItemDTO } from "@medusajs/medusa"
74
import {
85
useAdminDeleteReservation,
96
useAdminStockLocations,
107
useAdminUpdateReservation,
8+
useAdminVariantsInventory,
119
} from "medusa-react"
1210
import { useEffect, useMemo } from "react"
1311

1412
import Button from "../../../../components/fundamentals/button"
1513
import CrossIcon from "../../../../components/fundamentals/icons/cross-icon"
1614
import Select from "../../../../components/molecules/select/next-select/select"
1715
import SideModal from "../../../../components/molecules/modal/side-modal"
18-
import { nestedForm } from "../../../../utils/nested-form"
1916
import useNotification from "../../../../hooks/use-notification"
17+
import Thumbnail from "../../../../components/atoms/thumbnail"
18+
import { getFulfillableQuantity } from "../create-fulfillment/item-table"
2019

2120
type EditAllocationLineItemForm = {
2221
location: { label: string; value: string }
@@ -48,6 +47,10 @@ const EditAllocationDrawer = ({
4847

4948
const { stock_locations } = useAdminStockLocations(stockLocationsFilter)
5049

50+
const { variant, isLoading } = useAdminVariantsInventory(
51+
item.variant_id as string
52+
)
53+
5154
const { mutate: updateReservation } = useAdminUpdateReservation(
5255
reservation?.id || ""
5356
)
@@ -126,21 +129,51 @@ const EditAllocationDrawer = ({
126129
)
127130
}
128131

132+
const { availableQuantity, inStockQuantity } = useMemo(() => {
133+
if (isLoading || !selectedLocation?.value || !variant) {
134+
return {}
135+
}
136+
const { inventory } = variant
137+
const locationInventory = inventory[0].location_levels?.find(
138+
(inv) => inv.location_id === selectedLocation?.value
139+
)
140+
if (!locationInventory) {
141+
return {}
142+
}
143+
return {
144+
availableQuantity: locationInventory.available_quantity,
145+
inStockQuantity: locationInventory.stocked_quantity,
146+
}
147+
}, [variant, selectedLocation, isLoading])
148+
149+
// we can adjust up to fulfillable quantity - the quantity reserved in other reservations
150+
const lineItemReservationCapacity =
151+
getFulfillableQuantity(item) -
152+
(totalReservedQuantity - (reservation?.quantity || 0))
153+
154+
const inventoryItemReservationCapacity =
155+
typeof availableQuantity === "number" ? availableQuantity : 0
156+
157+
const maxReservation = Math.min(
158+
lineItemReservationCapacity,
159+
inventoryItemReservationCapacity
160+
)
161+
129162
return (
130163
<SideModal isVisible close={close}>
131164
<form
132165
className="text-grey-90 h-full w-full"
133166
onSubmit={handleSubmit(submit)}
134167
>
135-
<div className="flex h-full flex-col justify-between ">
136-
<div>
168+
<div className="flex h-full flex-col justify-between">
169+
<div className="flex grow flex-col">
137170
<div className="border-grey-20 flex items-center justify-between border-b px-8 py-6">
138171
<h1 className="inter-large-semibold ">Edit allocation</h1>
139172
<Button variant="ghost" className="p-1.5" onClick={close}>
140173
<CrossIcon />
141174
</Button>
142175
</div>
143-
<div className="flex flex-col gap-y-8 px-8 pt-6">
176+
<div className="flex h-full flex-col justify-between gap-y-8 px-8 pb-8 pt-6">
144177
<div>
145178
<h2 className="inter-base-semibold">Location</h2>
146179
<span className="inter-base-regular text-grey-50">
@@ -152,28 +185,81 @@ const EditAllocationDrawer = ({
152185
rules={{ required: true }}
153186
render={({ field: { value, onChange } }) => (
154187
<Select
188+
className="mt-4"
155189
value={value}
156190
onChange={onChange}
157191
options={locationOptions}
158192
/>
159193
)}
160194
/>
195+
<div>
196+
<h2 className="inter-base-semibold mt-8">
197+
Items to Allocate
198+
</h2>
199+
<span className="inter-base-regular text-grey-50">
200+
Select the number of items that you wish to allocate.
201+
</span>
202+
<div className="gap-x-base mt-6 flex w-full">
203+
<div className="min-w-9">
204+
<Thumbnail size="medium" src={item.thumbnail} />
205+
</div>
206+
<div className="text-grey-50 truncate">
207+
<p className="inter-base-semibold text-grey-90 truncate">
208+
{item.title}
209+
</p>
210+
<p className="inter-base-semibold gap-x-2xsmall flex">
211+
<p>{`(${item.variant.sku})`}</p>
212+
<span>&#183;</span>
213+
<span className="inter-base-regular gap-x-2xsmall flex">
214+
{item.variant.options
215+
?.map((option, i) => [
216+
<span key={`${option.id}-${i}`}>
217+
{option.value}
218+
</span>,
219+
<span key={`${option.id}-${i}.dot`}>&#183;</span>,
220+
])
221+
.flat()
222+
.slice(0, -1) ||
223+
item.variant.title ||
224+
"-"}
225+
</span>
226+
</p>
227+
</div>
228+
</div>
229+
230+
<div
231+
className={`
232+
bg-grey-5 text-grey-50 border-grey-20
233+
mt-8
234+
grid border-collapse grid-cols-2 grid-rows-3
235+
[&>*]:border-r [&>*]:border-b [&>*]:py-2
236+
[&>*:nth-child(odd)]:border-l [&>*:nth-child(odd)]:pl-4
237+
[&>*:nth-child(even)]:pr-4 [&>*:nth-child(even)]:text-right
238+
[&>*:nth-child(-n+2)]:border-t`}
239+
>
240+
<div className="rounded-tl-rounded">In stock</div>
241+
<div className="rounded-tr-rounded">
242+
{inStockQuantity ?? "N/A"}
243+
</div>
244+
<div className="">Available</div>
245+
<div className="">{availableQuantity ?? "N/A"}</div>
246+
<div className="rounded-bl-rounded">Allocate</div>
247+
<div className="bg-grey-0 rounded-br-rounded text-grey-80 flex items-center">
248+
<input
249+
className="remove-number-spinner inter-base-regular w-full shrink border-none bg-transparent text-right font-normal outline-none outline-0"
250+
{...form.register("item.quantity", {
251+
valueAsNumber: true,
252+
})}
253+
type="number"
254+
min={0}
255+
max={maxReservation}
256+
/>
257+
<span className="text-grey-50 nowrap whitespace-nowrap pl-2">{` / ${maxReservation} requested`}</span>
258+
</div>
259+
</div>
260+
</div>
161261
</div>
162-
<div>
163-
<h2 className="inter-base-semibold">Items to Allocate</h2>
164-
<span className="inter-base-regular text-grey-50">
165-
Select the number of items that you wish to allocate.
166-
</span>
167-
<AllocationLineItem
168-
form={nestedForm(form, `item` as "item")}
169-
item={item}
170-
compact
171-
locationId={selectedLocation?.value}
172-
reservedQuantity={
173-
totalReservedQuantity - (reservation?.quantity || 0)
174-
}
175-
/>
176-
</div>
262+
177263
<Button
178264
variant="ghost"
179265
className="my-1 w-full border text-rose-50"

0 commit comments

Comments
 (0)