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

Commit 9726e18

Browse files
authored
Merge pull request #32 from topcoder-platform/feature/work-periods-part-2
Feature/work periods part 2
2 parents 2930211 + c228666 commit 9726e18

File tree

23 files changed

+326
-144
lines changed

23 files changed

+326
-144
lines changed

src/constants/workPeriods.js

+3
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,9 @@ export const REQUIRED_FIELDS = [
3434
"workPeriods.startDate",
3535
"workPeriods.endDate",
3636
"workPeriods.paymentStatus",
37+
"workPeriods.paymentTotal",
3738
"workPeriods.daysWorked",
39+
"workPeriods.daysPaid",
3840
];
3941

4042
// Valid parameter names for requests.
@@ -58,6 +60,7 @@ export const SORT_BY_MAP = {
5860
[SORT_BY.END_DATE]: API_SORT_BY.END_DATE,
5961
[SORT_BY.WEEKLY_RATE]: API_SORT_BY.WEEKLY_RATE,
6062
[SORT_BY.PAYMENT_STATUS]: API_SORT_BY.PAYMENT_STATUS,
63+
[SORT_BY.PAYMENT_TOTAL]: API_SORT_BY.PAYMENT_TOTAL,
6164
[SORT_BY.WORKING_DAYS]: API_SORT_BY.WORKING_DAYS,
6265
};
6366

src/constants/workPeriods/apiSortBy.js

+1
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,5 @@ export const START_DATE = "startDate";
33
export const END_DATE = "endDate";
44
export const WEEKLY_RATE = "memberRate";
55
export const PAYMENT_STATUS = "workPeriods.paymentStatus";
6+
export const PAYMENT_TOTAL = "workPeriods.paymentTotal";
67
export const WORKING_DAYS = "workPeriods.daysWorked";

src/constants/workPeriods/sortBy.js

+1
Original file line numberDiff line numberDiff line change
@@ -5,4 +5,5 @@ export const END_DATE = "END_DATE";
55
export const ALERT = "ALERT";
66
export const WEEKLY_RATE = "WEEKLY_RATE";
77
export const PAYMENT_STATUS = "STATUS";
8+
export const PAYMENT_TOTAL = "TOTAL_PAYMENT";
89
export const WORKING_DAYS = "WORKING_DAYS";

src/routes/WorkPeriods/components/PaymentStatus/styles.module.scss

+2
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
@import "styles/mixins";
2+
@import "styles/variables";
23

34
.container {
45
display: inline-block;
@@ -40,4 +41,5 @@
4041
line-height: 20px;
4142
letter-spacing: normal;
4243
background: transparent;
44+
color: $text-color;
4345
}

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

+1-2
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,7 @@ const PeriodDetails = ({ className, details, isDisabled, isFailed }) => {
124124
</Button>
125125
</div>
126126
</td>
127-
<td colSpan={5} className={styles.periodHistory}>
127+
<td colSpan={6} className={styles.periodHistory}>
128128
<div className={styles.periodsContainer}>
129129
<div className={styles.periodsHeader}>
130130
<span className={styles.periodsHeaderTitle}>History</span>
@@ -146,7 +146,6 @@ const PeriodDetails = ({ className, details, isDisabled, isFailed }) => {
146146
</div>
147147
<PeriodsHistory
148148
isDisabled={isDisabled}
149-
periodId={periodId}
150149
periods={periodsVisible}
151150
/>
152151
</div>

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

+30-14
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,11 @@ import {
1717
updateWorkPeriodWorkingDays,
1818
} from "store/thunks/workPeriods";
1919
import { useUpdateEffect } from "utils/hooks";
20-
import { formatUserHandleLink, formatWeeklyRate } from "utils/formatters";
20+
import {
21+
currencyFormatter,
22+
formatUserHandleLink,
23+
formatWeeklyRate,
24+
} from "utils/formatters";
2125
import { stopPropagation } from "utils/misc";
2226
import styles from "./styles.module.scss";
2327

@@ -29,6 +33,7 @@ import styles from "./styles.module.scss";
2933
* @param {boolean} [props.isFailed] whether the item should be highlighted as failed
3034
* @param {boolean} props.isSelected whether the item is selected
3135
* @param {Object} props.item object describing a working period
36+
* @param {Object} props.data changeable working period data such as working days
3237
* @param {Object} [props.details] object with working period details
3338
* @returns {JSX.Element}
3439
*/
@@ -37,6 +42,7 @@ const PeriodItem = ({
3742
isFailed = false,
3843
isSelected,
3944
item,
45+
data,
4046
details,
4147
}) => {
4248
const dispatch = useDispatch();
@@ -53,16 +59,16 @@ const PeriodItem = ({
5359
}, [dispatch, item]);
5460

5561
const onWorkingDaysChange = useCallback(
56-
(workingDays) => {
57-
dispatch(setWorkPeriodWorkingDays({ periodId: item.id, workingDays }));
62+
(daysWorked) => {
63+
dispatch(setWorkPeriodWorkingDays(item.id, daysWorked));
5864
},
5965
[dispatch, item.id]
6066
);
6167

6268
const updateWorkingDays = useCallback(
6369
debounce(
64-
(workingDays) => {
65-
dispatch(updateWorkPeriodWorkingDays(item.id, workingDays));
70+
(daysWorked) => {
71+
dispatch(updateWorkPeriodWorkingDays(item.id, daysWorked));
6672
},
6773
300,
6874
{ leading: false }
@@ -72,8 +78,8 @@ const PeriodItem = ({
7278

7379
// Update working days on server if working days change.
7480
useUpdateEffect(() => {
75-
updateWorkingDays(item.workingDays);
76-
}, [item.workingDays]);
81+
updateWorkingDays(data.daysWorked);
82+
}, [data.daysWorked]);
7783

7884
return (
7985
<>
@@ -115,18 +121,24 @@ const PeriodItem = ({
115121
<td className={styles.weeklyRate}>
116122
<span>{formatWeeklyRate(item.weeklyRate)}</span>
117123
</td>
124+
<td className={styles.paymentTotal}>
125+
<span className={styles.paymentTotalSum}>
126+
{currencyFormatter.format(data.paymentTotal)}
127+
</span>
128+
<span className={styles.daysPaid}> ({data.daysPaid})</span>
129+
</td>
118130
<td>
119-
<PaymentStatus status={item.paymentStatus} />
131+
<PaymentStatus status={data.paymentStatus} />
120132
</td>
121-
<td className={styles.workingDays}>
133+
<td className={styles.daysWorked}>
122134
<IntegerField
123-
className={styles.workingDaysControl}
135+
className={styles.daysWorkedControl}
124136
isDisabled={isDisabled}
125137
name={`wp_wrk_days_${item.id}`}
126138
onChange={onWorkingDaysChange}
127139
maxValue={5}
128-
minValue={0}
129-
value={item.workingDays}
140+
minValue={data.daysPaid}
141+
value={data.daysWorked}
130142
/>
131143
</td>
132144
</tr>
@@ -155,9 +167,13 @@ PeriodItem.propTypes = {
155167
startDate: PT.string.isRequired,
156168
endDate: PT.string.isRequired,
157169
weeklyRate: PT.number,
170+
}).isRequired,
171+
data: PT.shape({
172+
daysWorked: PT.number.isRequired,
173+
daysPaid: PT.number.isRequired,
158174
paymentStatus: PT.string.isRequired,
159-
workingDays: PT.number.isRequired,
160-
}),
175+
paymentTotal: PT.number.isRequired,
176+
}).isRequired,
161177
details: PT.shape({
162178
periodId: PT.string.isRequired,
163179
rbId: PT.string.isRequired,

src/routes/WorkPeriods/components/PeriodItem/styles.module.scss

+17-3
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525
padding-left: 14px;
2626
}
2727

28-
&.workingDays {
28+
&.daysWorked {
2929
border-right: 1px solid #d6d6d6;
3030
padding-top: 4px;
3131
padding-right: 9px;
@@ -77,10 +77,24 @@ td.weeklyRate {
7777
}
7878
}
7979

80-
td.workingDays {
80+
td.paymentTotal {
81+
white-space: nowrap;
82+
}
83+
84+
.paymentTotalSum {
85+
display: inline-block;
86+
width: 70px;
87+
text-align: right;
88+
}
89+
90+
.daysPaid {
91+
color: #aaa;
92+
}
93+
94+
td.daysWorked {
8195
padding: 5px 10px;
8296
}
8397

84-
.workingDaysControl {
98+
.daysWorkedControl {
8599
width: 100px;
86100
}

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

+4-1
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import PeriodItem from "../PeriodItem";
77
import PeriodListHead from "../PeriodListHead";
88
import {
99
getWorkPeriods,
10+
getWorkPeriodsData,
1011
getWorkPeriodsDetails,
1112
getWorkPeriodsFailed,
1213
getWorkPeriodsIsProcessingPayments,
@@ -23,6 +24,7 @@ import styles from "./styles.module.scss";
2324
*/
2425
const PeriodList = ({ className }) => {
2526
const periods = useSelector(getWorkPeriods);
27+
const [periodsData] = useSelector(getWorkPeriodsData);
2628
const periodsDetails = useSelector(getWorkPeriodsDetails);
2729
const periodsFailed = useSelector(getWorkPeriodsFailed);
2830
const periodsSelected = useSelector(getWorkPeriodsSelected);
@@ -37,7 +39,7 @@ const PeriodList = ({ className }) => {
3739
</thead>
3840
<tbody>
3941
<tr>
40-
<td colSpan={8} className={styles.listTopMargin}></td>
42+
<td colSpan={9} className={styles.listTopMargin}></td>
4143
</tr>
4244
{periods.map((period) => (
4345
<PeriodItem
@@ -46,6 +48,7 @@ const PeriodList = ({ className }) => {
4648
isFailed={period.id in periodsFailed}
4749
isSelected={period.id in periodsSelected}
4850
item={period}
51+
data={periodsData[period.id]}
4952
details={periodsDetails[period.id]}
5053
/>
5154
))}

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

+1
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@ const HEAD_CELLS = [
7474
{ label: "Start Date", id: SORT_BY.START_DATE },
7575
{ label: "End Date", id: SORT_BY.END_DATE },
7676
{ label: "Weekly Rate", id: SORT_BY.WEEKLY_RATE },
77+
{ label: "Total Paid", id: SORT_BY.PAYMENT_TOTAL },
7778
{ label: "Status", id: SORT_BY.PAYMENT_STATUS },
7879
{ label: "Working Days", id: SORT_BY.WORKING_DAYS },
7980
];

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

+3-1
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
11
import React, { useCallback } from "react";
22
import { useSelector, useDispatch } from "react-redux";
33
import PT from "prop-types";
4+
import cn from "classnames";
45
import moment from "moment";
56
import WeekPicker from "components/WeekPicker";
67
import { getWorkPeriodsDateRange } from "store/selectors/workPeriods";
78
import { setWorkPeriodsDateRange } from "store/actions/workPeriods";
9+
import styles from "./styles.module.scss";
810

911
/**
1012
* Displays working periods' week picker.
@@ -34,7 +36,7 @@ const PeriodWeekPicker = ({ className }) => {
3436

3537
return (
3638
<WeekPicker
37-
className={className}
39+
className={cn(styles.container, className)}
3840
startDate={startDate}
3941
endDate={endDate}
4042
onWeekSelect={onWeekSelect}
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
.container {
2+
z-index: 4;
23
position: relative;
34
}

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

+7-4
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,10 @@ import { useSelector } from "react-redux";
33
import PT from "prop-types";
44
import cn from "classnames";
55
import PeriodHistoryItem from "../PeriodsHistoryItem";
6-
import { getWorkPeriodsDateRange } from "store/selectors/workPeriods";
6+
import {
7+
getWorkPeriodsData,
8+
getWorkPeriodsDateRange,
9+
} from "store/selectors/workPeriods";
710
import styles from "./styles.module.scss";
811

912
/**
@@ -12,7 +15,8 @@ import styles from "./styles.module.scss";
1215
* @param {Object} props component properties
1316
* @returns {JSX.Element}
1417
*/
15-
const PeriodsHistory = ({ className, isDisabled, periodId, periods }) => {
18+
const PeriodsHistory = ({ className, isDisabled, periods }) => {
19+
const [periodsData] = useSelector(getWorkPeriodsData);
1620
const [startDate] = useSelector(getWorkPeriodsDateRange);
1721
return (
1822
<div className={cn(styles.container, className)}>
@@ -21,9 +25,9 @@ const PeriodsHistory = ({ className, isDisabled, periodId, periods }) => {
2125
{periods.map((period) => (
2226
<PeriodHistoryItem
2327
key={period.id}
24-
periodId={periodId}
2528
isDisabled={isDisabled}
2629
item={period}
30+
data={periodsData[period.id]}
2731
currentStartDate={startDate}
2832
/>
2933
))}
@@ -36,7 +40,6 @@ const PeriodsHistory = ({ className, isDisabled, periodId, periods }) => {
3640
PeriodsHistory.propTypes = {
3741
className: PT.string,
3842
isDisabled: PT.bool.isRequired,
39-
periodId: PT.string.isRequired,
4043
periods: PT.arrayOf(PT.object),
4144
};
4245

0 commit comments

Comments
 (0)