Skip to content

Commit

Permalink
Merge pull request #4037 from unicef/PDU-updates-updates-list
Browse files Browse the repository at this point in the history
Pdu updates frontend
  • Loading branch information
mmaciekk authored Jul 11, 2024
2 parents 0376614 + 5e1f326 commit 5fa5ee2
Show file tree
Hide file tree
Showing 21 changed files with 657 additions and 447 deletions.
17 changes: 8 additions & 9 deletions frontend/src/api/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,28 +38,27 @@ export const api = {
return data;
},

async post(url: string, data: Record<string, any> = {}) {
const response = await fetch(`${this.baseURL}${url}`, {
async post(url: string, data: Record<string, any> | FormData) {
const isFormData = data instanceof FormData;
const fetchOptions: RequestInit = {
method: 'POST',
headers: {
...this.headers,
'Content-Type': 'application/json',
...(isFormData ? {} : { 'Content-Type': 'application/json' }),
},
body: JSON.stringify(data),
});
body: isFormData ? data : JSON.stringify(data),
};

const response = await fetch(`${this.baseURL}${url}`, fetchOptions);

if (!response.ok) {
throw new Error(`Error posting data to ${url}`);
}

// Check if the response is empty
const text = await response.text();
if (!text) {
// If the response is empty, return an object with a data property set to null
return { data: null };
}

// If the response is not empty, parse it as JSON and return it
return { data: JSON.parse(text) };
},
};
Original file line number Diff line number Diff line change
Expand Up @@ -12,35 +12,68 @@ export const fetchPeriodicDataUpdateTemplates = async (
return response;
};

export const fetchPeriodicDataUpdateTemplateDetails = async (
export const fetchPeriodicDataUpdateUpdates = async (
businessAreaSlug,
programId,
templateId,
params = {},
) => {
const response = await api.get(
`${businessAreaSlug}/programs/${programId}/periodic-data-update/periodic-data-update-templates/${templateId}/`,
`${businessAreaSlug}/programs/${programId}/periodic-data-update/periodic-data-update-uploads/`,
params,
);
return response;
};

export const exportPeriodicDataUpdateTemplate = async (
export const fetchPeriodicDataUpdateTemplateDetails = async (
businessAreaSlug,
programId,
templateId,
) => {
const response = await api.post(
const response = await api.get(
`${businessAreaSlug}/programs/${programId}/periodic-data-update/periodic-data-update-templates/${templateId}/`,
);
return response;
};

export const exportPeriodicDataUpdateTemplate = async (
businessAreaSlug: string,
programId: string,
templateId: string,
): Promise<any> => {
const response = await api.get(
`${businessAreaSlug}/programs/${programId}/periodic-data-update/periodic-data-update-templates/${templateId}/export/`,
);
return response.data;
};

export const downloadPeriodicDataUpdateTemplate = async (
businessAreaSlug,
programId,
templateId,
) => {
export const fetchPeriodicDataUpdateTemplate = async (
businessAreaSlug: string,
programId: string,
templateId: string,
): Promise<any> => {
const response = await api.get(
`${businessAreaSlug}/programs/${programId}/periodic-data-update/periodic-data-update-templates/${templateId}/download/`,
);
return response.data;
};

export const uploadPeriodicDataUpdateTemplate = async (
businessAreaSlug: string,
programId: string,
file: File,
additionalParams: Record<string, any> = {},
) => {
const formData = new FormData();
formData.append('file', file);

Object.keys(additionalParams).forEach((key) => {
formData.append(key, additionalParams[key]);
});

const response = await api.post(
`${businessAreaSlug}/programs/${programId}/periodic-data-update/periodic-data-update-templates/`,
formData,
);

return response;
};
4 changes: 2 additions & 2 deletions frontend/src/components/core/BaseSection.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ const BoxContainer = styled(Box)`
interface BaseSectionProps {
children?: ReactElement | ReactElement[];
buttons?: ReactElement;
title: string | ReactElement;
title?: string | ReactElement;
description?: string;
p?: number;
noPaper?: boolean;
Expand All @@ -33,7 +33,7 @@ interface BaseSectionProps {
export const BaseSection = ({
children = <></>,
buttons,
title,
title = '',
description,
p = 3,
noPaper = false,
Expand Down
12 changes: 2 additions & 10 deletions frontend/src/components/core/Drawer/menuItems.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -70,27 +70,19 @@ export const menuItems: MenuItem[] = [
{
name: 'Households',
href: '/population/household',
selectedRegexp: /^\/population\/household(?!-members).*$/,
selectedRegexp: /^\/population\/household.*$/,
icon: <PeopleAltRoundedIcon />,
permissionModule: 'HOUSEHOLDS',
scopes: [SCOPE_PROGRAM],
},
{
name: 'Individuals',
name: 'Household Members',
href: '/population/individuals',
selectedRegexp: /^\/population\/individuals.*$/,
icon: <FaceIcon />,
permissionModule: 'INDIVIDUALS',
scopes: [SCOPE_PROGRAM],
},
{
name: 'Household Members',
href: '/population/household-members',
selectedRegexp: /^\/population\/household-members.*$/,
icon: <FaceIcon />,
permissionModule: 'INDIVIDUALS',
scopes: [SCOPE_PROGRAM],
},
],
},
{
Expand Down
171 changes: 95 additions & 76 deletions frontend/src/components/periodicDataUpdates/FieldsToUpdate.tsx
Original file line number Diff line number Diff line change
@@ -1,97 +1,116 @@
import { useState } from 'react';
import React from 'react';
import { FieldArray } from 'formik';
import {
Table,
TableBody,
TableCell,
TableContainer,
TableHead,
TableRow,
Paper,
Checkbox,
MenuItem,
Select,
Box,
} from '@mui/material';

const initialFields = [
interface Field {
id: number;
name: string;
}

interface SelectedField extends Field {
roundNumber?: number;
}

interface FieldsToUpdateProps {
values: {
selectedFields: SelectedField[];
};
setFieldValue: (field: string, value: any, shouldValidate?: boolean) => void;
}

const initialFields: Field[] = [
{ id: 1, name: 'Field 1' },
{ id: 2, name: 'Field 2' },
{ id: 3, name: 'Field 3' },
// Add more fields as needed
];

export const FieldsToUpdate = () => {
const [selectedFields, setSelectedFields] = useState([]);

const handleSelectField = (fieldId, roundNumber) => {
const updatedSelection = selectedFields.find(
(field) => field.id === fieldId,
)
? selectedFields.map((field) =>
field.id === fieldId ? { ...field, roundNumber } : field,
)
: [...selectedFields, { id: fieldId, roundNumber }];

setSelectedFields(updatedSelection);
};

const handleRoundChange = (event, fieldId) => {
handleSelectField(fieldId, event.target.value);
};

const handleCheckboxChange = (event, fieldId) => {
if (event.target.checked) {
handleSelectField(fieldId, 1); // Default to round 1 if not specified
} else {
setSelectedFields(selectedFields.filter((field) => field.id !== fieldId));
}
};

export const FieldsToUpdate: React.FC<FieldsToUpdateProps> = ({
values,
setFieldValue,
}) => {
return (
<TableContainer component={Paper}>
<Table>
<TableHead>
<TableRow>
<TableCell>Select</TableCell>
<TableCell>Field</TableCell>
<TableCell>Round Number</TableCell>
</TableRow>
</TableHead>
<TableBody>
{initialFields.map((field) => (
<TableRow key={field.id}>
<TableCell>
<Checkbox
checked={selectedFields.some(
(selectedField) => selectedField.id === field.id,
)}
onChange={(event) => handleCheckboxChange(event, field.id)}
/>
</TableCell>
<TableCell>{field.name}</TableCell>
<TableCell>
<Select
value={
selectedFields.find(
(selectedField) => selectedField.id === field.id,
)?.roundNumber || ''
}
onChange={(event) => handleRoundChange(event, field.id)}
displayEmpty
>
<MenuItem value="" disabled>
Select Round
</MenuItem>
{[...Array(10).keys()].map((num) => (
<MenuItem key={num + 1} value={num + 1}>
{num + 1}
</MenuItem>
))}
</Select>
</TableCell>
</TableRow>
))}
</TableBody>
</Table>
</TableContainer>
<FieldArray
name="selectedFields"
render={(arrayHelpers) => (
<TableContainer component={Box}>
<Table>
<TableHead>
<TableRow>
<TableCell>Select</TableCell>
<TableCell>Field</TableCell>
<TableCell>Round Number</TableCell>
</TableRow>
</TableHead>
<TableBody>
{initialFields.map((field) => (
<TableRow key={field.id}>
<TableCell>
<Checkbox
checked={values.selectedFields.some(
(selectedField) => selectedField.id === field.id,
)}
onChange={(event) => {
const selectedIndex = values.selectedFields.findIndex(
(selectedField) => selectedField.id === field.id,
);
if (event.target.checked) {
arrayHelpers.push({
id: field.id,
roundNumber: 1, // Default round number when first selected
});
} else if (selectedIndex > -1) {
arrayHelpers.remove(selectedIndex);
}
}}
/>
</TableCell>
<TableCell>{field.name}</TableCell>
<TableCell>
<Select
value={
values.selectedFields.find(
(selectedField) => selectedField.id === field.id,
)?.roundNumber || ''
}
onChange={(event) => {
const selectedIndex = values.selectedFields.findIndex(
(selectedField) => selectedField.id === field.id,
);
setFieldValue(
`selectedFields[${selectedIndex}].roundNumber`,
event.target.value,
);
}}
displayEmpty
>
<MenuItem value="" disabled>
Select Round
</MenuItem>
{[...Array(10).keys()].map((num) => (
<MenuItem key={num + 1} value={num + 1}>
{num + 1}
</MenuItem>
))}
</Select>
</TableCell>
</TableRow>
))}
</TableBody>
</Table>
</TableContainer>
)}
/>
);
};
Loading

0 comments on commit 5fa5ee2

Please sign in to comment.