From aa0d642685624cf84f8d8f8f3501a0476e3578fd Mon Sep 17 00:00:00 2001 From: Oleg Petrov Date: Mon, 14 Jun 2021 18:54:49 +0300 Subject: [PATCH 01/10] Completely removed 'Lock Working Days' code. --- .../components/PeriodDetails/index.jsx | 20 ------------------- .../PeriodDetails/styles.module.scss | 8 -------- src/store/actionTypes/workPeriods.js | 2 -- src/store/actions/workPeriods.js | 5 ----- src/store/reducers/workPeriods.js | 16 --------------- 5 files changed, 51 deletions(-) diff --git a/src/routes/WorkPeriods/components/PeriodDetails/index.jsx b/src/routes/WorkPeriods/components/PeriodDetails/index.jsx index 146d645..862067c 100644 --- a/src/routes/WorkPeriods/components/PeriodDetails/index.jsx +++ b/src/routes/WorkPeriods/components/PeriodDetails/index.jsx @@ -12,7 +12,6 @@ import { hideWorkPeriodDetails, setBillingAccount, setDetailsHidePastPeriods, - // setDetailsLockWorkingDays, } from "store/actions/workPeriods"; import styles from "./styles.module.scss"; import { updateWorkPeriodBillingAccount } from "store/thunks/workPeriods"; @@ -42,7 +41,6 @@ const PeriodDetails = ({ className, details, isDisabled, isFailed }) => { periodsVisible, periodsIsLoading, hidePastPeriods, - // lockWorkingDays, } = details; const onHideDetailsBtnClick = useCallback(() => { @@ -56,13 +54,6 @@ const PeriodDetails = ({ className, details, isDisabled, isFailed }) => { [dispatch, periodId] ); - // const onChangeLockWorkingDays = useCallback( - // (lock) => { - // dispatch(setDetailsLockWorkingDays(periodId, lock)); - // }, - // [dispatch, periodId] - // ); - const onChangeBillingAccount = useCallback( (value) => { dispatch(setBillingAccount(periodId, value)); @@ -113,16 +104,6 @@ const PeriodDetails = ({ className, details, isDisabled, isFailed }) => { - {/*
-
Lock Working Days
- -
*/}
Billing Account
({ payload: { periodId, hide }, }); -export const setDetailsLockWorkingDays = (periodId, lock) => ({ - type: ACTION_TYPE.WP_SET_DETAILS_LOCK_WORKING_DAYS, - payload: { periodId, lock }, -}); - /** * Creates an action to reset working periods' filters. * diff --git a/src/store/reducers/workPeriods.js b/src/store/reducers/workPeriods.js index 706ca1a..50b7f16 100644 --- a/src/store/reducers/workPeriods.js +++ b/src/store/reducers/workPeriods.js @@ -59,7 +59,6 @@ const initPeriodDetails = ( periodsVisible: [], periodsIsLoading: true, hidePastPeriods: false, - lockWorkingDays: false, }); const initialState = { @@ -375,21 +374,6 @@ const actionHandlers = { periodsDetails, }; }, - [ACTION_TYPE.WP_SET_DETAILS_LOCK_WORKING_DAYS]: ( - state, - { periodId, lock } - ) => { - const periodsDetails = { ...state.periodsDetails }; - let periodDetails = periodsDetails[periodId]; - if (!periodDetails) { - return state; - } - periodsDetails[periodId] = { ...periodDetails, lockWorkingDays: lock }; - return { - ...state, - periodsDetails, - }; - }, [ACTION_TYPE.WP_SET_DETAILS_WORKING_DAYS]: ( state, { parentPeriodId, periodId, workingDays } From 94daee3f655062f95b8adf533e39d2076be4b5e8 Mon Sep 17 00:00:00 2001 From: Oleg Petrov Date: Mon, 14 Jun 2021 19:05:31 +0300 Subject: [PATCH 02/10] Removed falsy or empty-array values from query object sent to /work-period-payments/query. --- src/services/workPeriods.js | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/services/workPeriods.js b/src/services/workPeriods.js index b4a5515..3ddef89 100644 --- a/src/services/workPeriods.js +++ b/src/services/workPeriods.js @@ -142,6 +142,15 @@ export const postWorkPeriodsPayments = (payments) => { * @returns {Promise} */ export const postWorkPeriodsPaymentsAll = (query) => { + for (let key in query) { + let value = query[key]; + if ( + (typeof value !== "number" && !value) || + (Array.isArray(value) && !value.length) + ) { + delete query[key]; + } + } return axios .post(`${PAYMENTS_API_URL}/query`, { query }) .then(extractResponseData); From a89442b31c55183d28d91840b41d0a5b6803267b Mon Sep 17 00:00:00 2001 From: Oleg Petrov Date: Mon, 14 Jun 2021 19:27:11 +0300 Subject: [PATCH 03/10] Refactored function that sends query to /work-period-payments/query. --- src/services/workPeriods.js | 13 +++++++++---- src/store/thunks/workPeriods.js | 2 +- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/src/services/workPeriods.js b/src/services/workPeriods.js index 3ddef89..8928618 100644 --- a/src/services/workPeriods.js +++ b/src/services/workPeriods.js @@ -144,11 +144,16 @@ export const postWorkPeriodsPayments = (payments) => { export const postWorkPeriodsPaymentsAll = (query) => { for (let key in query) { let value = query[key]; - if ( - (typeof value !== "number" && !value) || - (Array.isArray(value) && !value.length) - ) { + if (typeof value !== "number" && !value) { delete query[key]; + continue; + } + if (Array.isArray(value)) { + if (value.length) { + query[key] = value.join(","); + } else { + delete query[key]; + } } } return axios diff --git a/src/store/thunks/workPeriods.js b/src/store/thunks/workPeriods.js index 7712130..289123f 100644 --- a/src/store/thunks/workPeriods.js +++ b/src/store/thunks/workPeriods.js @@ -265,7 +265,7 @@ const processPaymentsAll = async (dispatch, getState) => { status: RESOURCE_BOOKING_STATUS.PLACED, ["workPeriods.userHandle"]: filters.userHandle, ["workPeriods.startDate"]: startDate.format(DATE_FORMAT_API), - ["workPeriods.paymentStatus"]: paymentStatuses.join(","), + ["workPeriods.paymentStatus"]: paymentStatuses, }); let data = null; let errorMessage = null; From 455f75daace5e4a9756c7a4ad62803fe4da86a87 Mon Sep 17 00:00:00 2001 From: Oleg Petrov Date: Mon, 14 Jun 2021 20:49:34 +0300 Subject: [PATCH 04/10] Fixed: inconsistent periods' selection state If page size was greater than the total number of periods select-all-on-page checkbox and the number of selected periods in the message above the periods' table had incorrect state. --- src/store/reducers/workPeriods.js | 32 +++++++++++++++++++++++++------ 1 file changed, 26 insertions(+), 6 deletions(-) diff --git a/src/store/reducers/workPeriods.js b/src/store/reducers/workPeriods.js index 50b7f16..110d2d8 100644 --- a/src/store/reducers/workPeriods.js +++ b/src/store/reducers/workPeriods.js @@ -439,7 +439,15 @@ const actionHandlers = { delete periodsSelected[periodId]; } } - if (Object.keys(periodsSelected).length === state.pagination.pageSize) { + const selectedCount = Object.keys(periodsSelected).length; + const pageSize = state.pagination.pageSize; + const totalCount = state.pagination.totalCount; + if (totalCount > pageSize) { + if (selectedCount === pageSize) { + isSelectedPeriodsVisible = true; + } + } else if (selectedCount === totalCount) { + isSelectedPeriodsAll = true; isSelectedPeriodsVisible = true; } return { @@ -533,7 +541,15 @@ const actionHandlers = { const isSelected = !periodsSelected[periodId]; if (isSelected) { periodsSelected[periodId] = true; - if (Object.keys(periodsSelected).length === state.pagination.pageSize) { + const selectedCount = Object.keys(periodsSelected).length; + const pageSize = state.pagination.pageSize; + const totalCount = state.pagination.totalCount; + if (totalCount > pageSize) { + if (selectedCount === pageSize) { + isSelectedPeriodsVisible = true; + } + } else if (selectedCount === totalCount) { + isSelectedPeriodsAll = true; isSelectedPeriodsVisible = true; } } else { @@ -564,18 +580,22 @@ const actionHandlers = { }; }, [ACTION_TYPE.WP_TOGGLE_PERIODS_VISIBLE]: (state, on) => { - const isSelected = on === null ? !state.isSelectedPeriodsVisible : on; + let isSelectedPeriodsAll = false; + const isSelectedPeriodsVisible = + on === null ? !state.isSelectedPeriodsVisible : on; const periodsSelected = {}; - if (isSelected) { + if (isSelectedPeriodsVisible) { for (let period of state.periods) { periodsSelected[period.id] = true; } + isSelectedPeriodsAll = + state.periods.length === state.pagination.totalCount; } return { ...state, periodsSelected, - isSelectedPeriodsAll: false, - isSelectedPeriodsVisible: isSelected, + isSelectedPeriodsAll, + isSelectedPeriodsVisible, }; }, [ACTION_TYPE.WP_TOGGLE_PROCESSING_PAYMENTS]: (state, on) => { From e0527253288ab59e064aa62b6fe1fbdf115de32c Mon Sep 17 00:00:00 2001 From: Oleg Petrov Date: Mon, 14 Jun 2021 21:05:23 +0300 Subject: [PATCH 05/10] Fixed: prop-types' warnings. --- .../WorkPeriods/components/PeriodDetails/index.jsx | 2 +- src/routes/WorkPeriods/components/PeriodItem/index.jsx | 10 +++------- .../components/PeriodsHistoryItem/index.jsx | 2 +- 3 files changed, 5 insertions(+), 9 deletions(-) diff --git a/src/routes/WorkPeriods/components/PeriodDetails/index.jsx b/src/routes/WorkPeriods/components/PeriodDetails/index.jsx index 862067c..a5a86b8 100644 --- a/src/routes/WorkPeriods/components/PeriodDetails/index.jsx +++ b/src/routes/WorkPeriods/components/PeriodDetails/index.jsx @@ -169,7 +169,7 @@ PeriodDetails.propTypes = { billingAccounts: PT.arrayOf( PT.shape({ label: PT.string.isRequired, - value: PT.string.isRequired, + value: PT.number.isRequired, }) ), billingAccountsError: PT.string, diff --git a/src/routes/WorkPeriods/components/PeriodItem/index.jsx b/src/routes/WorkPeriods/components/PeriodItem/index.jsx index 7b790ab..ae5cf84 100644 --- a/src/routes/WorkPeriods/components/PeriodItem/index.jsx +++ b/src/routes/WorkPeriods/components/PeriodItem/index.jsx @@ -166,16 +166,12 @@ PeriodItem.propTypes = { billingAccountId: PT.number.isRequired, billingAccounts: PT.arrayOf( PT.shape({ - value: PT.string.isRequired, label: PT.string.isRequired, + value: PT.number.isRequired, }) - ), + ).isRequired, billingAccountsIsLoading: PT.bool.isRequired, - periods: PT.arrayOf( - PT.shape({ - id: PT.string.isRequired, - }) - ), + periods: PT.array.isRequired, periodsIsLoading: PT.bool.isRequired, }), }; diff --git a/src/routes/WorkPeriods/components/PeriodsHistoryItem/index.jsx b/src/routes/WorkPeriods/components/PeriodsHistoryItem/index.jsx index 8934dff..5bbfabc 100644 --- a/src/routes/WorkPeriods/components/PeriodsHistoryItem/index.jsx +++ b/src/routes/WorkPeriods/components/PeriodsHistoryItem/index.jsx @@ -105,7 +105,7 @@ PeriodsHistoryItem.propTypes = { endDate: PT.oneOfType([PT.string, PT.number]).isRequired, paymentStatus: PT.string.isRequired, payments: PT.array, - weeklyRate: PT.number.isRequired, + weeklyRate: PT.number, workingDays: PT.number.isRequired, }).isRequired, currentStartDate: PT.oneOfType([PT.string, PT.number, PT.object]).isRequired, From 649482280200e377809bde1691ea89e4fd7d2234 Mon Sep 17 00:00:00 2001 From: Oleg Petrov Date: Mon, 14 Jun 2021 21:17:27 +0300 Subject: [PATCH 06/10] Minor improvements in ProjectName component --- src/components/ProjectName/index.jsx | 11 +++++++---- src/components/ProjectName/styles.module.scss | 5 +++++ 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/src/components/ProjectName/index.jsx b/src/components/ProjectName/index.jsx index 463c531..33be6fd 100644 --- a/src/components/ProjectName/index.jsx +++ b/src/components/ProjectName/index.jsx @@ -1,4 +1,4 @@ -import React, { useContext, useEffect } from "react"; +import React, { memo, useContext, useEffect } from "react"; import PT from "prop-types"; import cn from "classnames"; import { ProjectNameContext } from "components/ProjectNameContextProvider"; @@ -6,13 +6,16 @@ import styles from "./styles.module.scss"; const ProjectName = ({ className, projectId }) => { const [getName, fetchName] = useContext(ProjectNameContext); + useEffect(() => { fetchName(projectId); }, [fetchName, projectId]); + const projectName = getName(projectId) || projectId; + return ( - - {getName(projectId) || projectId} + + {projectName} ); }; @@ -22,4 +25,4 @@ ProjectName.propTypes = { projectId: PT.number.isRequired, }; -export default ProjectName; +export default memo(ProjectName); diff --git a/src/components/ProjectName/styles.module.scss b/src/components/ProjectName/styles.module.scss index f098c8d..5900b9c 100644 --- a/src/components/ProjectName/styles.module.scss +++ b/src/components/ProjectName/styles.module.scss @@ -1,5 +1,10 @@ @import "styles/mixins"; .container { + display: block; + max-width: 20em; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; @include roboto-medium; } From 56f9c68c2400feb5107857801c3d488c37b9ff8d Mon Sep 17 00:00:00 2001 From: Oleg Petrov Date: Tue, 15 Jun 2021 19:52:18 +0300 Subject: [PATCH 07/10] Fixed: checkboxes in sidebar overlaid search field suggestions' list. --- src/components/SearchHandleField/styles.module.scss | 1 + 1 file changed, 1 insertion(+) diff --git a/src/components/SearchHandleField/styles.module.scss b/src/components/SearchHandleField/styles.module.scss index 266d7d4..1cc06f8 100644 --- a/src/components/SearchHandleField/styles.module.scss +++ b/src/components/SearchHandleField/styles.module.scss @@ -2,6 +2,7 @@ @import "styles/mixins"; .container { + z-index: 3; position: relative; display: flex; align-items: center; From f38a3049892abe631fea9413149ae604525314c7 Mon Sep 17 00:00:00 2001 From: Oleg Petrov Date: Tue, 15 Jun 2021 20:20:33 +0300 Subject: [PATCH 08/10] Avoiding processing periods using query when page size is large enough. --- .../components/PeriodsSelectionMessage/index.jsx | 15 +++++---------- src/store/thunks/workPeriods.js | 6 ++++-- 2 files changed, 9 insertions(+), 12 deletions(-) diff --git a/src/routes/WorkPeriods/components/PeriodsSelectionMessage/index.jsx b/src/routes/WorkPeriods/components/PeriodsSelectionMessage/index.jsx index 1202bfd..f937827 100644 --- a/src/routes/WorkPeriods/components/PeriodsSelectionMessage/index.jsx +++ b/src/routes/WorkPeriods/components/PeriodsSelectionMessage/index.jsx @@ -29,25 +29,20 @@ const PeriodsSelectionMessage = ({ className }) => { dispatch(toggleWorkingPeriodsAll()); }, [dispatch]); - const infoText = isSelectedAll - ? `All ${totalCount} Records are selected. ` - : `All ${pageSize} Records on this page are selected. `; - const btnText = isSelectedAll - ? "Deselect" - : `Select all ${totalCount} Records`; - return (
- {isSelectedVisible && ( + {isSelectedVisible && totalCount > pageSize && ( - {infoText} + {isSelectedAll + ? `All ${totalCount} Records are selected. ` + : `All ${pageSize} Records on this page are selected. `} - {btnText} + {isSelectedAll ? "Deselect" : `Select all ${totalCount} Records`} )} diff --git a/src/store/thunks/workPeriods.js b/src/store/thunks/workPeriods.js index 289123f..78d44c8 100644 --- a/src/store/thunks/workPeriods.js +++ b/src/store/thunks/workPeriods.js @@ -242,8 +242,10 @@ export const updateWorkPeriodWorkingDays = */ export const processPayments = async (dispatch, getState) => { dispatch(actions.toggleWorkPeriodsProcessingPeyments(true)); - const isSelectedAll = selectors.getWorkPeriodsIsSelectedAll(getState()); - if (isSelectedAll) { + const state = getState(); + const isSelectedAll = selectors.getWorkPeriodsIsSelectedAll(state); + const { pageSize, totalCount } = selectors.getWorkPeriodsPagination(state); + if (isSelectedAll && totalCount > pageSize) { processPaymentsAll(dispatch, getState); } else { processPaymentsSpecific(dispatch, getState); From 85f052d75448faf5ccdb17e1c75a64b1bccae7ea Mon Sep 17 00:00:00 2001 From: Oleg Petrov Date: Tue, 15 Jun 2021 22:02:37 +0300 Subject: [PATCH 09/10] Additional modifications - Made checkboxes' background white. - Removed info about each successfully scheduled period from toastr warning message and made its background monotonic. --- src/components/Checkbox/styles.module.scss | 1 + .../components/ToastPaymentsWarning/index.jsx | 24 +++++++------------ .../ToastPaymentsWarning/styles.module.scss | 7 +----- src/routes/WorkPeriods/utils/toasts.jsx | 2 -- 4 files changed, 10 insertions(+), 24 deletions(-) diff --git a/src/components/Checkbox/styles.module.scss b/src/components/Checkbox/styles.module.scss index e07c408..c07881a 100644 --- a/src/components/Checkbox/styles.module.scss +++ b/src/components/Checkbox/styles.module.scss @@ -56,6 +56,7 @@ input.checkbox { border-radius: 3px; line-height: 18px; user-select: none; + background-color: #fff; color: transparent; &::before { diff --git a/src/routes/WorkPeriods/components/ToastPaymentsWarning/index.jsx b/src/routes/WorkPeriods/components/ToastPaymentsWarning/index.jsx index 256f86d..7a73bd1 100644 --- a/src/routes/WorkPeriods/components/ToastPaymentsWarning/index.jsx +++ b/src/routes/WorkPeriods/components/ToastPaymentsWarning/index.jsx @@ -8,10 +8,17 @@ import styles from "./styles.module.scss"; * payments have been scheduled or failed to schedule. * * @param {Object} props component properties + * @param {number} props.resourcesSucceededCount the number of resources + * for which payments have been successfully scheduled + * @param {Array} [props.resourcesFailed] array with data for resources + * for which payments were failed to be scheduled + * @param {number} props.resourcesFailedCount the number of resources + * for which payments were failed to be scheduled + * @param {() => void} [props.remove] function that must be called + * on toast message removal intent * @returns {JSX.Element} */ const ToastPaymentsWarning = ({ - resourcesSucceeded, resourcesSucceededCount, resourcesFailed, resourcesFailedCount, @@ -23,15 +30,6 @@ const ToastPaymentsWarning = ({
Payment scheduled for {resourcesSucceededCount} resources
- {resourcesSucceeded && resourcesSucceeded.length && ( -
- {resourcesSucceeded.map((period) => ( -
- {period.workPeriodId} -
- ))} -
- )}
@@ -53,12 +51,6 @@ const ToastPaymentsWarning = ({ }; ToastPaymentsWarning.propTypes = { - resourcesSucceeded: PT.arrayOf( - PT.shape({ - workPeriodId: PT.string.isRequired, - amount: PT.number, - }) - ), resourcesSucceededCount: PT.number.isRequired, resourcesFailed: PT.arrayOf( PT.shape({ diff --git a/src/routes/WorkPeriods/components/ToastPaymentsWarning/styles.module.scss b/src/routes/WorkPeriods/components/ToastPaymentsWarning/styles.module.scss index fcc4b34..5b0aebb 100644 --- a/src/routes/WorkPeriods/components/ToastPaymentsWarning/styles.module.scss +++ b/src/routes/WorkPeriods/components/ToastPaymentsWarning/styles.module.scss @@ -3,10 +3,5 @@ } .sectionSucceeded { - margin-bottom: 10px; - background: #1dcfa0; -} - -.sectionFailed { - background: #ff7b7b; + margin-bottom: 5px; } diff --git a/src/routes/WorkPeriods/utils/toasts.jsx b/src/routes/WorkPeriods/utils/toasts.jsx index f653c5f..7a420b4 100644 --- a/src/routes/WorkPeriods/utils/toasts.jsx +++ b/src/routes/WorkPeriods/utils/toasts.jsx @@ -44,8 +44,6 @@ export function makeToastPaymentsSuccess(resourceCount) { * payments were successfully scheduled * @param {number} props.resourcesFailedCount the number of periods for which * payments were failed to be scheduled - * @param {Array} [props.resourcesSucceeded] periods for which payments were - * successfully scheduled * @param {Array} [props.resourcesFailed] periods for which payments were failed * to be scheduled */ From ceef619a1571a165145c11cbc75faf1c7466c9ed Mon Sep 17 00:00:00 2001 From: Oleg Petrov Date: Tue, 15 Jun 2021 23:02:49 +0300 Subject: [PATCH 10/10] Minor change: removed unneeded object property. --- src/store/thunks/workPeriods.js | 1 - 1 file changed, 1 deletion(-) diff --git a/src/store/thunks/workPeriods.js b/src/store/thunks/workPeriods.js index 78d44c8..e04818a 100644 --- a/src/store/thunks/workPeriods.js +++ b/src/store/thunks/workPeriods.js @@ -334,7 +334,6 @@ const processPaymentsSpecific = async (dispatch, getState) => { if (resourcesSucceeded.length) { if (resourcesFailed.length) { makeToastPaymentsWarning({ - resourcesSucceeded, resourcesSucceededCount: resourcesSucceeded.length, resourcesFailed, resourcesFailedCount: resourcesFailed.length,