diff --git a/src/actions/base-actions.js b/src/actions/base-actions.js index 9e1640563..36416379b 100644 --- a/src/actions/base-actions.js +++ b/src/actions/base-actions.js @@ -52,6 +52,12 @@ export const snackbarSuccessHandler = (message) => (dispatch, state) => state ); +export const snackbarWarningHandler = (message) => (dispatch, state) => + setSnackbarMessage({ ...message, type: "warning", code: CODE_200 })( + dispatch, + state + ); + export const snackbarErrorMsg = (message) => (dispatch, state) => setSnackbarMessage({ ...message, type: "error", code: CODE_200 })( dispatch, diff --git a/src/actions/sponsor-pages-actions.js b/src/actions/sponsor-pages-actions.js index 7ce4ec5ba..00d6e1230 100644 --- a/src/actions/sponsor-pages-actions.js +++ b/src/actions/sponsor-pages-actions.js @@ -27,7 +27,11 @@ import { getAccessTokenSafely, normalizeSelectAllField } from "../utils/methods"; -import { snackbarErrorHandler, snackbarSuccessHandler } from "./base-actions"; +import { + snackbarErrorHandler, + snackbarSuccessHandler, + snackbarWarningHandler +} from "./base-actions"; import { DEFAULT_CURRENT_PAGE, DEFAULT_ORDER_DIR, @@ -228,26 +232,46 @@ export const saveSponsorManagedPage = }); } - const normalizedEntity = normalizeSponsorManagedPage(entity); + const selectedPageIds = entity.pages ?? []; + const { managedPages } = getState().sponsorState; + const existingPageIds = new Set(managedPages.pages?.map((p) => p.id) ?? []); + const newPageIds = selectedPageIds.filter((id) => !existingPageIds.has(id)); + const alreadyCount = selectedPageIds.length - newPageIds.length; + const successTitle = T.translate("general.success"); + + if (selectedPageIds.length && !newPageIds.length) { + dispatch( + snackbarWarningHandler({ + title: successTitle, + html: T.translate( + "edit_sponsor.pages_tab.managed_page_already_added", + { alreadyCount } + ) + }) + ); + dispatch(stopLoading()); + return { skipped: true, reason: "already-added" }; + } + + const html = + alreadyCount > 0 + ? T.translate("edit_sponsor.pages_tab.managed_page_partially_added", { + addedCount: newPageIds.length, + alreadyCount + }) + : T.translate("edit_sponsor.pages_tab.managed_page_created"); return postRequest( null, createAction(SPONSOR_MANAGED_PAGE_ADDED), `${window.SPONSOR_PAGES_API_URL}/api/v1/summits/${currentSummit.id}/sponsors/${sponsorId}/managed-pages`, - normalizedEntity, + normalizeSponsorManagedPage({ ...entity, pages: newPageIds }), snackbarErrorHandler )(params)(dispatch) - .then(() => { - dispatch( - snackbarSuccessHandler({ - title: T.translate("general.success"), - html: T.translate("edit_sponsor.pages_tab.managed_page_created") - }) - ); - }) - .finally(() => { - dispatch(stopLoading()); - }); + .then(() => + dispatch(snackbarSuccessHandler({ title: successTitle, html })) + ) + .finally(() => dispatch(stopLoading())); }; export const deleteSponsorManagedPage = diff --git a/src/i18n/en.json b/src/i18n/en.json index f5a408eb3..f9c506668 100644 --- a/src/i18n/en.json +++ b/src/i18n/en.json @@ -2548,6 +2548,8 @@ "custom_page_created": "Custom Sponsor Page created successfully", "managed_page_saved": "Sponsor Managed Page saved successfully", "managed_page_created": "Sponsor Managed Page created successfully", + "managed_page_already_added": "Selected page(s) have already been added ({alreadyCount}).", + "managed_page_partially_added": "Added {addedCount} page(s). {alreadyCount} page(s) were already added.", "page_delete_warning": "Please verify you want to delete {page}" }, "cart_tab": { diff --git a/src/pages/sponsors/sponsor-page/tabs/sponsor-pages-tab/__tests__/sponsor-pages-tab.test.js b/src/pages/sponsors/sponsor-page/tabs/sponsor-pages-tab/__tests__/sponsor-pages-tab.test.js index 8390173b8..36b8a1f46 100644 --- a/src/pages/sponsors/sponsor-page/tabs/sponsor-pages-tab/__tests__/sponsor-pages-tab.test.js +++ b/src/pages/sponsors/sponsor-page/tabs/sponsor-pages-tab/__tests__/sponsor-pages-tab.test.js @@ -23,9 +23,12 @@ jest.mock( return (
- +
); } @@ -370,6 +373,98 @@ describe("SponsorPagesTab", () => { screen.queryByTestId("page-template-popup") ).not.toBeInTheDocument(); }); + + it("should send template selection to action for duplicate managed pages", async () => { + renderWithRedux( + , + { + initialState: { + ...defaultState, + sponsorPagePagesListState: { + ...defaultState.sponsorPagePagesListState, + managedPages: { + ...defaultState.sponsorPagePagesListState.managedPages, + pages: [createManagedPage(1)], + totalItems: 1 + } + } + } + } + ); + + const usingTemplateButton = screen.getByText( + "edit_sponsor.pages_tab.using_template" + ); + + await act(async () => { + await userEvent.click(usingTemplateButton); + }); + + expect( + screen.getByTestId("add-sponsor-page-template-popup") + ).toBeInTheDocument(); + + const submitButton = screen.getByText("Submit"); + await act(async () => { + await userEvent.click(submitButton); + }); + + expect(saveSponsorManagedPage).toHaveBeenCalledWith({ + pages: [1], + add_ons: [] + }); + expect( + screen.queryByTestId("add-sponsor-page-template-popup") + ).not.toBeInTheDocument(); + }); + + it("should send mixed template selection to action", async () => { + renderWithRedux( + , + { + initialState: { + ...defaultState, + sponsorPagePagesListState: { + ...defaultState.sponsorPagePagesListState, + managedPages: { + ...defaultState.sponsorPagePagesListState.managedPages, + pages: [createManagedPage(1)], + totalItems: 1 + } + } + } + } + ); + + const usingTemplateButton = screen.getByText( + "edit_sponsor.pages_tab.using_template" + ); + + await act(async () => { + await userEvent.click(usingTemplateButton); + }); + + const submitMixedButton = screen.getByText("Submit Mixed"); + await act(async () => { + await userEvent.click(submitMixedButton); + }); + + expect(saveSponsorManagedPage).toHaveBeenCalledWith({ + pages: [1, 2], + add_ons: [] + }); + expect( + screen.queryByTestId("add-sponsor-page-template-popup") + ).not.toBeInTheDocument(); + }); }); it("should call archiveCustomizedPage for non-archived item", async () => {