Skip to content

Commit

Permalink
PIMS-2000: Make non-optional checkboxes mandatory (#2640)
Browse files Browse the repository at this point in the history
Co-authored-by: dbarkowsky <[email protected]>
Co-authored-by: Dylan Barkowsky <[email protected]>
  • Loading branch information
3 people committed Sep 11, 2024
1 parent 4d75a1f commit 6ea197d
Show file tree
Hide file tree
Showing 4 changed files with 69 additions and 5 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import { MigrationInterface, QueryRunner } from 'typeorm';

export class UpdateTaskStatus1724686432998 implements MigrationInterface {
public async up(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(`
UPDATE task SET status_id = 14 WHERE id = 3;
`);
await queryRunner.query(`
UPDATE task SET status_id = 15 WHERE id = 4;
`);
await queryRunner.query(`
UPDATE task SET is_optional = true WHERE id = 24;
`);
await queryRunner.query(`
UPDATE timestamp_type SET status_id = 21, is_optional = false WHERE id = 11;
`);
await queryRunner.query(`
UPDATE task SET name = 'Preparation and Due Diligence complete', is_optional = false WHERE id IN (9, 19);
`);
}

public async down(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(`
UPDATE task SET status_id = 7 WHERE id = 3;
`);
await queryRunner.query(`
UPDATE task SET status_id = 8 WHERE id = 4;
`);
await queryRunner.query(`
UPDATE task SET is_optional = false WHERE id = 24;
`);
await queryRunner.query(`
UPDATE timestamp_type SET status_id = 14, is_optional = true WHERE id = 11;
`);
await queryRunner.query(`
UPDATE task SET name = 'Preparation and due diligence', is_optional = true WHERE id IN (9, 19);
`);
}
}
19 changes: 17 additions & 2 deletions react-app/src/components/form/DateFormField.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,25 @@ import React from 'react';
import { Controller, useFormContext } from 'react-hook-form';
import { DateField, LocalizationProvider } from '@mui/x-date-pickers';
import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs';
import { Box, Typography, useTheme } from '@mui/material';

type DateFieldFormProps = {
name: string;
label: string;
disabled?: boolean;
required?: boolean;
};

const DateFormField = (props: DateFieldFormProps) => {
const { control } = useFormContext();
const { name, label, disabled } = props;
const theme = useTheme();
const { name, label, disabled, required } = props;
return (
<Controller
control={control}
name={name}
render={({ field: { onChange, value } }) => {
rules={{ validate: (value) => !required || value || 'Required field.' }}
render={({ field: { onChange, value }, fieldState: { error } }) => {
return (
<LocalizationProvider dateAdapter={AdapterDayjs}>
<DateField
Expand All @@ -26,7 +30,18 @@ const DateFormField = (props: DateFieldFormProps) => {
value={value}
label={label}
format={'LL'}
required={required}
slotProps={{ textField: { error: !!error && !!error.message } }}
/>
{!!error && !!error.message ? (
<Box>
<Typography ml={'3.2em'} fontSize={'smaller'} color={theme.palette.error.main}>
{error.message}
</Typography>
</Box>
) : (
<></>
)}
</LocalizationProvider>
);
}}
Expand Down
3 changes: 2 additions & 1 deletion react-app/src/components/form/SingleSelectBoxFormField.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ const SingleSelectBoxFormField = (props: SingleSelectBoxFormFieldProps) => {
name={name}
control={control}
rules={{ validate: (value) => !required || value || 'Required field.' }}
render={({ field: { onChange, value }, fieldState: { error } }) => (
render={({ field: { onChange, value, onBlur }, fieldState: { error } }) => (
<>
<Box
sx={{
Expand All @@ -29,6 +29,7 @@ const SingleSelectBoxFormField = (props: SingleSelectBoxFormFieldProps) => {
<Checkbox
id={`single-checkbox-${name}`}
onChange={(_, data) => onChange(data)}
onBlur={onBlur}
checked={!!value}
required={required}
/>
Expand Down
13 changes: 11 additions & 2 deletions react-app/src/components/projects/ProjectDialog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,8 @@ export const ProjectGeneralInfoDialog = (props: IProjectGeneralInfoDialog) => {
TimestampTypes,
});
}
}, [projectFormMethods.watch('StatusId')]); //When status id changes, fetch a new set of tasks possible for this status...
projectFormMethods.clearErrors();
}, [projectFormMethods.watch('StatusId'), lookupData]); //When status id changes, fetch a new set of tasks possible for this status...

useEffect(() => {
//Subsequently, we need to default the values of the form either to the already present value in the Project data blob, or just set it to false.
Expand Down Expand Up @@ -167,6 +168,7 @@ export const ProjectGeneralInfoDialog = (props: IProjectGeneralInfoDialog) => {
const requireNotificationAcknowledge =
approvedStatus == status && status !== initialValues?.StatusId;
const isAdmin = keycloak.hasRoles([Roles.ADMIN]);
console.log('project form values', projectFormMethods.getValues());
return (
<ConfirmDialog
title={'Update Project'}
Expand All @@ -176,14 +178,17 @@ export const ProjectGeneralInfoDialog = (props: IProjectGeneralInfoDialog) => {
}}
onConfirm={async () => {
const isValid = await projectFormMethods.trigger();
console.log('lookupData and isValid', lookupData, isValid);
if (lookupData && isValid) {
const values = projectFormMethods.getValues();
submit(+initialValues.Id, {
...values,
Id: initialValues.Id,
ProjectProperties: initialValues.ProjectProperties,
Timestamps: values.Timestamps.filter((a) => dayjs(a.Date).isValid()),
}).then(() => postSubmit());
})
.then(() => postSubmit())
.catch((reason) => console.log(reason));
}
}}
onCancel={async () => onCancel()}
Expand Down Expand Up @@ -211,6 +216,7 @@ export const ProjectGeneralInfoDialog = (props: IProjectGeneralInfoDialog) => {
key={`${task.Id}-${idx}`}
name={`Tasks.${idx}.IsCompleted`}
label={task.Name}
required={!lookupData?.Tasks.find((t) => task.Id === t.Id)?.IsOptional}
/>
))}
</Box>
Expand Down Expand Up @@ -268,6 +274,9 @@ export const ProjectGeneralInfoDialog = (props: IProjectGeneralInfoDialog) => {
key={`${ts.Id}-${idx}`}
name={`Timestamps.${idx}.Date`}
label={columnNameFormatter(ts.Name)}
required={
!lookupData?.TimestampTypes?.find((tt) => ts.Id === tt.Id)?.IsOptional
}
/>
</Grid>
))}
Expand Down

0 comments on commit 6ea197d

Please sign in to comment.