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
+72
View File
@@ -1075,4 +1075,76 @@ export class Product {
}
)
}
/**
* This method manages image-variant associations for a specific image. It sends a request to the
* [Batch Image Variants](https://docs.medusajs.com/api/admin#products_postproductsidimagesimage_idvariantsbatch)
* API route.
*
* @param productId - The product's ID.
* @param imageId - The image's ID.
* @param body - The variants to add or remove from the image.
* @param headers - Headers to pass in the request
* @returns The batch operation details.
*
* @example
* sdk.admin.product.batchImageVariants("prod_123", "img_123", {
* add: ["variant_123", "variant_456"],
* remove: ["variant_789"]
* })
* .then(({ added, removed }) => {
* console.log(added, removed)
* })
*/
async batchImageVariants(
productId: string,
imageId: string,
body: HttpTypes.AdminBatchImageVariantRequest,
headers?: ClientHeaders
) {
return await this.client.fetch<HttpTypes.AdminBatchImageVariantResponse>(
`/admin/products/${productId}/images/${imageId}/variants/batch`,
{
method: "POST",
headers,
body,
}
)
}
/**
* This method manages variant-image associations for a specific variant. It sends a request to the
* [Batch Variant Images](https://docs.medusajs.com/api/admin#products_postproductsidvariantsvariant_idimagesbatch)
* API route.
*
* @param productId - The product's ID.
* @param variantId - The variant's ID.
* @param body - The images to add or remove from the variant.
* @param headers - Headers to pass in the request
* @returns The batch operation details.
*
* @example
* sdk.admin.product.batchVariantImages("prod_123", "variant_123", {
* add: ["img_123", "img_456"],
* remove: ["img_789"]
* })
* .then(({ added, removed }) => {
* console.log(added, removed)
* })
*/
async batchVariantImages(
productId: string,
variantId: string,
body: HttpTypes.AdminBatchVariantImagesRequest,
headers?: ClientHeaders
) {
return await this.client.fetch<HttpTypes.AdminBatchVariantImagesResponse>(
`/admin/products/${productId}/variants/${variantId}/images/batch`,
{
method: "POST",
headers,
body,
}
)
}
}