From 1cb7a9f9a851f0bebaf8a2c2ba9b3bb7e060fbbd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1s=20Castillo?= Date: Wed, 18 Dec 2024 23:31:45 -0300 Subject: [PATCH 1/6] New fields and relations for get summit by id, replace props used for timezone MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Tomás Castillo --- src/actions/attendee-actions.js | 6 +- src/actions/audit-log-actions.js | 2 +- src/actions/event-actions.js | 8 +- src/actions/order-actions.js | 2 +- src/actions/sponsor-actions.js | 640 +++++++++--------- src/actions/summit-actions.js | 109 ++- src/actions/summit-builder-actions.js | 6 +- src/actions/ticket-actions.js | 2 +- src/components/forms/tax-type-form.js | 1 - .../schedule-admin-dashboard.js | 175 +++-- .../schedule-admin-empty-spots-list.js | 91 +-- .../schedule-admin-empty-spots-modal.js | 113 ++-- src/components/schedule-modal/index.js | 19 +- .../summit-event-bulk-editor-form.js | 8 +- .../summit-event-bulk-editor-item.js | 10 +- .../attendees/summit-attendees-list-page.js | 4 +- src/pages/events/summit-event-list-page.js | 16 +- src/pages/orders/purchase-order-list-page.js | 4 +- src/pages/summits/summit-dashboard-page.js | 117 ++-- src/utils/constants.js | 6 + src/utils/summitUtils.js | 8 +- 21 files changed, 730 insertions(+), 617 deletions(-) diff --git a/src/actions/attendee-actions.js b/src/actions/attendee-actions.js index f4c04539a..cb13d778f 100644 --- a/src/actions/attendee-actions.js +++ b/src/actions/attendee-actions.js @@ -223,7 +223,7 @@ export const getAttendees = const { currentSummitState } = getState(); const accessToken = await getAccessTokenSafely(); const { currentSummit } = currentSummitState; - const summitTZ = currentSummit.time_zone.name; + const summitTZ = currentSummit.time_zone_id; dispatch(startLoading()); const params = { @@ -311,7 +311,9 @@ export const getAttendee = (attendeeId) => async (dispatch, getState) => { createAction(RECEIVE_ATTENDEE), `${window.API_BASE_URL}/api/v1/summits/${currentSummit.id}/attendees/${attendeeId}`, authErrorHandler - )(params)(dispatch).then(({ response }) => getAttendeeOrders(response)(dispatch, getState)); + )(params)(dispatch).then(({ response }) => + getAttendeeOrders(response)(dispatch, getState) + ); }; export const getAttendeeOrders = (attendee) => async (dispatch) => { diff --git a/src/actions/audit-log-actions.js b/src/actions/audit-log-actions.js index 4bf9ffc58..e61fb6a24 100644 --- a/src/actions/audit-log-actions.js +++ b/src/actions/audit-log-actions.js @@ -79,7 +79,7 @@ export const getAuditLog = const { currentSummitState } = getState(); const accessToken = await getAccessTokenSafely(); const { currentSummit } = currentSummitState; - const summitTZ = currentSummit.time_zone.name; + const summitTZ = currentSummit.time_zone_id; const summitFilter = [`summit_id==${currentSummit.id}`]; dispatch(startLoading()); diff --git a/src/actions/event-actions.js b/src/actions/event-actions.js index 9b1784c1b..a4e39c81c 100644 --- a/src/actions/event-actions.js +++ b/src/actions/event-actions.js @@ -546,7 +546,7 @@ export const getEvents = const { currentSummitState } = getState(); const accessToken = await getAccessTokenSafely(); const { currentSummit } = currentSummitState; - const summitTZ = currentSummit.time_zone.name; + const summitTZ = currentSummit.time_zone_id; dispatch(startLoading()); @@ -665,7 +665,7 @@ export const getEventsForOccupancy = const accessToken = await getAccessTokenSafely(); const { currentSummit } = currentSummitState; const filter = []; - const summitTZ = currentSummit.time_zone.name; + const summitTZ = currentSummit.time_zone_id; let endPoint = "events/published"; dispatch(startLoading()); @@ -731,7 +731,7 @@ export const getEventsForOccupancyCSV = const accessToken = await getAccessTokenSafely(); const { currentSummit } = currentSummitState; const filter = []; - const summitTZ = currentSummit.time_zone.name; + const summitTZ = currentSummit.time_zone_id; dispatch(startLoading()); @@ -792,7 +792,7 @@ export const getCurrentEventForOccupancy = const accessToken = await getAccessTokenSafely(); const { currentSummit } = currentSummitState; const filter = []; - const summitTZ = currentSummit.time_zone.name; + const summitTZ = currentSummit.time_zone_id; let endPoint = `${window.API_BASE_URL}/api/v1/summits/${currentSummit.id}`; dispatch(startLoading()); diff --git a/src/actions/order-actions.js b/src/actions/order-actions.js index 6c521553a..7ff6646fc 100644 --- a/src/actions/order-actions.js +++ b/src/actions/order-actions.js @@ -524,7 +524,7 @@ export const getPurchaseOrders = const { currentSummitState } = getState(); const accessToken = await getAccessTokenSafely(); const { currentSummit } = currentSummitState; - const summitTZ = currentSummit.time_zone.name; + const summitTZ = currentSummit.time_zone_id; dispatch(startLoading()); diff --git a/src/actions/sponsor-actions.js b/src/actions/sponsor-actions.js index 094f733a4..729615047 100644 --- a/src/actions/sponsor-actions.js +++ b/src/actions/sponsor-actions.js @@ -159,50 +159,50 @@ export const getSponsors = order = "order", orderDir = 1 ) => - async (dispatch, getState) => { - const { currentSummitState } = getState(); - const accessToken = await getAccessTokenSafely(); - const { currentSummit } = currentSummitState; - const filter = []; + async (dispatch, getState) => { + const { currentSummitState } = getState(); + const accessToken = await getAccessTokenSafely(); + const { currentSummit } = currentSummitState; + const filter = []; - dispatch(startLoading()); + dispatch(startLoading()); - if (term) { - const escapedTerm = escapeFilterValue(term); - filter.push( - `company_name=@${escapedTerm},sponsorship_name=@${escapedTerm},sponsorship_size=@${escapedTerm}` - ); - } + if (term) { + const escapedTerm = escapeFilterValue(term); + filter.push( + `company_name=@${escapedTerm},sponsorship_name=@${escapedTerm},sponsorship_size=@${escapedTerm}` + ); + } - const params = { - page, - per_page: perPage, - expand: "company,sponsorship,sponsorship.type", - relations: "company.none,sponsorship.none,sponsorship.type.none,none", - fields: "id,company.name,company.id,sponsorship.id,sponsorship.type.name", - access_token: accessToken - }; + const params = { + page, + per_page: perPage, + expand: "company,sponsorship,sponsorship.type", + relations: "company.none,sponsorship.none,sponsorship.type.none,none", + fields: "id,company.name,company.id,sponsorship.id,sponsorship.type.name", + access_token: accessToken + }; - if (filter.length > 0) { - params["filter[]"] = filter; - } + if (filter.length > 0) { + params["filter[]"] = filter; + } - // order - if (order != null && orderDir != null) { - const orderDirSign = orderDir === 1 ? "+" : "-"; - params.order = `${orderDirSign}${order}`; - } + // order + if (order != null && orderDir != null) { + const orderDirSign = orderDir === 1 ? "+" : "-"; + params.order = `${orderDirSign}${order}`; + } - return getRequest( - createAction(REQUEST_SPONSORS), - createAction(RECEIVE_SPONSORS), - `${window.API_BASE_URL}/api/v1/summits/${currentSummit.id}/sponsors`, - authErrorHandler, - { page, perPage, order, orderDir, term } - )(params)(dispatch).then(() => { - dispatch(stopLoading()); - }); - }; + return getRequest( + createAction(REQUEST_SPONSORS), + createAction(RECEIVE_SPONSORS), + `${window.API_BASE_URL}/api/v1/summits/${currentSummit.id}/sponsors`, + authErrorHandler, + { page, perPage, order, orderDir, term } + )(params)(dispatch).then(() => { + dispatch(stopLoading()); + }); + }; export const getSponsorsWithBadgeScans = () => async (dispatch, getState) => { const { currentSummitState } = getState(); @@ -457,26 +457,26 @@ export const getExtraQuestionMeta = () => async (dispatch, getState) => { export const updateExtraQuestionOrder = (extraQuestions, sponsorId, questionId, newOrder) => - async (dispatch, getState) => { - const { currentSummitState } = getState(); - const accessToken = await getAccessTokenSafely(); - const { currentSummit } = currentSummitState; - - const params = { - access_token: accessToken - }; + async (dispatch, getState) => { + const { currentSummitState } = getState(); + const accessToken = await getAccessTokenSafely(); + const { currentSummit } = currentSummitState; - putRequest( - null, - createAction(SPONSOR_EXTRA_QUESTION_ORDER_UPDATED)(extraQuestions), - `${window.API_BASE_URL}/api/v1/summits/${currentSummit.id}/sponsors/${sponsorId}/extra-questions/${questionId}`, - { order: newOrder }, - authErrorHandler - )(params)(dispatch).then(() => { - dispatch(stopLoading()); - }); + const params = { + access_token: accessToken }; + putRequest( + null, + createAction(SPONSOR_EXTRA_QUESTION_ORDER_UPDATED)(extraQuestions), + `${window.API_BASE_URL}/api/v1/summits/${currentSummit.id}/sponsors/${sponsorId}/extra-questions/${questionId}`, + { order: newOrder }, + authErrorHandler + )(params)(dispatch).then(() => { + dispatch(stopLoading()); + }); + }; + export const deleteExtraQuestion = (sponsorId, questionId) => async (dispatch, getState) => { const { currentSummitState } = getState(); @@ -699,37 +699,37 @@ export const deleteSponsorExtraQuestionValue = export const getSummitSponsorships = (order = "name", orderDir = 1) => - async (dispatch, getState) => { - const { currentSummitState } = getState(); - const accessToken = await getAccessTokenSafely(); - const { currentSummit } = currentSummitState; - - dispatch(startLoading()); - - const params = { - page: 1, - per_page: 100, - access_token: accessToken, - expand: "type" - }; + async (dispatch, getState) => { + const { currentSummitState } = getState(); + const accessToken = await getAccessTokenSafely(); + const { currentSummit } = currentSummitState; - // order - if (order != null && orderDir != null) { - const orderDirSign = orderDir === 1 ? "+" : "-"; - params.order = `${orderDirSign}${order}`; - } + dispatch(startLoading()); - return getRequest( - createAction(REQUEST_SUMMIT_SPONSORSHIPS), - createAction(RECEIVE_SUMMIT_SPONSORSHIPS), - `${window.API_BASE_URL}/api/v1/summits/${currentSummit.id}/sponsorships-types`, - authErrorHandler, - { order, orderDir } - )(params)(dispatch).then(() => { - dispatch(stopLoading()); - }); + const params = { + page: 1, + per_page: 100, + access_token: accessToken, + expand: "type" }; + // order + if (order != null && orderDir != null) { + const orderDirSign = orderDir === 1 ? "+" : "-"; + params.order = `${orderDirSign}${order}`; + } + + return getRequest( + createAction(REQUEST_SUMMIT_SPONSORSHIPS), + createAction(RECEIVE_SUMMIT_SPONSORSHIPS), + `${window.API_BASE_URL}/api/v1/summits/${currentSummit.id}/sponsorships-types`, + authErrorHandler, + { order, orderDir } + )(params)(dispatch).then(() => { + dispatch(stopLoading()); + }); + }; + export const getSummitSponsorship = (sponsorshipId) => async (dispatch, getState) => { const { currentSummitState } = getState(); @@ -955,86 +955,86 @@ export const getBadgeScans = order = "attendee_last_name", orderDir = 1 ) => - async (dispatch, getState) => { - const { currentSummitState } = getState(); - const accessToken = await getAccessTokenSafely(); - const { currentSummit } = currentSummitState; - const filter = []; - const summitTZ = currentSummit.time_zone.name; + async (dispatch, getState) => { + const { currentSummitState } = getState(); + const accessToken = await getAccessTokenSafely(); + const { currentSummit } = currentSummitState; + const filter = []; + const summitTZ = currentSummit.time_zone_id; - dispatch(startLoading()); + dispatch(startLoading()); - if (sponsorId) { - filter.push(`sponsor_id==${sponsorId}`); - } + if (sponsorId) { + filter.push(`sponsor_id==${sponsorId}`); + } - const params = { - access_token: accessToken, - page, - per_page: perPage, - expand: - "badge,badge.ticket,badge.ticket.owner,badge.ticket.owner.member,scanned_by", - relations: - "scanned_by,badge,scanned_by.none,badge.none,badge.ticket.none,badge.ticket.owner.none,badge.ticket.owner.member.none", - fields: - "id,created,scan_date,attendee_first_name,attendee_last_name,attendee_email,attendee_company,scanned_by.email,scanned_by.first_name,scanned_by.last_name,badge.ticket,badge.ticket.owner,badge.ticket.owner.member.first_name,badge.ticket.owner.member.last_name,badge.ticket.owner.email,badge.ticket.owner.company,badge.ticket.owner.first_name,badge.ticket.owner.last_name" - }; + const params = { + access_token: accessToken, + page, + per_page: perPage, + expand: + "badge,badge.ticket,badge.ticket.owner,badge.ticket.owner.member,scanned_by", + relations: + "scanned_by,badge,scanned_by.none,badge.none,badge.ticket.none,badge.ticket.owner.none,badge.ticket.owner.member.none", + fields: + "id,created,scan_date,attendee_first_name,attendee_last_name,attendee_email,attendee_company,scanned_by.email,scanned_by.first_name,scanned_by.last_name,badge.ticket,badge.ticket.owner,badge.ticket.owner.member.first_name,badge.ticket.owner.member.last_name,badge.ticket.owner.email,badge.ticket.owner.company,badge.ticket.owner.first_name,badge.ticket.owner.last_name" + }; - if (filter.length > 0) { - params["filter[]"] = filter; - } + if (filter.length > 0) { + params["filter[]"] = filter; + } - // order - if (order != null && orderDir != null) { - const orderDirSign = orderDir === 1 ? "+" : "-"; - params.order = `${orderDirSign}${order}`; - } + // order + if (order != null && orderDir != null) { + const orderDirSign = orderDir === 1 ? "+" : "-"; + params.order = `${orderDirSign}${order}`; + } - return getRequest( - createAction(REQUEST_BADGE_SCANS), - createAction(RECEIVE_BADGE_SCANS), - `${window.API_BASE_URL}/api/v1/summits/${currentSummit.id}/badge-scans`, - authErrorHandler, - { page, perPage, order, orderDir, sponsorId, summitTZ } - )(params)(dispatch).then(() => { - dispatch(stopLoading()); - }); - }; + return getRequest( + createAction(REQUEST_BADGE_SCANS), + createAction(RECEIVE_BADGE_SCANS), + `${window.API_BASE_URL}/api/v1/summits/${currentSummit.id}/badge-scans`, + authErrorHandler, + { page, perPage, order, orderDir, sponsorId, summitTZ } + )(params)(dispatch).then(() => { + dispatch(stopLoading()); + }); + }; export const exportBadgeScans = (sponsor = null, order = "attendee_last_name", orderDir = 1) => - async (dispatch, getState) => { - const { currentSummitState } = getState(); - const accessToken = await getAccessTokenSafely(); - const { currentSummit } = currentSummitState; - const filter = []; - const filename = `${sponsor.company.name}-BadgeScans.csv`; - const params = { - access_token: accessToken, - columns: - "scan_date,scanned_by,attendee_first_name,attendee_last_name,attendee_email,attendee_company" - }; + async (dispatch, getState) => { + const { currentSummitState } = getState(); + const accessToken = await getAccessTokenSafely(); + const { currentSummit } = currentSummitState; + const filter = []; + const filename = `${sponsor.company.name}-BadgeScans.csv`; + const params = { + access_token: accessToken, + columns: + "scan_date,scanned_by,attendee_first_name,attendee_last_name,attendee_email,attendee_company" + }; - filter.push(`sponsor_id==${sponsor.id}`); + filter.push(`sponsor_id==${sponsor.id}`); - if (filter.length > 0) { - params["filter[]"] = filter; - } + if (filter.length > 0) { + params["filter[]"] = filter; + } - // order - if (order != null && orderDir != null) { - const orderDirSign = orderDir === 1 ? "+" : "-"; - params.order = `${orderDirSign}${order}`; - } + // order + if (order != null && orderDir != null) { + const orderDirSign = orderDir === 1 ? "+" : "-"; + params.order = `${orderDirSign}${order}`; + } - dispatch( - getCSV( - `${window.API_BASE_URL}/api/v1/summits/${currentSummit.id}/badge-scans/csv`, - params, - filename - ) - ); - }; + dispatch( + getCSV( + `${window.API_BASE_URL}/api/v1/summits/${currentSummit.id}/badge-scans/csv`, + params, + filename + ) + ); + }; export const getBadgeScan = (scanId) => async (dispatch, getState) => { const { currentSummitState } = getState(); @@ -1124,10 +1124,10 @@ export const attachSponsorImage = picAttr === "header_image" ? uploadHeaderImage : picAttr === "side_image" - ? uploadSideImage - : picAttr === "header_mobile_image" - ? uploadHeaderMobileImage - : uploadCarouselImage; + ? uploadSideImage + : picAttr === "header_mobile_image" + ? uploadHeaderMobileImage + : uploadCarouselImage; if (entity.id) { dispatch(uploadFile(entity, file)); @@ -1245,10 +1245,10 @@ export const removeSponsorImage = (entity, picAttr) => async (dispatch) => { picAttr === "header_image" ? removeHeaderImage : picAttr === "side_image" - ? removeSideImage - : picAttr === "header_mobile_image" - ? removeHeaderMobileImage - : removeCarouselImage; + ? removeSideImage + : picAttr === "header_mobile_image" + ? removeHeaderMobileImage + : removeCarouselImage; return dispatch(removeFile(entity)); }; @@ -1336,32 +1336,32 @@ export const removeCarouselImage = (entity) => async (dispatch, getState) => { export const getSponsorAdvertisements = (sponsorId, order = "order", orderDir = 1) => - async (dispatch, getState) => { - const { currentSummitState } = getState(); - const accessToken = await getAccessTokenSafely(); - const { currentSummit } = currentSummitState; + async (dispatch, getState) => { + const { currentSummitState } = getState(); + const accessToken = await getAccessTokenSafely(); + const { currentSummit } = currentSummitState; - dispatch(startLoading()); + dispatch(startLoading()); - const params = { - access_token: accessToken - }; + const params = { + access_token: accessToken + }; - // order - if (order != null && orderDir != null) { - const orderDirSign = orderDir === 1 ? "+" : "-"; - params.order = `${orderDirSign}${order}`; - } + // order + if (order != null && orderDir != null) { + const orderDirSign = orderDir === 1 ? "+" : "-"; + params.order = `${orderDirSign}${order}`; + } - return getRequest( - null, - createAction(RECEIVE_SPONSOR_ADVERTISEMENTS), - `${window.API_BASE_URL}/api/v1/summits/${currentSummit.id}/sponsors/${sponsorId}/ads`, - authErrorHandler - )(params)(dispatch).then(() => { - dispatch(stopLoading()); - }); - }; + return getRequest( + null, + createAction(RECEIVE_SPONSOR_ADVERTISEMENTS), + `${window.API_BASE_URL}/api/v1/summits/${currentSummit.id}/sponsors/${sponsorId}/ads`, + authErrorHandler + )(params)(dispatch).then(() => { + dispatch(stopLoading()); + }); + }; export const saveSponsorAdvertisement = (entity) => async (dispatch, getState) => { @@ -1581,32 +1581,32 @@ export const removeSponsorAdvertisementImage = export const getSponsorMaterials = (sponsorId, order = "order", orderDir = 1) => - async (dispatch, getState) => { - const { currentSummitState } = getState(); - const accessToken = await getAccessTokenSafely(); - const { currentSummit } = currentSummitState; + async (dispatch, getState) => { + const { currentSummitState } = getState(); + const accessToken = await getAccessTokenSafely(); + const { currentSummit } = currentSummitState; - dispatch(startLoading()); + dispatch(startLoading()); - const params = { - access_token: accessToken - }; + const params = { + access_token: accessToken + }; - // order - if (order != null && orderDir != null) { - const orderDirSign = orderDir === 1 ? "+" : "-"; - params.order = `${orderDirSign}${order}`; - } + // order + if (order != null && orderDir != null) { + const orderDirSign = orderDir === 1 ? "+" : "-"; + params.order = `${orderDirSign}${order}`; + } - return getRequest( - null, - createAction(RECEIVE_SPONSOR_MATERIALS), - `${window.API_BASE_URL}/api/v1/summits/${currentSummit.id}/sponsors/${sponsorId}/materials`, - authErrorHandler - )(params)(dispatch).then(() => { - dispatch(stopLoading()); - }); - }; + return getRequest( + null, + createAction(RECEIVE_SPONSOR_MATERIALS), + `${window.API_BASE_URL}/api/v1/summits/${currentSummit.id}/sponsors/${sponsorId}/materials`, + authErrorHandler + )(params)(dispatch).then(() => { + dispatch(stopLoading()); + }); + }; export const saveSponsorMaterial = (entity) => async (dispatch, getState) => { const { currentSummitState, currentSponsorState } = getState(); @@ -1928,91 +1928,91 @@ export const getSponsorPromocodes = order = "order", orderDir = 1 ) => - async (dispatch, getState) => { - const { currentSummitState } = getState(); - const accessToken = await getAccessTokenSafely(); - const { currentSummit } = currentSummitState; - const filter = []; + async (dispatch, getState) => { + const { currentSummitState } = getState(); + const accessToken = await getAccessTokenSafely(); + const { currentSummit } = currentSummitState; + const filter = []; - dispatch(startLoading()); + dispatch(startLoading()); - if (term) { - const escapedTerm = escapeFilterValue(term); - filter.push( - `sponsor_company_name@@${escapedTerm},tier_name@@${escapedTerm},code@@${escapedTerm}` - ); - } + if (term) { + const escapedTerm = escapeFilterValue(term); + filter.push( + `sponsor_company_name@@${escapedTerm},tier_name@@${escapedTerm},code@@${escapedTerm}` + ); + } - const params = { - page, - per_page: perPage, - expand: - "sponsor,owner,sponsor.company,sponsor.sponsorship,sponsor.sponsorship.type,badge_features,allowed_ticket_types,ticket_types_rules,ticket_types_rules.ticket_type", - access_token: accessToken - }; + const params = { + page, + per_page: perPage, + expand: + "sponsor,owner,sponsor.company,sponsor.sponsorship,sponsor.sponsorship.type,badge_features,allowed_ticket_types,ticket_types_rules,ticket_types_rules.ticket_type", + access_token: accessToken + }; - if (filter.length > 0) { - params["filter[]"] = filter; - } + if (filter.length > 0) { + params["filter[]"] = filter; + } - // order - if (order != null && orderDir != null) { - const orderDirSign = orderDir === 1 ? "+" : "-"; - params.order = `${orderDirSign}${order}`; - } + // order + if (order != null && orderDir != null) { + const orderDirSign = orderDir === 1 ? "+" : "-"; + params.order = `${orderDirSign}${order}`; + } - return getRequest( - createAction(REQUEST_SPONSOR_PROMOCODES), - createAction(RECEIVE_SPONSOR_PROMOCODES), - `${window.API_BASE_URL}/api/v1/summits/${currentSummit.id}/sponsor-promo-codes`, - authErrorHandler, - { page, perPage, order, orderDir, term } - )(params)(dispatch).then(() => { - dispatch(stopLoading()); - }); - }; + return getRequest( + createAction(REQUEST_SPONSOR_PROMOCODES), + createAction(RECEIVE_SPONSOR_PROMOCODES), + `${window.API_BASE_URL}/api/v1/summits/${currentSummit.id}/sponsor-promo-codes`, + authErrorHandler, + { page, perPage, order, orderDir, term } + )(params)(dispatch).then(() => { + dispatch(stopLoading()); + }); + }; export const exportSponsorPromocodes = (term = null, order = "order", orderDir = 1) => - async (dispatch, getState) => { - const { currentSummitState } = getState(); - const accessToken = await getAccessTokenSafely(); - const { currentSummit } = currentSummitState; - const filter = []; - const filename = `${currentSummit.name}-SponsorPromocodes.csv`; + async (dispatch, getState) => { + const { currentSummitState } = getState(); + const accessToken = await getAccessTokenSafely(); + const { currentSummit } = currentSummitState; + const filter = []; + const filename = `${currentSummit.name}-SponsorPromocodes.csv`; - dispatch(startLoading()); + dispatch(startLoading()); - if (term) { - const escapedTerm = escapeFilterValue(term); - filter.push( - `sponsor_company_name@@${escapedTerm},tier_name@@${escapedTerm},code@@${escapedTerm}` - ); - } + if (term) { + const escapedTerm = escapeFilterValue(term); + filter.push( + `sponsor_company_name@@${escapedTerm},tier_name@@${escapedTerm},code@@${escapedTerm}` + ); + } - const params = { - expand: "", - access_token: accessToken - }; + const params = { + expand: "", + access_token: accessToken + }; - if (filter.length > 0) { - params["filter[]"] = filter; - } + if (filter.length > 0) { + params["filter[]"] = filter; + } - // order - if (order != null && orderDir != null) { - const orderDirSign = orderDir === 1 ? "+" : "-"; - params.order = `${orderDirSign}${order}`; - } + // order + if (order != null && orderDir != null) { + const orderDirSign = orderDir === 1 ? "+" : "-"; + params.order = `${orderDirSign}${order}`; + } - dispatch( - getCSV( - `${window.API_BASE_URL}/api/v1/summits/${currentSummit.id}/sponsor-promo-codes/csv`, - params, - filename - ) - ); - }; + dispatch( + getCSV( + `${window.API_BASE_URL}/api/v1/summits/${currentSummit.id}/sponsor-promo-codes/csv`, + params, + filename + ) + ); + }; export const importSponsorPromocodesCSV = (file) => async (dispatch, getState) => { @@ -2039,67 +2039,67 @@ export const importSponsorPromocodesCSV = export const sendEmails = (recipientEmail = null) => - async (dispatch, getState) => { - const { currentSummitState, currentSponsorPromocodeListState } = getState(); - const { term, currentFlowEvent, selectedAll, selectedIds, excludedIds } = - currentSponsorPromocodeListState; - const accessToken = await getAccessTokenSafely(); - const { currentSummit } = currentSummitState; - const filter = []; - - const params = { - access_token: accessToken - }; + async (dispatch, getState) => { + const { currentSummitState, currentSponsorPromocodeListState } = getState(); + const { term, currentFlowEvent, selectedAll, selectedIds, excludedIds } = + currentSponsorPromocodeListState; + const accessToken = await getAccessTokenSafely(); + const { currentSummit } = currentSummitState; + const filter = []; - if (!selectedAll && selectedIds.length > 0) { - // we don't need the filter criteria, we have the ids - filter.push(`id==${selectedIds.join("||")}`); - } else { - if (term) { - const escapedTerm = escapeFilterValue(term); - filter.push( - `sponsor_company_name@@${escapedTerm},tier_name@@${escapedTerm},code@@${escapedTerm}` - ); - } + const params = { + access_token: accessToken + }; - if (selectedAll && excludedIds.length > 0) { - filter.push(`not_id==${excludedIds.join("||")}`); - } + if (!selectedAll && selectedIds.length > 0) { + // we don't need the filter criteria, we have the ids + filter.push(`id==${selectedIds.join("||")}`); + } else { + if (term) { + const escapedTerm = escapeFilterValue(term); + filter.push( + `sponsor_company_name@@${escapedTerm},tier_name@@${escapedTerm},code@@${escapedTerm}` + ); } - if (filter.length > 0) { - params["filter[]"] = filter; + if (selectedAll && excludedIds.length > 0) { + filter.push(`not_id==${excludedIds.join("||")}`); } + } - const payload = { - email_flow_event: currentFlowEvent - }; + if (filter.length > 0) { + params["filter[]"] = filter; + } - if (recipientEmail) { - payload.test_email_recipient = recipientEmail; - } + const payload = { + email_flow_event: currentFlowEvent + }; - dispatch(startLoading()); + if (recipientEmail) { + payload.test_email_recipient = recipientEmail; + } - const success_message = { - title: T.translate("general.done"), - html: T.translate("registration_invitation_list.resend_done"), - type: "success" - }; + dispatch(startLoading()); - return putRequest( - null, - createAction(SEND_SPONSOR_PROMOCODES_EMAILS), - `${window.API_BASE_URL}/api/v1/summits/${currentSummit.id}/sponsors/all/promo-codes/all/send`, - payload, - authErrorHandler - )(params)(dispatch).then((payload) => { - dispatch(showMessage(success_message)); - dispatch(stopLoading()); - return payload; - }); + const success_message = { + title: T.translate("general.done"), + html: T.translate("registration_invitation_list.resend_done"), + type: "success" }; + return putRequest( + null, + createAction(SEND_SPONSOR_PROMOCODES_EMAILS), + `${window.API_BASE_URL}/api/v1/summits/${currentSummit.id}/sponsors/all/promo-codes/all/send`, + payload, + authErrorHandler + )(params)(dispatch).then((payload) => { + dispatch(showMessage(success_message)); + dispatch(stopLoading()); + return payload; + }); + }; + /** **************** LEAD REPORT SETTINGS *************************************** */ export const getSponsorLeadReportSettingsMeta = diff --git a/src/actions/summit-actions.js b/src/actions/summit-actions.js index 129fefde4..041a47168 100644 --- a/src/actions/summit-actions.js +++ b/src/actions/summit-actions.js @@ -63,7 +63,6 @@ export const getSummitById = (summitId) => async (dispatch) => { "track_groups," + "locations," + "locations.rooms," + - "locations.attributes.type," + "locations.floor," + "meeting_booking_room_allowed_attributes," + "meeting_booking_room_allowed_attributes.values," + @@ -75,8 +74,112 @@ export const getSummitById = (summitId) => async (dispatch) => { "badge_features," + "badge_features_types," + "badge_access_level_types," + - "badge_view_types," + - "tax_types" + "badge_view_types", + fields: + "id," + + "name," + + "active," + + "allow_update_attendee_extra_questions," + + "available_on_api," + + "calendar_sync_desc," + + "calendar_sync_name," + + "dates_label," + + "end_date," + + "event_types,event_types.id,event_types.name,event_types.order" + + "link," + + "locations,locations.id,locations.name,locations.order,locations.class_name,locations.rooms,locations.floors," + + "logo," + + "secondary_logo," + + "presentation_voters_count," + + "presentation_votes_count," + + "presentations_submitted_count," + + "published_events_count," + + "reassign_ticket_till_date," + + "registration_begin_date," + + "registration_end_date," + + "registration_link," + + "registration_disclaimer_content," + + "registration_disclaimer_mandatory," + + "registration_slug_prefix," + + "schedule_start_date," + + "secondary_registration_label," + + "secondary_registration_link," + + "speaker_announcement_email_accepted_alternate_count," + + "speaker_announcement_email_accepted_count," + + "speaker_announcement_email_accepted_rejected_count," + + "speaker_announcement_email_alternate_count," + + "speaker_announcement_email_alternate_rejected_count," + + "speaker_announcement_email_rejected_count," + + "speakers_count," + + "start_date," + + "start_showing_venues_date," + + "slug," + + "supported_currencies," + + "default_ticket_type_currency," + + "ticket_types,ticket_types.id,ticket_types.name," + + "time_zone_id," + + "time_zone_label," + + "tracks,tracks.id,tracks.name,tracks.parent_id,tracks.order,tracks.chair_visible,tracks.subtracks," + + "selection_plans,selection_plans.id,selection_plans.name,selection_plans.is_enabled,selection_plans.order,selection_plans.submission_begin_date,selection_plans.submission_end_date,selection_plans.voting_begin_date,selection_plans.voting_end_date,selection_plans.selection_begin_date,selection_plans.selection_end_date,selection_plans.track_groups," + + "meeting_booking_room_allowed_attributes,meeting_booking_room_allowed_attributes.id,meeting_booking_room_allowed_attributes.created,meeting_booking_room_allowed_attributes.last_edited,meeting_booking_room_allowed_attributes.type,meeting_booking_room_allowed_attributes.summit_id,meeting_booking_room_allowed_attributes.values.value," + + "meeting_room_booking_end_time," + + "meeting_room_booking_max_allowed," + + "meeting_room_booking_slot_length," + + "meeting_room_booking_start_time," + + "api_feed_type," + + "api_feed_url," + + "api_feed_key," + + "badge_access_level_types,badge_access_level_types.id,badge_access_level_types.name," + + "badge_types,badge_types.id,badge_types.name,badge_types.allowed_view_types," + + "badge_features," + + "badge_view_types,badge_view_types.id,badge_view_types.name," + + "order_extra_questions," + + "begin_allow_booking_date," + + "end_allow_booking_date," + + "external_summit_id," + + "external_registration_feed_type," + + "external_registration_feed_api_key," + + "virtual_site_url," + + "marketing_site_url," + + "mux_token_id," + + "mux_token_secret," + + "mux_allowed_domains,mux_allowed_domains.label,mux_allowed_domains.value," + + "help_users," + + "registration_send_qr_as_image_attachment_on_ticket_email," + + "registration_send_ticket_as_pdf_attachment_on_ticket_email," + + "registration_allow_automatic_reminder_emails," + + "registration_send_order_email_automatically," + + "qr_codes_enc_key," + + "speaker_confirmation_default_page_url," + + "marketing_site_oauth2_client_id," + + "marketing_site_oauth2_client_scopes," + + "available_lead_report_columns," + + "created," + + "last_edited," + + "invite_only_registration," + + "registration_reminder_email_days_interval," + + "support_email," + + "speakers_support_email," + + "registration_send_ticket_email_automatically," + + "registration_allowed_refund_request_till_date," + + "default_ticket_type_currency_symbol," + + "virtual_site_oauth2_client_id," + + "paid_tickets_count," + + "track_groups,track_groups.id,track_groups.name," + + "lead_report_settings,lead_report_settings.sponsor_id,lead_report_settings.columns," + + "presentation_action_types,presentation_action_types.id,presentation_action_types.label," + + "badge_features_types,badge_features_types.id,badge_features_types.name," + + "", + relations: + "event_types.none," + + "tracks.none," + + "tracks_groups.none," + + "locations,locations.rooms,locations.floor,locations.none," + + "meeting_booking_room_allowed_attributes.values," + + "selection_plans.track_groups,selection_plans.none," + + "ticket_types.none," + + "badge_types.none," + + "none" }; // set id diff --git a/src/actions/summit-builder-actions.js b/src/actions/summit-builder-actions.js index 24ec0975e..d3d812997 100644 --- a/src/actions/summit-builder-actions.js +++ b/src/actions/summit-builder-actions.js @@ -270,7 +270,7 @@ export const changeSource = (selectedSource) => (dispatch) => { export const getPublishedEventsBySummitDayLocation = (currentSummit, currentDay, currentLocation) => async (dispatch) => { const accessToken = await getAccessTokenSafely(); - currentDay = moment.tz(currentDay, currentSummit.time_zone.name); + currentDay = moment.tz(currentDay, currentSummit.time_zone_id); const startDate = currentDay.clone().hours(0).minutes(0).seconds(0).valueOf() / MILLISECONDS_IN_SECOND; @@ -317,7 +317,7 @@ export const getShowAlwaysEvents = const accessToken = await getAccessTokenSafely(); const proposedSchedDayMoment = moment.tz( proposedSchedDay, - summit.time_zone.name + summit.time_zone_id ); const startDate = proposedSchedDayMoment.clone().hours(0).minutes(0).seconds(0).valueOf() / @@ -366,7 +366,7 @@ export const getProposedEvents = const accessToken = await getAccessTokenSafely(); const proposedSchedDayMoment = moment.tz( proposedSchedDay, - summit.time_zone.name + summit.time_zone_id ); const startDate = proposedSchedDayMoment.clone().hours(0).minutes(0).seconds(0).valueOf() / diff --git a/src/actions/ticket-actions.js b/src/actions/ticket-actions.js index 7c81487d6..848a9c8d3 100644 --- a/src/actions/ticket-actions.js +++ b/src/actions/ticket-actions.js @@ -893,7 +893,7 @@ export const getTicketTypes = dispatch(startLoading()); - const summitTZ = currentSummit.time_zone.name; + const summitTZ = currentSummit.time_zone_id; const params = { page: currentPage, diff --git a/src/components/forms/tax-type-form.js b/src/components/forms/tax-type-form.js index a81b7955c..04cab57dd 100644 --- a/src/components/forms/tax-type-form.js +++ b/src/components/forms/tax-type-form.js @@ -101,7 +101,6 @@ class TaxTypeForm extends React.Component { render() { const { entity } = this.state; - const { currentSummit } = this.props; const ticketColumns = [ { columnKey: "name", value: T.translate("edit_tax_type.name") }, diff --git a/src/components/schedule-builder/schedule-admin-dashboard.js b/src/components/schedule-builder/schedule-admin-dashboard.js index 55a4ccb72..9d8f78ebe 100644 --- a/src/components/schedule-builder/schedule-admin-dashboard.js +++ b/src/components/schedule-builder/schedule-admin-dashboard.js @@ -9,12 +9,27 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. - **/ + * */ import React from "react"; import { HTML5Backend } from "react-dnd-html5-backend"; import { DndProvider } from "react-dnd"; import { Modal } from "react-bootstrap"; import { connect } from "react-redux"; +import { + BulkActionEdit, + BulkActionUnPublish +} from "openstack-uicore-foundation/lib/components/schedule-builder-constants"; +import T from "i18n-react/dist/i18n-react"; +import moment from "moment-timezone"; +import * as Scroll from "react-scroll"; +import Swal from "sweetalert2"; +import { + Dropdown, + OperatorInput, + BulkActionsSelector, + ScheduleBuilderView +} from "openstack-uicore-foundation/lib/components"; +import { SummitEvent } from "openstack-uicore-foundation/lib/models"; import { getUnScheduleEventsPage, publishEvent, @@ -49,10 +64,6 @@ import { unPublishBulkAction } from "../../actions/summit-event-bulk-actions"; import UnScheduleEventList from "./unschedule-event-list"; -import { - BulkActionEdit, - BulkActionUnPublish -} from "openstack-uicore-foundation/lib/components/schedule-builder-constants"; import ScheduleAdminEventTypeSelector from "./schedule-admin-event-type-selector"; import ScheduleAdminTrackSelector from "./schedule-admin-track-selector"; import ScheduleAdminPresentationSelectionStatusSelector from "./schedule-admin-presentation-selection-status-selector"; @@ -61,21 +72,16 @@ import ScheduleAdminSearchFreeTextUnScheduleEvents from "./schedule-admin-search import ScheduleAdminSearchFreeTextScheduleEvents from "./schedule-admin-search-free-text-schedule-events"; import ScheduleAdminScheduleEventsSearchResults from "./schedule-admin-schedule-events-search-results"; import ScheduleAdminOrderSelector from "./schedule-admin-order-selector"; -import T from "i18n-react/dist/i18n-react"; -import moment from "moment-timezone"; import FragmentParser from "../../utils/fragmen-parser"; -import * as Scroll from "react-scroll"; -import Swal from "sweetalert2"; import ScheduleAdminEmptySpotsModal from "./schedule-admin-empty-spots-modal"; import ScheduleAdminEmptySpotsList from "./schedule-admin-empty-spots-list"; -import { - Dropdown, - OperatorInput, - BulkActionsSelector, - ScheduleBuilderView -} from "openstack-uicore-foundation/lib/components"; -import { SummitEvent } from "openstack-uicore-foundation/lib/models"; import UnlockScheduleButton from "../UnlockScheduleButton"; +import { + MILLISECONDS_IN_SECOND, + MINUTE_STEP_SIZE_5, + TIMEOUT_1500, + TWENTY_PER_PAGE +} from "../../utils/constants"; class ScheduleAdminDashBoard extends React.Component { constructor(props) { @@ -141,13 +147,13 @@ class ScheduleAdminDashBoard extends React.Component { if (!currentSummit) return; - for (let key in hash) { - let value = hash[key]; + for (const key in hash) { + const value = hash[key]; switch (key) { case "day": filters.currentDay = value; break; - case "location_id": + case "location_id": { const location = currentSummit.locations .filter((l) => l.id === parseInt(value)) .shift(); @@ -155,10 +161,11 @@ class ScheduleAdminDashBoard extends React.Component { filters.currentLocation = location; } if (value === 0) { - //special case TBD location + // special case TBD location filters.currentLocation = { id: 0, name: "TBD" }; } break; + } case "event": filters.currentEvent = value; break; @@ -195,7 +202,7 @@ class ScheduleAdminDashBoard extends React.Component { this.props.getUnScheduleEventsPage( currentSummit.id, 1, - 20, + TWENTY_PER_PAGE, eventTypeId, trackId, currentPresentationSelectionStatus, @@ -221,7 +228,7 @@ class ScheduleAdminDashBoard extends React.Component { this.filters.currentLocation ); - window.onhashchange = (event) => { + window.onhashchange = () => { if (this.byPassHashRefresh) { this.byPassHashRefresh = false; return; @@ -271,16 +278,15 @@ class ScheduleAdminDashBoard extends React.Component { onScheduleEvent(event, currentDay, startDateTime, duration = null) { const eventModel = new SummitEvent(event, this.props.currentSummit); - const newDuration = duration - ? duration - : eventModel.getMinutesDuration(this.props.slotSize); + const newDuration = + duration || eventModel.getMinutesDuration(this.props.slotSize); this.props.publishEvent(event, currentDay, startDateTime, newDuration); } onDayChanged(day) { - let { currentLocation } = this.props; + const { currentLocation } = this.props; this.props.changeCurrentSelectedDay(day); - let locationId = currentLocation != null ? currentLocation.id : null; + const locationId = currentLocation != null ? currentLocation.id : null; this.buildFragment(locationId, day); this.filters = this.parseFilterFromFragment(); this.byPassHashRefresh = true; @@ -288,7 +294,7 @@ class ScheduleAdminDashBoard extends React.Component { } onVenueChanged(location) { - let { currentDay } = this.props; + const { currentDay } = this.props; this.props.changeCurrentSelectedLocation(location); this.buildFragment(location.id, currentDay); this.filters = this.parseFilterFromFragment(); @@ -336,12 +342,12 @@ class ScheduleAdminDashBoard extends React.Component { currentUnScheduleOrderBy, currentDuration } = this.props; - let trackId = currentTrack == null ? null : currentTrack.id; - let eventTypeId = currentEventType == null ? null : currentEventType.id; + const trackId = currentTrack == null ? null : currentTrack.id; + const eventTypeId = currentEventType == null ? null : currentEventType.id; this.props.getUnScheduleEventsPage( currentSummit.id, currentPage, - 20, + TWENTY_PER_PAGE, eventTypeId, trackId, currentPresentationSelectionStatus, @@ -363,8 +369,8 @@ class ScheduleAdminDashBoard extends React.Component { currentUnScheduleOrderBy, currentDuration } = this.props; - let trackId = currentTrack == null ? null : currentTrack.id; - let eventTypeId = eventType == null ? null : eventType.id; + const trackId = currentTrack == null ? null : currentTrack.id; + const eventTypeId = eventType == null ? null : eventType.id; let selectionStatus = currentPresentationSelectionStatus; let order = currentUnScheduleOrderBy; if (!eventType || eventType.class_name !== "PresentationType") { @@ -377,7 +383,7 @@ class ScheduleAdminDashBoard extends React.Component { this.props.getUnScheduleEventsPage( currentSummit.id, 1, - 20, + TWENTY_PER_PAGE, eventTypeId, trackId, selectionStatus, @@ -398,13 +404,13 @@ class ScheduleAdminDashBoard extends React.Component { currentUnScheduleOrderBy, currentDuration } = this.props; - let eventTypeId = currentEventType == null ? null : currentEventType.id; - let trackId = track == null ? null : track.id; + const eventTypeId = currentEventType == null ? null : currentEventType.id; + const trackId = track == null ? null : track.id; this.props.changeCurrentTrack(track); this.props.getUnScheduleEventsPage( currentSummit.id, 1, - 20, + TWENTY_PER_PAGE, eventTypeId, trackId, currentPresentationSelectionStatus, @@ -425,8 +431,8 @@ class ScheduleAdminDashBoard extends React.Component { currentUnScheduleOrderBy, currentDuration } = this.props; - let eventTypeId = currentEventType == null ? null : currentEventType.id; - let trackId = currentTrack == null ? null : currentTrack.id; + const eventTypeId = currentEventType == null ? null : currentEventType.id; + const trackId = currentTrack == null ? null : currentTrack.id; let order = currentUnScheduleOrderBy; if (!presentationSelectionStatus) { @@ -443,7 +449,7 @@ class ScheduleAdminDashBoard extends React.Component { this.props.getUnScheduleEventsPage( currentSummit.id, 1, - 20, + TWENTY_PER_PAGE, eventTypeId, trackId, presentationSelectionStatus, @@ -464,9 +470,9 @@ class ScheduleAdminDashBoard extends React.Component { currentUnScheduleOrderBy, currentDuration } = this.props; - let eventTypeId = currentEventType == null ? null : currentEventType.id; - let trackId = currentTrack == null ? null : currentTrack.id; - let order = currentUnScheduleOrderBy; + const eventTypeId = currentEventType == null ? null : currentEventType.id; + const trackId = currentTrack == null ? null : currentTrack.id; + const order = currentUnScheduleOrderBy; this.props.changeCurrentPresentationSelectionPlan( presentationSelectionPlan @@ -474,7 +480,7 @@ class ScheduleAdminDashBoard extends React.Component { this.props.getUnScheduleEventsPage( currentSummit.id, 1, - 20, + TWENTY_PER_PAGE, eventTypeId, trackId, currentPresentationSelectionStatus, @@ -494,13 +500,13 @@ class ScheduleAdminDashBoard extends React.Component { currentPresentationSelectionPlan, currentDuration } = this.props; - let eventTypeId = currentEventType == null ? null : currentEventType.id; - let trackId = currentTrack == null ? null : currentTrack.id; + const eventTypeId = currentEventType == null ? null : currentEventType.id; + const trackId = currentTrack == null ? null : currentTrack.id; this.props.changeCurrentUnscheduleSearchTerm(term); this.props.getUnScheduleEventsPage( currentSummit.id, 1, - 20, + TWENTY_PER_PAGE, eventTypeId, trackId, currentPresentationSelectionStatus, @@ -568,14 +574,14 @@ class ScheduleAdminDashBoard extends React.Component { window.location.hash = this.fragmentParser.serialize(); this.filters = this.parseFilterFromFragment(); } - }, 1500); + }, TIMEOUT_1500); } scrollToElement(elementId) { - var el = document.getElementById(elementId); + const el = document.getElementById(elementId); if (!el) return; - let yPos = el.getClientRects()[0].top; - var scroll = Scroll.animateScroll; + const yPos = el.getClientRects()[0].top; + const scroll = Scroll.animateScroll; scroll.scrollTo(yPos, { duration: 1500, @@ -585,7 +591,7 @@ class ScheduleAdminDashBoard extends React.Component { } onEditEvent(event) { - let { history, currentSummit } = this.props; + const { history, currentSummit } = this.props; history.push(`/app/summits/${currentSummit.id}/events/${event.id}`); } @@ -614,7 +620,7 @@ class ScheduleAdminDashBoard extends React.Component { } onOrderByChanged(orderBy) { - let { + const { currentSummit, currentEventType, currentTrack, @@ -624,14 +630,14 @@ class ScheduleAdminDashBoard extends React.Component { unScheduleEventsCurrentSearchTerm, unScheduleEventsCurrentPage } = this.props; - let eventTypeId = currentEventType == null ? null : currentEventType.id; - let trackId = currentTrack == null ? null : currentTrack.id; + const eventTypeId = currentEventType == null ? null : currentEventType.id; + const trackId = currentTrack == null ? null : currentTrack.id; this.props.changeCurrentUnScheduleOrderBy(orderBy); this.props.getUnScheduleEventsPage( currentSummit.id, unScheduleEventsCurrentPage, - 20, + TWENTY_PER_PAGE, eventTypeId, trackId, currentPresentationSelectionStatus, @@ -661,9 +667,9 @@ class ScheduleAdminDashBoard extends React.Component { onClickSpot(spot) { const { currentSummit } = this.props; - let start_date = moment.tz( - spot.start_date * 1000, - currentSummit.time_zone.name + const start_date = moment.tz( + spot.start_date * MILLISECONDS_IN_SECOND, + currentSummit.time_zone_id ); this.fragmentParser.setParam("q", ""); this.fragmentParser.setParam("event", ""); @@ -672,7 +678,7 @@ class ScheduleAdminDashBoard extends React.Component { // round minutes to upper limit let minute = start_date.minute(); - minute = Math.ceil(minute / 5) * 5; + minute = Math.ceil(minute / MINUTE_STEP_SIZE_5) * MINUTE_STEP_SIZE_5; start_date.minute(minute); this.fragmentParser.setParam("time", start_date.format("hh_mm")); window.location.hash = this.fragmentParser.serialize(); @@ -733,14 +739,14 @@ class ScheduleAdminDashBoard extends React.Component { this.props.setBulkEventSelectedState(evt.target.checked); } - onSelectedBulkActionUnPublished(bulkAction) { - let { selectedUnPublishedEvents, selectedAllUnPublished } = this.props; + onSelectedBulkActionUnPublished() { + const { selectedUnPublishedEvents, selectedAllUnPublished } = this.props; if (selectedUnPublishedEvents.length === 0 && !selectedAllUnPublished) return; this.props.editBulkAction("unpublished"); } - onDurationFilterApplied(ev) { + onDurationFilterApplied() { const { currentSummit, currentEventType, @@ -750,14 +756,14 @@ class ScheduleAdminDashBoard extends React.Component { unScheduleEventsCurrentSearchTerm, currentUnScheduleOrderBy } = this.props; - let eventTypeId = currentEventType == null ? null : currentEventType.id; - let trackId = currentTrack == null ? null : currentTrack.id; + const eventTypeId = currentEventType == null ? null : currentEventType.id; + const trackId = currentTrack == null ? null : currentTrack.id; const { durationFilter } = this.state; this.props.changeCurrentDuration(durationFilter); this.props.getUnScheduleEventsPage( currentSummit.id, 1, - 20, + TWENTY_PER_PAGE, eventTypeId, trackId, currentPresentationSelectionStatus, @@ -769,7 +775,7 @@ class ScheduleAdminDashBoard extends React.Component { } handleDurationFilter(ev) { - let { value, type, id } = ev.target; + let { value, type } = ev.target; if (type === "operatorinput") { value = Array.isArray(value) ? value @@ -902,8 +908,8 @@ class ScheduleAdminDashBoard extends React.Component { // parse event types const eventTypes = []; for (let i = 0; i < currentSummit.event_types.length; i++) { - let event_type = currentSummit.event_types[i]; - let option = { value: event_type, label: event_type.name }; + const event_type = currentSummit.event_types[i]; + const option = { value: event_type, label: event_type.name }; if (currentEventType != null && currentEventType.id === event_type.id) currentEventTypeSelectorItem = option; eventTypes.push(option); @@ -912,8 +918,8 @@ class ScheduleAdminDashBoard extends React.Component { // parse tracks const tracks = []; for (let i = 0; i < currentSummit.tracks.length; i++) { - let track = currentSummit.tracks[i]; - let option = { value: track, label: track.name }; + const track = currentSummit.tracks[i]; + const option = { value: track, label: track.name }; if (currentTrack != null && currentTrack.id === track.id) currentTrackSelectorItem = option; tracks.push(option); @@ -921,7 +927,7 @@ class ScheduleAdminDashBoard extends React.Component { // presentation selection status - let presentationSelectionStatusOptions = [ + const presentationSelectionStatusOptions = [ { value: "selected", label: "Selected" }, { value: "accepted", label: "Accepted" }, { value: "rejected", label: "Rejected" }, @@ -930,33 +936,22 @@ class ScheduleAdminDashBoard extends React.Component { // selection plan options - let presentationSelectionPlanOptions = currentSummit.selection_plans.map( + const presentationSelectionPlanOptions = currentSummit.selection_plans.map( (sp) => ({ value: sp.id, label: sp.name }) ); // sort options - let orderByOptions = [ + const orderByOptions = [ { value: "title", label: "Title" }, { value: "id", label: "Id" }, { value: "start_date", label: "Start Date" }, { value: "trackchairsel", label: "Track Chair Sel." } ]; - // bulk options published - - let bulkOptionsPublished = [ - { - value: BulkActionEdit, - label: T.translate("published_bulk_actions_selector.options.edit") - }, - { - value: BulkActionUnPublish, - label: T.translate("published_bulk_actions_selector.options.unpublish") - } - ]; + // bulk options unpublished - let bulkOptionsUnPublished = [ + const bulkOptionsUnPublished = [ { value: BulkActionEdit, label: T.translate("published_bulk_actions_selector.options.edit") @@ -1048,8 +1043,8 @@ class ScheduleAdminDashBoard extends React.Component { value={selectedFilters} onChange={this.handleFiltersChange} options={filters_ddl} - isClearable={true} - isMulti={true} + isClearable + isMulti /> @@ -1197,7 +1192,7 @@ class ScheduleAdminDashBoard extends React.Component { /> )} {emptySpots.length === 0 && searchingEmpty && ( - + {T.translate("empty_spots_modal.find_empty_spots")} diff --git a/src/components/schedule-builder/schedule-admin-empty-spots-list.js b/src/components/schedule-builder/schedule-admin-empty-spots-list.js index cbe0e4244..91df893cf 100644 --- a/src/components/schedule-builder/schedule-admin-empty-spots-list.js +++ b/src/components/schedule-builder/schedule-admin-empty-spots-list.js @@ -9,61 +9,62 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. - **/ + * */ import React from "react"; import moment from "moment-timezone"; +import { MILLISECONDS_IN_SECOND } from "../../utils/constants"; -class ScheduleAdminEmptySpotsList extends React.Component { - render() { - let { emptySpots, currentSummit, onClickSpot } = this.props; - - let emptySpotsItems = []; - let lastLocation = null; - let idx = 1; - for (let spot of emptySpots) { - if (lastLocation == null || lastLocation.id !== spot.location_id) { - lastLocation = currentSummit.locations - .filter((location) => location.id === spot.location_id) - .shift(); - emptySpotsItems.push( -
  • -

    {lastLocation.name}

    -
  • - ); - ++idx; - } - let start_date = moment.tz( - spot.start_date * 1000, - currentSummit.time_zone.name - ); - let end_date = moment.tz( - spot.end_date * 1000, - currentSummit.time_zone.name - ); +const ScheduleAdminEmptySpotsList = ({ + emptySpots, + currentSummit, + onClickSpot +}) => { + const emptySpotsItems = []; + let lastLocation = null; + let idx = 1; + for (const spot of emptySpots) { + if (lastLocation == null || lastLocation.id !== spot.location_id) { + lastLocation = currentSummit.locations + .filter((location) => location.id === spot.location_id) + .shift(); emptySpotsItems.push( -
  • -
    onClickSpot(spot)} - > - From  - - {start_date.format("YYYY-MM-DD hh:mm")} - - To  - {end_date.format("YYYY-MM-DD hh:mm")} -  - Empty Spot ( - {spot.total_minutes} minutes) -
    +
  • +

    {lastLocation.name}

  • ); ++idx; } - return
      {emptySpotsItems}
    ; + const start_date = moment.tz( + spot.start_date * MILLISECONDS_IN_SECOND, + currentSummit.time_zone_id + ); + const end_date = moment.tz( + spot.end_date * MILLISECONDS_IN_SECOND, + currentSummit.time_zone_id + ); + + emptySpotsItems.push( +
  • +
    onClickSpot(spot)} + > + From  + {start_date.format("YYYY-MM-DD hh:mm")} + To  + {end_date.format("YYYY-MM-DD hh:mm")} +  - Empty Spot ( + {spot.total_minutes} minutes) +
    +
  • + ); + ++idx; } -} + + return
      {emptySpotsItems}
    ; +}; export default ScheduleAdminEmptySpotsList; diff --git a/src/components/schedule-builder/schedule-admin-empty-spots-modal.js b/src/components/schedule-builder/schedule-admin-empty-spots-modal.js index 48449c95f..54ae4ebf9 100644 --- a/src/components/schedule-builder/schedule-admin-empty-spots-modal.js +++ b/src/components/schedule-builder/schedule-admin-empty-spots-modal.js @@ -9,7 +9,7 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. - **/ + * */ import { Modal, Button, FormGroup, FormControl } from "react-bootstrap"; import React from "react"; import { @@ -18,20 +18,32 @@ import { } from "openstack-uicore-foundation/lib/components"; import moment from "moment-timezone"; import T from "i18n-react/dist/i18n-react"; +import { + GAP_SIZE, + MILLISECONDS_IN_SECOND, + TIME_19_HOURS, + TIME_7_HOURS +} from "../../utils/constants"; class ScheduleAdminEmptySpotsModal extends React.Component { constructor(props) { super(props); const { currentSummit } = this.props; - let defaultValueStart = moment - .tz(currentSummit.start_date * 1000, currentSummit.time_zone.name) - .hour(7) + const defaultValueStart = moment + .tz( + currentSummit.start_date * MILLISECONDS_IN_SECOND, + currentSummit.time_zone_id + ) + .hour(TIME_7_HOURS) .minute(0) .second(0); - let defaultValueEnd = moment - .tz(currentSummit.start_date * 1000, currentSummit.time_zone.name) - .hour(19) + const defaultValueEnd = moment + .tz( + currentSummit.start_date * MILLISECONDS_IN_SECOND, + currentSummit.time_zone_id + ) + .hour(TIME_19_HOURS) .minute(0) .second(0); @@ -58,7 +70,7 @@ class ScheduleAdminEmptySpotsModal extends React.Component { isValidForm() { let valid = true; - for (var key in this.validationState) { + for (const key in this.validationState) { valid = valid && this.validationState[key]; } return valid; @@ -68,32 +80,32 @@ class ScheduleAdminEmptySpotsModal extends React.Component { if (!this.isValidForm()) return; this.props.onFindEmptySpots({ currentLocation: this.state.currentLocation.value, - dateFrom: this.state.dateFrom.valueOf() / 1000, - dateTo: this.state.dateTo.valueOf() / 1000, + dateFrom: this.state.dateFrom.valueOf() / MILLISECONDS_IN_SECOND, + dateTo: this.state.dateTo.valueOf() / MILLISECONDS_IN_SECOND, gapSize: this.state.gapSize }); } handleChangeDateFrom(ev) { - let { value, id } = ev.target; + const { value } = ev.target; this.setState({ ...this.state, dateFrom: value }); } getValidationDateFrom() { - let { dateFrom } = this.state; - let isValid = dateFrom != null && dateFrom !== ""; + const { dateFrom } = this.state; + const isValid = dateFrom != null && dateFrom !== ""; this.validationState = { ...this.validationState, dateFrom: isValid }; return isValid ? "success" : "warning"; } handleChangeDateTo(ev) { - let { value, id } = ev.target; + const { value } = ev.target; this.setState({ ...this.state, dateTo: value }); } getValidationDateTo() { - let { dateTo, dateFrom } = this.state; - let isValid = + const { dateTo, dateFrom } = this.state; + const isValid = dateTo != null && dateTo !== "" && dateFrom != null && @@ -103,15 +115,15 @@ class ScheduleAdminEmptySpotsModal extends React.Component { } onVenueChanged(location) { - let option = + const option = location != null ? { value: location, label: location.name } : null; this.setState({ ...this.state, currentLocation: option }); } getValidationStateVenue() { - let { currentLocation } = this.state; + const { currentLocation } = this.state; - let isValid = currentLocation != null; + const isValid = currentLocation != null; this.validationState = { ...this.validationState, currentLocation: isValid @@ -126,51 +138,48 @@ class ScheduleAdminEmptySpotsModal extends React.Component { getValidationStateGapSize() { let { gapSize } = this.state; gapSize = parseInt(gapSize); - let isValid = gapSize >= 5; + const isValid = gapSize >= GAP_SIZE; this.validationState = { ...this.validationState, gapSize: isValid }; return isValid ? "success" : "warning"; } render() { - let { showModal, onCloseModal, currentSummit } = this.props; - let { currentLocation, dateFrom, dateTo, gapSize } = this.state; + const { showModal, onCloseModal, currentSummit } = this.props; + const { currentLocation, dateFrom, dateTo, gapSize } = this.state; // process venues - let venues = []; + const venues = []; for (let i = 0; i < currentSummit.locations.length; i++) { - let location = currentSummit.locations[i]; + const location = currentSummit.locations[i]; if (location.class_name !== "SummitVenue") continue; - let option = { value: location, label: location.name }; + const option = { value: location, label: location.name }; venues.push(option); if (!location.hasOwnProperty("rooms")) continue; for (let j = 0; j < location.rooms.length; j++) { - let subOption = { + const subOption = { value: location.rooms[j], label: location.rooms[j].name }; venues.push(subOption); } } - let currenSummitStartDate = moment - .tz(currentSummit.start_date * 1000, currentSummit.time_zone.name) + const currenSummitStartDate = moment + .tz( + currentSummit.start_date * MILLISECONDS_IN_SECOND, + currentSummit.time_zone_id + ) .hour(0) .minute(0) .second(0); - let currenSummitEndDate = moment - .tz(currentSummit.end_date * 1000, currentSummit.time_zone.name) - .hour(23) - .minute(59) - .second(59); - let defaultValueStart = moment - .tz(currentSummit.start_date * 1000, currentSummit.time_zone.name) - .hour(7) - .minute(0) - .second(0); - let defaultValueEnd = moment - .tz(currentSummit.start_date * 1000, currentSummit.time_zone.name) - .hour(22) - .minute(0) - .second(0); + const currenSummitEndDate = moment + .tz( + currentSummit.end_date * MILLISECONDS_IN_SECOND, + currentSummit.time_zone_id + ) + .hour(TIME_23_HOURS) + .minute(TIME_59_MINS) + .second(TIME_59_SECS); + return ( @@ -208,11 +217,14 @@ class ScheduleAdminEmptySpotsModal extends React.Component { "empty_spots_modal.placeholders.start_date" ) }} - timezone={currentSummit.time_zone.name} + timezone={currentSummit.time_zone_id} timeConstraints={{ hours: { min: 7, max: 22 } }} validation={{ - after: currenSummitStartDate.valueOf() / 1000, - before: currenSummitEndDate.valueOf() / 1000 + after: + currenSummitStartDate.valueOf() / + MILLISECONDS_IN_SECOND, + before: + currenSummitEndDate.valueOf() / MILLISECONDS_IN_SECOND }} onChange={this.handleChangeDateFrom} value={dateFrom} @@ -232,10 +244,13 @@ class ScheduleAdminEmptySpotsModal extends React.Component { "empty_spots_modal.placeholders.end_date" ) }} - timezone={currentSummit.time_zone.name} + timezone={currentSummit.time_zone_id} validation={{ - after: currenSummitStartDate.valueOf() / 1000, - before: currenSummitEndDate.valueOf() / 1000 + after: + currenSummitStartDate.valueOf() / + MILLISECONDS_IN_SECOND, + before: + currenSummitEndDate.valueOf() / MILLISECONDS_IN_SECOND }} onChange={this.handleChangeDateTo} value={dateTo} diff --git a/src/components/schedule-modal/index.js b/src/components/schedule-modal/index.js index 9d8c75ab2..4dccabdfd 100644 --- a/src/components/schedule-modal/index.js +++ b/src/components/schedule-modal/index.js @@ -9,13 +9,14 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. - **/ + * */ import React from "react"; import T from "i18n-react/dist/i18n-react"; import moment from "moment-timezone"; import { Modal } from "react-bootstrap"; import "./schedule-modal.less"; +import { MILLISECONDS_IN_SECOND } from "../../utils/constants"; export default class ScheduleModal extends React.Component { constructor(props) { @@ -25,30 +26,30 @@ export default class ScheduleModal extends React.Component { } getFormattedTime(atime) { - atime = atime * 1000; + atime *= MILLISECONDS_IN_SECOND; return moment(atime).tz(this.props.summit.time_zone.name).format("h:mm a"); } getFormattedDay(atime) { - atime = atime * 1000; + atime *= MILLISECONDS_IN_SECOND; return moment(atime).tz(this.props.summit.time_zone.name).format("dddd D"); } getFormattedLocation(location_id) { - let venue = this.props.summit.locations.find( + const venue = this.props.summit.locations.find( (l) => l.id === location_id ).name; return venue; } getFormatedSchedule() { - let groupedSchedule = {}; - let sortedSchedule = this.props.schedule.sort((a, b) => + const groupedSchedule = {}; + const sortedSchedule = this.props.schedule.sort((a, b) => a.start_date > b.start_date ? 1 : a.start_date < b.start_date ? -1 : 0 ); - for (var i in sortedSchedule) { - let day = this.getFormattedDay(sortedSchedule[i].start_date); + for (const i in sortedSchedule) { + const day = this.getFormattedDay(sortedSchedule[i].start_date); if (!groupedSchedule.hasOwnProperty(day)) groupedSchedule[day] = []; groupedSchedule[day].push(sortedSchedule[i]); } @@ -83,7 +84,7 @@ export default class ScheduleModal extends React.Component { } render() { - let { show, title, onClose, schedule } = this.props; + const { show, title, onClose, schedule } = this.props; return ( diff --git a/src/components/summit-event-bulk-actions/summit-event-bulk-editor-form.js b/src/components/summit-event-bulk-actions/summit-event-bulk-editor-form.js index 93f918f1c..f3a671511 100644 --- a/src/components/summit-event-bulk-actions/summit-event-bulk-editor-form.js +++ b/src/components/summit-event-bulk-actions/summit-event-bulk-editor-form.js @@ -342,7 +342,7 @@ class SummitEventBulkEditorForm extends React.Component { const currentSummitStartDate = moment .tz( currentSummit.start_date * MILLISECONDS_IN_SECOND, - currentSummit.time_zone.name + currentSummit.time_zone_id ) .hour(0) .minute(0) @@ -350,7 +350,7 @@ class SummitEventBulkEditorForm extends React.Component { const currentSummitEndDate = moment .tz( currentSummit.end_date * MILLISECONDS_IN_SECOND, - currentSummit.time_zone.name + currentSummit.time_zone_id ) .hour(TIME_23_HOURS) .minute(TIME_59_MINS) @@ -458,7 +458,7 @@ class SummitEventBulkEditorForm extends React.Component { "bulk_actions_page.placeholders.start_date" ) }} - timezone={currentSummit.time_zone.name} + timezone={currentSummit.time_zone_id} value={epochToMomentTimeZone( currentBulkStartDate, currentSummit.time_zone_id @@ -485,7 +485,7 @@ class SummitEventBulkEditorForm extends React.Component { "bulk_actions_page.placeholders.end_date" ) }} - timezone={currentSummit.time_zone.name} + timezone={currentSummit.time_zone_id} value={epochToMomentTimeZone( currentBulkEndDate, currentSummit.time_zone_id diff --git a/src/components/summit-event-bulk-actions/summit-event-bulk-editor-item.js b/src/components/summit-event-bulk-actions/summit-event-bulk-editor-item.js index 100921702..6de864b4f 100644 --- a/src/components/summit-event-bulk-actions/summit-event-bulk-editor-item.js +++ b/src/components/summit-event-bulk-actions/summit-event-bulk-editor-item.js @@ -62,7 +62,7 @@ class SummitEventBulkEditorItem extends React.Component { if (atime == null) return ""; if (!atime) return atime; atime *= MILLISECONDS_IN_SECOND; - return moment(atime).tz(this.props.currentSummit.time_zone.name); + return moment(atime).tz(this.props.currentSummit.time_zone_id); } getValidationEventTitle() { @@ -232,7 +232,7 @@ class SummitEventBulkEditorItem extends React.Component { const currentSummitStartDate = moment .tz( currentSummit.start_date * MILLISECONDS_IN_SECOND, - currentSummit.time_zone.name + currentSummit.time_zone_id ) .hour(0) .minute(0) @@ -240,7 +240,7 @@ class SummitEventBulkEditorItem extends React.Component { const currentSummitEndDate = moment .tz( currentSummit.end_date * MILLISECONDS_IN_SECOND, - currentSummit.time_zone.name + currentSummit.time_zone_id ) .hour(TIME_23_HOURS) .minute(TIME_59_MINS) @@ -316,7 +316,7 @@ class SummitEventBulkEditorItem extends React.Component { "bulk_actions_page.placeholders.start_date" ) }} - timezone={currentSummit.time_zone.name} + timezone={currentSummit.time_zone_id} timeConstraints={{ hours: { min: 7, max: 22 } }} validation={{ after: @@ -341,7 +341,7 @@ class SummitEventBulkEditorItem extends React.Component { "bulk_actions_page.placeholders.end_date" ) }} - timezone={currentSummit.time_zone.name} + timezone={currentSummit.time_zone_id} validation={{ after: currentSummitStartDate.valueOf() / MILLISECONDS_IN_SECOND, diff --git a/src/pages/attendees/summit-attendees-list-page.js b/src/pages/attendees/summit-attendees-list-page.js index a5378ba93..a612a076f 100644 --- a/src/pages/attendees/summit-attendees-list-page.js +++ b/src/pages/attendees/summit-attendees-list-page.js @@ -1013,7 +1013,7 @@ class SummitAttendeeListPage extends React.Component { "attendee_list.placeholders.checkin_date_from" ) }} - timezone={currentSummit.time_zone.name} + timezone={currentSummit.time_zone_id} onChange={(ev) => this.handleCheckInDate(ev, false)} value={epochToMomentTimeZone( attendeeFilters.checkinDateFilter[0], @@ -1034,7 +1034,7 @@ class SummitAttendeeListPage extends React.Component { "attendee_list.placeholders.checkin_date_to" ) }} - timezone={currentSummit.time_zone.name} + timezone={currentSummit.time_zone_id} onChange={(ev) => this.handleCheckInDate(ev, true)} value={epochToMomentTimeZone( attendeeFilters.checkinDateFilter[1], diff --git a/src/pages/events/summit-event-list-page.js b/src/pages/events/summit-event-list-page.js index 68b7ca3dd..b4a89d4f0 100644 --- a/src/pages/events/summit-event-list-page.js +++ b/src/pages/events/summit-event-list-page.js @@ -1610,7 +1610,7 @@ class SummitEventListPage extends React.Component { "event_list.placeholders.start_date_from" ) }} - timezone={currentSummit.time_zone.name} + timezone={currentSummit.time_zone_id} onChange={(ev) => this.handleChangeDateFilter(ev, false)} value={epochToMomentTimeZone( eventFilters.start_date_filter[0], @@ -1628,7 +1628,7 @@ class SummitEventListPage extends React.Component { "event_list.placeholders.start_date_to" ) }} - timezone={currentSummit.time_zone.name} + timezone={currentSummit.time_zone_id} onChange={(ev) => this.handleChangeDateFilter(ev, true)} value={epochToMomentTimeZone( eventFilters.start_date_filter[1], @@ -1650,7 +1650,7 @@ class SummitEventListPage extends React.Component { "event_list.placeholders.end_date_from" ) }} - timezone={currentSummit.time_zone.name} + timezone={currentSummit.time_zone_id} onChange={(ev) => this.handleChangeDateFilter(ev, false)} value={epochToMomentTimeZone( eventFilters.end_date_filter[0], @@ -1668,7 +1668,7 @@ class SummitEventListPage extends React.Component { "event_list.placeholders.end_date_to" ) }} - timezone={currentSummit.time_zone.name} + timezone={currentSummit.time_zone_id} onChange={(ev) => this.handleChangeDateFilter(ev, true)} value={epochToMomentTimeZone( eventFilters.end_date_filter[1], @@ -1690,7 +1690,7 @@ class SummitEventListPage extends React.Component { "event_list.placeholders.created_from" ) }} - timezone={currentSummit.time_zone.name} + timezone={currentSummit.time_zone_id} onChange={(ev) => this.handleChangeDateFilter(ev, false)} value={epochToMomentTimeZone( eventFilters.created_filter[0], @@ -1708,7 +1708,7 @@ class SummitEventListPage extends React.Component { "event_list.placeholders.created_to" ) }} - timezone={currentSummit.time_zone.name} + timezone={currentSummit.time_zone_id} onChange={(ev) => this.handleChangeDateFilter(ev, true)} value={epochToMomentTimeZone( eventFilters.created_filter[1], @@ -1730,7 +1730,7 @@ class SummitEventListPage extends React.Component { "event_list.placeholders.modified_from" ) }} - timezone={currentSummit.time_zone.name} + timezone={currentSummit.time_zone_id} onChange={(ev) => this.handleChangeDateFilter(ev, false)} value={epochToMomentTimeZone( eventFilters.modified_filter[0], @@ -1748,7 +1748,7 @@ class SummitEventListPage extends React.Component { "event_list.placeholders.modified_to" ) }} - timezone={currentSummit.time_zone.name} + timezone={currentSummit.time_zone_id} onChange={(ev) => this.handleChangeDateFilter(ev, true)} value={epochToMomentTimeZone( eventFilters.modified_filter[1], diff --git a/src/pages/orders/purchase-order-list-page.js b/src/pages/orders/purchase-order-list-page.js index 1c5258cc8..a9c983084 100644 --- a/src/pages/orders/purchase-order-list-page.js +++ b/src/pages/orders/purchase-order-list-page.js @@ -430,7 +430,7 @@ class PurchaseOrderListPage extends React.Component { "purchase_order_list.placeholders.purchased_from" ) }} - timezone={currentSummit.time_zone.name} + timezone={currentSummit.time_zone_id} onChange={(ev) => this.handleChangeDateFilter(ev, false)} value={epochToMomentTimeZone( purchaseOrderFilters.purchase_date_filter[0], @@ -448,7 +448,7 @@ class PurchaseOrderListPage extends React.Component { "purchase_order_list.placeholders.purchased_to" ) }} - timezone={currentSummit.time_zone.name} + timezone={currentSummit.time_zone_id} onChange={(ev) => this.handleChangeDateFilter(ev, true)} value={epochToMomentTimeZone( purchaseOrderFilters.purchase_date_filter[1], diff --git a/src/pages/summits/summit-dashboard-page.js b/src/pages/summits/summit-dashboard-page.js index 4185da456..c78d5d0f9 100644 --- a/src/pages/summits/summit-dashboard-page.js +++ b/src/pages/summits/summit-dashboard-page.js @@ -9,15 +9,16 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. - **/ + * */ import React from "react"; import { connect } from "react-redux"; import moment from "moment-timezone"; -import { getSummitById } from "../../actions/summit-actions"; import T from "i18n-react/dist/i18n-react"; import { Breadcrumb } from "react-breadcrumbs"; +import { getSummitById } from "../../actions/summit-actions"; import Member from "../../models/member"; import "../../styles/summit-dashboard-page.less"; +import { MILLISECONDS_IN_SECOND } from "../../utils/constants"; class SummitDashboardPage extends React.Component { constructor(props) { @@ -37,18 +38,21 @@ class SummitDashboardPage extends React.Component { } onCollapseChange(section) { - let newCollapseState = { ...this.state.collapseState }; + const newCollapseState = { ...this.state.collapseState }; newCollapseState[section] = !newCollapseState[section]; this.setState({ ...this.state, collapseState: newCollapseState }); } componentDidMount() { const { currentSummit } = this.props; - this.interval = setInterval(this.localTimer.bind(this), 1000); + this.interval = setInterval( + this.localTimer.bind(this), + MILLISECONDS_IN_SECOND + ); if (currentSummit) { - let localtime = moment().tz(currentSummit.time_zone.name); - this.setState({ ...this.state, localtime: localtime }); + const localtime = moment().tz(currentSummit.time_zone_id); + this.setState({ ...this.state, localtime }); } } @@ -63,9 +67,9 @@ class SummitDashboardPage extends React.Component { } getFormattedTime(atime) { - atime = atime * 1000; + atime *= MILLISECONDS_IN_SECOND; return moment(atime) - .tz(this.props.currentSummit.time_zone.name) + .tz(this.props.currentSummit.time_zone_id) .format("MMMM Do YYYY, h:mm:ss a"); } @@ -77,8 +81,8 @@ class SummitDashboardPage extends React.Component { render() { const { currentSummit, match, member } = this.props; - let memberObj = new Member(member); - let canEditSummit = memberObj.canEditSummit(); + const memberObj = new Member(member); + const canEditSummit = memberObj.canEditSummit(); if (!currentSummit.id) return
    ; @@ -97,20 +101,19 @@ class SummitDashboardPage extends React.Component {

    {T.translate("dashboard.dates")}

    -
    {currentSummit.time_zone.name}
    +
    {currentSummit.time_zone_id}
    {" "} - {this.getFormattedTime(this.state.localtime / 1000)}{" "} + {this.getFormattedTime( + this.state.localtime / MILLISECONDS_IN_SECOND + )}{" "}
    {" "} @@ -130,13 +133,10 @@ class SummitDashboardPage extends React.Component {
    {" "} @@ -160,17 +160,14 @@ class SummitDashboardPage extends React.Component {
    {canEditSummit && currentSummit.selection_plans.map((sp) => ( -
    +
    {sp.name}
    {" "} @@ -191,13 +188,10 @@ class SummitDashboardPage extends React.Component {
    {" "} @@ -218,13 +212,10 @@ class SummitDashboardPage extends React.Component {
    {" "} @@ -253,24 +244,24 @@ class SummitDashboardPage extends React.Component {

    {T.translate("dashboard.events")}  - {this.state.collapseState["events"] && ( + {this.state.collapseState.events && ( this.onCollapseChange("events")} className="fa fa-plus-square clickable" aria-hidden="true" - > + /> )} - {!this.state.collapseState["events"] && ( + {!this.state.collapseState.events && ( this.onCollapseChange("events")} className="fa fa-minus-square clickable" aria-hidden="true" - > + /> )}

    - {!this.state.collapseState["events"] && ( + {!this.state.collapseState.events && (
    @@ -309,24 +300,24 @@ class SummitDashboardPage extends React.Component {

    {T.translate("dashboard.voting")}  - {this.state.collapseState["voting"] && ( + {this.state.collapseState.voting && ( this.onCollapseChange("voting")} className="fa fa-plus-square clickable" aria-hidden="true" - > + /> )} - {!this.state.collapseState["voting"] && ( + {!this.state.collapseState.voting && ( this.onCollapseChange("voting")} className="fa fa-minus-square clickable" aria-hidden="true" - > + /> )}

    - {!this.state.collapseState["voting"] && ( + {!this.state.collapseState.voting && (
    @@ -345,24 +336,24 @@ class SummitDashboardPage extends React.Component {

    {T.translate("dashboard.emails")}  - {this.state.collapseState["emails"] && ( + {this.state.collapseState.emails && ( this.onCollapseChange("emails")} className="fa fa-plus-square clickable" aria-hidden="true" - > + /> )} - {!this.state.collapseState["emails"] && ( + {!this.state.collapseState.emails && ( this.onCollapseChange("emails")} className="fa fa-minus-square clickable" aria-hidden="true" - > + /> )}

    - {!this.state.collapseState["emails"] && ( + {!this.state.collapseState.emails && (
    diff --git a/src/utils/constants.js b/src/utils/constants.js index affd4098d..6600d6042 100644 --- a/src/utils/constants.js +++ b/src/utils/constants.js @@ -89,8 +89,12 @@ export const HOUR_AND_HALF = 5400; export const SECONDS_TO_MINUTES = 60; export const MILLISECONDS_IN_SECOND = 1000; export const TIME_23_HOURS = 23; +export const TIME_7_HOURS = 7; +export const TIME_19_HOURS = 19; export const TIME_59_MINS = 59; export const TIME_59_SECS = 59; +export const MINUTE_STEP_SIZE_5 = 5; +export const GAP_SIZE = 5; export const SORT_ASCENDING = 1; export const SORT_DESCENDING = -1; @@ -147,6 +151,8 @@ export const LANGUAGE_CODE_LENGTH = 2; export const SLICE_TICKET_NUMBER = -15; +export const TIMEOUT_1500 = 1500; + export const MARKETING_SETTING_TYPE_TEXT = "TEXT"; export const MARKETING_SETTING_TYPE_TEXTAREA = "TEXTAREA"; export const MARKETING_SETTING_TYPE_FILE = "FILE"; diff --git a/src/utils/summitUtils.js b/src/utils/summitUtils.js index c31ee8eee..e49ba1287 100644 --- a/src/utils/summitUtils.js +++ b/src/utils/summitUtils.js @@ -23,7 +23,7 @@ const formatDuration = (duration) => { export const formatEventData = (e, summit) => { const published_date = e.is_published ? moment(e.published_date * MILLISECONDS_IN_SECOND) - .tz(summit.time_zone.name) + .tz(summit.time_zone_id) .format("MMMM Do YYYY, h:mm a") : "No"; @@ -116,12 +116,12 @@ export const formatEventData = (e, summit) => { streaming_type: e.streaming_type ? e.streaming_type : "N/A", start_date: e.start_date ? moment(e.start_date * MILLISECONDS_IN_SECOND) - .tz(summit.time_zone.name) + .tz(summit.time_zone_id) .format("MMMM Do YYYY, h:mm a") : "TBD", end_date: e.end_date ? moment(e.end_date * MILLISECONDS_IN_SECOND) - .tz(summit.time_zone.name) + .tz(summit.time_zone_id) .format("MMMM Do YYYY, h:mm a") : "TBD", sponsor: @@ -133,7 +133,7 @@ export const formatEventData = (e, summit) => { ? e?.media_uploads?.map((m) => ({ ...m, created: moment(m.created * MILLISECONDS_IN_SECOND) - .tz(summit.time_zone.name) + .tz(summit.time_zone_id) .format("MMMM Do YYYY, h:mm a") })) : "N/A", From c5c0e5195b717c649ee533113a5920739a038fe7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1s=20Castillo?= Date: Fri, 20 Dec 2024 12:03:24 -0300 Subject: [PATCH 2/6] add missing fields for selection plans and tracks MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Tomás Castillo --- src/actions/summit-actions.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/actions/summit-actions.js b/src/actions/summit-actions.js index 041a47168..a2d422d9b 100644 --- a/src/actions/summit-actions.js +++ b/src/actions/summit-actions.js @@ -68,7 +68,7 @@ export const getSummitById = (summitId) => async (dispatch) => { "meeting_booking_room_allowed_attributes.values," + "lead_report_settings," + "presentation_action_types," + - "selection_plans," + + "selection_plans,selection_plans.track_groups," + "ticket_types," + "badge_types," + "badge_features," + @@ -119,8 +119,8 @@ export const getSummitById = (summitId) => async (dispatch) => { "ticket_types,ticket_types.id,ticket_types.name," + "time_zone_id," + "time_zone_label," + - "tracks,tracks.id,tracks.name,tracks.parent_id,tracks.order,tracks.chair_visible,tracks.subtracks," + - "selection_plans,selection_plans.id,selection_plans.name,selection_plans.is_enabled,selection_plans.order,selection_plans.submission_begin_date,selection_plans.submission_end_date,selection_plans.voting_begin_date,selection_plans.voting_end_date,selection_plans.selection_begin_date,selection_plans.selection_end_date,selection_plans.track_groups," + + "tracks,tracks.id,tracks.name,tracks.parent_id,tracks.order,tracks.chair_visible,tracks.subtracks,tracks.track_groups," + + "selection_plans,selection_plans.id,selection_plans.name,selection_plans.is_enabled,selection_plans.order,selection_plans.submission_begin_date,selection_plans.submission_end_date,selection_plans.voting_begin_date,selection_plans.voting_end_date,selection_plans.selection_begin_date,selection_plans.selection_end_date,selection_plans.track_groups,selection_plans.allowed_presentation_questions," + "meeting_booking_room_allowed_attributes,meeting_booking_room_allowed_attributes.id,meeting_booking_room_allowed_attributes.created,meeting_booking_room_allowed_attributes.last_edited,meeting_booking_room_allowed_attributes.type,meeting_booking_room_allowed_attributes.summit_id,meeting_booking_room_allowed_attributes.values.value," + "meeting_room_booking_end_time," + "meeting_room_booking_max_allowed," + @@ -172,11 +172,11 @@ export const getSummitById = (summitId) => async (dispatch) => { "", relations: "event_types.none," + - "tracks.none," + + "tracks.subtracks,tracks.track_groups," + "tracks_groups.none," + "locations,locations.rooms,locations.floor,locations.none," + "meeting_booking_room_allowed_attributes.values," + - "selection_plans.track_groups,selection_plans.none," + + "selection_plans.track_groups,selection_plans.allowed_presentation_questions," + "ticket_types.none," + "badge_types.none," + "none" From f5915e603a9c029776613ba285e865f5aca06575 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1s=20Castillo?= Date: Fri, 7 Feb 2025 12:57:25 -0300 Subject: [PATCH 3/6] WIP input implementation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Tomás Castillo --- src/actions/location-actions.js | 128 ++++++++++- src/components/forms/room-booking-form.js | 26 +-- src/components/inputs/bookable-room-input.js | 123 ++++++++++ .../inputs/location-grouped-dropdown.js | 213 +++++++++++------- .../inputs/locations-grouped-async-input.js | 150 ++++++++++++ src/components/inputs/rooms-input.js | 115 ++++++++++ src/components/inputs/venue-input.js | 117 ++++++++++ .../track-timeframes/DayTimeframeTable.js | 15 +- src/pages/signage/index.js | 47 +++- src/utils/constants.js | 1 + 10 files changed, 819 insertions(+), 116 deletions(-) create mode 100644 src/components/inputs/bookable-room-input.js create mode 100644 src/components/inputs/locations-grouped-async-input.js create mode 100644 src/components/inputs/rooms-input.js create mode 100644 src/components/inputs/venue-input.js diff --git a/src/actions/location-actions.js b/src/actions/location-actions.js index 935d86e3c..b140e5d7e 100644 --- a/src/actions/location-actions.js +++ b/src/actions/location-actions.js @@ -28,10 +28,15 @@ import { getCSV, geoCodeAddress, geoCodeLatLng, - authErrorHandler + authErrorHandler, + escapeFilterValue, + fetchResponseHandler, + fetchErrorHandler } from "openstack-uicore-foundation/lib/utils/actions"; +import URI from "urijs"; import history from "../history"; import { getAccessTokenSafely } from "../utils/methods"; +import { DEBOUNCE_WAIT, TWO_HUNDRED_PER_PAGE } from "../utils/constants"; export const REQUEST_LOCATIONS = "REQUEST_LOCATIONS"; export const RECEIVE_LOCATIONS = "RECEIVE_LOCATIONS"; @@ -1013,3 +1018,124 @@ const normalizeMapEntity = (entity) => { return normalizedEntity; }; + +export const queryGroupLocations = _.debounce( + async (summitId, input, callback) => { + const accessToken = await getAccessTokenSafely(); + + const endpoint = URI( + `${window.API_BASE_URL}/api/v1/summits/${summitId}/locations` + ); + + endpoint.addQuery("access_token", accessToken); + endpoint.addQuery("per_page", TWO_HUNDRED_PER_PAGE); + endpoint.addQuery("expand", "rooms,floors"); + endpoint.addQuery("fields", "id,name,order,class_name,rooms,floors"); + endpoint.addQuery("relations", "rooms,floors,none"); + + if (input) { + input = escapeFilterValue(input); + endpoint.addQuery("filter[]", `rooms=@${input}`); + } + + fetch(endpoint) + .then(fetchResponseHandler) + .then((json) => { + const options = [...json.data]; + callback(options); + }) + .catch(fetchErrorHandler); + }, + DEBOUNCE_WAIT +); + +export const queryAllRooms = _.debounce(async (summitId, input, callback) => { + const accessToken = await getAccessTokenSafely(); + + console.log("query all rooms"); + + const endpoint = URI( + `${window.API_BASE_URL}/api/v1/summits/${summitId}/locations/venues/all/rooms` + ); + + endpoint.addQuery("access_token", accessToken); + endpoint.addQuery("per_page", TWO_HUNDRED_PER_PAGE); + // endpoint.addQuery("expand", "rooms,floors"); + // endpoint.addQuery("fields", "id,name,order,class_name,rooms,floors"); + // endpoint.addQuery("relations", "rooms,floors,none"); + + if (input) { + input = escapeFilterValue(input); + endpoint.addQuery("filter[]", `name=@${input}`); + } + + fetch(endpoint) + .then(fetchResponseHandler) + .then((json) => { + const options = [...json.data]; + callback(options); + }) + .catch(fetchErrorHandler); +}, DEBOUNCE_WAIT); + +export const queryBookableRooms = _.debounce( + async (summitId, input, callback) => { + const accessToken = await getAccessTokenSafely(); + + const endpoint = URI( + `${window.API_BASE_URL}/api/v1/summits/${summitId}/locations/venues/all/bookable-rooms` + ); + + endpoint.addQuery("access_token", accessToken); + endpoint.addQuery("per_page", TWO_HUNDRED_PER_PAGE); + endpoint.addQuery("expand", "attributes.type, floor"); + endpoint.addQuery( + "fields", + "id,name,image.url,currency,time_slot_cost,capacity,attributes.type.type,attributes.value,floor.name" + ); + endpoint.addQuery("relations", "none"); + + if (input) { + input = escapeFilterValue(input); + endpoint.addQuery("filter[]", `name=@${input}`); + } + + fetch(endpoint) + .then(fetchResponseHandler) + .then((json) => { + const options = [...json.data]; + callback(options); + }) + .catch(fetchErrorHandler); + }, + DEBOUNCE_WAIT +); + +export const queryVenues = _.debounce(async (summitId, input, callback) => { + const accessToken = await getAccessTokenSafely(); + + console.log("query venues"); + + const endpoint = URI( + `${window.API_BASE_URL}/api/v1/summits/${summitId}/locations/venues` + ); + + endpoint.addQuery("access_token", accessToken); + endpoint.addQuery("per_page", TWO_HUNDRED_PER_PAGE); + // endpoint.addQuery("expand", "rooms,floors"); + // endpoint.addQuery("fields", "id,name,order,class_name,rooms,floors"); + // endpoint.addQuery("relations", "rooms,floors,none"); + + if (input) { + input = escapeFilterValue(input); + endpoint.addQuery("filter[]", `rooms=@${input}`); + } + + fetch(endpoint) + .then(fetchResponseHandler) + .then((json) => { + const options = [...json.data]; + callback(options); + }) + .catch(fetchErrorHandler); +}, DEBOUNCE_WAIT); diff --git a/src/components/forms/room-booking-form.js b/src/components/forms/room-booking-form.js index d6f1eb58b..40bf5f11c 100644 --- a/src/components/forms/room-booking-form.js +++ b/src/components/forms/room-booking-form.js @@ -27,6 +27,7 @@ import { } from "../../utils/methods"; import "../../styles/booking-room.less"; +import BookableRoomsDropdown from "../inputs/bookable-room-input"; const RoomBookingForm = ({ entity, @@ -51,9 +52,7 @@ const RoomBookingForm = ({ const handleEntityChange = (newEntity) => { if (newEntity.id) { - const currentRoom = currentSummit.locations.find( - (l) => l.id === newEntity.room_id - ); + const currentRoom = newEntity.room_id; const availableDates = getAvailableBookingDates(currentSummit); const bookingDate = getDayFromReservation(newEntity, availableDates); if (bookingDate) getAvailableSlots(currentRoom.id, bookingDate); @@ -70,11 +69,12 @@ const RoomBookingForm = ({ }; const handleRoomChange = (ev) => { - const { value } = ev.target; - const currentRoom = currentSummit.locations.find( - (l) => l.id === parseInt(value) - ); - setCurrentRoom(currentRoom); + const { value, room } = ev.target; + setCurrentRoom(room); + setStateEntity((prevState) => ({ + ...prevState, + room_id: value.id + })); }; const handleBookingDateChange = (ev) => { @@ -144,10 +144,6 @@ const RoomBookingForm = ({ return ""; }; - const rooms_ddl = currentSummit.locations - .filter((v) => v.class_name === "SummitBookableVenueRoom") - .map((l) => ({ label: l.name, value: l.id })); - const available_booking_dates_ddl = getAvailableBookingDates( currentSummit ).map((v) => ({ value: v.epoch, label: v.str })); @@ -172,11 +168,11 @@ const RoomBookingForm = ({
    - {currentRoom.attributes.length > 0 ? currentRoom.attributes - .map((a) => `${a.type.type}: ${a.value}`) + .map((a) => `${a.type?.type}: ${a.value}`) .join(" | ") : ""}
    diff --git a/src/components/inputs/bookable-room-input.js b/src/components/inputs/bookable-room-input.js new file mode 100644 index 000000000..009bee12c --- /dev/null +++ b/src/components/inputs/bookable-room-input.js @@ -0,0 +1,123 @@ +/** + * Copyright 2017 OpenStack Foundation + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * */ + +import React, { useEffect, useState } from "react"; +import AsyncSelect from "react-select/lib/Async"; +import { queryBookableRooms } from "../../actions/location-actions"; + +const BookableRoomsDropdown = ({ + summitId, + placeholder, + error, + value, + onChange, + id, + multi, + ...rest +}) => { + const [theValue, setTheValue] = useState(null); + const [allOptions, setAllOptions] = useState([]); + const [allOptionsWithData, setAllOptionsWithData] = useState([]); + + const isMulti = multi || rest.isMulti; + + useEffect(() => { + if (isMulti && value.length > 0) { + const updatedValue = []; + allOptions.forEach((op) => { + if (value.includes((v) => v === op.value)) { + updatedValue.push(op); + } + }); + setTheValue(updatedValue); + } else if (!isMulti && value) { + allOptions.forEach((op) => { + if (op.value === value) { + setTheValue(op); + } + }); + } + }, [allOptions]); + + const handleChange = (value) => { + let theValue = null; + let roomData = null; + if (value) { + theValue = isMulti + ? value.map((v) => ({ id: v.value, value: v.label })) + : { id: value.value, value: value.label }; + roomData = isMulti + ? allOptionsWithData.filter((opt) => + value.some((v) => v.value === opt.id) + ) + : allOptionsWithData.find((opt) => opt.id === value.value); + } + + const ev = { + target: { + id, + value: theValue, + type: "bookableroominput", + room: roomData + } + }; + + onChange(ev); + }; + + const getRooms = (input, callback) => { + // we need to map into value/label because of a bug in react-select 2 + // https://github.com/JedWatson/react-select/issues/2998 + + const translateOptions = (locations) => { + const newOptions = locations.map((c) => ({ + value: c.id, + label: c.name + })); + + if (!allOptions.length && !input) { + setAllOptions(newOptions); + setAllOptionsWithData(locations); + } + + callback(newOptions); + }; + + queryBookableRooms(summitId, input, translateOptions); + }; + + const has_error = error && error !== ""; + + return ( +
    + ({ + ...baseStyles, + zIndex: 2000 + }) + }} + {...rest} + /> + {has_error &&

    {error}

    } +
    + ); +}; + +export default BookableRoomsDropdown; diff --git a/src/components/inputs/location-grouped-dropdown.js b/src/components/inputs/location-grouped-dropdown.js index 050d45d75..815303852 100644 --- a/src/components/inputs/location-grouped-dropdown.js +++ b/src/components/inputs/location-grouped-dropdown.js @@ -1,95 +1,150 @@ -import React from "react"; -import Select, { createFilter } from "react-select"; +/** + * Copyright 2017 OpenStack Foundation + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * */ -const RoomLabel = ({ room }) => ( - - {room.name} - {room.id} - -); +import React, { useState, useEffect } from "react"; +import AsyncSelect from "react-select/lib/Async"; +import { queryGroupLocations } from "../../actions/location-actions"; -const LocationGroupedDropdown = ({ - value, - locations, - className, +const LocationGroupedAsyncDropdown = ({ + summitId, placeholder, + error, + value, + onChange, + id, + multi, ...rest }) => { - let options = []; - let theValue = null; - - const filterOptions = (candidate, input) => { - if (input) { - return candidate.label.props.room?.name - .toLowerCase() - .includes(input.toLowerCase()); + const [theValue, setTheValue] = useState(null); + const [allOptions, setAllOptions] = useState([]); + + const isMulti = multi || rest.isMulti; + + useEffect(() => { + if (isMulti) { + const updatedValue = allOptions + .flatMap((op) => (op.options ? op.options : op)) + .filter((op) => value.includes(op.value)); + setTheValue(updatedValue); + } else if (!isMulti && value) { + const foundOption = allOptions + .flatMap((op) => (op.options ? op.options : op)) + .find((op) => op.value === value); + if (foundOption) { + setTheValue(foundOption); + } } - return true; + }, [allOptions, value]); + + const handleChange = (value) => { + let newValue = null; + const isMulti = multi || rest.isMulti; + if (value) { + newValue = isMulti ? value.map((v) => v.value) : value.value; + } + + const ev = { + target: { + id, + value: newValue, + type: "groupedlocationinput" + } + }; + + onChange(ev); }; - locations.forEach((loc) => { - const roomsWithoutFloors = - loc.rooms?.filter((rm) => rm.floor_id === 0) || []; - - options.push({ - label: ( - - All {loc.name} locations - - ), - value: loc.id - }); - options = options.concat( - roomsWithoutFloors.map((rm) => ({ - label: , - value: rm.id - })) - ); - - loc.floors?.forEach((fl) => { - const floorRooms = loc.rooms.filter((rm) => rm.floor_id === fl.id); - options.push({ - label: fl.name, - options: floorRooms.map((rm) => ({ - label: , - value: rm.id - })) + const RoomLabel = ({ room }) => ( + + {room.name}{" "} + - {room.id} + + ); + + const getLocations = (input, callback) => { + // we need to map into value/label because of a bug in react-select 2 + // https://github.com/JedWatson/react-select/issues/2998 + + const translateOptions = (locations) => { + let newOptions = []; + + locations.forEach((loc) => { + const roomsWithoutFloors = + loc.rooms?.filter((rm) => rm.floor_id === 0) || []; + + newOptions.push({ + label: ( + + All {loc.name} locations + + ), + value: loc.id + }); + newOptions = newOptions.concat( + roomsWithoutFloors.map((rm) => ({ + label: , + value: rm.id + })) + ); + + loc.floors?.forEach((fl) => { + const floorRooms = loc.rooms.filter((rm) => rm.floor_id === fl.id); + newOptions.push({ + label: fl.name, + options: floorRooms.map((rm) => ({ + label: , + value: rm.id + })) + }); + }); }); - }); - }); - options.forEach((op) => { - if (op.value === value) { - theValue = op; - return; - } - if (op.options) { - const foundOption = op.options.find((opp) => opp.value === value); - if (foundOption) { - theValue = foundOption; - return; + if (!input) { + setAllOptions(newOptions); } - } - }); + + callback(newOptions); + }; + + queryGroupLocations(summitId, input, translateOptions); + }; + + const has_error = error && error !== ""; return ( - this.handleFilterChange(ev.target.value)} + summitId={summitId} + venuesRooms {...rest} />
    diff --git a/src/components/forms/event-form.js b/src/components/forms/event-form.js index 2cf51f5f5..f249c42db 100644 --- a/src/components/forms/event-form.js +++ b/src/components/forms/event-form.js @@ -20,7 +20,6 @@ import { epochToMomentTimeZone } from "openstack-uicore-foundation/lib/utils/met import { TextEditor, Dropdown, - GroupedDropdown, DateTimePicker, TagInput, SpeakerInput, @@ -64,6 +63,7 @@ import { ONE_MINUTE } from "../../utils/constants"; import CopyClipboard from "../buttons/copy-clipboard"; +import LocationGroupedAsyncDropdown from "../inputs/location-grouped-dropdown"; class EventForm extends React.Component { constructor(props) { @@ -855,7 +855,6 @@ class EventForm extends React.Component { levelOpts, typeOpts, trackOpts, - locationOpts, rsvpTemplateOpts, selectionPlansOpts, history, @@ -895,18 +894,6 @@ class EventForm extends React.Component { .filter((track) => track.subtracks.length === 0) .map((t) => ({ label: t.name, value: t.id })); - const venues = locationOpts - .filter((v) => v.class_name === "SummitVenue") - .map((l) => { - let options = []; - if (l.rooms) { - options = l.rooms.map((r) => ({ label: r.name, value: r.id })); - } - return { label: l.name, value: l.id, options }; - }); - - const locations_ddl = [{ label: "TBD", value: 0 }, ...venues]; - const levels_ddl = levelOpts.map((l) => ({ label: l, value: l })); let selection_plans_ddl = []; @@ -1018,7 +1005,7 @@ class EventForm extends React.Component {
      - {entity?.created_by && ( + {entity.created_by && ( - 0) { const updatedValue = []; allOptions.forEach((op) => { - if (value.includes((v) => v === op.value)) { + if (value.includes(op.value)) { updatedValue.push(op); } }); diff --git a/src/components/inputs/rooms-input.js b/src/components/inputs/rooms-input.js index 84c98ebe7..bbe076297 100644 --- a/src/components/inputs/rooms-input.js +++ b/src/components/inputs/rooms-input.js @@ -61,7 +61,7 @@ const RoomsInput = ({ target: { id, value: theValue, - type: "bookableroominput" + type: "roominput" } }; diff --git a/src/components/inputs/venue-input.js b/src/components/inputs/venue-input.js index 0bc6c6c67..2448fc251 100644 --- a/src/components/inputs/venue-input.js +++ b/src/components/inputs/venue-input.js @@ -23,6 +23,7 @@ const VenuesDropdown = ({ onChange, id, multi, + venuesRooms, ...rest }) => { const [theValue, setTheValue] = useState(null); @@ -31,22 +32,24 @@ const VenuesDropdown = ({ const isMulti = multi || rest.isMulti; useEffect(() => { - if (isMulti && value.length > 0) { + if (isMulti && value) { const updatedValue = []; allOptions.forEach((op) => { - if (value.includes((v) => v === op.value)) { + if (value.includes(op.value)) { updatedValue.push(op); } }); setTheValue(updatedValue); } else if (!isMulti && value) { allOptions.forEach((op) => { - if (op.value === value) { + if (op.value === value || op.value === value.id) { setTheValue(op); } }); + } else if (!value) { + setTheValue(isMulti ? [] : null); } - }, [allOptions]); + }, [allOptions, value]); const handleChange = (value) => { let theValue = null; @@ -69,8 +72,6 @@ const VenuesDropdown = ({ }; const getRooms = (input, callback) => { - console.log("get venue locations"); - // we need to map into value/label because of a bug in react-select 2 // https://github.com/JedWatson/react-select/issues/2998 @@ -87,7 +88,7 @@ const VenuesDropdown = ({ callback(newOptions); }; - queryVenues(summitId, input, translateOptions); + queryVenues(summitId, input, translateOptions, venuesRooms); }; const has_error = error && error !== ""; diff --git a/src/components/reports/metrics-report.js b/src/components/reports/metrics-report.js index 10ddb2ac6..adb123b47 100644 --- a/src/components/reports/metrics-report.js +++ b/src/components/reports/metrics-report.js @@ -9,7 +9,7 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. - **/ + * */ import React from "react"; import moment from "moment-timezone"; @@ -21,11 +21,13 @@ import { Panel, Table } from "openstack-uicore-foundation/lib/components"; -const Query = require("graphql-query-builder"); +import ReactDOMServer from "react-dom/server"; +import RoomsInput from "../inputs/rooms-input"; import wrapReport from "./report-wrapper"; import { groupByDate } from "../../utils/methods"; import { flattenData } from "../../actions/report-actions"; -import ReactDOMServer from "react-dom/server"; + +const Query = require("graphql-query-builder"); const RawMetricsTable = ({ data, timezone }) => { const columns = [ @@ -166,12 +168,12 @@ class MetricsReport extends React.Component { const metrics = new Query("uniqueMetrics", overallFilter); metrics.find(metricsFields); const sponsors = new Query(...sponsorsMessage); - sponsors.find(["id", "companyName", { metrics: metrics }]); + sponsors.find(["id", "companyName", { metrics }]); const events = new Query(...eventsMessage, eventQueryFilter); - events.find(["id", "title", { metrics: metrics }]); + events.find(["id", "title", { metrics }]); const rooms = new Query(...roomsMessage, roomQueryFilter); const venueRoom = new Query(...venueRoomMessage); - venueRoom.find([{ metrics: metrics }]); + venueRoom.find([{ metrics }]); const extraQuestions = new Query("orderExtraQuestions"); extraQuestions.find(["id", "name"]); @@ -183,20 +185,20 @@ class MetricsReport extends React.Component { const posters = new Query("events", { type_Type: "Poster" }); posters.find(["id", "title", { metrics: posterMetrics }]); - const findQueries = ["id", "title", { extraQuestions: extraQuestions }]; + const findQueries = ["id", "title", { extraQuestions }]; if (eventType === "EVENT") { - rooms.find(["id", "name", { events: events }]); - findQueries.push({ rooms: rooms }); + rooms.find(["id", "name", { events }]); + findQueries.push({ rooms }); } else if (eventType === "ROOM") { rooms.find(["id", "name", { venueroom: venueRoom }]); - findQueries.push({ rooms: rooms }); + findQueries.push({ rooms }); } else if (eventType === "SPONSOR") { - findQueries.push({ sponsors: sponsors }); + findQueries.push({ sponsors }); } else if (eventType === "POSTER") { - findQueries.push({ posters: posters }); + findQueries.push({ posters }); } else { - findQueries.push({ metrics: metrics }); + findQueries.push({ metrics }); } query.find(findQueries); @@ -232,9 +234,9 @@ class MetricsReport extends React.Component { listFilters.onlyFinished = true; } - let query = new Query("metrics", listFilters); - let results = new Query("results", filters); - let eventmetric = new Query("eventmetric"); + const query = new Query("metrics", listFilters); + const results = new Query("results", filters); + const eventmetric = new Query("eventmetric"); eventmetric.find(["subType"]); results.find([ "type", @@ -245,10 +247,10 @@ class MetricsReport extends React.Component { "sponsorName", "locationName", "ip", - { eventmetric: eventmetric } + { eventmetric } ]); - query.find([{ results: results }, "totalCount"]); + query.find([{ results }, "totalCount"]); return query; }; @@ -287,8 +289,8 @@ class MetricsReport extends React.Component { listFilters.onlyFinished = true; } - let query = new Query("metrics", listFilters); - let results = new Query("results", filters); + const query = new Query("metrics", listFilters); + const results = new Query("results", filters); results.find([ "type", "ingressDate", @@ -302,9 +304,9 @@ class MetricsReport extends React.Component { "ip" ]); - query.find([{ results: results }, "totalCount"]); + query.find([{ results }, "totalCount"]); - return "{ reportData: " + query + " }"; + return `{ reportData: ${query} }`; }; async toggleDrillDownData(target, id, metric) { @@ -422,7 +424,7 @@ class MetricsReport extends React.Component { preProcessData(data, extraData, forExport = false) { const { currentSummit } = this.props; - let { eventType, showAnswers } = this.state; + const { eventType, showAnswers } = this.state; let processedData = []; let columns = []; @@ -438,7 +440,7 @@ class MetricsReport extends React.Component { .utc(d.ingressDate) .tz(currentSummit.time_zone_id) .format("dddd, MMMM Do YYYY, h:mm a (z)"), - origin: origin, + origin, member: d.memberName, subtype: d.eventmetric?.subType, ip: d.ip @@ -466,7 +468,7 @@ class MetricsReport extends React.Component { ]; processedData = Object.entries(processedData).reduce((result, item) => { - const [key, value] = item; + const [value] = item; result = [...result, ...value]; return result; }, []); @@ -512,51 +514,45 @@ class MetricsReport extends React.Component { return { reportData: processedData, tableColumns: columns }; processedData = data.rooms - .map((rm) => { - return { - ...rm, - events: rm.events - .filter((ev) => ev?.metrics?.length) - .map((ev) => { - const metrics = ev.metrics.map((m) => { - const metric = this.parseMetricData(m); - return { - ...metric, - metric: forExport ? ( - metric.metric - ) : ( -
    - - this.toggleDrillDownData( - evt.target, - ev.id, - metric - ) - } - > - {metric.metric} - -
    -
    - ), - ingress: moment - .utc(metric.ingress) - .tz(currentSummit.time_zone_id) - .format("dddd, MMMM Do YYYY, h:mm a (z)"), - outgress: metric.outgress - ? moment - .utc(metric.outgress) - .tz(currentSummit.time_zone_id) - .format("dddd, MMMM Do YYYY, h:mm a (z)") - : "-" - }; - }); - return { ...ev, metrics }; - }) - }; - }) + .map((rm) => ({ + ...rm, + events: rm.events + .filter((ev) => ev?.metrics?.length) + .map((ev) => { + const metrics = ev.metrics.map((m) => { + const metric = this.parseMetricData(m); + return { + ...metric, + metric: forExport ? ( + metric.metric + ) : ( +
    + + this.toggleDrillDownData(evt.target, ev.id, metric) + } + > + {metric.metric} + +
    +
    + ), + ingress: moment + .utc(metric.ingress) + .tz(currentSummit.time_zone_id) + .format("dddd, MMMM Do YYYY, h:mm a (z)"), + outgress: metric.outgress + ? moment + .utc(metric.outgress) + .tz(currentSummit.time_zone_id) + .format("dddd, MMMM Do YYYY, h:mm a (z)") + : "-" + }; + }); + return { ...ev, metrics }; + }) + })) .filter((rm) => rm.events.length); if (forExport) { @@ -746,7 +742,7 @@ class MetricsReport extends React.Component { } handleFilterChange(ev) { - let { id, value, type, checked } = ev.target; + const { id, value, type, checked } = ev.target; const { state } = this; state[id] = type === "checkbox" ? checked : value; if (id === "eventType") { @@ -754,10 +750,13 @@ class MetricsReport extends React.Component { state.eventFilter = null; state.subTypeFilter = null; } + if (id === "roomFilter") { + state.roomFilter = value.id; + } this.setState(state); } - filterReport(ev) { + filterReport() { this.props.onReload(); } @@ -851,11 +850,11 @@ class MetricsReport extends React.Component { tables = data .filter((rm) => rm.events.length) .map((room) => { - const name = room.name; - const id = room.id; + const {name} = room; + const {id} = room; return ( -
    +
    {name}
    {room.events.map((ev) => { @@ -885,8 +884,8 @@ class MetricsReport extends React.Component { }); } else if (eventType === "ROOM") { tables = data.map((room) => { - const name = room.name; - const id = room.id; + const {name} = room; + const {id} = room; const sectionId = `section_${id}`; @@ -941,7 +940,7 @@ class MetricsReport extends React.Component { const report_options = { sortCol: sortKey, - sortDir: sortDir, + sortDir, actions: {} }; @@ -961,11 +960,6 @@ class MetricsReport extends React.Component { { label: "Virtual", value: "VIRTUAL" } ]; - const room_ddl = currentSummit.locations.map((l) => ({ - label: l.name, - value: l.id - })); - return (
    @@ -993,11 +987,12 @@ class MetricsReport extends React.Component { {eventType === "ROOM" && (
    -
    @@ -1010,7 +1005,7 @@ class MetricsReport extends React.Component { summit={currentSummit} value={eventFilter} onChange={this.handleFilterChange} - onlyPublished={true} + onlyPublished isClearable />
    diff --git a/src/components/reports/report-wrapper.js b/src/components/reports/report-wrapper.js index 24feef87a..fba7ceb8d 100644 --- a/src/components/reports/report-wrapper.js +++ b/src/components/reports/report-wrapper.js @@ -217,13 +217,11 @@ const wrapReport = (ReportComponent, specs) => {
    l.class_name === "SummitVenueRoom" - )} onChange={(value) => { this.handleFilterChange("room", value, true); }} isMulti + summitId={currentSummit.id} />
    ); diff --git a/src/pages/events/edit-summit-event-page.js b/src/pages/events/edit-summit-event-page.js index c210d6e7c..5098d3122 100644 --- a/src/pages/events/edit-summit-event-page.js +++ b/src/pages/events/edit-summit-event-page.js @@ -280,7 +280,6 @@ function EditSummitEventPage(props) { levelOpts={levelOptions} trackOpts={currentSummit.tracks} typeOpts={currentSummit.event_types} - locationOpts={currentSummit.locations} selectionPlansOpts={currentSummit.selection_plans} rsvpTemplateOpts={rsvpTemplateOptions} actionTypes={actionTypes} diff --git a/src/pages/events/summit-event-list-page.js b/src/pages/events/summit-event-list-page.js index b4a89d4f0..0301de657 100644 --- a/src/pages/events/summit-event-list-page.js +++ b/src/pages/events/summit-event-list-page.js @@ -66,6 +66,7 @@ import { import { CONTEXT_ACTIVITIES } from "../../utils/filter-criteria-constants"; import EditableTable from "../../components/tables/editable-table/EditableTable"; import { saveEventMaterial } from "../../actions/event-material-actions"; +import RoomsInput from "../../components/inputs/rooms-input"; const fieldNames = (allSelectionPlans, allTracks, event_types) => [ { @@ -1034,10 +1035,6 @@ class SummitEventListPage extends React.Component { ?.sort((a, b) => a.order - b.order) .map((sp) => ({ label: sp.name, value: sp.id })); - const location_ddl = currentSummit.locations - ?.sort((a, b) => a.order - b.order) - .map((l) => ({ label: l.name, value: l.id })); - const selection_status_ddl = [ { label: "Pending", value: "pending" }, { label: "Accepted", value: "accepted" }, @@ -1409,12 +1406,12 @@ class SummitEventListPage extends React.Component { )} {enabledFilters.includes("location_id_filter") && (
    - diff --git a/src/pages/room_occupancy/room-occupancy-page.js b/src/pages/room_occupancy/room-occupancy-page.js index c08b80066..6785e8573 100644 --- a/src/pages/room_occupancy/room-occupancy-page.js +++ b/src/pages/room_occupancy/room-occupancy-page.js @@ -16,8 +16,7 @@ import { connect } from "react-redux"; import T from "i18n-react/dist/i18n-react"; import { Pagination } from "react-bootstrap"; import { - FreeTextSearch, - Dropdown + FreeTextSearch } from "openstack-uicore-foundation/lib/components"; import { getSummitById } from "../../actions/summit-actions"; import { @@ -31,6 +30,7 @@ import OccupancyTable from "../../components/tables/room-occupancy-table/Occupan import FragmentParser from "../../utils/fragmen-parser"; import "../../styles/room-occupancy-page.less"; +import VenuesDropdown from "../../components/inputs/venue-input"; class RoomOccupancyPage extends React.Component { constructor(props) { @@ -111,7 +111,7 @@ class RoomOccupancyPage extends React.Component { handleRoomFilter(ev) { const { term, order, orderDir, page, perPage, currentEvents } = this.props; - const roomId = ev.target.value; + const roomId = ev.target.value.id; this.fragmentParser.setParam("room", roomId); window.location.hash = this.fragmentParser.serialize(); @@ -238,10 +238,6 @@ class RoomOccupancyPage extends React.Component { if (!currentSummit.id) return
    ; - const room_ddl = currentSummit.locations - .filter((v) => v.class_name === "SummitVenueRoom") - .map((r) => ({ label: r.name, value: r.id })); - return (
    @@ -257,15 +253,18 @@ class RoomOccupancyPage extends React.Component { />
    -
    From f9533938fdc83f5fd62f14de01d98dbf5f6b2473 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1s=20Castillo?= Date: Wed, 2 Apr 2025 11:08:17 -0300 Subject: [PATCH 5/6] add required fields on action MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Tomás Castillo --- src/actions/summit-actions.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/actions/summit-actions.js b/src/actions/summit-actions.js index 08da891fd..ea7b82e67 100644 --- a/src/actions/summit-actions.js +++ b/src/actions/summit-actions.js @@ -63,7 +63,7 @@ export const getSummitById = (summitId) => async (dispatch) => { "track_groups," + "locations," + "locations.rooms," + - "locations.floor," + + "locations.rooms.floor," + "meeting_booking_room_allowed_attributes," + "meeting_booking_room_allowed_attributes.values," + "lead_report_settings," + @@ -87,7 +87,7 @@ export const getSummitById = (summitId) => async (dispatch) => { "end_date," + "event_types,event_types.id,event_types.name,event_types.order,event_types.allows_attachment,event_types.allows_level,event_types.allows_location,event_types.allows_location_timeframe_collision,event_types.allows_publishing_dates," + "link," + - "locations,locations.id,locations.name,locations.order,locations.class_name,locations.rooms,locations.floors," + + "locations,locations.id,locations.name,locations.order,locations.class_name,locations.rooms.id,locations.rooms.name,locations.rooms.floor.id,locations.rooms.floor.name," + "logo," + "secondary_logo," + "presentation_voters_count," + @@ -174,7 +174,7 @@ export const getSummitById = (summitId) => async (dispatch) => { "event_types.none," + "tracks.subtracks,tracks.track_groups," + "tracks_groups.none," + - "locations,locations.rooms,locations.floor,locations.none," + + "locations,locations.rooms,locations.rooms.none,locations.floor,locations.none," + "meeting_booking_room_allowed_attributes.values," + "selection_plans.track_groups,selection_plans.allowed_presentation_questions," + "ticket_types.none," + From 2141af2b1352d5bba874ac6e5434b2c50e7726a3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1s=20Castillo?= Date: Wed, 2 Apr 2025 11:18:16 -0300 Subject: [PATCH 6/6] clean comments and unused code MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Tomás Castillo --- src/pages/signage/index.js | 25 ------------------------- 1 file changed, 25 deletions(-) diff --git a/src/pages/signage/index.js b/src/pages/signage/index.js index 6e507a48b..64820c7a2 100644 --- a/src/pages/signage/index.js +++ b/src/pages/signage/index.js @@ -204,31 +204,6 @@ const SignagePage = ({ onChange={(op) => onChangeLocation(op.target.value)} summitId={summit.id} /> - {/* onChangeLocation(op.target.value)} - summitId={summit.id} - /> - onChangeLocation(op.target.value.id)} - summitId={summit.id} /> - onChangeLocation(op.target.value.id)} - summitId={summit.id} /> - onChangeLocation(op.target.value.id)} - summitId={summit.id} /> */}