From 7cfbc123e4e2d91a8d7f84e0d7a0318e94e582c3 Mon Sep 17 00:00:00 2001 From: Oleg Petrov Date: Mon, 21 Jun 2021 12:00:26 +0300 Subject: [PATCH 1/2] Fixes for popups and pagination. Fixed: popups caused unwanted scrollbar. Fixed: switching failed payments' toggle didn't reset page number. --- src/components/Popup/index.jsx | 1 + src/store/actions/workPeriods.js | 13 +++++++------ src/store/reducers/workPeriods.js | 4 ++++ src/store/thunks/workPeriods.js | 19 ++++++++++++------- src/styles/mixins/_screenSizes.scss | 2 +- src/styles/variables/_screenSizes.scss | 8 ++++---- 6 files changed, 29 insertions(+), 18 deletions(-) diff --git a/src/components/Popup/index.jsx b/src/components/Popup/index.jsx index 3186f4c..8a1525f 100644 --- a/src/components/Popup/index.jsx +++ b/src/components/Popup/index.jsx @@ -9,6 +9,7 @@ const Popup = ({ children, className, referenceElement }) => { const [arrowElement, setArrowElement] = useState(null); const { styles, attributes } = usePopper(referenceElement, popperElement, { placement: "bottom", + strategy: "fixed", modifiers: [ { name: "arrow", options: { element: arrowElement, padding: 10 } }, { name: "offset", options: { offset: [0, 5] } }, diff --git a/src/store/actions/workPeriods.js b/src/store/actions/workPeriods.js index bfb2e1c..e1e72a4 100644 --- a/src/store/actions/workPeriods.js +++ b/src/store/actions/workPeriods.js @@ -4,7 +4,7 @@ import * as ACTION_TYPE from "store/actionTypes/workPeriods"; let nextErrorId = 1; /** - * Creates an action denoting the start of loading specific challenge page. + * Creates an action denoting the start of loading specific working period page. * * @param {Object} cancelSource object that can be used to cancel network request * @returns {Object} @@ -17,14 +17,15 @@ export const loadWorkPeriodsPagePending = (cancelSource) => ({ /** * Creates an action denoting the saving of fetched working periods' page. * - * @param {Array} periods array of challenge objects - * @param {number} totalCount total number of periods for current filters' state - * @param {number} pageCount total number of pages + * @param {Object} payload action payload + * @param {Array} payload.periods array of working period objects + * @param {number} payload.totalCount total number of periods for current filters' state + * @param {number} payload.pageCount total number of pages * @returns {Object} */ -export const loadWorkPeriodsPageSuccess = (periods, totalCount, pageCount) => ({ +export const loadWorkPeriodsPageSuccess = (payload) => ({ type: ACTION_TYPE.WP_LOAD_PAGE_SUCCESS, - payload: { periods, totalCount, pageCount }, + payload, }); /** diff --git a/src/store/reducers/workPeriods.js b/src/store/reducers/workPeriods.js index b49849c..e34ddeb 100644 --- a/src/store/reducers/workPeriods.js +++ b/src/store/reducers/workPeriods.js @@ -610,6 +610,10 @@ const actionHandlers = { ...filters, onlyFailedPayments: on, }, + pagination: { + ...state.pagination, + pageNumber: 1, + }, }; }, [ACTION_TYPE.WP_TOGGLE_PERIOD]: (state, periodId) => { diff --git a/src/store/thunks/workPeriods.js b/src/store/thunks/workPeriods.js index 01d0c1e..a406918 100644 --- a/src/store/thunks/workPeriods.js +++ b/src/store/thunks/workPeriods.js @@ -64,7 +64,7 @@ export const loadWorkPeriodsPage = async (dispatch, getState) => { // For parameter description see: // https://topcoder-platform.github.io/taas-apis/#/ResourceBookings/get_resourceBookings - const params = { + const [promise, cancelSource] = services.fetchResourceBookings({ fields: API_FIELDS_QUERY, page: pagination.pageNumber, perPage: pagination.pageSize, @@ -75,11 +75,10 @@ export const loadWorkPeriodsPage = async (dispatch, getState) => { ["workPeriods.userHandle"]: userHandle, ["workPeriods.startDate"]: startDate.format(DATE_FORMAT_API), ["workPeriods.paymentStatus"]: paymentStatuses, - }; - if (onlyFailedPayments) { - params["workPeriods.payments.status"] = API_CHALLENGE_PAYMENT_STATUS.FAILED; - } - const [promise, cancelSource] = services.fetchResourceBookings(params); + ["workPeriods.payments.status"]: onlyFailedPayments + ? API_CHALLENGE_PAYMENT_STATUS.FAILED + : null, + }); dispatch(actions.loadWorkPeriodsPagePending(cancelSource)); let totalCount, periods, pageCount; try { @@ -95,7 +94,13 @@ export const loadWorkPeriodsPage = async (dispatch, getState) => { } return; } - dispatch(actions.loadWorkPeriodsPageSuccess(periods, totalCount, pageCount)); + dispatch( + actions.loadWorkPeriodsPageSuccess({ + periods, + totalCount, + pageCount, + }) + ); }; /** diff --git a/src/styles/mixins/_screenSizes.scss b/src/styles/mixins/_screenSizes.scss index 52f0263..2adaeda 100644 --- a/src/styles/mixins/_screenSizes.scss +++ b/src/styles/mixins/_screenSizes.scss @@ -1,4 +1,4 @@ -@import 'variables/screenSizes'; +@import "variables/screenSizes"; // There's no need for phone() mixin for phone and larger screens to exist // because styles for these screens are simply added without media queries. diff --git a/src/styles/variables/_screenSizes.scss b/src/styles/variables/_screenSizes.scss index b1b0794..57f8881 100644 --- a/src/styles/variables/_screenSizes.scss +++ b/src/styles/variables/_screenSizes.scss @@ -2,9 +2,9 @@ $screen-codes: phone tablet desktop desktop-lg; // This map defines minimum screen widths for different devices. $screen-sizes: ( - 'phone': 320px, - 'tablet': 768px, - 'desktop': 1280px, + "phone": 320px, + "tablet": 768px, + "desktop": 1280px, ); // Media queries' mixins will use minimum screen widths from this map. @@ -20,7 +20,7 @@ $screen-min-px: (); $screen-min-px: map-merge( $screen-min-px, ( - 'desktop-lg': 1920px, + "desktop-lg": 1920px, ) ); From c2100b0bf0d73f3a0674902e9ebb34f1fd8c8457 Mon Sep 17 00:00:00 2001 From: Oleg Petrov Date: Mon, 21 Jun 2021 12:31:34 +0300 Subject: [PATCH 2/2] Fixed: popups inside period details were overlaying container. --- src/components/Popup/index.jsx | 20 +++++++++++++++++-- .../components/PaymentError/index.jsx | 11 ++++++++-- .../components/PaymentTotal/index.jsx | 12 +++++++++-- .../components/PeriodItem/index.jsx | 2 ++ 4 files changed, 39 insertions(+), 6 deletions(-) diff --git a/src/components/Popup/index.jsx b/src/components/Popup/index.jsx index 8a1525f..dd22d5b 100644 --- a/src/components/Popup/index.jsx +++ b/src/components/Popup/index.jsx @@ -4,12 +4,27 @@ import PT from "prop-types"; import cn from "classnames"; import compStyles from "./styles.module.scss"; -const Popup = ({ children, className, referenceElement }) => { +/** + * Displays a popup near the reference element. + * + * @param {Object} props component properties + * @param {any} [props.children] child nodes + * @param {string} [props.className] class name to be added to root element + * @param {Object} props.referenceElement reference element + * @param {'absolute'|'fixed'} [props.strategy] positioning strategy + * @returns {JSX.Element} + */ +const Popup = ({ + children, + className, + referenceElement, + strategy = "absolute", +}) => { const [popperElement, setPopperElement] = useState(null); const [arrowElement, setArrowElement] = useState(null); const { styles, attributes } = usePopper(referenceElement, popperElement, { placement: "bottom", - strategy: "fixed", + strategy, modifiers: [ { name: "arrow", options: { element: arrowElement, padding: 10 } }, { name: "offset", options: { offset: [0, 5] } }, @@ -34,6 +49,7 @@ Popup.propTypes = { children: PT.node, className: PT.string, referenceElement: PT.object.isRequired, + strategy: PT.oneOf(["absolute", "fixed"]), }; export default Popup; diff --git a/src/routes/WorkPeriods/components/PaymentError/index.jsx b/src/routes/WorkPeriods/components/PaymentError/index.jsx index f437efe..81557e8 100644 --- a/src/routes/WorkPeriods/components/PaymentError/index.jsx +++ b/src/routes/WorkPeriods/components/PaymentError/index.jsx @@ -14,9 +14,15 @@ import styles from "./styles.module.scss"; * @param {string} [props.className] class name to be added to root element * @param {Object} [props.errorDetails] error details object * @param {boolean} [props.isImportant] whether the error deemed important + * @param {'absolute'|'fixed'} [props.popupStrategy] popup positioning strategy * @returns {JSX.Element} */ -const PaymentError = ({ className, errorDetails, isImportant = true }) => { +const PaymentError = ({ + className, + errorDetails, + isImportant = true, + popupStrategy = "absolute", +}) => { const [isShowPopup, setIsShowPopup] = useState(false); const [refElem, setRefElem] = useState(null); const containerRef = useRef(null); @@ -42,7 +48,7 @@ const PaymentError = ({ className, errorDetails, isImportant = true }) => { tabIndex={0} /> {isShowPopup && errorDetails && ( - + )} @@ -54,6 +60,7 @@ PaymentError.propTypes = { className: PT.string, errorDetails: PT.object, isImportant: PT.bool, + popupStrategy: PT.oneOf(["absolute", "fixed"]), }; export default PaymentError; diff --git a/src/routes/WorkPeriods/components/PaymentTotal/index.jsx b/src/routes/WorkPeriods/components/PaymentTotal/index.jsx index 4c7952d..8b2d1cb 100644 --- a/src/routes/WorkPeriods/components/PaymentTotal/index.jsx +++ b/src/routes/WorkPeriods/components/PaymentTotal/index.jsx @@ -17,9 +17,16 @@ import styles from "./styles.module.scss"; * @param {Array} [props.payments] an array with payments information * @param {number} props.paymentTotal total paid sum * @param {number} props.daysPaid number of paid days + * @param {'absolute'|'fixed'} [props.popupStrategy] popup positioning strategy * @returns {JSX.Element} */ -const PaymentTotal = ({ className, payments, paymentTotal, daysPaid }) => { +const PaymentTotal = ({ + className, + payments, + paymentTotal, + daysPaid, + popupStrategy = "absolute", +}) => { const [isShowPopup, setIsShowPopup] = useState(false); const [refElem, setRefElem] = useState(null); const containerRef = useRef(null); @@ -56,7 +63,7 @@ const PaymentTotal = ({ className, payments, paymentTotal, daysPaid }) => { ({daysPaid}) {hasPayments && isShowPopup && ( - + )} @@ -69,6 +76,7 @@ PaymentTotal.propTypes = { payments: PT.array, paymentTotal: PT.number.isRequired, daysPaid: PT.number.isRequired, + popupStrategy: PT.oneOf(["absolute", "fixed"]), }; export default PaymentTotal; diff --git a/src/routes/WorkPeriods/components/PeriodItem/index.jsx b/src/routes/WorkPeriods/components/PeriodItem/index.jsx index 35a0f9e..7e68b21 100644 --- a/src/routes/WorkPeriods/components/PeriodItem/index.jsx +++ b/src/routes/WorkPeriods/components/PeriodItem/index.jsx @@ -126,6 +126,7 @@ const PeriodItem = ({ className={styles.paymentError} errorDetails={data.paymentErrorLast} isImportant={data.paymentStatus !== PAYMENT_STATUS.COMPLETED} + popupStrategy="fixed" /> )}