Skip to content

Commit

Permalink
feat(dashboard,icons,types,js-sdk): add providers to location UI (#8328)
Browse files Browse the repository at this point in the history
  • Loading branch information
riqwan authored Jul 30, 2024
1 parent b539c6d commit c976361
Show file tree
Hide file tree
Showing 22 changed files with 609 additions and 96 deletions.
26 changes: 26 additions & 0 deletions packages/admin-next/dashboard/src/hooks/api/stock-locations.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import { HttpTypes } from "@medusajs/types"
import { sdk } from "../../lib/client"
import { queryClient } from "../../lib/query-client"
import { queryKeysFactory } from "../../lib/query-key-factory"
import { fulfillmentProvidersQueryKeys } from "./fulfillment-providers"

const STOCK_LOCATIONS_QUERY_KEY = "stock_locations" as const
export const stockLocationsQueryKeys = queryKeysFactory(
Expand Down Expand Up @@ -175,3 +176,28 @@ export const useCreateStockLocationFulfillmentSet = (
...options,
})
}

export const useUpdateStockLocationFulfillmentProviders = (
id: string,
options?: UseMutationOptions<
HttpTypes.AdminStockLocationResponse,
FetchError,
HttpTypes.AdminBatchLink
>
) => {
return useMutation({
mutationFn: (payload) =>
sdk.admin.stockLocation.updateFulfillmentProviders(id, payload),
onSuccess: async (data, variables, context) => {
await queryClient.invalidateQueries({
queryKey: stockLocationsQueryKeys.details(),
})
await queryClient.invalidateQueries({
queryKey: fulfillmentProvidersQueryKeys.all,
})

options?.onSuccess?.(data, variables, context)
},
...options,
})
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { HttpTypes } from "@medusajs/types"
import { createColumnHelper } from "@tanstack/react-table"
import { useMemo } from "react"
import { useTranslation } from "react-i18next"
import {
TextCell,
TextHeader,
} from "../../../components/table/table-cells/common/text-cell"
import { formatProvider } from "../../../lib/format-provider"

const columnHelper = createColumnHelper<HttpTypes.AdminFulfillmentProvider>()

export const useFulfillmentProviderTableColumns = () => {
const { t } = useTranslation()

return useMemo(
() => [
columnHelper.accessor("id", {
header: () => <TextHeader text={"Provider"} />,
cell: ({ getValue }) => <TextCell text={formatProvider(getValue())} />,
}),
],
[t]
)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import { HttpTypes } from "@medusajs/types"
import { useQueryParams } from "../../use-query-params"

type UseFulfillmentProviderTableQueryProps = {
prefix?: string
pageSize?: number
}

export const useFulfillmentProvidersTableQuery = ({
prefix,
pageSize = 20,
}: UseFulfillmentProviderTableQueryProps) => {
const queryObject = useQueryParams(
["offset", "q", "stock_location_id"],
prefix
)

const { offset, q, stock_location_id } = queryObject

const searchParams: HttpTypes.AdminFulfillmentProviderListParams = {
limit: pageSize,
offset: offset ? Number(offset) : 0,
stock_location_id,
q,
}

return {
searchParams,
raw: queryObject,
}
}
9 changes: 9 additions & 0 deletions packages/admin-next/dashboard/src/i18n/translations/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -1020,6 +1020,15 @@
"delete": {
"confirmation": "You are about to delete the stock location {{name}}. This action cannot be undone."
},
"fulfillmentProviders": {
"header": "Fulfillment Providers",
"shippingOptionsTooltip": "This dropdown will only consist of providers enabled for this location. Add them to the location if the dropdown is disabled.",
"label": "Connected fulfillment providers",
"connectedTo": "Connected to {{count}} of {{total}} fulfillment providers",
"noProviders": "This Stock Location is not connected to any fulfillment providers.",
"action": "Connect Providers",
"successToast": "Fulfillment providers for stock location were successfully updated."
},
"fulfillmentSets": {
"pickup": {
"header": "Pickup"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -871,6 +871,13 @@ export const RouteMap: RouteObject[] = [
lazy: () =>
import("../../routes/locations/location-sales-channels"),
},
{
path: "fulfillment-providers",
lazy: () =>
import(
"../../routes/locations/location-fulfillment-providers"
),
},
{
path: "fulfillment-set/:fset_id",
children: [
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from "./location-fulfillment-providers-section"
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
import { HandTruck, PencilSquare } from "@medusajs/icons"
import { HttpTypes } from "@medusajs/types"
import { Container, Heading } from "@medusajs/ui"
import { useTranslation } from "react-i18next"

import { ActionMenu } from "../../../../../components/common/action-menu"
import { NoRecords } from "../../../../../components/common/empty-table-content"
import { IconAvatar } from "../../../../../components/common/icon-avatar"
import { useFulfillmentProviders } from "../../../../../hooks/api"
import { formatProvider } from "../../../../../lib/format-provider"

type LocationsFulfillmentProvidersSectionProps = {
location: HttpTypes.AdminStockLocation
}

function LocationsFulfillmentProvidersSection({
location,
}: LocationsFulfillmentProvidersSectionProps) {
const { t } = useTranslation()
const { fulfillment_providers } = useFulfillmentProviders({
stock_location_id: location.id,
fields: "id",
})

return (
<Container className="flex flex-col px-6 py-4">
<div className="flex items-center justify-between">
<Heading level="h2">
{t("stockLocations.fulfillmentProviders.header")}
</Heading>

<ActionMenu
groups={[
{
actions: [
{
label: t("actions.edit"),
to: "fulfillment-providers",
icon: <PencilSquare />,
},
],
},
]}
/>
</div>

{fulfillment_providers?.length ? (
<div className="flex flex-col gap-y-4 pt-4">
<div className="grid grid-cols-[28px_1fr] items-center gap-x-3 gap-y-3">
{fulfillment_providers?.map((fulfillmentProvider) => {
return (
<>
<IconAvatar>
<HandTruck className="text-ui-fg-subtle" />
</IconAvatar>

<div className="txt-compact-small">
{formatProvider(fulfillmentProvider.id)}
</div>
</>
)
})}
</div>
</div>
) : (
<NoRecords
className="h-fit pb-2 pt-6 text-center"
action={{
label: t("stockLocations.fulfillmentProviders.action"),
to: "fulfillment-providers",
}}
message={t("stockLocations.fulfillmentProviders.noProviders")}
/>
)}
</Container>
)
}

export default LocationsFulfillmentProvidersSection
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
export const detailsFields =
"name,*sales_channels,*address,fulfillment_sets.type,fulfillment_sets.name,*fulfillment_sets.service_zones.geo_zones,*fulfillment_sets.service_zones,*fulfillment_sets.service_zones.shipping_options,*fulfillment_sets.service_zones.shipping_options.rules,*fulfillment_sets.service_zones.shipping_options.shipping_profile"
"name,*sales_channels,*address,fulfillment_sets.type,fulfillment_sets.name,*fulfillment_sets.service_zones.geo_zones,*fulfillment_sets.service_zones,*fulfillment_sets.service_zones.shipping_options,*fulfillment_sets.service_zones.shipping_options.rules,*fulfillment_sets.service_zones.shipping_options.shipping_profile,*fulfillment_providers"
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import after from "virtual:medusa/widgets/location/details/after"
import before from "virtual:medusa/widgets/location/details/before"
import sideAfter from "virtual:medusa/widgets/location/details/side/after"
import sideBefore from "virtual:medusa/widgets/location/details/side/before"
import LocationsFulfillmentProvidersSection from "./components/location-fulfillment-providers-section/location-fulfillment-providers-section"
import { detailsFields } from "./const"

export const LocationDetail = () => {
Expand All @@ -23,15 +24,7 @@ export const LocationDetail = () => {
isPending: isLoading,
isError,
error,
} = useStockLocation(
location_id!,
{
fields: detailsFields,
},
{
initialData,
}
)
} = useStockLocation(location_id!, { fields: detailsFields }, { initialData })

// TODO: Move to loading.tsx and set as Suspense fallback for the route
if (isLoading || !location) {
Expand Down Expand Up @@ -73,7 +66,10 @@ export const LocationDetail = () => {
</div>
)
})}

<LocationsSalesChannelsSection location={location} />
<LocationsFulfillmentProvidersSection location={location} />

{sideAfter.widgets.map((w, i) => {
return (
<div key={i}>
Expand Down
Loading

0 comments on commit c976361

Please sign in to comment.