From 8a84ed0420bb4f397fac18596368147e521b6f5e Mon Sep 17 00:00:00 2001 From: "Nina.van.hoof" Date: Thu, 21 Dec 2023 09:54:06 +0100 Subject: [PATCH 1/3] added date validations --- frontend/src/components/controls/Modal.tsx | 3 ++- frontend/src/components/controls/other/DateValidator.tsx | 9 +++++++++ frontend/src/components/project/CopyProject.tsx | 3 +++ frontend/src/components/project/EditProject.tsx | 3 ++- 4 files changed, 16 insertions(+), 2 deletions(-) create mode 100644 frontend/src/components/controls/other/DateValidator.tsx diff --git a/frontend/src/components/controls/Modal.tsx b/frontend/src/components/controls/Modal.tsx index 31331681..bce84e58 100644 --- a/frontend/src/components/controls/Modal.tsx +++ b/frontend/src/components/controls/Modal.tsx @@ -33,6 +33,7 @@ type ModalProps = BaseModalProps & { children: any, /** For custom sizing of the Modal etc */ dialogClassName?: string, + disableSave?: boolean } export const Modal = (props: ModalProps) => { @@ -54,7 +55,7 @@ export const Modal = (props: ModalProps) => { {t('close')} {props.onConfirm ? ( - + {props.confirmText || t('save')} ) : null} diff --git a/frontend/src/components/controls/other/DateValidator.tsx b/frontend/src/components/controls/other/DateValidator.tsx new file mode 100644 index 00000000..922b157d --- /dev/null +++ b/frontend/src/components/controls/other/DateValidator.tsx @@ -0,0 +1,9 @@ +import {Moment} from "moment"; + +export const isDateIntervalValid = (startDate: Moment, endDate: Moment) => { + return startDate.diff(endDate) < 0; +}; + +export const isProjectExtensionDateValid = (previousProjectEndDate: Moment, newProjectStartDate: Moment) => { + return previousProjectEndDate.diff(newProjectStartDate) < 0; +} \ No newline at end of file diff --git a/frontend/src/components/project/CopyProject.tsx b/frontend/src/components/project/CopyProject.tsx index 64715e7b..981efef8 100644 --- a/frontend/src/components/project/CopyProject.tsx +++ b/frontend/src/components/project/CopyProject.tsx @@ -10,6 +10,7 @@ import {saveProject} from '../../actions/projectActions'; import {ArrayInput} from '../controls/form-controls/inputs/ArrayInput'; import {FullFormConfig} from '../../models'; import {ContractStatus} from '../client/models/ContractModels'; +import {isDateIntervalValid, isProjectExtensionDateValid} from '../controls/other/DateValidator'; type CopyProjectProps = { projectToCopy: IProjectModel; @@ -47,6 +48,8 @@ export const CopyProject = ({projectToCopy}: CopyProjectProps) => { onClose={() => setOpen(false)} onConfirm={() => dispatch(saveProject(project, history, 'to-details') as any)} title={t('project.copy.modalTitle')} + disableSave={(project.endDate ? !isDateIntervalValid(project.startDate, project.endDate) : false) + || !isProjectExtensionDateValid(projectToCopy.endDate!, project.startDate)} >
diff --git a/frontend/src/components/project/EditProject.tsx b/frontend/src/components/project/EditProject.tsx index f1ff1567..ec358050 100644 --- a/frontend/src/components/project/EditProject.tsx +++ b/frontend/src/components/project/EditProject.tsx @@ -23,6 +23,7 @@ import {Col} from 'react-bootstrap'; import { SingleContractIcon } from "../client/contract/SingleContractIcon"; import {EnhanceWithConfirmation} from '../enhancers/EnhanceWithConfirmation'; import {Button} from '../controls/form-controls/Button'; +import {isDateIntervalValid} from '../controls/other/DateValidator'; const ConfirmationButton = EnhanceWithConfirmation(Button); @@ -102,7 +103,7 @@ export const EditProject = () => { const isButtonDisabled = !project.consultantId || !project.client || !project.client.clientId || (!project.client.defaultInvoiceLines.length && !project.client.defaultInvoiceLines[0].price) - || !project.startDate; + || !project.startDate || (project.endDate ? !isDateIntervalValid(project.startDate, project.endDate) : false); return ( From f9f33c4863751434f1a79bf4ed5013b93ce9d2c1 Mon Sep 17 00:00:00 2001 From: JochemVH1 Date: Fri, 5 Jul 2024 15:08:52 +0200 Subject: [PATCH 2/3] Renamed DateValidator to ProjectValidator Added test for ProjectValidator Adjusted CopyProject to disable button is project is not valid --- .../controls/other/DateValidator.tsx | 9 --- .../controls/other/ProjectValidator.ts | 11 +++ .../controls/spec/ProjectValidator.spec.ts | 74 +++++++++++++++++++ .../src/components/project/CopyProject.tsx | 5 +- .../src/components/project/EditProject.tsx | 2 +- 5 files changed, 88 insertions(+), 13 deletions(-) delete mode 100644 frontend/src/components/controls/other/DateValidator.tsx create mode 100644 frontend/src/components/controls/other/ProjectValidator.ts create mode 100644 frontend/src/components/controls/spec/ProjectValidator.spec.ts diff --git a/frontend/src/components/controls/other/DateValidator.tsx b/frontend/src/components/controls/other/DateValidator.tsx deleted file mode 100644 index 922b157d..00000000 --- a/frontend/src/components/controls/other/DateValidator.tsx +++ /dev/null @@ -1,9 +0,0 @@ -import {Moment} from "moment"; - -export const isDateIntervalValid = (startDate: Moment, endDate: Moment) => { - return startDate.diff(endDate) < 0; -}; - -export const isProjectExtensionDateValid = (previousProjectEndDate: Moment, newProjectStartDate: Moment) => { - return previousProjectEndDate.diff(newProjectStartDate) < 0; -} \ No newline at end of file diff --git a/frontend/src/components/controls/other/ProjectValidator.ts b/frontend/src/components/controls/other/ProjectValidator.ts new file mode 100644 index 00000000..50d0bc07 --- /dev/null +++ b/frontend/src/components/controls/other/ProjectValidator.ts @@ -0,0 +1,11 @@ +import {Moment} from "moment"; + +export const isDateIntervalValid = (startDate: Moment, endDate: Moment | undefined):boolean => { + return startDate.diff(endDate) < 0; +}; + +export const isProjectValid = (startDate: Moment, endDate: Moment | undefined, previousProjectEndDate: Moment):boolean =>{ + const intervalValid = isDateIntervalValid(startDate, endDate) + const projectValid = isDateIntervalValid(previousProjectEndDate, startDate) + return intervalValid && projectValid +} diff --git a/frontend/src/components/controls/spec/ProjectValidator.spec.ts b/frontend/src/components/controls/spec/ProjectValidator.spec.ts new file mode 100644 index 00000000..69aa39fe --- /dev/null +++ b/frontend/src/components/controls/spec/ProjectValidator.spec.ts @@ -0,0 +1,74 @@ +import moment from "moment" +import { isDateIntervalValid, isProjectValid } from "../other/ProjectValidator" + +describe('ProjectValidator is date inteval valid', () => { + it('Should return true if start date is smaller then end date', () => { + const startDate = moment('2024-01-01') + const endDate = moment('2024-01-31') + + const res = isDateIntervalValid(startDate, endDate) + + expect(res).toBeTruthy() + }) + + it('Should return true if end date is undefined', () => { + const startDate = moment('2024-01-01') + const endDate = undefined + + const res = isDateIntervalValid(startDate, endDate) + + expect(res).toBeTruthy() + }) + + it('Should return false if start date is bigger then end date', () => { + const startDate = moment('2024-02-01') + const endDate = moment('2024-01-31') + + const res = isDateIntervalValid(startDate, endDate) + + expect(res).toBeFalsy() + }) +}) + + +describe('ProjectValidator is project valid', () => { + it('Should return true if previous end date is smaller then new start date and end date is undefined', () => { + const startDate = moment('2024-01-01') + const endDate = undefined + const previousProjectEndDate = moment('2023-12-31') + + const res = isProjectValid(startDate, endDate, previousProjectEndDate) + + expect(res).toBeTruthy() + }) + + it('Should return true if previous end date is smaller then new start date and new end date is bigger then new start date', () => { + const startDate = moment('2024-01-01') + const endDate = moment('2024-01-31') + const previousProjectEndDate = moment('2023-12-31') + + const res = isProjectValid(startDate, endDate, previousProjectEndDate) + + expect(res).toBeTruthy() + }) + + it('Should return false if previous end date is bigger then new start date and new end date is undefined', () => { + const startDate = moment('2024-12-31') + const endDate = undefined + const previousProjectEndDate = moment('2023-01-01') + + const res = isProjectValid(startDate, endDate, previousProjectEndDate) + + expect(res).toBeFalsy() + }) + + it('Should return false if new start date is bigger then new end date', () => { + const startDate = moment('2024-01-02') + const endDate = moment('2023-01-01') + const previousProjectEndDate = moment('2023-01-01') + + const res = isProjectValid(startDate, endDate, previousProjectEndDate) + + expect(res).toBeFalsy() + }) +}) diff --git a/frontend/src/components/project/CopyProject.tsx b/frontend/src/components/project/CopyProject.tsx index 981efef8..a73f87aa 100644 --- a/frontend/src/components/project/CopyProject.tsx +++ b/frontend/src/components/project/CopyProject.tsx @@ -10,7 +10,7 @@ import {saveProject} from '../../actions/projectActions'; import {ArrayInput} from '../controls/form-controls/inputs/ArrayInput'; import {FullFormConfig} from '../../models'; import {ContractStatus} from '../client/models/ContractModels'; -import {isDateIntervalValid, isProjectExtensionDateValid} from '../controls/other/DateValidator'; +import {isProjectValid} from '../controls/other/ProjectValidator'; type CopyProjectProps = { projectToCopy: IProjectModel; @@ -48,8 +48,7 @@ export const CopyProject = ({projectToCopy}: CopyProjectProps) => { onClose={() => setOpen(false)} onConfirm={() => dispatch(saveProject(project, history, 'to-details') as any)} title={t('project.copy.modalTitle')} - disableSave={(project.endDate ? !isDateIntervalValid(project.startDate, project.endDate) : false) - || !isProjectExtensionDateValid(projectToCopy.endDate!, project.startDate)} + disableSave={!isProjectValid(project.startDate, project.endDate, projectToCopy.endDate!)} >
diff --git a/frontend/src/components/project/EditProject.tsx b/frontend/src/components/project/EditProject.tsx index ec358050..cdb599e4 100644 --- a/frontend/src/components/project/EditProject.tsx +++ b/frontend/src/components/project/EditProject.tsx @@ -23,7 +23,7 @@ import {Col} from 'react-bootstrap'; import { SingleContractIcon } from "../client/contract/SingleContractIcon"; import {EnhanceWithConfirmation} from '../enhancers/EnhanceWithConfirmation'; import {Button} from '../controls/form-controls/Button'; -import {isDateIntervalValid} from '../controls/other/DateValidator'; +import {isDateIntervalValid} from '../controls/other/ProjectValidator'; const ConfirmationButton = EnhanceWithConfirmation(Button); From 89e10caa3be6fc0770d4efcf8683096ef2449be3 Mon Sep 17 00:00:00 2001 From: JochemVH1 Date: Fri, 5 Jul 2024 15:14:25 +0200 Subject: [PATCH 3/3] Adjusted EditProject isDateIntervalValid function because enddate can be undefined now --- frontend/src/components/project/EditProject.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/src/components/project/EditProject.tsx b/frontend/src/components/project/EditProject.tsx index cdb599e4..0c0ad48e 100644 --- a/frontend/src/components/project/EditProject.tsx +++ b/frontend/src/components/project/EditProject.tsx @@ -103,7 +103,7 @@ export const EditProject = () => { const isButtonDisabled = !project.consultantId || !project.client || !project.client.clientId || (!project.client.defaultInvoiceLines.length && !project.client.defaultInvoiceLines[0].price) - || !project.startDate || (project.endDate ? !isDateIntervalValid(project.startDate, project.endDate) : false); + || !project.startDate || !isDateIntervalValid(project.startDate, project.endDate); return (