feat(admin-ui): Rename allocation to reservation (#4133)

* rename allocation -> reservation

* add changeset

* edit-reservation modal

* rename
This commit is contained in:
Philip Korsholm authored and GitHub committed 2023-06-05 16:28:29 +02:00
1 parent 572280e1d1
commit 869628bf4c
7 files changed
+92 -83

No files matched your search

+5
View File
@@ -0,0 +1,5 @@
---
"@medusajs/admin-ui": patch
---
feat(admin-ui): rename allocation to reservation
@@ -8,8 +8,8 @@ import {
import Button from "../../fundamentals/button" import Button from "../../fundamentals/button"
import DeletePrompt from "../../organisms/delete-prompt" import DeletePrompt from "../../organisms/delete-prompt"
import EditAllocationDrawer from "../../../domain/orders/details/allocations/edit-allocation-modal"
import EditIcon from "../../fundamentals/icons/edit-icon" import EditIcon from "../../fundamentals/icons/edit-icon"
import EditReservationDrawer from "../../../domain/orders/details/reservation/edit-reservation-modal"
import Fade from "../../atoms/fade-wrapper" import Fade from "../../atoms/fade-wrapper"
import NewReservation from "./new" import NewReservation from "./new"
import { NextSelect } from "../../molecules/select/next-select" import { NextSelect } from "../../molecules/select/next-select"
@@ -340,7 +340,7 @@ const ReservationRow = ({
})} })}
</Table.Row> </Table.Row>
{showEditReservation && ( {showEditReservation && (
<EditAllocationDrawer <EditReservationDrawer
close={() => setShowEditReservation(null)} close={() => setShowEditReservation(null)}
reservation={row.original} reservation={row.original}
/> />
@@ -1,14 +1,15 @@
import React from "react"
import { LineItem } from "@medusajs/medusa"
import { sum } from "lodash"
import { ReservationItemDTO } from "@medusajs/types"
import { useAdminStockLocations, useAdminVariantsInventory } from "medusa-react" import { useAdminStockLocations, useAdminVariantsInventory } from "medusa-react"
import Tooltip from "../../../../components/atoms/tooltip"
import CircleQuarterSolid from "../../../../components/fundamentals/icons/circle-quarter-solid"
import WarningCircleIcon from "../../../../components/fundamentals/icons/warning-circle"
import CheckCircleFillIcon from "../../../../components/fundamentals/icons/check-circle-fill-icon"
import EditAllocationDrawer from "../../details/allocations/edit-allocation-modal"
import Button from "../../../../components/fundamentals/button" import Button from "../../../../components/fundamentals/button"
import CheckCircleFillIcon from "../../../../components/fundamentals/icons/check-circle-fill-icon"
import CircleQuarterSolid from "../../../../components/fundamentals/icons/circle-quarter-solid"
import EditReservationDrawer from "../../details/reservation/edit-reservation-modal"
import { LineItem } from "@medusajs/medusa"
import React from "react"
import { ReservationItemDTO } from "@medusajs/types"
import Tooltip from "../../../../components/atoms/tooltip"
import WarningCircleIcon from "../../../../components/fundamentals/icons/warning-circle"
import { sum } from "lodash"
const ReservationIndicator = ({ const ReservationIndicator = ({
reservations, reservations,
@@ -35,9 +36,9 @@ const ReservationIndicator = ({
const reservationsSum = sum(reservations?.map((r) => r.quantity) || []) const reservationsSum = sum(reservations?.map((r) => r.quantity) || [])
const allocatableSum = lineItem.quantity - (lineItem?.fulfilled_quantity || 0) const reservableSum = lineItem.quantity - (lineItem?.fulfilled_quantity || 0)
const awaitingAllocation = allocatableSum - reservationsSum const awaitingReservation = reservableSum - reservationsSum
if ( if (
isLoading || isLoading ||
@@ -49,19 +50,19 @@ const ReservationIndicator = ({
} }
return ( return (
<div className={awaitingAllocation ? "text-rose-50" : "text-grey-40"}> <div className={awaitingReservation ? "text-rose-50" : "text-grey-40"}>
<Tooltip <Tooltip
content={ content={
<div className="inter-small-regular flex flex-col items-center px-1 pt-1 pb-2"> <div className="inter-small-regular flex flex-col items-center px-1 pt-1 pb-2">
{reservationsSum || awaitingAllocation ? ( {reservationsSum || awaitingReservation ? (
<div className="gap-y-base grid grid-cols-1 divide-y"> <div className="gap-y-base grid grid-cols-1 divide-y">
{!!awaitingAllocation && ( {!!awaitingReservation && (
<span className="flex w-full items-center"> <span className="flex w-full items-center">
{awaitingAllocation} items await allocation {awaitingReservation} items not reserved
</span> </span>
)} )}
{reservations?.map((reservation) => ( {reservations?.map((reservation) => (
<EditAllocationButton <EditReservationButton
key={reservation.id} key={reservation.id}
locationName={locationMap.get(reservation.location_id)} locationName={locationMap.get(reservation.location_id)}
totalReservedQuantity={reservationsSum} totalReservedQuantity={reservationsSum}
@@ -80,7 +81,7 @@ const ReservationIndicator = ({
} }
side="bottom" side="bottom"
> >
{awaitingAllocation ? ( {awaitingReservation ? (
reservationsSum ? ( reservationsSum ? (
<CircleQuarterSolid size={20} /> <CircleQuarterSolid size={20} />
) : ( ) : (
@@ -92,7 +93,7 @@ const ReservationIndicator = ({
</Tooltip> </Tooltip>
{reservation && ( {reservation && (
<EditAllocationDrawer <EditReservationDrawer
totalReservedQuantity={reservationsSum} totalReservedQuantity={reservationsSum}
close={() => setReservation(null)} close={() => setReservation(null)}
reservation={reservation} reservation={reservation}
@@ -103,7 +104,7 @@ const ReservationIndicator = ({
) )
} }
const EditAllocationButton = ({ const EditReservationButton = ({
reservation, reservation,
locationName, locationName,
onClick, onClick,
@@ -123,7 +124,7 @@ const EditAllocationButton = ({
size="small" size="small"
className="mt-2 w-full border" className="mt-2 w-full border"
> >
Edit Allocation Edit reservation
</Button> </Button>
</div> </div>
) )
@@ -1,24 +1,25 @@
import React, { useMemo } from "react"
import { sum } from "lodash"
import { import {
AdminGetVariantsVariantInventoryRes, AdminGetVariantsVariantInventoryRes,
DraftOrder, DraftOrder,
VariantInventory, VariantInventory,
} from "@medusajs/medusa" } from "@medusajs/medusa"
import Badge from "../../../../components/fundamentals/badge" import React, { useMemo } from "react"
import ImagePlaceholder from "../../../../components/fundamentals/image-placeholder"
import BodyCard from "../../../../components/organisms/body-card"
import { formatAmountWithSymbol } from "../../../../utils/prices"
import { DisplayTotal } from "../templates"
import { ActionType } from "../../../../components/molecules/actionables"
import { useFeatureFlag } from "../../../../providers/feature-flag-provider"
import useToggleState from "../../../../hooks/use-toggle-state"
import { useAdminReservations, useMedusa } from "medusa-react" import { useAdminReservations, useMedusa } from "medusa-react"
import { ReservationItemDTO } from "@medusajs/types"
import { ActionType } from "../../../../components/molecules/actionables"
import Badge from "../../../../components/fundamentals/badge"
import BodyCard from "../../../../components/organisms/body-card"
import { DisplayTotal } from "../templates"
import ImagePlaceholder from "../../../../components/fundamentals/image-placeholder"
import ReservationIndicator from "../../components/reservation-indicator/reservation-indicator" import ReservationIndicator from "../../components/reservation-indicator/reservation-indicator"
import AllocateItemsModal from "../allocations/allocate-items-modal" import { ReservationItemDTO } from "@medusajs/types"
import ReserveItemsModal from "../reservation/reserve-items-modal"
import { Response } from "@medusajs/medusa-js" import { Response } from "@medusajs/medusa-js"
import StatusIndicator from "../../../../components/fundamentals/status-indicator" import StatusIndicator from "../../../../components/fundamentals/status-indicator"
import { formatAmountWithSymbol } from "../../../../utils/prices"
import { sum } from "lodash"
import { useFeatureFlag } from "../../../../providers/feature-flag-provider"
import useToggleState from "../../../../hooks/use-toggle-state"
type DraftSummaryCardProps = { type DraftSummaryCardProps = {
order: DraftOrder order: DraftOrder
@@ -102,9 +103,9 @@ const DraftSummaryCard: React.FC<DraftSummaryCardProps> = ({ order }) => {
}, [reservations, inventoryEnabled]) }, [reservations, inventoryEnabled])
const { const {
state: allocationModalIsOpen, state: reservationModalIsOpen,
open: showAllocationModal, open: showReservationModal,
close: closeAllocationModal, close: closeReservationModal,
} = useToggleState() } = useToggleState()
const allItemsReserved = useMemo(() => { const allItemsReserved = useMemo(() => {
@@ -132,11 +133,11 @@ const DraftSummaryCard: React.FC<DraftSummaryCardProps> = ({ order }) => {
if (inventoryEnabled && !allItemsReserved) { if (inventoryEnabled && !allItemsReserved) {
actionables.push({ actionables.push({
label: "Allocate", label: "Allocate",
onClick: showAllocationModal, onClick: showReservationModal,
}) })
} }
return actionables return actionables
}, [inventoryEnabled, showAllocationModal, allItemsReserved]) }, [inventoryEnabled, showReservationModal, allItemsReserved])
return ( return (
<BodyCard <BodyCard
@@ -146,9 +147,9 @@ const DraftSummaryCard: React.FC<DraftSummaryCardProps> = ({ order }) => {
isFeatureEnabled("inventoryService") && isFeatureEnabled("inventoryService") &&
Array.isArray(reservations) && ( Array.isArray(reservations) && (
<StatusIndicator <StatusIndicator
onClick={allItemsReserved ? undefined : showAllocationModal} onClick={allItemsReserved ? undefined : showReservationModal}
variant={allItemsReserved ? "success" : "danger"} variant={allItemsReserved ? "success" : "danger"}
title={allItemsReserved ? "Allocated" : "Awaits allocation"} title={allItemsReserved ? "Allocated" : "Not fully allocated"}
className="rounded-rounded border px-3 py-1.5" className="rounded-rounded border px-3 py-1.5"
/> />
) )
@@ -258,11 +259,11 @@ const DraftSummaryCard: React.FC<DraftSummaryCardProps> = ({ order }) => {
totalTitle={`Total`} totalTitle={`Total`}
/> />
</div> </div>
{allocationModalIsOpen && ( {reservationModalIsOpen && (
<AllocateItemsModal <ReserveItemsModal
reservationItemsMap={reservationItemsMap} reservationItemsMap={reservationItemsMap}
items={cart.items} items={cart.items}
close={closeAllocationModal} close={closeReservationModal}
/> />
)} )}
</BodyCard> </BodyCard>
@@ -7,13 +7,13 @@ import { DisplayTotal, PaymentDetails } from "../templates"
import React, { useContext, useMemo } from "react" import React, { useContext, useMemo } from "react"
import { ActionType } from "../../../../components/molecules/actionables" import { ActionType } from "../../../../components/molecules/actionables"
import AllocateItemsModal from "../allocations/allocate-items-modal"
import Badge from "../../../../components/fundamentals/badge" import Badge from "../../../../components/fundamentals/badge"
import BodyCard from "../../../../components/organisms/body-card" import BodyCard from "../../../../components/organisms/body-card"
import CopyToClipboard from "../../../../components/atoms/copy-to-clipboard" import CopyToClipboard from "../../../../components/atoms/copy-to-clipboard"
import { OrderEditContext } from "../../edit/context" import { OrderEditContext } from "../../edit/context"
import OrderLine from "../order-line" import OrderLine from "../order-line"
import { ReservationItemDTO } from "@medusajs/types" import { ReservationItemDTO } from "@medusajs/types"
import ReserveItemsModal from "../reservation/reserve-items-modal"
import { Response } from "@medusajs/medusa-js" import { Response } from "@medusajs/medusa-js"
import StatusIndicator from "../../../../components/fundamentals/status-indicator" import StatusIndicator from "../../../../components/fundamentals/status-indicator"
import { sum } from "lodash" import { sum } from "lodash"
@@ -28,9 +28,9 @@ type SummaryCardProps = {
const SummaryCard: React.FC<SummaryCardProps> = ({ order, reservations }) => { const SummaryCard: React.FC<SummaryCardProps> = ({ order, reservations }) => {
const { const {
state: allocationModalIsOpen, state: reservationModalIsOpen,
open: showAllocationModal, open: showReservationModal,
close: closeAllocationModal, close: closeReservationModal,
} = useToggleState() } = useToggleState()
const { showModal } = useContext(OrderEditContext) const { showModal } = useContext(OrderEditContext)
@@ -158,11 +158,11 @@ const SummaryCard: React.FC<SummaryCardProps> = ({ order, reservations }) => {
if (isFeatureEnabled("inventoryService") && !allItemsReserved) { if (isFeatureEnabled("inventoryService") && !allItemsReserved) {
actionables.push({ actionables.push({
label: "Allocate", label: "Allocate",
onClick: showAllocationModal, onClick: showReservationModal,
}) })
} }
return actionables return actionables
}, [showModal, isFeatureEnabled, showAllocationModal, allItemsReserved]) }, [showModal, isFeatureEnabled, showReservationModal, allItemsReserved])
const isAllocatable = !["canceled", "archived"].includes(order.status) const isAllocatable = !["canceled", "archived"].includes(order.status)
@@ -177,13 +177,13 @@ const SummaryCard: React.FC<SummaryCardProps> = ({ order, reservations }) => {
onClick={ onClick={
allItemsReserved || !isAllocatable allItemsReserved || !isAllocatable
? undefined ? undefined
: showAllocationModal : showReservationModal
} }
variant={allItemsReserved || !isAllocatable ? "success" : "danger"} variant={allItemsReserved || !isAllocatable ? "success" : "danger"}
title={ title={
allItemsReserved || !isAllocatable allItemsReserved || !isAllocatable
? "Allocated" ? "Allocated"
: "Awaits allocation" : "Not fully allocated"
} }
className="rounded-rounded border px-3 py-1.5" className="rounded-rounded border px-3 py-1.5"
/> />
@@ -269,11 +269,11 @@ const SummaryCard: React.FC<SummaryCardProps> = ({ order, reservations }) => {
currency={order.currency_code} currency={order.currency_code}
/> />
</div> </div>
{allocationModalIsOpen && ( {reservationModalIsOpen && (
<AllocateItemsModal <ReserveItemsModal
reservationItemsMap={reservationItemsMap} reservationItemsMap={reservationItemsMap}
items={order.items} items={order.items}
close={closeAllocationModal} close={closeReservationModal}
/> />
)} )}
</BodyCard> </BodyCard>
@@ -17,11 +17,11 @@ import {
} from "medusa-react" } from "medusa-react"
import { useEffect, useMemo } from "react" import { useEffect, useMemo } from "react"
import { AllocationLineItemForm } from "./allocate-items-modal"
import Button from "../../../../components/fundamentals/button" import Button from "../../../../components/fundamentals/button"
import CrossIcon from "../../../../components/fundamentals/icons/cross-icon" import CrossIcon from "../../../../components/fundamentals/icons/cross-icon"
import InputField from "../../../../components/molecules/input" import InputField from "../../../../components/molecules/input"
import { LineItem } from "@medusajs/medusa" import { LineItem } from "@medusajs/medusa"
import { ReserveLineItemForm } from "./reserve-items-modal"
import Select from "../../../../components/molecules/select/next-select/select" import Select from "../../../../components/molecules/select/next-select/select"
import SideModal from "../../../../components/molecules/modal/side-modal" import SideModal from "../../../../components/molecules/modal/side-modal"
import Thumbnail from "../../../../components/atoms/thumbnail" import Thumbnail from "../../../../components/atoms/thumbnail"
@@ -30,13 +30,13 @@ import { nestedForm } from "../../../../utils/nested-form"
import useNotification from "../../../../hooks/use-notification" import useNotification from "../../../../hooks/use-notification"
import useToggleState from "../../../../hooks/use-toggle-state" import useToggleState from "../../../../hooks/use-toggle-state"
type EditAllocationLineItemForm = { type EditReservationLineItemForm = {
location: { label: string; value: string } location: { label: string; value: string }
item: AllocationLineItemForm item: ReserveLineItemForm
metadata: MetadataFormType metadata: MetadataFormType
} }
const EditAllocationDrawer = ({ const EditReservationDrawer = ({
close, close,
reservation, reservation,
item, item,
@@ -47,7 +47,7 @@ const EditAllocationDrawer = ({
item?: LineItem item?: LineItem
totalReservedQuantity?: number totalReservedQuantity?: number
}) => { }) => {
const form = useForm<EditAllocationLineItemForm>({ const form = useForm<EditReservationLineItemForm>({
defaultValues: { defaultValues: {
item: { item: {
description: reservation.description, description: reservation.description,
@@ -92,14 +92,14 @@ const EditAllocationDrawer = ({
deleteReservation(undefined, { deleteReservation(undefined, {
onSuccess: () => { onSuccess: () => {
notification( notification(
"Allocation was deleted", "Reservation was deleted",
"The allocated items have been released.", "The allocated items have been released.",
"success" "success"
) )
close() close()
}, },
onError: () => { onError: () => {
notification("Error", "Failed to delete the allocation ", "error") notification("Error", "Failed to delete the reservation ", "error")
}, },
}) })
} }
@@ -130,7 +130,7 @@ const EditAllocationDrawer = ({
} }
}, [reservation, setValue]) }, [reservation, setValue])
const submit = (data: EditAllocationLineItemForm) => { const submit = (data: EditReservationLineItemForm) => {
if (!data.item.quantity) { if (!data.item.quantity) {
return handleDelete() return handleDelete()
} }
@@ -139,20 +139,22 @@ const EditAllocationDrawer = ({
{ {
quantity: data.item.quantity, quantity: data.item.quantity,
location_id: data.location.value, location_id: data.location.value,
description: data.item.description, description: data.item.description || undefined,
metadata: hasMetadata ? getSubmittableMetadata(data.metadata) : null, metadata: hasMetadata
? getSubmittableMetadata(data.metadata)
: undefined,
}, },
{ {
onSuccess: () => { onSuccess: () => {
notification( notification(
"Allocation was updated", "Reservation was updated",
"The allocation change was saved.", "The reservation change was saved.",
"success" "success"
) )
close() close()
}, },
onError: () => { onError: () => {
notification("Errors", "Failed to update allocation", "error") notification("Errors", "Failed to update reservation", "error")
}, },
} }
) )
@@ -206,7 +208,7 @@ const EditAllocationDrawer = ({
> >
<div className="flex h-full flex-col justify-between"> <div className="flex h-full flex-col justify-between">
<div className="border-grey-20 flex items-center justify-between border-b px-8 py-6"> <div className="border-grey-20 flex items-center justify-between border-b px-8 py-6">
<h1 className="inter-large-semibold ">Edit allocation</h1> <h1 className="inter-large-semibold ">Edit Reservation</h1>
<Button <Button
variant="ghost" variant="ghost"
className="p-1.5" className="p-1.5"
@@ -326,7 +328,7 @@ const EditAllocationDrawer = ({
onClick={handleDelete} onClick={handleDelete}
type="button" type="button"
> >
Delete allocation Delete reservation
</Button> </Button>
</div> </div>
</div> </div>
@@ -349,4 +351,4 @@ const EditAllocationDrawer = ({
) )
} }
export default EditAllocationDrawer export default EditReservationDrawer
@@ -22,18 +22,18 @@ import { getFulfillableQuantity } from "../create-fulfillment/item-table"
import { sum } from "lodash" import { sum } from "lodash"
import useNotification from "../../../../hooks/use-notification" import useNotification from "../../../../hooks/use-notification"
type AllocationModalFormData = { type ReserveModalFormData = {
location?: { label: string; value: string } location?: { label: string; value: string }
items: AllocationLineItemForm[] items: ReserveLineItemForm[]
} }
type AllocateItemsModalProps = { type ReserveItemsModalProps = {
items: LineItem[] items: LineItem[]
reservationItemsMap: Record<string, ReservationItemDTO[]> reservationItemsMap: Record<string, ReservationItemDTO[]>
close: () => void close: () => void
} }
const AllocateItemsModal: React.FC<AllocateItemsModalProps> = ({ const ReserveItemsModal: React.FC<ReserveItemsModalProps> = ({
items, items,
close, close,
reservationItemsMap, reservationItemsMap,
@@ -42,7 +42,7 @@ const AllocateItemsModal: React.FC<AllocateItemsModalProps> = ({
const { client: medusaClient } = useMedusa() const { client: medusaClient } = useMedusa()
const notification = useNotification() const notification = useNotification()
const form = useForm<AllocationModalFormData>({ const form = useForm<ReserveModalFormData>({
defaultValues: { defaultValues: {
items: [], items: [],
}, },
@@ -64,7 +64,7 @@ const AllocateItemsModal: React.FC<AllocateItemsModalProps> = ({
})) }))
}, [stock_locations]) }, [stock_locations])
const onSubmit = async (data: AllocationModalFormData) => { const onSubmit = async (data: ReserveModalFormData) => {
if (!data.location?.value) { if (!data.location?.value) {
return return
} }
@@ -130,7 +130,7 @@ const AllocateItemsModal: React.FC<AllocateItemsModalProps> = ({
Cancel Cancel
</Button> </Button>
<Button size="small" variant="primary" type="submit"> <Button size="small" variant="primary" type="submit">
Save allocation Save reservation
</Button> </Button>
</div> </div>
</div> </div>
@@ -178,7 +178,7 @@ const AllocateItemsModal: React.FC<AllocateItemsModalProps> = ({
</p> </p>
{items?.map((item, i) => { {items?.map((item, i) => {
return ( return (
<AllocationLineItem <ReservationLineItem
form={nestedForm(form, `items.${i}` as "items.0")} form={nestedForm(form, `items.${i}` as "items.0")}
item={item} item={item}
key={i} key={i}
@@ -201,15 +201,15 @@ const AllocateItemsModal: React.FC<AllocateItemsModalProps> = ({
) )
} }
export type AllocationLineItemForm = { export type ReserveLineItemForm = {
inventory_item_id: string inventory_item_id: string
line_item_id: string line_item_id: string
quantity: number quantity: number
description?: string | null description?: string | null
} }
export const AllocationLineItem: React.FC<{ export const ReservationLineItem: React.FC<{
form: NestedForm<AllocationLineItemForm> form: NestedForm<ReserveLineItemForm>
item: LineItem item: LineItem
locationId?: string locationId?: string
reservedQuantity?: number reservedQuantity?: number
@@ -321,4 +321,4 @@ export const AllocationLineItem: React.FC<{
) )
} }
export default AllocateItemsModal export default ReserveItemsModal