Skip to content
This repository was archived by the owner on Mar 13, 2025. It is now read-only.

Commit 6de41de

Browse files
authored
Merge pull request #43 from MadOPcode/dev
Fixes for popups and pagination
2 parents d8fec86 + c2100b0 commit 6de41de

File tree

9 files changed

+67
-23
lines changed

9 files changed

+67
-23
lines changed

src/components/Popup/index.jsx

+18-1
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,27 @@ import PT from "prop-types";
44
import cn from "classnames";
55
import compStyles from "./styles.module.scss";
66

7-
const Popup = ({ children, className, referenceElement }) => {
7+
/**
8+
* Displays a popup near the reference element.
9+
*
10+
* @param {Object} props component properties
11+
* @param {any} [props.children] child nodes
12+
* @param {string} [props.className] class name to be added to root element
13+
* @param {Object} props.referenceElement reference element
14+
* @param {'absolute'|'fixed'} [props.strategy] positioning strategy
15+
* @returns {JSX.Element}
16+
*/
17+
const Popup = ({
18+
children,
19+
className,
20+
referenceElement,
21+
strategy = "absolute",
22+
}) => {
823
const [popperElement, setPopperElement] = useState(null);
924
const [arrowElement, setArrowElement] = useState(null);
1025
const { styles, attributes } = usePopper(referenceElement, popperElement, {
1126
placement: "bottom",
27+
strategy,
1228
modifiers: [
1329
{ name: "arrow", options: { element: arrowElement, padding: 10 } },
1430
{ name: "offset", options: { offset: [0, 5] } },
@@ -33,6 +49,7 @@ Popup.propTypes = {
3349
children: PT.node,
3450
className: PT.string,
3551
referenceElement: PT.object.isRequired,
52+
strategy: PT.oneOf(["absolute", "fixed"]),
3653
};
3754

3855
export default Popup;

src/routes/WorkPeriods/components/PaymentError/index.jsx

+9-2
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,15 @@ import styles from "./styles.module.scss";
1414
* @param {string} [props.className] class name to be added to root element
1515
* @param {Object} [props.errorDetails] error details object
1616
* @param {boolean} [props.isImportant] whether the error deemed important
17+
* @param {'absolute'|'fixed'} [props.popupStrategy] popup positioning strategy
1718
* @returns {JSX.Element}
1819
*/
19-
const PaymentError = ({ className, errorDetails, isImportant = true }) => {
20+
const PaymentError = ({
21+
className,
22+
errorDetails,
23+
isImportant = true,
24+
popupStrategy = "absolute",
25+
}) => {
2026
const [isShowPopup, setIsShowPopup] = useState(false);
2127
const [refElem, setRefElem] = useState(null);
2228
const containerRef = useRef(null);
@@ -42,7 +48,7 @@ const PaymentError = ({ className, errorDetails, isImportant = true }) => {
4248
tabIndex={0}
4349
/>
4450
{isShowPopup && errorDetails && (
45-
<Popup referenceElement={refElem}>
51+
<Popup referenceElement={refElem} strategy={popupStrategy}>
4652
<PaymentErrorDetails details={errorDetails} />
4753
</Popup>
4854
)}
@@ -54,6 +60,7 @@ PaymentError.propTypes = {
5460
className: PT.string,
5561
errorDetails: PT.object,
5662
isImportant: PT.bool,
63+
popupStrategy: PT.oneOf(["absolute", "fixed"]),
5764
};
5865

5966
export default PaymentError;

src/routes/WorkPeriods/components/PaymentTotal/index.jsx

+10-2
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,16 @@ import styles from "./styles.module.scss";
1717
* @param {Array} [props.payments] an array with payments information
1818
* @param {number} props.paymentTotal total paid sum
1919
* @param {number} props.daysPaid number of paid days
20+
* @param {'absolute'|'fixed'} [props.popupStrategy] popup positioning strategy
2021
* @returns {JSX.Element}
2122
*/
22-
const PaymentTotal = ({ className, payments, paymentTotal, daysPaid }) => {
23+
const PaymentTotal = ({
24+
className,
25+
payments,
26+
paymentTotal,
27+
daysPaid,
28+
popupStrategy = "absolute",
29+
}) => {
2330
const [isShowPopup, setIsShowPopup] = useState(false);
2431
const [refElem, setRefElem] = useState(null);
2532
const containerRef = useRef(null);
@@ -56,7 +63,7 @@ const PaymentTotal = ({ className, payments, paymentTotal, daysPaid }) => {
5663
<span className={styles.daysPaid}>({daysPaid})</span>
5764
</span>
5865
{hasPayments && isShowPopup && (
59-
<Popup referenceElement={refElem}>
66+
<Popup referenceElement={refElem} strategy={popupStrategy}>
6067
<PaymentsList payments={payments} />
6168
</Popup>
6269
)}
@@ -69,6 +76,7 @@ PaymentTotal.propTypes = {
6976
payments: PT.array,
7077
paymentTotal: PT.number.isRequired,
7178
daysPaid: PT.number.isRequired,
79+
popupStrategy: PT.oneOf(["absolute", "fixed"]),
7280
};
7381

7482
export default PaymentTotal;

src/routes/WorkPeriods/components/PeriodItem/index.jsx

+2
Original file line numberDiff line numberDiff line change
@@ -126,13 +126,15 @@ const PeriodItem = ({
126126
className={styles.paymentError}
127127
errorDetails={data.paymentErrorLast}
128128
isImportant={data.paymentStatus !== PAYMENT_STATUS.COMPLETED}
129+
popupStrategy="fixed"
129130
/>
130131
)}
131132
<PaymentTotal
132133
className={styles.paymentTotalContainer}
133134
daysPaid={data.daysPaid}
134135
payments={data.payments}
135136
paymentTotal={data.paymentTotal}
137+
popupStrategy="fixed"
136138
/>
137139
</td>
138140
<td>

src/store/actions/workPeriods.js

+7-6
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import * as ACTION_TYPE from "store/actionTypes/workPeriods";
44
let nextErrorId = 1;
55

66
/**
7-
* Creates an action denoting the start of loading specific challenge page.
7+
* Creates an action denoting the start of loading specific working period page.
88
*
99
* @param {Object} cancelSource object that can be used to cancel network request
1010
* @returns {Object}
@@ -17,14 +17,15 @@ export const loadWorkPeriodsPagePending = (cancelSource) => ({
1717
/**
1818
* Creates an action denoting the saving of fetched working periods' page.
1919
*
20-
* @param {Array} periods array of challenge objects
21-
* @param {number} totalCount total number of periods for current filters' state
22-
* @param {number} pageCount total number of pages
20+
* @param {Object} payload action payload
21+
* @param {Array} payload.periods array of working period objects
22+
* @param {number} payload.totalCount total number of periods for current filters' state
23+
* @param {number} payload.pageCount total number of pages
2324
* @returns {Object}
2425
*/
25-
export const loadWorkPeriodsPageSuccess = (periods, totalCount, pageCount) => ({
26+
export const loadWorkPeriodsPageSuccess = (payload) => ({
2627
type: ACTION_TYPE.WP_LOAD_PAGE_SUCCESS,
27-
payload: { periods, totalCount, pageCount },
28+
payload,
2829
});
2930

3031
/**

src/store/reducers/workPeriods.js

+4
Original file line numberDiff line numberDiff line change
@@ -610,6 +610,10 @@ const actionHandlers = {
610610
...filters,
611611
onlyFailedPayments: on,
612612
},
613+
pagination: {
614+
...state.pagination,
615+
pageNumber: 1,
616+
},
613617
};
614618
},
615619
[ACTION_TYPE.WP_TOGGLE_PERIOD]: (state, periodId) => {

src/store/thunks/workPeriods.js

+12-7
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ export const loadWorkPeriodsPage = async (dispatch, getState) => {
6464

6565
// For parameter description see:
6666
// https://topcoder-platform.github.io/taas-apis/#/ResourceBookings/get_resourceBookings
67-
const params = {
67+
const [promise, cancelSource] = services.fetchResourceBookings({
6868
fields: API_FIELDS_QUERY,
6969
page: pagination.pageNumber,
7070
perPage: pagination.pageSize,
@@ -75,11 +75,10 @@ export const loadWorkPeriodsPage = async (dispatch, getState) => {
7575
["workPeriods.userHandle"]: userHandle,
7676
["workPeriods.startDate"]: startDate.format(DATE_FORMAT_API),
7777
["workPeriods.paymentStatus"]: paymentStatuses,
78-
};
79-
if (onlyFailedPayments) {
80-
params["workPeriods.payments.status"] = API_CHALLENGE_PAYMENT_STATUS.FAILED;
81-
}
82-
const [promise, cancelSource] = services.fetchResourceBookings(params);
78+
["workPeriods.payments.status"]: onlyFailedPayments
79+
? API_CHALLENGE_PAYMENT_STATUS.FAILED
80+
: null,
81+
});
8382
dispatch(actions.loadWorkPeriodsPagePending(cancelSource));
8483
let totalCount, periods, pageCount;
8584
try {
@@ -95,7 +94,13 @@ export const loadWorkPeriodsPage = async (dispatch, getState) => {
9594
}
9695
return;
9796
}
98-
dispatch(actions.loadWorkPeriodsPageSuccess(periods, totalCount, pageCount));
97+
dispatch(
98+
actions.loadWorkPeriodsPageSuccess({
99+
periods,
100+
totalCount,
101+
pageCount,
102+
})
103+
);
99104
};
100105

101106
/**

src/styles/mixins/_screenSizes.scss

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
@import 'variables/screenSizes';
1+
@import "variables/screenSizes";
22

33
// There's no need for phone() mixin for phone and larger screens to exist
44
// because styles for these screens are simply added without media queries.

src/styles/variables/_screenSizes.scss

+4-4
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,9 @@ $screen-codes: phone tablet desktop desktop-lg;
22

33
// This map defines minimum screen widths for different devices.
44
$screen-sizes: (
5-
'phone': 320px,
6-
'tablet': 768px,
7-
'desktop': 1280px,
5+
"phone": 320px,
6+
"tablet": 768px,
7+
"desktop": 1280px,
88
);
99

1010
// Media queries' mixins will use minimum screen widths from this map.
@@ -20,7 +20,7 @@ $screen-min-px: ();
2020
$screen-min-px: map-merge(
2121
$screen-min-px,
2222
(
23-
'desktop-lg': 1920px,
23+
"desktop-lg": 1920px,
2424
)
2525
);
2626

0 commit comments

Comments
 (0)