diff --git a/src/actions/page-template-actions.js b/src/actions/page-template-actions.js index 1fa0f7fab..9c6fe5443 100644 --- a/src/actions/page-template-actions.js +++ b/src/actions/page-template-actions.js @@ -55,7 +55,10 @@ export const getPageTemplates = orderDir = DEFAULT_ORDER_DIR, hideArchived = false ) => - async (dispatch) => { + async (dispatch, getState) => { + const { currentSummitState } = getState(); + const { currentSummit } = currentSummitState; + const summitTZ = currentSummit.time_zone.name; const accessToken = await getAccessTokenSafely(); const filter = []; @@ -93,7 +96,7 @@ export const getPageTemplates = createAction(RECEIVE_PAGE_TEMPLATES), `${window.SPONSOR_PAGES_API_URL}/api/v1/page-templates`, authErrorHandler, - { order, orderDir, page, perPage, term, hideArchived } + { order, orderDir, page, perPage, term, hideArchived, summitTZ } )(params)(dispatch).then(() => { dispatch(stopLoading()); }); diff --git a/src/actions/sponsor-pages-actions.js b/src/actions/sponsor-pages-actions.js index bc4fa17ba..2de241fe7 100644 --- a/src/actions/sponsor-pages-actions.js +++ b/src/actions/sponsor-pages-actions.js @@ -22,19 +22,25 @@ import { stopLoading } from "openstack-uicore-foundation/lib/utils/actions"; import T from "i18n-react/dist/i18n-react"; +import moment from "moment-timezone"; import { escapeFilterValue, getAccessTokenSafely } from "../utils/methods"; import { DEFAULT_CURRENT_PAGE, DEFAULT_ORDER_DIR, - DEFAULT_PER_PAGE + DEFAULT_PER_PAGE, + PAGES_MODULE_KINDS } from "../utils/constants"; import { snackbarErrorHandler, snackbarSuccessHandler } from "./base-actions"; export const REQUEST_SPONSOR_PAGES = "REQUEST_SPONSOR_PAGES"; export const RECEIVE_SPONSOR_PAGES = "RECEIVE_SPONSOR_PAGES"; +export const RECEIVE_SPONSOR_PAGE = "RECEIVE_SPONSOR_PAGE"; +export const SPONSOR_PAGE_UPDATED = "SPONSOR_PAGE_UPDATED"; +export const SPONSOR_PAGE_ADDED = "SPONSOR_PAGE_ADDED"; export const SPONSOR_PAGE_ARCHIVED = "SPONSOR_PAGE_ARCHIVED"; export const SPONSOR_PAGE_UNARCHIVED = "SPONSOR_PAGE_UNARCHIVED"; +export const RESET_SPONSOR_PAGE_FORM = "RESET_SPONSOR_PAGE_FORM"; export const GLOBAL_PAGE_CLONED = "GLOBAL_PAGE_CLONED"; @@ -97,6 +103,123 @@ export const getSponsorPages = }); }; +export const getSponsorPage = (pageId) => async (dispatch, getState) => { + const { currentSummitState } = getState(); + const { currentSummit } = currentSummitState; + const accessToken = await getAccessTokenSafely(); + + dispatch(startLoading()); + + const params = { + access_token: accessToken, + expand: "modules,modules.file_type" + }; + + return getRequest( + null, + createAction(RECEIVE_SPONSOR_PAGE), + `${window.SPONSOR_PAGES_API_URL}/api/v1/summits/${currentSummit.id}/show-pages/${pageId}`, + authErrorHandler + )(params)(dispatch).then(() => { + dispatch(stopLoading()); + }); +}; + +const normalizeSponsorPage = (entity) => { + const normalizedEntity = { ...entity }; + + 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; + }); + + return normalizedEntity; +}; + +export const saveSponsorPage = (entity) => async (dispatch, getState) => { + const { currentSummitState } = getState(); + const { currentSummit } = currentSummitState; + const accessToken = await getAccessTokenSafely(); + + dispatch(startLoading()); + + const params = { + access_token: accessToken + }; + + const normalizedSponsorPage = normalizeSponsorPage(entity); + + if (entity.id) { + return putRequest( + null, + createAction(SPONSOR_PAGE_UPDATED), + `${window.SPONSOR_PAGES_API_URL}/api/v1/summits/${currentSummit.id}/show-pages/${entity.id}`, + normalizedSponsorPage, + snackbarErrorHandler, + entity + )(params)(dispatch) + .then(() => { + dispatch( + snackbarSuccessHandler({ + title: T.translate("general.success"), + html: T.translate("sponsor_pages.page_saved") + }) + ); + }) + .catch((err) => { + console.error(err); + }) + .finally(() => { + dispatch(stopLoading()); + }); + } + + return postRequest( + null, + createAction(SPONSOR_PAGE_ADDED), + `${window.SPONSOR_PAGES_API_URL}/api/v1/summits/${currentSummit.id}/show-pages`, + normalizedSponsorPage, + snackbarErrorHandler, + entity + )(params)(dispatch) + .then(() => { + dispatch( + snackbarSuccessHandler({ + title: T.translate("general.success"), + html: T.translate("sponsor_pages.page_created") + }) + ); + }) + .catch((err) => { + console.error(err); + }) + .finally(() => { + dispatch(stopLoading()); + }); +}; + +export const resetSponsorPageForm = () => (dispatch) => { + dispatch(createAction(RESET_SPONSOR_PAGE_FORM)({})); +}; + export const cloneGlobalPage = (pagesIds, sponsorIds, allSponsors) => async (dispatch, getState) => { const { currentSummitState } = getState(); diff --git a/src/i18n/en.json b/src/i18n/en.json index e2a953b18..e5a054a32 100644 --- a/src/i18n/en.json +++ b/src/i18n/en.json @@ -2650,6 +2650,8 @@ "filter": "Filter", "sort_by": "Sort By", "no_sponsors_pages": "No pages found for this search criteria.", + "page_saved": "Page updated successfully.", + "page_created": "Page created successfully.", "placeholders": { "search": "Search..." }, diff --git a/src/pages/sponsors-global/page-templates/page-template-list-page.js b/src/pages/sponsors-global/page-templates/page-template-list-page.js index 473b5fc0c..caa97692b 100644 --- a/src/pages/sponsors-global/page-templates/page-template-list-page.js +++ b/src/pages/sponsors-global/page-templates/page-template-list-page.js @@ -50,7 +50,8 @@ const PageTemplateListPage = ({ archivePageTemplate, unarchivePageTemplate, savePageTemplate, - deletePageTemplate + deletePageTemplate, + summitTZ }) => { const [pageTemplateId, setPageTemplateId] = useState(null); const [openCloneDialog, setOpenCloneDialog] = useState(false); @@ -268,6 +269,7 @@ const PageTemplateListPage = ({ open={!!pageTemplateId} onClose={() => setPageTemplateId(null)} onSave={handleSavePageTemplate} + summitTZ={summitTZ} /> { +const PageTemplatePopup = ({ + pageTemplate, + open, + onClose, + onSave, + summitTZ +}) => { const handleClose = () => { onClose(); }; @@ -108,10 +115,31 @@ const PageTemplatePopup = ({ pageTemplate, open, onClose, onSave }) => { } }); + const normalizeModules = (modules = [], summitTZ = "UTC") => + modules.map((m) => { + if (m.kind === PAGES_MODULE_KINDS.MEDIA) { + const normalizeModule = { ...m }; + if (m.upload_deadline) { + normalizeModule.upload_deadline = epochToMomentTimeZone( + m.upload_deadline, + summitTZ + ); + } + if (m.file_type) { + normalizeModule.file_type_id = { + value: m.file_type.id, + label: `${m.file_type.name} (${m.file_type.allowed_extensions})` + }; + } + return normalizeModule; + } + return m; + }); + const formik = useFormik({ initialValues: { ...pageTemplate, - modules: pageTemplate?.modules || [] + modules: normalizeModules(pageTemplate?.modules, summitTZ) || [] }, validationSchema: yup.object().shape({ code: yup.string().required(T.translate("validation.required")), diff --git a/src/pages/sponsors/sponsor-pages-list-page/index.js b/src/pages/sponsors/sponsor-pages-list-page/index.js index 68d6fe1ff..c22e94bc0 100644 --- a/src/pages/sponsors/sponsor-pages-list-page/index.js +++ b/src/pages/sponsors/sponsor-pages-list-page/index.js @@ -26,12 +26,15 @@ import AddIcon from "@mui/icons-material/Add"; import { getSponsorPages, archiveSponsorPage, - unarchiveSponsorPage + unarchiveSponsorPage, + getSponsorPage, + saveSponsorPage, + resetSponsorPageForm } from "../../../actions/sponsor-pages-actions"; -import { getSponsorForm } from "../../../actions/sponsor-forms-actions"; import CustomAlert from "../../../components/mui/custom-alert"; import MuiTable from "../../../components/mui/table/mui-table"; import GlobalPagePopup from "./components/global-page/global-page-popup"; +import PageTemplatePopup from "../../sponsors-global/page-templates/page-template-popup"; const SponsorPagesListPage = ({ sponsorPages, @@ -42,10 +45,13 @@ const SponsorPagesListPage = ({ orderDir, hideArchived, totalCount, + currentSponsorPage, getSponsorPages, archiveSponsorPage, unarchiveSponsorPage, - getSponsorForm + getSponsorPage, + saveSponsorPage, + resetSponsorPageForm }) => { const [openPopup, setOpenPopup] = useState(null); @@ -73,7 +79,7 @@ const SponsorPagesListPage = ({ }; const handleRowEdit = (row) => { - getSponsorForm(row.id).then(() => { + getSponsorPage(row.id).then(() => { setOpenPopup("new"); }); }; @@ -99,6 +105,18 @@ const SponsorPagesListPage = ({ ); }; + const handleSaveSponsorPage = (entity) => { + saveSponsorPage(entity).then(() => { + setOpenPopup(null); + getSponsorPages(); + }); + }; + + const handleTemplatePopupClose = () => { + resetSponsorPageForm(); + setOpenPopup(null); + }; + const columns = [ { columnKey: "code", @@ -222,10 +240,12 @@ const SponsorPagesListPage = ({ open={openPopup === "clone"} onClose={() => setOpenPopup(null)} /> - {/* setOpenPopup(null)} - /> */} + pageTemplate={currentSponsorPage} + onClose={handleTemplatePopupClose} + onSave={handleSaveSponsorPage} + /> ); }; @@ -238,5 +258,7 @@ export default connect(mapStateToProps, { getSponsorPages, archiveSponsorPage, unarchiveSponsorPage, - getSponsorForm + getSponsorPage, + saveSponsorPage, + resetSponsorPageForm })(SponsorPagesListPage); diff --git a/src/reducers/sponsors/sponsor-pages-list-reducer.js b/src/reducers/sponsors/sponsor-pages-list-reducer.js index 2a57d10b1..67f600950 100644 --- a/src/reducers/sponsors/sponsor-pages-list-reducer.js +++ b/src/reducers/sponsors/sponsor-pages-list-reducer.js @@ -13,14 +13,22 @@ import { LOGOUT_USER } from "openstack-uicore-foundation/lib/security/actions"; import { + RECEIVE_SPONSOR_PAGE, RECEIVE_SPONSOR_PAGES, REQUEST_SPONSOR_PAGES, SPONSOR_PAGE_ARCHIVED, - SPONSOR_PAGE_UNARCHIVED + SPONSOR_PAGE_UNARCHIVED, + RESET_SPONSOR_PAGE_FORM } from "../../actions/sponsor-pages-actions"; import { SET_CURRENT_SUMMIT } from "../../actions/summit-actions"; import { PAGES_MODULE_KINDS } from "../../utils/constants"; +const DEFAULT_SPONSOR_PAGE = { + code: "", + name: "", + modules: [] +}; + const DEFAULT_STATE = { sponsorPages: [], term: "", @@ -30,7 +38,9 @@ const DEFAULT_STATE = { lastPage: 1, perPage: 10, totalCount: 0, - hideArchived: false + hideArchived: false, + currentSponsorPage: DEFAULT_SPONSOR_PAGE, + summitTZ: null }; const sponsorPagesListReducer = (state = DEFAULT_STATE, action) => { @@ -42,7 +52,7 @@ const sponsorPagesListReducer = (state = DEFAULT_STATE, action) => { return DEFAULT_STATE; } case REQUEST_SPONSOR_PAGES: { - const { order, orderDir, page, term, hideArchived } = payload; + const { order, orderDir, page, term, hideArchived, summitTZ } = payload; return { ...state, @@ -51,7 +61,8 @@ const sponsorPagesListReducer = (state = DEFAULT_STATE, action) => { sponsorPages: [], currentPage: page, term, - hideArchived + hideArchived, + summitTZ }; } case RECEIVE_SPONSOR_PAGES: { @@ -104,6 +115,14 @@ const sponsorPagesListReducer = (state = DEFAULT_STATE, action) => { sponsorPages: [...pages] }; } + case RECEIVE_SPONSOR_PAGE: { + const sponsorPage = payload.response; + + return { ...state, currentSponsorPage: sponsorPage }; + } + case RESET_SPONSOR_PAGE_FORM: { + return { ...state, currentSponsorPage: DEFAULT_SPONSOR_PAGE }; + } default: return state; }