Skip to content

feat: add media galleries to entities - #6880

Draft
lkostrowski wants to merge 3 commits into
mainfrom
lkostrowski/gallery-to-more-entities
Draft

feat: add media galleries to entities#6880
lkostrowski wants to merge 3 commits into
mainfrom
lkostrowski/gallery-to-more-entities

Conversation

@lkostrowski

Copy link
Copy Markdown
Member

Scope of the change

  • I confirm I added ripples for changes (see src/ripples) or my feature doesn't contain any user-facing changes
  • I used analytics "trackEvent" for important events

@changeset-bot

changeset-bot Bot commented Aug 27, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: a0416ec

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
saleor-dashboard Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@codecov

codecov Bot commented Aug 27, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 33.79310% with 192 lines in your changes missing coverage. Please review.
✅ Project coverage is 57.40%. Comparing base (766b025) to head (a0416ec).

Files with missing lines Patch % Lines
src/media/useEntityMediaMutations.ts 0.00% 48 Missing ⚠️
...mponents/EntityMediaGallery/EntityMediaGallery.tsx 0.00% 42 Missing ⚠️
...ts/EntityMediaDetailPage/EntityMediaDetailPage.tsx 0.00% 36 Missing ⚠️
...ents/CategoryMediaGallery/CategoryMediaGallery.tsx 0.00% 6 Missing ⚠️
.../CollectionMediaGallery/CollectionMediaGallery.tsx 0.00% 6 Missing ⚠️
src/components/MediaDetailPage/MediaDetailPage.tsx 86.36% 6 Missing ⚠️
...components/ModelMediaGallery/ModelMediaGallery.tsx 0.00% 6 Missing ⚠️
src/categories/views/CategoryMedia.tsx 0.00% 4 Missing ⚠️
src/collections/views/CollectionMedia.tsx 0.00% 4 Missing ⚠️
src/media/mutations.staging.ts 0.00% 4 Missing ⚠️
... and 17 more
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #6880      +/-   ##
==========================================
- Coverage   57.46%   57.40%   -0.07%     
==========================================
  Files        3370     3383      +13     
  Lines       73200    73400     +200     
  Branches    19315    19352      +37     
==========================================
+ Hits        42068    42133      +65     
- Misses      29232    30646    +1414     
+ Partials     1900      621    -1279     
Flag Coverage Δ
storybook 53.32% <60.00%> (-0.01%) ⬇️
units 51.44% <33.10%> (-0.06%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@lkostrowski
lkostrowski force-pushed the lkostrowski/gallery-to-more-entities branch from cda3de7 to e9d08ef Compare September 1, 2026 09:07
Copilot AI lite review requested due to automatic review settings September 1, 2026 09:07

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR introduces a shared, generic media gallery + media detail experience for additional entity types (categories, collections, and models/pages) using the Saleor 3.24+ mediaCreate/mediaUpdate/mediaDelete/mediaReorder API (staging schema only), while refactoring product media UI to reuse the new shared components.

Changes:

  • Add generic entity media gallery/detail flows (upload, URL upload, reorder, bulk delete, metadata/alt editing) for categories/collections/pages gated behind staging schema.
  • Refactor product media views to reuse shared media UI dialogs/pages and unify copy in mediaMessages.
  • Add staging GraphQL fragments/mutations/queries and regenerate staging hooks/types/policies accordingly.

Reviewed changes

Copilot reviewed 63 out of 66 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
src/products/views/ProductUpdate/ProductUpdate.tsx Switches product media delete dialog + media success messages to shared media components/messages.
src/products/views/ProductUpdate/handlers/index.ts Adjusts upload handler to return created media id; switches to shared media messages.
src/products/views/ProductImage.tsx Migrates product media detail to shared MediaDetailPage + shared dialogs/messages.
src/products/components/ProductUpdatePage/ProductUpdatePage.tsx Replaces ProductMedia with shared MediaGallery and swaps URL dialog to shared MediaUrlDialog.
src/products/components/ProductUpdatePage/ProductUpdatePage.topNav.test.tsx Updates gallery mocking and adds a layout regression test for the media container.
src/products/components/ProductMediaPage/ProductMediaPage.tsx Removes legacy product-only media detail page implementation (deleted).
src/products/components/ProductMediaPage/index.ts Removes barrel export for deleted ProductMediaPage (deleted).
src/products/components/ProductMediaNavigation/index.ts Removes barrel export for product media navigation (deleted).
src/products/components/ProductMedia/index.ts Removes barrel export for ProductMedia (deleted).
src/modeling/views/ModelMedia.tsx Adds a page(model) media detail route/view backed by staging query.
src/modeling/urls.ts Adds modeling page media URL helpers.
src/modeling/queries.staging.ts Adds staging-only query for Page.media.
src/modeling/index.tsx Adds staging-gated route for model/page media detail.
src/modeling/components/PageDetailsPage/PageDetailsPage.tsx Embeds model/page media gallery into the page details view.
src/modeling/components/PageDetailsPage/PageDetailsPage.topNav.test.tsx Mocks the new model media gallery in top-nav tests.
src/modeling/components/ModelMediaGallery/ModelMediaGallery.tsx Adds staging-gated media gallery wrapper for models/pages.
src/media/useEntityMediaMutations.ts Adds generic staging mutations + Apollo cache patching for entity media CRUD/reorder.
src/media/types.ts Introduces shared entity media owner/media typing for non-product owners.
src/media/mutations.staging.ts Adds staging GraphQL documents for generic media mutations.
src/media/messages.ts Consolidates media-related success/error messages into mediaMessages.
src/media/fragments/media.staging.ts Adds staging Media fragment including metadata via inline fragment.
src/media/components/EntityMediaGallery/EntityMediaGallery.tsx Adds generic entity media gallery wiring (upload/URL/delete/reorder) using shared gallery UI.
src/media/components/EntityMediaDetailPage/EntityMediaDetailPage.tsx Adds generic entity media detail wiring (alt/metadata/delete) around shared detail UI.
src/graphql/typesStaging.generated.ts Regenerated staging types for new media API + scalar mappings (generated).
src/graphql/typePoliciesStaging.generated.ts Regenerated Apollo type policies for staging media types (generated).
src/graphql/hooksStaging.generated.ts Regenerated staging hooks for media queries/mutations (generated).
src/graphql/fragmentTypesStaging.generated.ts Regenerated fragment type map for staging media unions (generated).
src/components/MediaUrlDialog/messages.ts Adds i18n messages for shared media URL upload dialog.
src/components/MediaUrlDialog/MediaUrlDialog.tsx Introduces shared “upload by URL” modal.
src/components/MediaUrlDialog/MediaUrlDialog.test.tsx Updates tests to use the new shared dialog component.
src/components/MediaTile/MediaTile.tsx Adjusts tile prop typing to accept nullable type/oembedData.
src/components/MediaMetadataDialog/MediaMetadataDialog.tsx Generalizes metadata dialog to accept any media + a refetch document.
src/components/MediaMetadataDialog/MediaMetadataDialog.test.tsx Updates tests for the generalized metadata dialog API.
src/components/MediaGallery/validateMediaFiles.ts Renames/generalizes file validation helper for shared gallery usage.
src/components/MediaGallery/validateMediaFiles.test.ts Updates tests for the renamed validation helper.
src/components/MediaGallery/useMediaDrag.ts Generalizes drag/reorder hook to structural media type.
src/components/MediaGallery/useMediaDrag.test.ts Updates drag hook tests to use structural media type.
src/components/MediaGallery/types.ts Adds structural GalleryMedia type used by the shared gallery.
src/components/MediaGallery/messages.ts Adds shared gallery i18n messages (header/actions/hints).
src/components/MediaGallery/MediaGalleryDropzone.tsx Renames/generalizes dropzone component + switches to shared CSS module.
src/components/MediaGallery/MediaGallery.tsx Refactors gallery UI into shared MediaGallery using DetailSettingsCard.
src/components/MediaGallery/MediaGallery.test.tsx Updates gallery tests for new API + adds aligned-card shell test.
src/components/MediaGallery/MediaGallery.module.css Adds new CSS module for the shared gallery/dropzone styling.
src/components/MediaDetailPage/MediaNavigation.tsx Renames product-specific navigation to shared MediaNavigation and relaxes media field nullability.
src/components/MediaDetailPage/MediaDetailPage.tsx Adds shared media detail page shell (TopNav + preview + alt edit + savebar).
src/components/MediaDetailPage/MediaDetailPage.test.tsx Adds tests for shared detail page navigation behavior on save success/failure.
src/components/MediaDeleteDialog/messages.ts Renames product-specific delete dialog messages to shared media delete messages.
src/components/MediaDeleteDialog/MediaDeleteDialog.tsx Renames product-specific delete dialog component to shared MediaDeleteDialog.
src/components/EntityBackgroundImageField/EntityBackgroundImageField.tsx Switches background image field to the shared media dropzone + shared messages.
src/components/AppLayout/TopNav/destinationMessages.ts Adds TopNav destination messages for category/collection/model.
src/collections/views/CollectionMedia.tsx Adds collection media detail view (staging query + shared entity detail page).
src/collections/urls.ts Adds collection media URL helpers.
src/collections/queries.staging.ts Adds staging-only query for Collection.media.
src/collections/index.tsx Adds staging-gated route for collection media detail.
src/collections/components/CollectionMediaGallery/CollectionMediaGallery.tsx Adds staging-gated collection media gallery wrapper.
src/collections/components/CollectionDetailsPage/CollectionDetailsPage.tsx Embeds collection media gallery into collection details page.
src/categories/views/CategoryMedia.tsx Adds category media detail view (staging query + shared entity detail page).
src/categories/urls.ts Adds category media URL helpers.
src/categories/queries.staging.ts Adds staging-only query for Category.media.
src/categories/index.tsx Adds staging-gated route for category media detail.
src/categories/components/CategoryUpdatePage/CategoryUpdatePage.tsx Embeds category media gallery into category update page.
src/categories/components/CategoryMediaGallery/CategoryMediaGallery.tsx Adds staging-gated category media gallery wrapper.
schema-staging.graphql Updates staging schema snapshot with generic media API/types.
locale/defaultMessages.json Adds new default messages for TopNav destinations; removes some unrelated entries.
codegen-staging.ts Adds scalar mappings for staging codegen.
.changeset/entity-media-gallery.md Adds changeset describing the new entity media gallery feature and staging gating.
Suppressed comments (1)

src/components/MediaUrlDialog/MediaUrlDialog.tsx:58

  • If onSubmit returns errors (e.g. invalid URL / permission / backend validation), the dialog currently just stays open with no feedback. Please surface the failure (ideally inline near the URL input; a short error toast is a fallback).

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

ownerTypename="Collection"
ownerName={data?.collection?.name}
ownerUrl={collectionUrl(collectionId)}
ownerIcon={<TopNavDestinationIcon.categories />}
Comment on lines +51 to +56
reorderMedia(arrayMove([...media], oldIndex, newIndex)).then(
errors =>
errors.length === 0 &&
notify({ status: "success", text: intl.formatMessage(mediaMessages.mediaReorderSuccess) }),
notifyError,
);
Comment on lines +188 to +192
const handleSave = async () => {
const errors = await submit();

if (errors.length === 0) {
navigate(ownerUrl);
lkostrowski and others added 3 commits September 1, 2026 13:09
Two upstream changes landed under this branch during the rebase:

- use-react-router was dropped (#6907), so MediaDetailPage.test.tsx now
  uses useLocation from "react-router" like the rest of the codebase.
- knip's unused-file rule is error-level (#6903). ProductUpdate/messages.ts
  only survived because ProductUpdate.tsx imported its media messages;
  those moved to @dashboard/media/messages, and the remaining variant
  messages had no references anywhere, so the file is gone and
  defaultMessages.json re-extracted.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Barrel files were removed upstream (#6909). The rebase auto-merged these
files without touching their imports, so they still pointed at deleted
index modules.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings September 1, 2026 11:21
@lkostrowski
lkostrowski force-pushed the lkostrowski/gallery-to-more-entities branch from e9d08ef to a0416ec Compare September 1, 2026 11:21

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 60 out of 63 changed files in this pull request and generated no new comments.

Suppressed comments (4)

src/collections/views/CollectionMedia.tsx:30

  • ownerIcon points to the categories icon, but this page is for a collection. This makes the TopNav destination misleading; use the collections destination icon.
      ownerUrl={collectionUrl(collectionId)}
      ownerIcon={<TopNavDestinationIcon.categories />}
      ownerListLabel={intl.formatMessage(topNavDestinationMessages.collection)}
      media={data?.collection?.media}

src/media/components/EntityMediaGallery/EntityMediaGallery.tsx:55

  • If mediaReorder returns GraphQL errors (but not a network error), the current .then() branch does nothing, so the UI may keep the optimistic order without any error feedback. Treat non-empty errors as a failure and surface notifyError() (and/or revert).
    src/components/MediaUrlDialog/MediaUrlDialog.tsx:24
  • MediaUrlDialog currently types onSubmit errors as unknown[], which removes useful structural typing (message/field/code) that the dialog and callers rely on. Use a small structural "error-like" type instead so consumers get type safety without coupling to a specific schema.

This issue also appears on line 54 of the same file.
src/components/MediaUrlDialog/MediaUrlDialog.tsx:55

  • After tightening onSubmit typing, handleSubmit should return the same error element type instead of unknown[] so the form submit pipeline stays typed end-to-end.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants