From 2bd35b337bb4301e0f8ca3b38622ef7e13e50052 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1s=20Castillo?= Date: Fri, 6 Mar 2026 09:59:28 -0300 Subject: [PATCH 1/6] feat: WIP change columns, adjust popup, update actions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Tomás Castillo --- src/actions/sponsor-pages-actions.js | 209 ++++++++++-------- src/i18n/en.json | 9 +- src/pages/sponsors/sponsor-pages-tab/index.js | 22 +- 3 files changed, 141 insertions(+), 99 deletions(-) diff --git a/src/actions/sponsor-pages-actions.js b/src/actions/sponsor-pages-actions.js index 15cd232b4..6cc991c6a 100644 --- a/src/actions/sponsor-pages-actions.js +++ b/src/actions/sponsor-pages-actions.js @@ -39,6 +39,7 @@ export const REQUEST_SPONSOR_MANAGED_PAGES = "REQUEST_SPONSOR_MANAGED_PAGES"; export const RECEIVE_SPONSOR_MANAGED_PAGES = "RECEIVE_SPONSOR_MANAGED_PAGES"; export const SPONSOR_MANAGED_PAGE_ADDED = "SPONSOR_MANAGED_PAGE_ADDED"; export const SPONSOR_MANAGED_PAGE_DELETED = "SPONSOR_MANAGED_PAGE_DELETED"; +export const SPONSOR_MANAGED_PAGE_UPDATED = "SPONSOR_MANAGED_PAGE_UPDATED"; export const REQUEST_SPONSOR_CUSTOMIZED_PAGES = "REQUEST_SPONSOR_CUSTOMIZED_PAGES"; @@ -111,53 +112,53 @@ export const getSponsorManagedPages = orderDir = DEFAULT_ORDER_DIR, hideArchived = false ) => - async (dispatch, getState) => { - const { currentSummitState, currentSponsorState } = getState(); - const { currentSummit } = currentSummitState; - const { - entity: { id: sponsorId } - } = currentSponsorState; - const accessToken = await getAccessTokenSafely(); - const summitTZ = currentSummit.time_zone.name; - const filter = []; - - dispatch(startLoading()); - - if (term) { - const escapedTerm = escapeFilterValue(term); - filter.push(`name=@${escapedTerm},code=@${escapedTerm}`); - } - - const params = { - page, - fields: "id,code,name,kind,modules_count,allowed_add_ons,assigned_type", - per_page: perPage, - access_token: accessToken - }; - - if (hideArchived) filter.push("is_archived==0"); - - if (filter.length > 0) { - params["filter[]"] = filter; - } - - // order - if (order != null && orderDir != null) { - const orderDirSign = orderDir === 1 ? "" : "-"; - params.order = `${orderDirSign}${order}`; - } - - return getRequest( - createAction(REQUEST_SPONSOR_MANAGED_PAGES), - createAction(RECEIVE_SPONSOR_MANAGED_PAGES), - `${window.SPONSOR_PAGES_API_URL}/api/v1/summits/${currentSummit.id}/sponsors/${sponsorId}/managed-pages`, - snackbarErrorHandler, - { order, orderDir, page, perPage, term, hideArchived, summitTZ } - )(params)(dispatch).finally(() => { - dispatch(stopLoading()); - }); + async (dispatch, getState) => { + const { currentSummitState, currentSponsorState } = getState(); + const { currentSummit } = currentSummitState; + const { + entity: { id: sponsorId } + } = currentSponsorState; + const accessToken = await getAccessTokenSafely(); + const summitTZ = currentSummit.time_zone.name; + const filter = []; + + dispatch(startLoading()); + + if (term) { + const escapedTerm = escapeFilterValue(term); + filter.push(`name=@${escapedTerm},code=@${escapedTerm}`); + } + + const params = { + page, + fields: "id,code,name,kind,modules_count,allowed_add_ons,assigned_type", + per_page: perPage, + access_token: accessToken }; + if (hideArchived) filter.push("is_archived==0"); + + if (filter.length > 0) { + params["filter[]"] = filter; + } + + // order + if (order != null && orderDir != null) { + const orderDirSign = orderDir === 1 ? "" : "-"; + params.order = `${orderDirSign}${order}`; + } + + return getRequest( + createAction(REQUEST_SPONSOR_MANAGED_PAGES), + createAction(RECEIVE_SPONSOR_MANAGED_PAGES), + `${window.SPONSOR_PAGES_API_URL}/api/v1/summits/${currentSummit.id}/sponsors/${sponsorId}/managed-pages`, + snackbarErrorHandler, + { order, orderDir, page, perPage, term, hideArchived, summitTZ } + )(params)(dispatch).finally(() => { + dispatch(stopLoading()); + }); + }; + export const saveSponsorManagedPage = (entity) => async (dispatch, getState) => { const { currentSummitState, currentSponsorState } = getState(); @@ -176,6 +177,28 @@ export const saveSponsorManagedPage = fields: "id,code,name,kind,modules_count,allowed_add_ons" }; + if (entity.id) { + return putRequest( + null, + createAction(SPONSOR_CUSTOMIZED_PAGE_UPDATED), + `${window.SPONSOR_PAGES_API_URL}/api/v1/summits/${currentSummit.id}/sponsors/${sponsorId}/managed-pages/${entity.id}`, + normalizedEntity, + snackbarErrorHandler, + entity + )(params)(dispatch) + .then(() => { + dispatch( + snackbarSuccessHandler({ + title: T.translate("general.success"), + html: T.translate("edit_sponsor.pages_tab.managed_page_saved") + }) + ); + }) + .finally(() => { + dispatch(stopLoading()); + }); + } + return postRequest( null, createAction(SPONSOR_MANAGED_PAGE_ADDED), @@ -187,7 +210,7 @@ export const saveSponsorManagedPage = dispatch( snackbarSuccessHandler({ title: T.translate("general.success"), - html: T.translate("edit_sponsor.pages_tab.managed_page_saved") + html: T.translate("edit_sponsor.pages_tab.managed_page_created") }) ); }) @@ -256,55 +279,55 @@ export const getSponsorCustomizedPages = orderDir = DEFAULT_ORDER_DIR, hideArchived = false ) => - async (dispatch, getState) => { - const { currentSummitState, currentSponsorState } = getState(); - const { currentSummit } = currentSummitState; - const { - entity: { id: sponsorId } - } = currentSponsorState; - const accessToken = await getAccessTokenSafely(); - const summitTZ = currentSummit.time_zone.name; - const filter = []; - - dispatch(startLoading()); - - if (term) { - const escapedTerm = escapeFilterValue(term); - filter.push(`name=@${escapedTerm},code=@${escapedTerm}`); - } - - const params = { - page, - fields: - "id,code,name,allowed_add_ons,is_archived,modules,allowed_add_ons.type,allowed_add_ons.name,allowed_add_ons.id", - expand: "allowed_add_ons", - per_page: perPage, - access_token: accessToken - }; - - if (hideArchived) filter.push("is_archived==0"); - - if (filter.length > 0) { - params["filter[]"] = filter; - } - - // order - if (order != null && orderDir != null) { - const orderDirSign = orderDir === 1 ? "" : "-"; - params.order = `${orderDirSign}${order}`; - } - - return getRequest( - createAction(REQUEST_SPONSOR_CUSTOMIZED_PAGES), - createAction(RECEIVE_SPONSOR_CUSTOMIZED_PAGES), - `${window.SPONSOR_PAGES_API_URL}/api/v1/summits/${currentSummit.id}/sponsors/${sponsorId}/sponsor-pages`, - snackbarErrorHandler, - { order, orderDir, page, perPage, term, hideArchived, summitTZ } - )(params)(dispatch).finally(() => { - dispatch(stopLoading()); - }); + async (dispatch, getState) => { + const { currentSummitState, currentSponsorState } = getState(); + const { currentSummit } = currentSummitState; + const { + entity: { id: sponsorId } + } = currentSponsorState; + const accessToken = await getAccessTokenSafely(); + const summitTZ = currentSummit.time_zone.name; + const filter = []; + + dispatch(startLoading()); + + if (term) { + const escapedTerm = escapeFilterValue(term); + filter.push(`name=@${escapedTerm},code=@${escapedTerm}`); + } + + const params = { + page, + fields: + "id,code,name,allowed_add_ons,is_archived,modules,allowed_add_ons.type,allowed_add_ons.name,allowed_add_ons.id", + expand: "allowed_add_ons", + per_page: perPage, + access_token: accessToken }; + if (hideArchived) filter.push("is_archived==0"); + + if (filter.length > 0) { + params["filter[]"] = filter; + } + + // order + if (order != null && orderDir != null) { + const orderDirSign = orderDir === 1 ? "" : "-"; + params.order = `${orderDirSign}${order}`; + } + + return getRequest( + createAction(REQUEST_SPONSOR_CUSTOMIZED_PAGES), + createAction(RECEIVE_SPONSOR_CUSTOMIZED_PAGES), + `${window.SPONSOR_PAGES_API_URL}/api/v1/summits/${currentSummit.id}/sponsors/${sponsorId}/sponsor-pages`, + snackbarErrorHandler, + { order, orderDir, page, perPage, term, hideArchived, summitTZ } + )(params)(dispatch).finally(() => { + dispatch(stopLoading()); + }); + }; + export const getSponsorCustomizedPage = (pageId) => async (dispatch, getState) => { const { currentSummitState, currentSponsorState } = getState(); diff --git a/src/i18n/en.json b/src/i18n/en.json index 38bff22d6..09af154b4 100644 --- a/src/i18n/en.json +++ b/src/i18n/en.json @@ -2493,11 +2493,12 @@ "no_pages": "There are no pages that match the criteria", "add_page_using_template": "Add Page Template", "add_selected_page_template": "Add Selected Page Template", - "managed_page_saved": "Managed Page updated successfully.", - "custom_page_saved": "Custom Sponsor Page saved", - "custom_page_created": "Custom Sponsor Page created", "customized_page_archived": "Customized Sponsor Page successfully archived.", - "customized_page_unarchived": "Customized Sponsor Page successfully unarchived." + "customized_page_unarchived": "Customized Sponsor Page successfully unarchived.", + "custom_page_saved": "Custom Sponsor Page saved successfully", + "custom_page_created": "Custom Sponsor Page created successfully", + "managed_page_saved": "Sponsor Managed Page saved successfully", + "managed_page_created": "Sponsor Managed Page created successfully" }, "cart_tab": { "new_form": "New Form", diff --git a/src/pages/sponsors/sponsor-pages-tab/index.js b/src/pages/sponsors/sponsor-pages-tab/index.js index cc362d9f7..5526d5db4 100644 --- a/src/pages/sponsors/sponsor-pages-tab/index.js +++ b/src/pages/sponsors/sponsor-pages-tab/index.js @@ -23,6 +23,7 @@ import { Grid2 } from "@mui/material"; import AddIcon from "@mui/icons-material/Add"; +import ArrowForwardIcon from "@mui/icons-material/ArrowForward"; import { getSponsorManagedPages, getSponsorCustomizedPages, @@ -307,7 +308,25 @@ const SponsorPagesTab = ({ ]; const managedPagesColumns = [ - ...baseColumns(T.translate("edit_sponsor.pages_tab.managed_pages")) + ...baseColumns(T.translate("edit_sponsor.pages_tab.managed_pages")), + { + columnKey: "customize", + header: "", + width: 156, + align: "center", + render: (row) => ( + + ), + dottedBorder: true + } ]; const customizedPagesColumns = [ @@ -426,7 +445,6 @@ const SponsorPagesTab = ({ onPageChange={handleManagedPageChange} onPerPageChange={handleManagedPerPageChange} onSort={handleManagedSort} - onEdit={handleManagedEdit} onDelete={handleManagedDelete} canDelete={(row) => row.assigned_type === SPONSOR_MANAGED_PAGE_ASSIGNMENT.EXPLICIT From a4880ab5d5106dcf462cb9761bd04c94ac7edc86 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1s=20Castillo?= Date: Wed, 18 Mar 2026 23:53:21 -0300 Subject: [PATCH 2/6] fix: WIP new columns, actions to edit managed pages MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Tomás Castillo --- src/actions/sponsor-pages-actions.js | 29 ++++++++++++++++++- src/pages/sponsors/sponsor-pages-tab/index.js | 29 +++++++++++++++++-- .../sponsor-page-pages-list-reducer.js | 8 +++-- 3 files changed, 59 insertions(+), 7 deletions(-) diff --git a/src/actions/sponsor-pages-actions.js b/src/actions/sponsor-pages-actions.js index 6cc991c6a..a6cb7e48e 100644 --- a/src/actions/sponsor-pages-actions.js +++ b/src/actions/sponsor-pages-actions.js @@ -37,6 +37,7 @@ export const RESET_EDIT_PAGE = "RESET_EDIT_PAGE"; export const REQUEST_SPONSOR_MANAGED_PAGES = "REQUEST_SPONSOR_MANAGED_PAGES"; export const RECEIVE_SPONSOR_MANAGED_PAGES = "RECEIVE_SPONSOR_MANAGED_PAGES"; +export const RECEIVE_SPONSOR_MANAGED_PAGE = "RECEIVE_SPONSOR_MANAGED_PAGE"; export const SPONSOR_MANAGED_PAGE_ADDED = "SPONSOR_MANAGED_PAGE_ADDED"; export const SPONSOR_MANAGED_PAGE_DELETED = "SPONSOR_MANAGED_PAGE_DELETED"; export const SPONSOR_MANAGED_PAGE_UPDATED = "SPONSOR_MANAGED_PAGE_UPDATED"; @@ -159,6 +160,32 @@ export const getSponsorManagedPages = }); }; +export const getSponsorManagedPage = (pageId) => async (dispatch, getState) => { + const { currentSummitState, currentSponsorState } = getState(); + const { currentSummit } = currentSummitState; + const { + entity: { id: sponsorId } + } = currentSponsorState; + const accessToken = await getAccessTokenSafely(); + + dispatch(startLoading()); + + const params = { + // fields: "id,code,name,kind,modules_count,allowed_add_ons", + // expand: "modules", + access_token: accessToken + }; + + return getRequest( + null, + createAction(RECEIVE_SPONSOR_MANAGED_PAGE), + `${window.SPONSOR_PAGES_API_URL}/api/v1/summits/${currentSummit.id}/sponsors/${sponsorId}/managed-pages/${pageId}`, + snackbarErrorHandler + )(params)(dispatch).then(() => { + dispatch(stopLoading()); + }); +}; + export const saveSponsorManagedPage = (entity) => async (dispatch, getState) => { const { currentSummitState, currentSponsorState } = getState(); @@ -256,7 +283,7 @@ const normalizeSponsorManagedPage = (entity) => { show_page_ids: entity.pages }; - if (entity.add_ons.includes("all")) { + if (normalizedEntity.allowed_add_ons.includes("all")) { normalizedEntity.apply_to_all_add_ons = true; normalizedEntity.allowed_add_ons = []; } else { diff --git a/src/pages/sponsors/sponsor-pages-tab/index.js b/src/pages/sponsors/sponsor-pages-tab/index.js index 5526d5db4..66733ceb2 100644 --- a/src/pages/sponsors/sponsor-pages-tab/index.js +++ b/src/pages/sponsors/sponsor-pages-tab/index.js @@ -26,6 +26,7 @@ import AddIcon from "@mui/icons-material/Add"; import ArrowForwardIcon from "@mui/icons-material/ArrowForward"; import { getSponsorManagedPages, + getSponsorManagedPage, getSponsorCustomizedPages, saveSponsorManagedPage, saveSponsorCustomizedPage, @@ -55,6 +56,7 @@ const SponsorPagesTab = ({ summitTZ, currentEditPage, getSponsorManagedPages, + getSponsorManagedPage, saveSponsorManagedPage, getSponsorCustomizedPages, saveSponsorCustomizedPage, @@ -194,7 +196,8 @@ const SponsorPagesTab = ({ console.log("ARCHIVE MANAGED ", item); const handleManagedEdit = (item) => { - console.log("EDIT MANAGED ", item); + console.log("CHECK!", item); + getSponsorManagedPage(item.id).then(() => setOpenPopup("managedPagePopup")); }; const handleManagedDelete = (itemId) => { @@ -268,6 +271,21 @@ const SponsorPagesTab = ({ .finally(() => setOpenPopup(null)); }; + const handleSaveManagedPage = (entity) => { + saveSponsorManagedPage(entity) + .then(() => { + const { perPage, order, orderDir } = managedPages; + getSponsorManagedPages( + term, + DEFAULT_CURRENT_PAGE, + perPage, + order, + orderDir + ); + }) + .finally(() => setOpenPopup(null)); + }; + const handleClosePagePopup = () => { resetSponsorPage(); setOpenPopup(null); @@ -462,9 +480,13 @@ const SponsorPagesTab = ({ /> )} - {openPopup === "pagePopup" && ( + {(openPopup === "pagePopup" || openPopup === "managedPagePopup") && ( ({ export default connect(mapStateToProps, { getSponsorManagedPages, + getSponsorManagedPage, saveSponsorManagedPage, getSponsorCustomizedPage, getSponsorCustomizedPages, diff --git a/src/reducers/sponsors/sponsor-page-pages-list-reducer.js b/src/reducers/sponsors/sponsor-page-pages-list-reducer.js index 3ad921478..7869939a6 100644 --- a/src/reducers/sponsors/sponsor-page-pages-list-reducer.js +++ b/src/reducers/sponsors/sponsor-page-pages-list-reducer.js @@ -20,7 +20,8 @@ import { RECEIVE_SPONSOR_CUSTOMIZED_PAGE, RESET_EDIT_PAGE, SPONSOR_CUSTOMIZED_PAGE_ARCHIVED, - SPONSOR_CUSTOMIZED_PAGE_UNARCHIVED + SPONSOR_CUSTOMIZED_PAGE_UNARCHIVED, + RECEIVE_SPONSOR_MANAGED_PAGE } from "../../actions/sponsor-pages-actions"; import { SET_CURRENT_SUMMIT } from "../../actions/summit-actions"; import { RECEIVE_GLOBAL_SPONSORSHIPS } from "../../actions/sponsor-forms-actions"; @@ -172,9 +173,10 @@ const sponsorPagePagesListReducer = (state = DEFAULT_STATE, action) => { } }; } + case RECEIVE_SPONSOR_MANAGED_PAGE: case RECEIVE_SPONSOR_CUSTOMIZED_PAGE: { - const customizedPage = payload.response; - return { ...state, currentEditPage: customizedPage }; + const editPage = payload.response; + return { ...state, currentEditPage: editPage }; } case SPONSOR_CUSTOMIZED_PAGE_ARCHIVED: { const { pageId } = payload; From a5d6d41b33bde481f3cf4ff81bdc6679e7c6fa68 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1s=20Castillo?= Date: Thu, 26 Mar 2026 00:14:59 -0300 Subject: [PATCH 3/6] fix: adjust endpoint to get show page, adjust reducer and action, reload tables after save MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Tomás Castillo --- src/actions/sponsor-pages-actions.js | 68 +++++++++++++++---- src/pages/sponsors/sponsor-pages-tab/index.js | 14 ++-- .../sponsor-page-pages-list-reducer.js | 21 +++++- 3 files changed, 86 insertions(+), 17 deletions(-) diff --git a/src/actions/sponsor-pages-actions.js b/src/actions/sponsor-pages-actions.js index a6cb7e48e..836bf44e9 100644 --- a/src/actions/sponsor-pages-actions.js +++ b/src/actions/sponsor-pages-actions.js @@ -23,7 +23,10 @@ import { } from "openstack-uicore-foundation/lib/utils/actions"; import T from "i18n-react/dist/i18n-react"; import moment from "moment-timezone"; -import { getAccessTokenSafely } from "../utils/methods"; +import { + getAccessTokenSafely, + normalizeSelectAllField +} from "../utils/methods"; import { snackbarErrorHandler, snackbarSuccessHandler } from "./base-actions"; import { DEFAULT_CURRENT_PAGE, @@ -161,27 +164,23 @@ export const getSponsorManagedPages = }; export const getSponsorManagedPage = (pageId) => async (dispatch, getState) => { - const { currentSummitState, currentSponsorState } = getState(); + const { currentSummitState } = getState(); const { currentSummit } = currentSummitState; - const { - entity: { id: sponsorId } - } = currentSponsorState; const accessToken = await getAccessTokenSafely(); dispatch(startLoading()); const params = { - // fields: "id,code,name,kind,modules_count,allowed_add_ons", - // expand: "modules", - access_token: accessToken + access_token: accessToken, + expand: "modules" }; return getRequest( null, createAction(RECEIVE_SPONSOR_MANAGED_PAGE), - `${window.SPONSOR_PAGES_API_URL}/api/v1/summits/${currentSummit.id}/sponsors/${sponsorId}/managed-pages/${pageId}`, + `${window.SPONSOR_PAGES_API_URL}/api/v1/summits/${currentSummit.id}/show-pages/${pageId}`, snackbarErrorHandler - )(params)(dispatch).then(() => { + )(params)(dispatch).finally(() => { dispatch(stopLoading()); }); }; @@ -197,14 +196,14 @@ export const saveSponsorManagedPage = dispatch(startLoading()); - const normalizedEntity = normalizeSponsorManagedPage(entity); - const params = { access_token: accessToken, fields: "id,code,name,kind,modules_count,allowed_add_ons" }; if (entity.id) { + const normalizedEntity = normalizeSponsorManagedPageToCustomize(entity); + return putRequest( null, createAction(SPONSOR_CUSTOMIZED_PAGE_UPDATED), @@ -226,6 +225,8 @@ export const saveSponsorManagedPage = }); } + const normalizedEntity = normalizeSponsorManagedPage(entity); + return postRequest( null, createAction(SPONSOR_MANAGED_PAGE_ADDED), @@ -293,6 +294,49 @@ const normalizeSponsorManagedPage = (entity) => { return normalizedEntity; }; + +const normalizeSponsorManagedPageToCustomize = (entity) => { + const normalizedEntity = { + ...entity, + ...normalizeSelectAllField( + entity.allowed_add_ons, + "apply_to_all_types", + "allowed_add_ons" + ) + }; + + normalizedEntity.modules = entity.modules.map((module) => { + const normalizedModule = { ...module }; + + if (module.kind === PAGES_MODULE_KINDS.MEDIA && module.upload_deadline) { + normalizedModule.upload_deadline = moment + .utc(module.upload_deadline) + .unix(); + } + + if (module.kind === PAGES_MODULE_KINDS.MEDIA && module.file_type_id) { + normalizedModule.file_type_id = + module.file_type_id?.value || module.file_type_id; + } + + if (module.kind === PAGES_MODULE_KINDS.DOCUMENT && module.file) { + normalizedModule.file = module.file[0] || null; + } + + delete normalizedModule._tempId; + + return normalizedModule; + }); + + delete normalizedEntity.page_ptr_id; + delete normalizedEntity.sponsorship_types; + delete normalizedEntity.summit_id; + delete normalizedEntity.template_id; + delete normalizedEntity.modules_count; + delete normalizedEntity.id; + + return normalizedEntity; +}; /* ************************************************************************ */ /* CUSTOMIZED PAGES */ /* ************************************************************************ */ diff --git a/src/pages/sponsors/sponsor-pages-tab/index.js b/src/pages/sponsors/sponsor-pages-tab/index.js index 66733ceb2..19586b6b6 100644 --- a/src/pages/sponsors/sponsor-pages-tab/index.js +++ b/src/pages/sponsors/sponsor-pages-tab/index.js @@ -274,13 +274,19 @@ const SponsorPagesTab = ({ const handleSaveManagedPage = (entity) => { saveSponsorManagedPage(entity) .then(() => { - const { perPage, order, orderDir } = managedPages; getSponsorManagedPages( term, DEFAULT_CURRENT_PAGE, - perPage, - order, - orderDir + managedPages.perPage, + managedPages.order, + managedPages.orderDir + ); + getSponsorCustomizedPages( + term, + DEFAULT_CURRENT_PAGE, + customizedPages.perPage, + customizedPages.order, + customizedPages.orderDir ); }) .finally(() => setOpenPopup(null)); diff --git a/src/reducers/sponsors/sponsor-page-pages-list-reducer.js b/src/reducers/sponsors/sponsor-page-pages-list-reducer.js index 7869939a6..ed4c8cf4a 100644 --- a/src/reducers/sponsors/sponsor-page-pages-list-reducer.js +++ b/src/reducers/sponsors/sponsor-page-pages-list-reducer.js @@ -12,6 +12,7 @@ * */ import { LOGOUT_USER } from "openstack-uicore-foundation/lib/security/actions"; +import { epochToMomentTimeZone } from "openstack-uicore-foundation/lib/utils/methods"; import { REQUEST_SPONSOR_MANAGED_PAGES, RECEIVE_SPONSOR_MANAGED_PAGES, @@ -173,7 +174,25 @@ const sponsorPagePagesListReducer = (state = DEFAULT_STATE, action) => { } }; } - case RECEIVE_SPONSOR_MANAGED_PAGE: + case RECEIVE_SPONSOR_MANAGED_PAGE: { + const editPage = payload.response; + + const currentEditPage = { + ...editPage, + modules: editPage.modules.map((m) => ({ + ...m, + ...(m.upload_deadline + ? { + upload_deadline: epochToMomentTimeZone( + m.upload_deadline, + state.summitTZ || "UTC" + ) + } + : {}) + })) + }; + return { ...state, currentEditPage }; + } case RECEIVE_SPONSOR_CUSTOMIZED_PAGE: { const editPage = payload.response; return { ...state, currentEditPage: editPage }; From d3ed9e9dd97b03c9fa9584f181ee03df904dbb38 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1s=20Castillo?= Date: Thu, 26 Mar 2026 00:50:36 -0300 Subject: [PATCH 4/6] fix: add unit tests, custom title on page popup MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Tomás Castillo --- src/i18n/en.json | 4 +- .../page-template-popup/index.js | 23 +++- .../__tests__/sponsor-pages-tab.test.js | 123 ++++++++++++++++++ src/pages/sponsors/sponsor-pages-tab/index.js | 16 ++- 4 files changed, 156 insertions(+), 10 deletions(-) diff --git a/src/i18n/en.json b/src/i18n/en.json index 09af154b4..22da622a0 100644 --- a/src/i18n/en.json +++ b/src/i18n/en.json @@ -2493,6 +2493,7 @@ "no_pages": "There are no pages that match the criteria", "add_page_using_template": "Add Page Template", "add_selected_page_template": "Add Selected Page Template", + "title_customize": "Customize Managed Page", "customized_page_archived": "Customized Sponsor Page successfully archived.", "customized_page_unarchived": "Customized Sponsor Page successfully unarchived.", "custom_page_saved": "Custom Sponsor Page saved successfully", @@ -4047,7 +4048,8 @@ "sponsorship_type": "Always apply to" }, "page_crud": { - "title": "Create New Page", + "title_create": "Create New Page", + "title_edit": "Edit Page", "add_info": "Add Info", "add_doc": "Add Document Download", "add_media": "Add Media Request", diff --git a/src/pages/sponsors-global/page-templates/page-template-popup/index.js b/src/pages/sponsors-global/page-templates/page-template-popup/index.js index 6b75729f4..b576fc171 100644 --- a/src/pages/sponsors-global/page-templates/page-template-popup/index.js +++ b/src/pages/sponsors-global/page-templates/page-template-popup/index.js @@ -31,7 +31,21 @@ import DropdownCheckbox from "../../../../components/mui/dropdown-checkbox"; import MuiFormikSelectGroup from "../../../../components/mui/formik-inputs/mui-formik-select-group"; import { querySponsorAddons } from "../../../../actions/sponsor-actions"; -const PageTemplatePopup = ({ pageTemplate, onClose, onSave, sponsorships, summitId, sponsorId, sponsorshipIds }) => { +const PageTemplatePopup = ({ + pageTemplate, + onClose, + onSave, + sponsorships, + summitId, + sponsorId, + sponsorshipIds, + title +}) => { + const popupTitle = + title ?? + (pageTemplate?.id + ? T.translate("page_template_list.page_crud.title_edit") + : T.translate("page_template_list.page_crud.title_create")); const showSponsorships = Array.isArray(sponsorships) && sponsorships.length > 0; @@ -157,9 +171,7 @@ const PageTemplatePopup = ({ pageTemplate, onClose, onSave, sponsorships, summit return ( - - {T.translate("page_template_list.page_crud.title")} - + {popupTitle} @@ -278,7 +290,8 @@ PageTemplatePopup.propTypes = { sponsorships: PropTypes.array, sponsorshipIds: PropTypes.array, summitId: PropTypes.number, - sponsorId: PropTypes.number + sponsorId: PropTypes.number, + title: PropTypes.string }; export default PageTemplatePopup; diff --git a/src/pages/sponsors/sponsor-pages-tab/__tests__/sponsor-pages-tab.test.js b/src/pages/sponsors/sponsor-pages-tab/__tests__/sponsor-pages-tab.test.js index 27f9b9d39..6d25a17f5 100644 --- a/src/pages/sponsors/sponsor-pages-tab/__tests__/sponsor-pages-tab.test.js +++ b/src/pages/sponsors/sponsor-pages-tab/__tests__/sponsor-pages-tab.test.js @@ -6,6 +6,10 @@ import { renderWithRedux } from "../../../../utils/test-utils"; import { DEFAULT_STATE as sponsorPagesDefaultState } from "../../../../reducers/sponsors/sponsor-page-pages-list-reducer"; import { getSponsorCustomizedPage, + getSponsorManagedPage, + getSponsorManagedPages, + getSponsorCustomizedPages, + saveSponsorManagedPage, archiveCustomizedPage, unarchiveCustomizedPage } from "../../../../actions/sponsor-pages-actions"; @@ -49,6 +53,7 @@ jest.mock("../../../../actions/sponsor-pages-actions", () => ({ () => () => Promise.resolve({ id: 1, name: "Test Page" }) ), saveSponsorCustomizedPage: jest.fn(() => () => Promise.resolve()), + getSponsorManagedPage: jest.fn(() => () => Promise.resolve()), saveSponsorManagedPage: jest.fn(() => () => Promise.resolve()), resetSponsorPage: jest.fn(() => ({ type: "MOCK_ACTION" })), archiveCustomizedPage: jest.fn(() => () => Promise.resolve()), @@ -68,6 +73,14 @@ const createSponsor = (overrides = {}) => ({ ...overrides }); +const createManagedPage = (id, overrides = {}) => ({ + id, + code: `MANAGED-${id}`, + name: `Managed Page ${id}`, + assigned_type: "EXPLICIT", + ...overrides +}); + const createCustomizedPage = (id, overrides = {}) => ({ id, code: `CODE-${id}`, @@ -189,6 +202,116 @@ describe("SponsorPagesTab", () => { }); }); + it("should render Customize button in managed pages rows", async () => { + renderWithRedux( + , + { + initialState: { + sponsorPagePagesListState: { + ...defaultState.sponsorPagePagesListState, + managedPages: { + ...defaultState.sponsorPagePagesListState.managedPages, + pages: [createManagedPage(1)], + totalItems: 1 + } + } + } + } + ); + + expect( + screen.getByText("edit_sponsor.forms_tab.customize") + ).toBeInTheDocument(); + expect(screen.getByTestId("ArrowForwardIcon")).toBeInTheDocument(); + }); + + it("should call getSponsorManagedPage and open popup when Customize is clicked", async () => { + renderWithRedux( + , + { + initialState: { + sponsorPagePagesListState: { + ...defaultState.sponsorPagePagesListState, + managedPages: { + ...defaultState.sponsorPagePagesListState.managedPages, + pages: [createManagedPage(1)], + totalItems: 1 + } + } + } + } + ); + + const customizeButton = screen.getByText( + "edit_sponsor.forms_tab.customize" + ); + await act(async () => { + await userEvent.click(customizeButton); + }); + + expect(getSponsorManagedPage).toHaveBeenCalledWith(1); + await waitFor(() => { + expect(screen.getByTestId("page-template-popup")).toBeInTheDocument(); + }); + }); + + it("should call saveSponsorManagedPage, refresh both grids, and close popup after saving a managed page customization", async () => { + renderWithRedux( + , + { + initialState: { + sponsorPagePagesListState: { + ...defaultState.sponsorPagePagesListState, + managedPages: { + ...defaultState.sponsorPagePagesListState.managedPages, + pages: [createManagedPage(1)], + totalItems: 1 + } + } + } + } + ); + + const customizeButton = screen.getByText( + "edit_sponsor.forms_tab.customize" + ); + await act(async () => { + await userEvent.click(customizeButton); + }); + + await waitFor(() => { + expect(screen.getByTestId("page-template-popup")).toBeInTheDocument(); + }); + + const saveButton = screen.getByText("Save"); + await act(async () => { + await userEvent.click(saveButton); + }); + + expect(saveSponsorManagedPage).toHaveBeenCalled(); + + await waitFor(() => { + expect(getSponsorManagedPages).toHaveBeenCalledTimes(2); + expect(getSponsorCustomizedPages).toHaveBeenCalledTimes(2); + }); + + expect( + screen.queryByTestId("page-template-popup") + ).not.toBeInTheDocument(); + }); + it("should refresh customized pages list after save", async () => { const { getSponsorCustomizedPages diff --git a/src/pages/sponsors/sponsor-pages-tab/index.js b/src/pages/sponsors/sponsor-pages-tab/index.js index 19586b6b6..4c1ecdf48 100644 --- a/src/pages/sponsors/sponsor-pages-tab/index.js +++ b/src/pages/sponsors/sponsor-pages-tab/index.js @@ -173,7 +173,7 @@ const SponsorPagesTab = ({ }; const handleAddPage = () => { - setOpenPopup("pagePopup"); + setOpenPopup("customizedPagePopup"); }; const handleArchiveCustomizedPage = (item) => @@ -215,7 +215,9 @@ const SponsorPagesTab = ({ }; const handleCustomizedEdit = (item) => { - getSponsorCustomizedPage(item.id).then(() => setOpenPopup("pagePopup")); + getSponsorCustomizedPage(item.id).then(() => + setOpenPopup("customizedPagePopup") + ); }; const handleCustomizedDelete = (itemId) => { @@ -486,10 +488,16 @@ const SponsorPagesTab = ({ /> )} - {(openPopup === "pagePopup" || openPopup === "managedPagePopup") && ( + {(openPopup === "customizedPagePopup" || + openPopup === "managedPagePopup") && ( Date: Thu, 26 Mar 2026 00:53:16 -0300 Subject: [PATCH 5/6] fix: adjust prop on payload at normalize function MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Tomás Castillo --- src/actions/sponsor-pages-actions.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/actions/sponsor-pages-actions.js b/src/actions/sponsor-pages-actions.js index 836bf44e9..9fe23da72 100644 --- a/src/actions/sponsor-pages-actions.js +++ b/src/actions/sponsor-pages-actions.js @@ -300,7 +300,7 @@ const normalizeSponsorManagedPageToCustomize = (entity) => { ...entity, ...normalizeSelectAllField( entity.allowed_add_ons, - "apply_to_all_types", + "apply_to_all_add_ons", "allowed_add_ons" ) }; From 2b437c02b05900cac62ac319b18f9acb2edbb18f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1s=20Castillo?= Date: Thu, 26 Mar 2026 01:08:26 -0300 Subject: [PATCH 6/6] fix: add missing hideArchived parameter MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Tomás Castillo --- src/pages/sponsors/sponsor-pages-tab/index.js | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/pages/sponsors/sponsor-pages-tab/index.js b/src/pages/sponsors/sponsor-pages-tab/index.js index 4c1ecdf48..224dca9ba 100644 --- a/src/pages/sponsors/sponsor-pages-tab/index.js +++ b/src/pages/sponsors/sponsor-pages-tab/index.js @@ -252,7 +252,8 @@ const SponsorPagesTab = ({ DEFAULT_CURRENT_PAGE, perPage, order, - orderDir + orderDir, + hideArchived ); }) .finally(() => setOpenPopup(null)); @@ -267,7 +268,8 @@ const SponsorPagesTab = ({ DEFAULT_CURRENT_PAGE, perPage, order, - orderDir + orderDir, + hideArchived ); }) .finally(() => setOpenPopup(null)); @@ -281,14 +283,16 @@ const SponsorPagesTab = ({ DEFAULT_CURRENT_PAGE, managedPages.perPage, managedPages.order, - managedPages.orderDir + managedPages.orderDir, + hideArchived ); getSponsorCustomizedPages( term, DEFAULT_CURRENT_PAGE, customizedPages.perPage, customizedPages.order, - customizedPages.orderDir + customizedPages.orderDir, + hideArchived ); }) .finally(() => setOpenPopup(null));