feat(core-flows,product,types): scoped variant images (#13623)

* wip(product): variant images

* fix: return type

* wip: repo and list approach

* fix: redo repo method, make test pass

* fix: change getVariantImages impl

* feat: update test

* feat: API and core flows layer

* wip: integration spec

* fix: deterministic test

* chore: refactor and simplify, cleanup, remove repo method

* wip: batch add all images to all vairants

* fix: remove, expand testing

* refactor: pass variants instead of refetch

* chore: expand integration test

* feat: test multi assign route

* fix: remove `/admin/products/:id/variants/images` route

* feat: batch images to variant endpoint

* fix: length assertion

* feat: variant thumbnail

* fix: send variant thumbnail by default

* fix: product export test assertion

* fix: test

* feat: variant thumbnail on line item

* fix: add missing list and count method, update types

* feat: optimise variant images lookups

* feat: thumbnail management in core flows

* fix: typos, type, build

* feat: cascade delete to pivot table, rm unused unused fields

* feat(dashboard): variant images management UI (#13670)

* wip(dashboard): setup variant media form

* wip: cleanup table and images, wip check handler

* feat: proper sidebar functionallity

* fefat: add js-sdk and hooks

* feat: allow only one selection

* wip: lazy load variants in the table

* feat: new variants management for images on product details

* chore: refactor

* wip: variant details page work

* fix: cleanup media section, fix issues and types

* feat: correct scoped images, cleanup in edit modal

* feat: js sdk and hooks, filter out product images on variant details, labels, add API call and wrap UI

* chore: cleanup

* refacto: rename route

* feat: thumbnail functionallity

* fix: refresh checked after revalidation load

* fix: rm unused, refactor type

* Create thirty-clocks-refuse.md

* feat: new add remove variant media layout

* feat: new image add UX

---------

Co-authored-by: Oli Juhl <59018053+olivermrbl@users.noreply.github.com>

* fix: table name in migration

* chore: update changesets

---------

Co-authored-by: Oli Juhl <59018053+olivermrbl@users.noreply.github.com>
This commit is contained in:
Frane Polić
2025-10-26 15:15:40 +01:00
committed by GitHub
co-authored by Oli Juhl
parent bafd006094
commit 4757281677
57 changed files with 3323 additions and 80 deletions
@@ -419,3 +419,57 @@ export const useConfirmImportProducts = (
...options,
})
}
export const useBatchImageVariants = (
productId: string,
imageId: string,
options?: UseMutationOptions<
HttpTypes.AdminBatchImageVariantResponse,
FetchError,
HttpTypes.AdminBatchImageVariantRequest
>
) => {
return useMutation({
mutationFn: (payload) =>
sdk.admin.product.batchImageVariants(productId, imageId, payload),
onSuccess: (data, variables, context) => {
queryClient.invalidateQueries({
queryKey: productsQueryKeys.detail(productId),
})
queryClient.invalidateQueries({ queryKey: variantsQueryKeys.lists() })
queryClient.invalidateQueries({ queryKey: variantsQueryKeys.details() })
options?.onSuccess?.(data, variables, context)
},
...options,
})
}
export const useBatchVariantImages = (
productId: string,
variantId: string,
options?: UseMutationOptions<
HttpTypes.AdminBatchVariantImagesResponse,
FetchError,
HttpTypes.AdminBatchVariantImagesRequest
>
) => {
return useMutation({
mutationFn: (payload) =>
sdk.admin.product.batchVariantImages(productId, variantId, payload),
onSuccess: (data, variables, context) => {
queryClient.invalidateQueries({
queryKey: productsQueryKeys.detail(productId),
})
queryClient.invalidateQueries({
queryKey: variantsQueryKeys.list({ productId }),
})
queryClient.invalidateQueries({
queryKey: variantsQueryKeys.detail(variantId),
})
options?.onSuccess?.(data, variables, context)
},
...options,
})
}
@@ -0,0 +1,32 @@
import { HttpTypes } from "@medusajs/types"
import { useQueryParams } from "../../use-query-params"
type UseProductTagTableQueryProps = {
prefix?: string
pageSize?: number
}
export const useProductVariantTableQuery = ({
prefix,
pageSize = 20,
}: UseProductTagTableQueryProps) => {
const queryObject = useQueryParams(
["offset", "q", "order", "created_at", "updated_at"],
prefix
)
const { offset, q, order, created_at, updated_at } = queryObject
const searchParams: HttpTypes.AdminProductTagListParams = {
limit: pageSize,
offset: offset ? Number(offset) : 0,
order,
created_at: created_at ? JSON.parse(created_at) : undefined,
updated_at: updated_at ? JSON.parse(updated_at) : undefined,
q,
}
return {
searchParams,
raw: queryObject,
}
}