Skip to content

Comments

feat: add template popup on sponsor tab#804

Open
tomrndom wants to merge 3 commits intomasterfrom
feature/sponsor-page-tab-managed-popup
Open

feat: add template popup on sponsor tab#804
tomrndom wants to merge 3 commits intomasterfrom
feature/sponsor-page-tab-managed-popup

Conversation

@tomrndom
Copy link

@tomrndom tomrndom commented Feb 25, 2026

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

Signed-off-by: Tomás Castillo tcastilloboireau@gmail.com

Summary by CodeRabbit

  • New Features

    • Sponsors can now add pages using predefined page templates with flexible add-ons selection.
    • Template-based page creation includes sorting and search functionality for easier page discovery.
  • UI/UX Improvements

    • Select components now display customizable messaging when no options are available.

Signed-off-by: Tomás Castillo <tcastilloboireau@gmail.com>
Signed-off-by: Tomás Castillo <tcastilloboireau@gmail.com>
… templates

Signed-off-by: Tomás Castillo <tcastilloboireau@gmail.com>
@tomrndom tomrndom requested a review from smarcet February 25, 2026 15:41
@coderabbitai
Copy link

coderabbitai bot commented Feb 25, 2026

📝 Walkthrough

Walkthrough

The changes introduce a template-based workflow for adding sponsor-managed pages. This includes a new Redux action (saveSponsorManagedPage) for persisting pages, a new modal popup component for selecting pages and add-ons with sorting and search capabilities, integration into the sponsor pages tab, a form component enhancement for handling empty states, and supporting translation keys.

Changes

Cohort / File(s) Summary
Action Layer
src/actions/sponsor-pages-actions.js
Introduced SPONSOR_MANAGED_PAGE_ADDED action type, saveSponsorManagedPage async thunk that normalizes input (mapping pages to show_page_ids and add-ons with apply_to_all_add_ons flag) and POSTs to backend, and normalizeSponsorManagedPage helper function.
Form Component Enhancement
src/components/mui/formik-inputs/mui-formik-select-group.js
Added noOptionsLabel prop (default "No items") and refactored rendering logic into renderMenuContent function to handle loading, no-options, and normal option states.
Translations
src/i18n/en.json
Added three new translation keys under pages_tab.placeholders: no_add_ons, add_page_using_template, and add_selected_page_template.
Template Popup Component
src/pages/sponsors/sponsor-pages-tab/components/add-sponsor-page-template-popup/index.js
New React component providing modal dialog with Formik form, MUI table for sponsor page selection with sorting (A-Z/Z-A), search functionality, pagination, checkbox selection, and add-ons selection (with "all" support); validates at least one page or "all" add-on selection required.
Page Integration
src/pages/sponsors/sponsor-pages-tab/index.js
Extended SponsorPagesTab to include openPopup state, handleUsingTemplate trigger, AddSponsorPageTemplatePopup rendering, and handleSaveManagedPageFromTemplate handler that invokes saveSponsorManagedPage and refreshes managed pages list; added sponsor and summitId props and integrated saveSponsorManagedPage into mapDispatchToProps.

Sequence Diagram

sequenceDiagram
    participant User as User
    participant UI as React Component<br/>(SponsorPagesTab)
    participant Popup as AddSponsorPageTemplate<br/>Popup
    participant Form as Formik Form<br/>(Validation)
    participant Redux as Redux Store<br/>(Actions)
    participant API as Backend API

    User->>UI: Click "Using template"
    UI->>UI: Set openPopup = "template"
    UI->>Popup: Render popup with onSubmit<br/>callback
    
    Popup->>Popup: Fetch pages on mount
    Popup->>Redux: Dispatch getShowPages
    Redux->>API: GET pages
    API-->>Redux: Pages data
    Redux-->>Popup: Pages loaded
    Popup->>Popup: Render pages table
    
    User->>Popup: Select pages, sort, search
    User->>Popup: Select add-ons
    User->>Popup: Click "Add"
    
    Popup->>Form: Validate selections
    alt Validation passes
        Form-->>Popup: Valid
        Popup->>Popup: Package entity<br/>(pages, add-ons)
        Popup->>UI: Call onSubmit(entity)
        UI->>Redux: Dispatch saveSponsorManagedPage
        Redux->>API: POST sponsor-managed-page
        API-->>Redux: Created
        Redux->>Redux: Dispatch SPONSOR_MANAGED_PAGE_ADDED
        UI->>Redux: Refresh managed pages list
        UI->>Popup: Close popup
    else Validation fails
        Form-->>Popup: Show error
    end
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

Suggested reviewers

  • smarcet
  • romanetar

Poem

🐰 A template for pages, oh what a delight,
Pages and add-ons all sorted just right,
Select, search, and save with a popup so neat,
Sponsor management now is a triumph complete! ✨

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'feat: add template popup on sponsor tab' directly describes the main feature addition—a template popup for the sponsor tab—which aligns with the primary objective of implementing a popup modal to add managed sponsor pages from templates.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

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

✨ Finishing Touches
  • 📝 Generate docstrings (stacked PR)
  • 📝 Generate docstrings (commit on current branch)
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feature/sponsor-page-tab-managed-popup

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

@tomrndom tomrndom changed the title Feature/sponsor page tab managed popup feat: add template popup on sponsor tab Feb 25, 2026
Copy link

@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: 5

🧹 Nitpick comments (2)
src/actions/sponsor-pages-actions.js (1)

172-185: normalizeSponsorManagedPage handles "all" correctly, but the initial .map() on line 175 is wasteful when "all" is present.

When add_ons is ["all"], line 175 calls "all".idundefined, then lines 179-182 immediately overwrite allowed_add_ons with []. Consider checking the "all" case first to avoid the unnecessary mapping and the transient [undefined] value.

♻️ Suggested refactor
 const normalizeSponsorManagedPage = (entity) => {
+  const isAll = entity.add_ons.includes("all");
   const normalizedEntity = {
     show_page_ids: entity.pages,
-    allowed_add_ons: entity.add_ons.map((a) => a.id),
-    apply_to_all_add_ons: false
+    allowed_add_ons: isAll ? [] : entity.add_ons.map((a) => a.id),
+    apply_to_all_add_ons: isAll
   };
 
-  if (entity.add_ons.includes("all")) {
-    normalizedEntity.apply_to_all_add_ons = true;
-    normalizedEntity.allowed_add_ons = [];
-  }
-
   return normalizedEntity;
 };
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/actions/sponsor-pages-actions.js` around lines 172 - 185,
normalizeSponsorManagedPage currently maps entity.add_ons to ids before checking
for the "all" sentinel, producing a transient [undefined]; change the logic so
you first check if entity.add_ons.includes("all") and if so set
apply_to_all_add_ons = true and allowed_add_ons = [] immediately, otherwise
compute allowed_add_ons = entity.add_ons.map(a => a.id); preserve show_page_ids
assignment and default apply_to_all_add_ons = false, and update only within the
normalizeSponsorManagedPage function.
src/pages/sponsors/sponsor-pages-tab/components/add-sponsor-page-template-popup/index.js (1)

301-303: Incomplete PropTypes declaration.

Only onClose is declared. onSubmit, sponsor, and summitId are required for correct operation but are missing from propTypes.

♻️ Suggested improvement
 AddSponsorPageTemplatePopup.propTypes = {
-  onClose: PropTypes.func.isRequired
+  onClose: PropTypes.func.isRequired,
+  onSubmit: PropTypes.func.isRequired,
+  sponsor: PropTypes.object.isRequired,
+  summitId: PropTypes.oneOfType([PropTypes.string, PropTypes.number]).isRequired
 };
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@src/pages/sponsors/sponsor-pages-tab/components/add-sponsor-page-template-popup/index.js`
around lines 301 - 303, Add missing PropTypes for AddSponsorPageTemplatePopup:
extend AddSponsorPageTemplatePopup.propTypes to include onSubmit
(PropTypes.func.isRequired), sponsor (PropTypes.object.isRequired or a more
specific shape if available), and summitId
(PropTypes.oneOfType([PropTypes.string, PropTypes.number]).isRequired) alongside
the existing onClose declaration so the component's required props are
explicitly validated.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/actions/sponsor-pages-actions.js`:
- Around line 161-170: The loading state isn't cleared on failures because
stopLoading is only dispatched in the .then() of the postRequest call; update
the postRequest invocation (the call that returns
postRequest(...)(params)(dispatch) in this file) to call .finally(() => {
dispatch(stopLoading()); }) instead of .then(...), so stopLoading runs on both
success and failure (follow the same pattern used in cloneGlobalPage).

In
`@src/pages/sponsors/sponsor-pages-tab/components/add-sponsor-page-template-popup/index.js`:
- Around line 229-242: Replace the two hardcoded English strings with i18n
calls: change the selected count label currently rendered in the Grid2 that
shows "{selectedPages.length} items selected" to use T.translate with a key like
"forms_tab.items_selected" (or reuse an existing key) and interpolate
selectedPages.length, and change the MenuButton children text "sort by" to
T.translate("forms_tab.sort_by") (or the appropriate locale key); keep the
SwapVertIcon and the MenuButton menuItems using
T.translate("forms_tab.sort_asc_label") and
T.translate("forms_tab.sort_desc_label") for "A-Z"/"Z-A" if not already, and
update code around MenuButton, handleSort, selectedPages to pass the translated
strings.
- Around line 46-51: sponsor.sponsorships can be null/undefined so mapping
directly causes runtime errors; fix by using a safe fallback when creating
sponsorshipIds and sponsorshipTypeIds (e.g. map over sponsor?.sponsorships ?? []
or (sponsor.sponsorships || [])) so the declarations for sponsorshipIds and
sponsorshipTypeIds use that fallback and avoid throwing when sponsorships is
missing.
- Around line 89-124: handlePageChange and handleSort call getShowPages with the
Redux prop term while handleOnSearch uses local searchTerm, causing the search
to be lost on pagination/sort; fix by using a single source of truth—either
(preferred) pass the local searchTerm from handlePageChange and handleSort into
getShowPages (replace term with searchTerm) or update the Redux term when
handleOnSearch runs so all handlers use the Redux term. Update the function
calls in handlePageChange and handleSort (and any other pagination/sort
handlers) to use the chosen search value and keep other parameters (currentPage,
perPage/FIVE_PER_PAGE, order, orderDir, sponsorshipTypeIds) unchanged so
searches persist across pages and sorts.

In `@src/pages/sponsors/sponsor-pages-tab/index.js`:
- Around line 195-200: The handler handleSaveManagedPageFromTemplate currently
calls saveSponsorManagedPage(entity).then(...) but has no .catch(), allowing
snackbarErrorHandler to swallow errors and still run setOpenPopup(null) and
getSponsorManagedPages(); change it to only close the popup and refresh on true
success by attaching a .catch() (or using async/await with try/catch) around
saveSponsorManagedPage: on success call setOpenPopup(null) and
getSponsorManagedPages(), on failure do not close the popup and let
snackbarErrorHandler display the error (or rethrow/return a rejected promise) so
failure paths prevent closing and refreshing.

---

Nitpick comments:
In `@src/actions/sponsor-pages-actions.js`:
- Around line 172-185: normalizeSponsorManagedPage currently maps entity.add_ons
to ids before checking for the "all" sentinel, producing a transient
[undefined]; change the logic so you first check if
entity.add_ons.includes("all") and if so set apply_to_all_add_ons = true and
allowed_add_ons = [] immediately, otherwise compute allowed_add_ons =
entity.add_ons.map(a => a.id); preserve show_page_ids assignment and default
apply_to_all_add_ons = false, and update only within the
normalizeSponsorManagedPage function.

In
`@src/pages/sponsors/sponsor-pages-tab/components/add-sponsor-page-template-popup/index.js`:
- Around line 301-303: Add missing PropTypes for AddSponsorPageTemplatePopup:
extend AddSponsorPageTemplatePopup.propTypes to include onSubmit
(PropTypes.func.isRequired), sponsor (PropTypes.object.isRequired or a more
specific shape if available), and summitId
(PropTypes.oneOfType([PropTypes.string, PropTypes.number]).isRequired) alongside
the existing onClose declaration so the component's required props are
explicitly validated.

ℹ️ Review info

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between f0fbe8c and b3b9132.

📒 Files selected for processing (5)
  • src/actions/sponsor-pages-actions.js
  • src/components/mui/formik-inputs/mui-formik-select-group.js
  • src/i18n/en.json
  • src/pages/sponsors/sponsor-pages-tab/components/add-sponsor-page-template-popup/index.js
  • src/pages/sponsors/sponsor-pages-tab/index.js

Comment on lines +161 to +170
return postRequest(
null,
createAction(SPONSOR_MANAGED_PAGE_ADDED),
`${window.SPONSOR_PAGES_API_URL}/api/v1/summits/${currentSummit.id}/sponsors/${sponsorId}/managed-pages`,
normalizedEntity,
snackbarErrorHandler
)(params)(dispatch).then(() => {
dispatch(stopLoading());
});
};
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Loading state never cleared on request failure.

stopLoading is dispatched inside .then(), so if the POST request fails, the loading indicator stays indefinitely. Compare with cloneGlobalPage (line 80) which uses .finally().

🐛 Proposed fix
     return postRequest(
       null,
       createAction(SPONSOR_MANAGED_PAGE_ADDED),
       `${window.SPONSOR_PAGES_API_URL}/api/v1/summits/${currentSummit.id}/sponsors/${sponsorId}/managed-pages`,
       normalizedEntity,
       snackbarErrorHandler
-    )(params)(dispatch).then(() => {
-      dispatch(stopLoading());
-    });
+    )(params)(dispatch).finally(() => {
+      dispatch(stopLoading());
+    });
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
return postRequest(
null,
createAction(SPONSOR_MANAGED_PAGE_ADDED),
`${window.SPONSOR_PAGES_API_URL}/api/v1/summits/${currentSummit.id}/sponsors/${sponsorId}/managed-pages`,
normalizedEntity,
snackbarErrorHandler
)(params)(dispatch).then(() => {
dispatch(stopLoading());
});
};
return postRequest(
null,
createAction(SPONSOR_MANAGED_PAGE_ADDED),
`${window.SPONSOR_PAGES_API_URL}/api/v1/summits/${currentSummit.id}/sponsors/${sponsorId}/managed-pages`,
normalizedEntity,
snackbarErrorHandler
)(params)(dispatch).finally(() => {
dispatch(stopLoading());
});
};
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/actions/sponsor-pages-actions.js` around lines 161 - 170, The loading
state isn't cleared on failures because stopLoading is only dispatched in the
.then() of the postRequest call; update the postRequest invocation (the call
that returns postRequest(...)(params)(dispatch) in this file) to call
.finally(() => { dispatch(stopLoading()); }) instead of .then(...), so
stopLoading runs on both success and failure (follow the same pattern used in
cloneGlobalPage).

Comment on lines +46 to +51
const [searchTerm, setSearchTerm] = useState("");
const [selectedPages, setSelectedPages] = useState([]);

const sponsorshipIds = sponsor.sponsorships.map((e) => e.id);

const sponsorshipTypeIds = sponsor.sponsorships.map((e) => e.type.id);
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Missing null-safety on sponsor.sponsorships.

If sponsor.sponsorships is undefined or null, lines 49 and 51 will throw. Consider adding a fallback.

🛡️ Proposed fix
-  const sponsorshipIds = sponsor.sponsorships.map((e) => e.id);
-  const sponsorshipTypeIds = sponsor.sponsorships.map((e) => e.type.id);
+  const sponsorships = sponsor?.sponsorships || [];
+  const sponsorshipIds = sponsorships.map((e) => e.id);
+  const sponsorshipTypeIds = sponsorships.map((e) => e.type.id);
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const [searchTerm, setSearchTerm] = useState("");
const [selectedPages, setSelectedPages] = useState([]);
const sponsorshipIds = sponsor.sponsorships.map((e) => e.id);
const sponsorshipTypeIds = sponsor.sponsorships.map((e) => e.type.id);
const [searchTerm, setSearchTerm] = useState("");
const [selectedPages, setSelectedPages] = useState([]);
const sponsorships = sponsor?.sponsorships || [];
const sponsorshipIds = sponsorships.map((e) => e.id);
const sponsorshipTypeIds = sponsorships.map((e) => e.type.id);
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@src/pages/sponsors/sponsor-pages-tab/components/add-sponsor-page-template-popup/index.js`
around lines 46 - 51, sponsor.sponsorships can be null/undefined so mapping
directly causes runtime errors; fix by using a safe fallback when creating
sponsorshipIds and sponsorshipTypeIds (e.g. map over sponsor?.sponsorships ?? []
or (sponsor.sponsorships || [])) so the declarations for sponsorshipIds and
sponsorshipTypeIds use that fallback and avoid throwing when sponsorships is
missing.

Comment on lines +89 to +124
const handlePageChange = (page) => {
getShowPages(
term,
page,
FIVE_PER_PAGE,
order,
orderDir,
false,
sponsorshipTypeIds
);
};

const handleSort = (key, dir) => {
getShowPages(
term,
currentPage,
FIVE_PER_PAGE,
key,
dir,
false,
sponsorshipTypeIds
);
};

const handleOnSearch = (ev) => {
if (ev.key === "Enter")
getShowPages(
searchTerm,
currentPage,
perPage,
order,
orderDir,
false,
sponsorshipTypeIds
);
};
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

Search term inconsistency between local state and Redux prop causes pagination/sort to lose search query.

handlePageChange (line 90-92) and handleSort (line 101-104) use term from Redux props, but handleOnSearch (line 115-116) uses local searchTerm state. After searching, paginating or sorting would revert to the stale Redux term, losing the user's search.

Use a single source of truth — either the local searchTerm for all handlers, or update the Redux term when searching.

🐛 Proposed fix (use local searchTerm consistently)
   const handlePageChange = (page) => {
     getShowPages(
-      term,
+      searchTerm,
       page,
       FIVE_PER_PAGE,
       order,
       orderDir,
       false,
       sponsorshipTypeIds
     );
   };
 
   const handleSort = (key, dir) => {
     getShowPages(
-      term,
+      searchTerm,
       currentPage,
       FIVE_PER_PAGE,
       key,
       dir,
       false,
       sponsorshipTypeIds
     );
   };
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@src/pages/sponsors/sponsor-pages-tab/components/add-sponsor-page-template-popup/index.js`
around lines 89 - 124, handlePageChange and handleSort call getShowPages with
the Redux prop term while handleOnSearch uses local searchTerm, causing the
search to be lost on pagination/sort; fix by using a single source of
truth—either (preferred) pass the local searchTerm from handlePageChange and
handleSort into getShowPages (replace term with searchTerm) or update the Redux
term when handleOnSearch runs so all handlers use the Redux term. Update the
function calls in handlePageChange and handleSort (and any other pagination/sort
handlers) to use the chosen search value and keep other parameters (currentPage,
perPage/FIVE_PER_PAGE, order, orderDir, sponsorshipTypeIds) unchanged so
searches persist across pages and sorts.

Comment on lines +229 to +242
<Grid2 size={4}>{selectedPages.length} items selected</Grid2>
</Grid2>
<Grid2 container spacing={2} size={6}>
<Grid2 size={4}>
<MenuButton
buttonId="sort-button"
menuId="sort-menu"
menuItems={[
{ label: "A-Z", onClick: () => handleSort("name", 1) },
{ label: "Z-A", onClick: () => handleSort("name", 0) }
]}
>
<SwapVertIcon fontSize="large" sx={{ mr: 1 }} /> sort by
</MenuButton>
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Hardcoded English strings — use i18n translations.

"items selected" (line 229) and "sort by" (line 241) are hardcoded in English. The rest of the UI properly uses T.translate(). The forms_tab section already has sort_asc_label / sort_desc_label translations for "A-Z" / "Z-A" that could be reused.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@src/pages/sponsors/sponsor-pages-tab/components/add-sponsor-page-template-popup/index.js`
around lines 229 - 242, Replace the two hardcoded English strings with i18n
calls: change the selected count label currently rendered in the Grid2 that
shows "{selectedPages.length} items selected" to use T.translate with a key like
"forms_tab.items_selected" (or reuse an existing key) and interpolate
selectedPages.length, and change the MenuButton children text "sort by" to
T.translate("forms_tab.sort_by") (or the appropriate locale key); keep the
SwapVertIcon and the MenuButton menuItems using
T.translate("forms_tab.sort_asc_label") and
T.translate("forms_tab.sort_desc_label") for "A-Z"/"Z-A" if not already, and
update code around MenuButton, handleSort, selectedPages to pass the translated
strings.

Comment on lines +195 to +200
const handleSaveManagedPageFromTemplate = (entity) => {
saveSponsorManagedPage(entity).then(() => {
setOpenPopup(null);
getSponsorManagedPages();
});
};
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

rg -n "snackbarErrorHandler" --type=js -A 10 | head -80

Repository: fntechgit/summit-admin

Length of output: 5635


🏁 Script executed:

rg -n "export.*snackbarErrorHandler\|const snackbarErrorHandler\|function snackbarErrorHandler" --type=js -B 2 -A 15

Repository: fntechgit/summit-admin

Length of output: 48


🏁 Script executed:

fd -type f -name "*.js" | xargs rg -l "saveSponsorManagedPage" | head -10

Repository: fntechgit/summit-admin

Length of output: 336


🏁 Script executed:

cat src/actions/base-actions.js | head -100

Repository: fntechgit/summit-admin

Length of output: 1946


🏁 Script executed:

rg -n "export.*saveSponsorManagedPage\|const saveSponsorManagedPage" src/actions/sponsor-pages-actions.js -A 20

Repository: fntechgit/summit-admin

Length of output: 48


🏁 Script executed:

rg -n "saveSponsorManagedPage" src/actions/sponsor-pages-actions.js -A 25

Repository: fntechgit/summit-admin

Length of output: 1038


🏁 Script executed:

grep -n "saveSponsorManagedPage" src/actions/sponsor-pages-actions.js

Repository: fntechgit/summit-admin

Length of output: 107


🏁 Script executed:

rg -n "postRequest" openstack-uicore-foundation 2>/dev/null || echo "Library not in repo, checking usage patterns"

Repository: fntechgit/summit-admin

Length of output: 110


🏁 Script executed:

# Check how other components handle saveSponsorManagedPage or similar patterns
rg -B 2 -A 8 "\.then\(\(\) => {.*setOpen" src/pages --type=js | head -40

Repository: fntechgit/summit-admin

Length of output: 191


🏁 Script executed:

# Search for similar then/catch patterns after saveSponsorManagedPage or similar save actions
rg -n "saveSponsorManagedPage.*then|getSponsorManagedPages" src/pages/sponsors/sponsor-pages-tab/index.js -A 5 -B 2

Repository: fntechgit/summit-admin

Length of output: 2263


🏁 Script executed:

# Look for .catch() patterns in the same file
rg -n "\.catch\(" src/pages/sponsors/sponsor-pages-tab/index.js

Repository: fntechgit/summit-admin

Length of output: 48


🏁 Script executed:

# Check getSponsorManagedPages implementation
rg -n "export const getSponsorManagedPages" src/actions/sponsor-pages-actions.js -A 15

Repository: fntechgit/summit-admin

Length of output: 601


Add error handling to prevent closing the popup and refreshing the list on failed save.

handleSaveManagedPageFromTemplate chains .then() on saveSponsorManagedPage(entity) without a .catch(). Since snackbarErrorHandler (used in the action) doesn't re-throw the error, the promise resolves normally even on failure. This causes setOpenPopup(null) and getSponsorManagedPages() to execute regardless of whether the save succeeded, closing the popup and refreshing the list even when the request fails.

Add a .catch() handler or restructure to ensure the popup only closes and the list only refreshes on confirmed success.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/pages/sponsors/sponsor-pages-tab/index.js` around lines 195 - 200, The
handler handleSaveManagedPageFromTemplate currently calls
saveSponsorManagedPage(entity).then(...) but has no .catch(), allowing
snackbarErrorHandler to swallow errors and still run setOpenPopup(null) and
getSponsorManagedPages(); change it to only close the popup and refresh on true
success by attaching a .catch() (or using async/await with try/catch) around
saveSponsorManagedPage: on success call setOpenPopup(null) and
getSponsorManagedPages(), on failure do not close the popup and let
snackbarErrorHandler display the error (or rethrow/return a rejected promise) so
failure paths prevent closing and refreshing.

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