fix: Several fixes based on preview testing (#7906)

* fix: Add searchable properties on currency

* fix: Format product type dates in table

* fix: Preserve line whitespace in section row

* fix: Continue through tabs on Enter in create product form

* fix: Pagination in variant prices section

* fix: Add missing inventory edit item translation

* fix: Use the correct options URL for editing

* fix: Correctly get the variant title in inventory item details

* fix: Completely remove variant titles section in inventory item
This commit is contained in:
Stevche Radevski
2024-07-02 14:56:34 +02:00
committed by GitHub
parent ef5f5363a1
commit 8244fe03b7
8 changed files with 47 additions and 41 deletions
@@ -24,7 +24,11 @@ export const SectionRow = ({ title, value, actions }: SectionRowProps) => {
</Text> </Text>
{isValueString ? ( {isValueString ? (
<Text size="small" leading="compact" className="text-pretty"> <Text
size="small"
leading="compact"
className="whitespace-pre-line text-pretty"
>
{value ?? "-"} {value ?? "-"}
</Text> </Text>
) : ( ) : (
@@ -502,6 +502,7 @@
"associatedVariants": "Associated variants", "associatedVariants": "Associated variants",
"manageLocations": "Manage locations", "manageLocations": "Manage locations",
"deleteWarning": "You are about to delete an inventory item. This action cannot be undone.", "deleteWarning": "You are about to delete an inventory item. This action cannot be undone.",
"editItemDetails": "Edit item details",
"create": { "create": {
"title": "Add item", "title": "Add item",
"details": "Details", "details": "Details",
@@ -5,26 +5,14 @@ import { InventoryItemRes } from "../../../../types/api-responses"
import { PencilSquare } from "@medusajs/icons" import { PencilSquare } from "@medusajs/icons"
import { SectionRow } from "../../../../components/common/section" import { SectionRow } from "../../../../components/common/section"
import { useTranslation } from "react-i18next" import { useTranslation } from "react-i18next"
import { HttpTypes } from "@medusajs/types"
type InventoryItemGeneralSectionProps = { type InventoryItemGeneralSectionProps = {
inventoryItem: InventoryItemRes["inventory_item"] & { inventoryItem: InventoryItemRes["inventory_item"]
variant: HttpTypes.AdminProductVariant | HttpTypes.AdminProductVariant[]
}
} }
export const InventoryItemGeneralSection = ({ export const InventoryItemGeneralSection = ({
inventoryItem, inventoryItem,
}: InventoryItemGeneralSectionProps) => { }: InventoryItemGeneralSectionProps) => {
const { t } = useTranslation() const { t } = useTranslation()
const variantArray = inventoryItem.variant
? Array.isArray(inventoryItem.variant)
? inventoryItem.variant
: [inventoryItem.variant]
: []
const variantTitles = variantArray.map((variant) => variant.title)
return ( return (
<Container className="divide-y p-0"> <Container className="divide-y p-0">
<div className="flex items-center justify-between px-6 py-4"> <div className="flex items-center justify-between px-6 py-4">
@@ -44,10 +32,6 @@ export const InventoryItemGeneralSection = ({
/> />
</div> </div>
<SectionRow title={t("fields.sku")} value={inventoryItem.sku ?? "-"} /> <SectionRow title={t("fields.sku")} value={inventoryItem.sku ?? "-"} />
<SectionRow
title={t("inventory.associatedVariants")}
value={variantTitles?.length ? variantTitles.join(", ") : "-"}
/>
<SectionRow <SectionRow
title={t("fields.inStock")} title={t("fields.inStock")}
value={getQuantityFormat( value={getQuantityFormat(
@@ -3,6 +3,7 @@ import { createColumnHelper } from "@tanstack/react-table"
import { useMemo } from "react" import { useMemo } from "react"
import { useTranslation } from "react-i18next" import { useTranslation } from "react-i18next"
import { ProductTypeRowActions } from "./product-table-row-actions" import { ProductTypeRowActions } from "./product-table-row-actions"
import { DateCell } from "../../../../../components/table/table-cells/common/date-cell"
const columnHelper = createColumnHelper<HttpTypes.AdminProductType>() const columnHelper = createColumnHelper<HttpTypes.AdminProductType>()
@@ -17,11 +18,18 @@ export const useProductTypeTableColumns = () => {
}), }),
columnHelper.accessor("created_at", { columnHelper.accessor("created_at", {
header: () => t("fields.createdAt"), header: () => t("fields.createdAt"),
cell: ({ getValue }) => getValue(),
cell: ({ getValue }) => {
const date = new Date(getValue())
return <DateCell date={date} />
},
}), }),
columnHelper.accessor("updated_at", { columnHelper.accessor("updated_at", {
header: () => t("fields.updatedAt"), header: () => t("fields.updatedAt"),
cell: ({ getValue }) => getValue(), cell: ({ getValue }) => {
const date = new Date(getValue())
return <DateCell date={date} />
},
}), }),
columnHelper.display({ columnHelper.display({
id: "actions", id: "actions",
@@ -15,19 +15,16 @@ type VariantPricesSectionProps = {
export function VariantPricesSection({ variant }: VariantPricesSectionProps) { export function VariantPricesSection({ variant }: VariantPricesSectionProps) {
const { t } = useTranslation() const { t } = useTranslation()
const prices = variant.prices const prices = variant.prices
.filter((p) => !Object.keys(p.rules || {}).length) // display just currency prices .filter((p) => !Object.keys(p.rules || {}).length) // display just currency prices
.sort((p1, p2) => p1.currency_code?.localeCompare(p2.currency_code)) .sort((p1, p2) => p1.currency_code?.localeCompare(p2.currency_code))
const [current, setCurrent] = useState(Math.min(prices.length, 3))
const hasPrices = !!prices.length const hasPrices = !!prices.length
const [pageSize, setPageSize] = useState(3)
const displayPrices = prices.slice(0, current) const displayPrices = prices.slice(0, pageSize)
const onShowMore = () => { const onShowMore = () => {
setCurrent(Math.min(current + 3, prices.length)) setPageSize(pageSize + 3)
} }
return ( return (
@@ -67,12 +64,12 @@ export function VariantPricesSection({ variant }: VariantPricesSectionProps) {
<span className="font-medium"> <span className="font-medium">
{t("products.variant.pricesPagination", { {t("products.variant.pricesPagination", {
total: prices.length, total: prices.length,
current, current: Math.min(pageSize, prices.length),
})} })}
</span> </span>
<Button <Button
onClick={onShowMore} onClick={onShowMore}
disabled={current >= prices.length} disabled={pageSize >= prices.length}
className="-mr-3 text-blue-500" className="-mr-3 text-blue-500"
variant="transparent" variant="transparent"
> >
@@ -93,16 +93,11 @@ export const ProductCreateForm = ({
const handleSubmit = form.handleSubmit( const handleSubmit = form.handleSubmit(
async (values, e) => { async (values, e) => {
if (!(e?.nativeEvent instanceof SubmitEvent)) { let isDraftSubmission = false
return if (e?.nativeEvent instanceof SubmitEvent) {
const submitter = e?.nativeEvent?.submitter as HTMLButtonElement
isDraftSubmission = submitter.dataset.name === SAVE_DRAFT_BUTTON
} }
const submitter = e?.nativeEvent?.submitter as HTMLButtonElement
if (!(submitter instanceof HTMLButtonElement)) {
return
}
const isDraftSubmission = submitter.dataset.name === SAVE_DRAFT_BUTTON
const media = values.media || [] const media = values.media || []
const payload = { ...values, media: undefined } const payload = { ...values, media: undefined }
@@ -219,7 +214,24 @@ export const ProductCreateForm = ({
return ( return (
<RouteFocusModal> <RouteFocusModal>
<RouteFocusModal.Form form={form}> <RouteFocusModal.Form form={form}>
<form onSubmit={handleSubmit} className="flex h-full flex-col"> <form
onKeyDown={(e) => {
// We want to continue to the next tab on enter instead of saving as draft immediately
if (e.key === "Enter") {
if (tab !== Tab.VARIANTS) {
e.preventDefault()
e.stopPropagation()
onNext(tab)
} else {
e.preventDefault()
e.stopPropagation()
handleSubmit(e)
}
}
}}
onSubmit={handleSubmit}
className="flex h-full flex-col"
>
<ProgressTabs <ProgressTabs
value={tab} value={tab}
onValueChange={async (tab) => { onValueChange={async (tab) => {
+1 -1
View File
@@ -223,7 +223,7 @@ export class Product {
headers?: ClientHeaders headers?: ClientHeaders
) { ) {
return await this.client.fetch<HttpTypes.AdminProductResponse>( return await this.client.fetch<HttpTypes.AdminProductResponse>(
`/admin/products/${productId}/variants/${id}`, `/admin/products/${productId}/options/${id}`,
{ {
method: "POST", method: "POST",
headers, headers,
@@ -1,10 +1,10 @@
import { model } from "@medusajs/utils" import { model } from "@medusajs/utils"
export default model.define("currency", { export default model.define("currency", {
code: model.text().primaryKey(), code: model.text().primaryKey().searchable(),
symbol: model.text(), symbol: model.text(),
symbol_native: model.text(), symbol_native: model.text(),
name: model.text(), name: model.text().searchable(),
decimal_digits: model.number().default(0), decimal_digits: model.number().default(0),
rounding: model.bigNumber().default(0), rounding: model.bigNumber().default(0),
}) })