Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(dashboard): Allow re-ordering product images #10143

Closed
wants to merge 20 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/flat-mugs-try.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@medusajs/dashboard": patch
---

feat(dashboard): Allow re-ordering product images
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,13 @@ import { Form } from "../../common/form"

type RouteModalFormProps<TFieldValues extends FieldValues> = PropsWithChildren<{
form: UseFormReturn<TFieldValues>
blockSearch?: boolean
blockSearchParams?: boolean
onClose?: (isSubmitSuccessful: boolean) => void
}>

export const RouteModalForm = <TFieldValues extends FieldValues = any>({
form,
blockSearch = false,
blockSearchParams: blockSearch = false,
children,
onClose,
}: RouteModalFormProps<TFieldValues>) => {
Expand Down
14 changes: 13 additions & 1 deletion packages/admin/dashboard/src/i18n/translations/$schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -1578,6 +1578,12 @@
"create": {
"type": "object",
"properties": {
"title": {
"type": "string"
},
"description": {
"type": "string"
},
"header": {
"type": "string"
},
Expand Down Expand Up @@ -1742,6 +1748,8 @@
}
},
"required": [
"title",
"description",
"header",
"tabs",
"errors",
Expand Down Expand Up @@ -1990,6 +1998,9 @@
"action"
],
"additionalProperties": false
},
"successToast": {
"type": "string"
}
},
"required": [
Expand All @@ -2008,7 +2019,8 @@
"galleryLabel",
"downloadImageLabel",
"deleteImageLabel",
"emptyState"
"emptyState",
"successToast"
],
"additionalProperties": false
},
Expand Down
5 changes: 4 additions & 1 deletion packages/admin/dashboard/src/i18n/translations/de.json
Original file line number Diff line number Diff line change
Expand Up @@ -386,6 +386,8 @@
"successToast": "Produkz {{title}} angepasst."
},
"create": {
"title": "Produkt erstellen",
"description": "Erstellen Sie ein neues Produkt.",
"header": "Allgemein",
"tabs": {
"details": "Details",
Expand Down Expand Up @@ -490,7 +492,8 @@
"header": "Noch keine Medien",
"description": "Fügen Sie dem Produkt Medien hinzu, um es in Ihrem Schaufenster zu präsentieren.",
"action": "Medien hinzufügen"
}
},
"successToast": "Medien wurden erfolgreich aktualisiert."
},
"discountableHint": "Wenn diese Option deaktiviert ist, werden auf dieses Produkt keine Rabatte gewährt.",
"noSalesChannels": "In keinem Vertriebskanal verfügbar",
Expand Down
5 changes: 4 additions & 1 deletion packages/admin/dashboard/src/i18n/translations/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -386,6 +386,8 @@
"successToast": "Product {{title}} was successfully updated."
},
"create": {
"title": "Create Product",
"description": "Create a new product.",
"header": "General",
"tabs": {
"details": "Details",
Expand Down Expand Up @@ -490,7 +492,8 @@
"header": "No media yet",
"description": "Add media to the product to showcase it in your storefront.",
"action": "Add media"
}
},
"successToast": "Media was successfully updated."
},
"discountableHint": "When unchecked, discounts will not be applied to this product.",
"noSalesChannels": "Not available in any sales channels",
Expand Down
7 changes: 5 additions & 2 deletions packages/admin/dashboard/src/i18n/translations/pl.json
Original file line number Diff line number Diff line change
Expand Up @@ -386,6 +386,8 @@
"successToast": "Produkt {{title}} został pomyślnie zaktualizowany."
},
"create": {
"title": "Utwórz produkt",
"description": "Utwórz nowy produkt.",
"header": "Ogólne",
"tabs": {
"details": "Szczegóły",
Expand Down Expand Up @@ -490,7 +492,8 @@
"header": "Brak mediów",
"description": "Dodaj media do produktu, aby zaprezentować go w swoim sklepie.",
"action": "Dodaj media"
}
},
"successToast": "Media zostały pomyślnie zaktualizowane."
},
"discountableHint": "Jeśli odznaczone, rabaty nie będą stosowane do tego produktu.",
"noSalesChannels": "Niedostępny w żadnych kanałach sprzedaży",
Expand Down Expand Up @@ -2752,4 +2755,4 @@
"seconds_one": "Drugi",
"seconds_other": "Towary drugiej jakości"
}
}
}
5 changes: 4 additions & 1 deletion packages/admin/dashboard/src/i18n/translations/tr.json
Original file line number Diff line number Diff line change
Expand Up @@ -386,6 +386,8 @@
"successToast": "Ürün {{title}} başarıyla güncellendi."
},
"create": {
"title": "Ürün Oluştur",
"description": "Yeni bir ürün oluşturun.",
"header": "Genel",
"tabs": {
"details": "Detaylar",
Expand Down Expand Up @@ -490,7 +492,8 @@
"header": "Henüz medya yok",
"description": "Ürünü mağazanızda sergilemek için medya ekleyin.",
"action": "Medya ekle"
}
},
"successToast": "Medya başarıyla güncellendi."
},
"discountableHint": "İşaretlenmediğinde, bu ürüne indirim uygulanmayacaktır.",
"noSalesChannels": "Hiçbir satış kanalında mevcut değil",
Expand Down

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { useCallback } from "react"
import { UseFormReturn } from "react-hook-form"
import { useTranslation } from "react-i18next"
import { z } from "zod"
Expand Down Expand Up @@ -45,25 +46,40 @@ export const UploadMediaFormItem = ({
}) => {
const { t } = useTranslation()

const hasInvalidFiles = (fileList: FileType[]) => {
const invalidFile = fileList.find(
(f) => !SUPPORTED_FORMATS.includes(f.file.type)
)
const hasInvalidFiles = useCallback(
(fileList: FileType[]) => {
const invalidFile = fileList.find(
(f) => !SUPPORTED_FORMATS.includes(f.file.type)
)

if (invalidFile) {
form.setError("media", {
type: "invalid_file",
message: t("products.media.invalidFileType", {
name: invalidFile.file.name,
types: SUPPORTED_FORMATS_FILE_EXTENSIONS.join(", "),
}),
})
if (invalidFile) {
form.setError("media", {
type: "invalid_file",
message: t("products.media.invalidFileType", {
name: invalidFile.file.name,
types: SUPPORTED_FORMATS_FILE_EXTENSIONS.join(", "),
}),
})

return true
}
return true
}

return false
},
[form, t]
)

return false
}
const onUploaded = useCallback(
(files: FileType[]) => {
form.clearErrors("media")
if (hasInvalidFiles(files)) {
return
}

files.forEach((f) => append({ ...f, isThumbnail: false }))
},
[form, append, hasInvalidFiles]
)

return (
<Form.Field
Expand All @@ -87,15 +103,7 @@ export const UploadMediaFormItem = ({
hint={t("products.media.uploadImagesHint")}
hasError={!!form.formState.errors.media}
formats={SUPPORTED_FORMATS}
onUploaded={(files) => {
form.clearErrors("media")
if (hasInvalidFiles(files)) {
return
}

// TODO: For now all files that get uploaded are not thumbnails, revisit this logic
files.forEach((f) => append({ ...f, isThumbnail: false }))
}}
onUploaded={onUploaded}
/>
</Form.Control>
<Form.ErrorMessage />
Expand Down
Loading
Loading