Skip to content

fix: replace image popover with image preview dialog#965

Open
priscila-moneo wants to merge 3 commits into
masterfrom
fix/form-template-grid-image-preview
Open

fix: replace image popover with image preview dialog#965
priscila-moneo wants to merge 3 commits into
masterfrom
fix/form-template-grid-image-preview

Conversation

@priscila-moneo
Copy link
Copy Markdown

@priscila-moneo priscila-moneo commented Jun 5, 2026

ref: https://app.clickup.com/t/86ba8twjm

2nd commit:
Extended the ImagePreviewCell migration from the first commit to the remaining sponsor form item pages that had the same pattern.

image

Summary by CodeRabbit

  • New Features

    • Added a reusable image preview cell component across the app for consistent image viewing.
    • Enhanced image preview modal with graceful fallback UI for broken or missing images.
  • Refactor

    • Consolidated image preview functionality into a shared component for improved maintainability.
  • Tests

    • Added comprehensive test coverage for image preview components and URL validation utilities.

Signed-off-by: Priscila Moneo <priscila_moneo@hotmail.com.ar>
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Jun 5, 2026

Looking for one thing? Review this PR in Change Stack to search files, summaries, diffs, and code without losing your place.

Review Change Stack

📝 Walkthrough

Walkthrough

This PR introduces a shared ImagePreviewCell component to centralize image preview functionality across multiple pages. A refactored PreviewModal now handles image load failures with a broken-image placeholder. New isImageUrl utility validates image extensions. FormTemplateItemListPage and InventoryListPage are updated to use the shared component, removing duplicate local implementations.

Changes

Image Preview Centralization

Layer / File(s) Summary
Image URL validation utility
src/utils/methods.js, src/utils/__tests__/methods.test.js
Added isImageUrl(url) function matching image file extensions with case-insensitive regex and optional query-string suffix. Updated getFileUploadAllowedExtensions to normalize configuration from array, comma-separated string, or missing value. Full test coverage for extension validation, query-string handling, and edge cases.
PreviewModal image error handling
src/components/mui/PreviewModal/index.jsx, src/components/mui/__tests__/preview-modal.test.js, src/i18n/en.json
Refactored PreviewModal to track image load failures with useState/useEffect, rendering a broken-image placeholder when url is missing or the image fails to load. Image-error state resets when modal opens or url changes. Added BrokenImage subcomponent and i18n string for preview title. Tests cover rendering, conditional content, close behavior, and error state reset.
ImagePreviewCell shared component
src/components/image-preview-cell.js, src/components/__tests__/image-preview-cell.test.js
New memoized component renders MUI icon button that opens PreviewModal. Derives filename from fileName prop or URL path with decoding. Renders nothing when imageUrl is missing. Wires local open state to PreviewModal with metadata props. Tests verify null/empty handling, button rendering, dialog open/close, and filename resolution logic.
FormTemplateItemListPage integration
src/pages/sponsors-global/form-templates/form-template-item-list-page.js
Replaced inline icon-with-tooltip preview with ImagePreviewCell. Updated hasImage column render to validate image URL via isImageUrl before rendering. Removed unused deleteFormTemplateItem from Redux mapDispatchToProps.
InventoryListPage integration
src/pages/sponsors-global/inventory/inventory-list-page.js
Replaced local InventoryImagePreviewCell with shared ImagePreviewCell. Updated hasImage column render to validate image URL via isImageUrl. Removed unused deleteInventoryItem from Redux mapDispatchToProps. Removed local image preview tests and component definition.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

  • fntechgit/summit-admin#953: Both PRs refactor PreviewModal to add broken-image placeholder behavior, introducing and expanding the component's error-handling capabilities.
  • fntechgit/summit-admin#819: Both PRs modify the inventory list's image preview implementation by replacing duplicate cell components with either a shared component or a refactored approach.

Suggested reviewers

  • caseylocker
  • martinquiroga-exo
  • smarcet

Poem

🐰 A preview that's shared, no duplication today,
Modal and cell work together to display,
When images fail, a placeholder appears,
One component to rule them, calming all fears! 🖼️✨

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title 'fix: replace image popover with image preview dialog' directly and accurately summarizes the main changes in the PR, which refactors image preview functionality from a popover to a dialog-based approach.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/form-template-grid-image-preview

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 3

🧹 Nitpick comments (1)
src/components/__tests__/image-preview-cell.test.js (1)

40-54: ⚡ Quick win

Add a regression test for malformed URL-encoded filenames.

Given the filename derivation path, please add a case with an invalid encoded segment (e.g., %E0%A4%A) to ensure the component doesn’t crash and still renders a fallback filename.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/components/__tests__/image-preview-cell.test.js` around lines 40 - 54,
Add a new test in src/components/__tests__/image-preview-cell.test.js that
renders <ImagePreviewCell> without a fileName but with an imageUrl whose last
path segment contains a malformed percent-encoding (e.g., "%E0%A4%A"), then
simulate the click on the preview button and assert the component does not crash
and shows a filename/fallback; specifically, reuse the existing test pattern
(userEvent.setup(), render(<ImagePreviewCell imageUrl={badUrl} />), await
user.click(screen.getByRole("button", { name: title }))) and assert the UI
contains either a safe fallback or the raw segment using a tolerant matcher (for
example
expect(screen.getByText(/sponsor_banner\.png|%E0%A4%A/)).toBeInTheDocument()),
so the test verifies resilience of ImagePreviewCell's filename extraction logic.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/components/image-preview-cell.js`:
- Around line 26-27: The filename decoding step for resolvedFileName can throw
on malformed percent-encodings; wrap the decodeURIComponent call that uses
imageUrl.split("/").pop().split("?")[0] in a safe guard: try to decode and on
any exception fall back to the raw segment (or a sanitized fallback like an
empty string); update the expression that assigns resolvedFileName (refer to
resolvedFileName, imageUrl) to use this safe decode logic so render-time errors
are avoided.

In `@src/pages/sponsors-global/form-templates/form-template-item-list-page.js`:
- Around line 209-213: The render callback currently destructures file_url from
row.images[0] which can throw if the first array element is nullish; update the
render implementation used for the column to read the URL via optional chaining
(e.g., access row.images?.[0]?.file_url) before calling isImageUrl, and only
return <ImagePreviewCell imageUrl={url} /> when url is a valid string and
isImageUrl(url) is true; keep the checks around row.images length/existence and
use the same symbols (render, row.images, isImageUrl, ImagePreviewCell) so the
change is localized to that render function.

In `@src/utils/methods.js`:
- Around line 637-641: getFileUploadAllowedExtensions currently returns raw
tokens without trimming, so inputs like "jpg, png,   " produce entries with
whitespace; update the function (getFileUploadAllowedExtensions) to normalize
tokens by mapping each element (whether coming from an array or from
String(ext).split(",")) through .toString()/String(...) then .trim(), and then
filter(Boolean) to remove empty strings—i.e., convert ext to an array, trim
every item, and filter out falsy values before returning.

---

Nitpick comments:
In `@src/components/__tests__/image-preview-cell.test.js`:
- Around line 40-54: Add a new test in
src/components/__tests__/image-preview-cell.test.js that renders
<ImagePreviewCell> without a fileName but with an imageUrl whose last path
segment contains a malformed percent-encoding (e.g., "%E0%A4%A"), then simulate
the click on the preview button and assert the component does not crash and
shows a filename/fallback; specifically, reuse the existing test pattern
(userEvent.setup(), render(<ImagePreviewCell imageUrl={badUrl} />), await
user.click(screen.getByRole("button", { name: title }))) and assert the UI
contains either a safe fallback or the raw segment using a tolerant matcher (for
example
expect(screen.getByText(/sponsor_banner\.png|%E0%A4%A/)).toBeInTheDocument()),
so the test verifies resilience of ImagePreviewCell's filename extraction logic.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 737d8ee1-de60-4ff6-92d2-78089fe1cd24

📥 Commits

Reviewing files that changed from the base of the PR and between 8243964 and a35504f.

⛔ Files ignored due to path filters (1)
  • yarn.lock is excluded by !**/yarn.lock, !**/*.lock
📒 Files selected for processing (10)
  • src/components/__tests__/image-preview-cell.test.js
  • src/components/image-preview-cell.js
  • src/components/mui/PreviewModal/index.jsx
  • src/components/mui/__tests__/preview-modal.test.js
  • src/i18n/en.json
  • src/pages/sponsors-global/form-templates/form-template-item-list-page.js
  • src/pages/sponsors-global/inventory/__tests__/inventory-list-page.test.js
  • src/pages/sponsors-global/inventory/inventory-list-page.js
  • src/utils/__tests__/methods.test.js
  • src/utils/methods.js
💤 Files with no reviewable changes (1)
  • src/pages/sponsors-global/inventory/tests/inventory-list-page.test.js

Comment thread src/components/image-preview-cell.js Outdated
Comment thread src/utils/methods.js
Signed-off-by: Priscila Moneo <priscila_moneo@hotmail.com.ar>
Signed-off-by: Priscila Moneo <priscila_moneo@hotmail.com.ar>
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.

1 participant