Skip to content

Commit

Permalink
CM-458: add detailed view of deduplication task
Browse files Browse the repository at this point in the history
  • Loading branch information
Jan committed Jan 29, 2024
1 parent 6ed5754 commit ec10865
Show file tree
Hide file tree
Showing 3 changed files with 233 additions and 0 deletions.
158 changes: 158 additions & 0 deletions src/components/BeneficiaryDuplicatesTable.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,158 @@
/* eslint-disable react/no-array-index-key */
import React, { useState, useEffect } from 'react';
import {
makeStyles, Table, TableBody, TableCell, TableContainer, TableHead, TableRow, Checkbox,
} from '@material-ui/core';
import {
FormattedMessage,
} from '@openimis/fe-core';

const useStyles = makeStyles((theme) => ({
paper: theme.paper.paper,
table: theme.table,
tableTitle: theme.table.title,
tableHeader: theme.table.header,
tableRow: theme.table.row,
title: theme.paper.title,
tableContainer: {
overflow: 'auto',
},
hoverableCell: {
'&:hover': {
backgroundColor: '#f0f0f0',
},
cursor: 'pointer',
},
selectedCell: {
backgroundColor: '#a1caf1',
},
checkboxCell: {
textAlign: 'center',
},
deactivatedRow: {
opacity: 0.5,
},
}));

function BeneficiaryDuplicatesTable({
headers, rows, setAdditionalData, beneficiaryUuids,
}) {
const classes = useStyles();
const [selectedCells, setSelectedCells] = useState([]);
const [selectedRow, setSelectedRow] = useState(null);

useEffect(() => {
const additionalData = (
{ values: selectedCells.map((cell) => ({ [cell.header]: cell.value })), beneficiaryIds: beneficiaryUuids }
);
// eslint-disable-next-line max-len
const additionalDataString = `{\\"values\\": ${JSON.stringify(additionalData.values).replace(/"/g, '\\"')},\\"beneficiaryIds\\": ${JSON.stringify(additionalData.beneficiaryIds).replace(/"/g, '\\"')}}`;
setAdditionalData(additionalDataString);
}, [selectedCells]);
const isCellSelected = (rowIndex, header) => selectedCells.some(
(cell) => cell.rowIndex === rowIndex && cell.header === header,
);

const clearCellSelection = (rowIndex, header) => {
const restCells = selectedCells.filter((cell) => !(cell.rowIndex === rowIndex && cell.header === header));
setSelectedCells(restCells);
};

const clearRowSelection = (rowIndex) => {
const restCells = selectedCells.filter((cell) => !(cell.rowIndex === rowIndex));
setSelectedCells(restCells);
};

const clearAllCellSelection = () => {
setSelectedCells([]);
};

const checkIfEveryCellInOneRow = (rowIndex) => selectedCells.every((cell) => cell.rowIndex === rowIndex);

const handleCellClick = (rowIndex, header, value) => {
if (header === 'individual') {
return;
}

const isCellSelectedInColumn = selectedCells.some((cell) => cell.header === header);
const isCellClicked = isCellSelected(rowIndex, header);

if (isCellClicked) {
clearCellSelection(rowIndex, header);
return;
}

if (isCellSelectedInColumn) {
const updatedSelectedCells = selectedCells.filter((cell) => cell.header !== header);
setSelectedCells(updatedSelectedCells);
}

setSelectedCells((prevSelectedCells) => [...prevSelectedCells, { rowIndex, header, value }]);

if (!checkIfEveryCellInOneRow(rowIndex)) {
setSelectedRow(null);
}
};

const handleCheckboxChange = (rowIndex) => {
if (selectedRow === rowIndex) {
clearRowSelection(rowIndex);
setSelectedRow(null);
} else {
clearAllCellSelection();
const selectedCells = headers
.filter((header) => header !== 'individual')
.map((header) => ({ rowIndex, header, value: rows[rowIndex][header] }));
setSelectedCells(selectedCells);
setSelectedRow(rowIndex);
}
};

return (
<div className={classes.tableContainer}>
<TableContainer className={classes.paper}>
<Table size="small" className={classes.table} aria-label="dynamic table">
<TableHead className={classes.header}>
<TableRow className={classes.header}>
<TableCell key="checkbox-header" className={classes.checkboxCell}>
<FormattedMessage module="deduplication" id="BeneficiaryDuplicatesTable.checkbox.header" />
</TableCell>
{headers.map((header, index) => (
<TableCell key={index}>{header}</TableCell>
))}
</TableRow>
</TableHead>
<TableBody>
{rows.map((row, rowIndex) => (
<TableRow
key={rowIndex}
className={classes.tableRow}
>
<TableCell key={`checkbox-cell-${rowIndex}`} className={classes.checkboxCell}>
<Checkbox
color="primary"
checked={rowIndex === selectedRow}
onChange={() => handleCheckboxChange(rowIndex)}
/>
</TableCell>
{headers.map((header, headerIndex) => (
<TableCell
key={headerIndex}
className={`${isCellSelected(rowIndex, header) ? classes.selectedCell : ''} ${
!isCellSelected(rowIndex, header) && header !== 'individual' ? classes.hoverableCell : ''
} ${header === 'individual' ? classes.tableDisabledCell : ''}`}
onClick={() => handleCellClick(rowIndex, header, row[header])}
>
{row[header]}
</TableCell>
))}
</TableRow>
))}
</TableBody>
</Table>
</TableContainer>
</div>
);
}

export default BeneficiaryDuplicatesTable;
69 changes: 69 additions & 0 deletions src/components/tasks/DeduplicationResolutionTask.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
import React from 'react';
import { Typography, makeStyles } from '@material-ui/core';
import BeneficiaryDuplicatesTable from '../BeneficiaryDuplicatesTable';

const useStyles = makeStyles((theme) => ({
paper: theme.paper.paper,
title: theme.paper.title,
}));

function BeneficiaryDeduplicationTaskDisplay({
businessData, setAdditionalData,
}) {
const classes = useStyles();
const beneficiaryUuids = (businessData?.ids || []).map((id) => id.uuid);
const beneficiaries = (businessData?.ids || []).map((id) => {
// eslint-disable-next-line camelcase
const { individual, json_ext, ...rest } = id;
return {
...rest,
...individual,
// eslint-disable-next-line camelcase
...json_ext,
individual: individual.uuid,
};
});

const headers = businessData?.headers || [];
const individualIndex = headers.indexOf('individual');

if (individualIndex !== -1) {
headers.splice(individualIndex, 1);
headers.unshift('individual');
}

return (
<div>
<Typography className={classes.title} style={{ textAlign: 'center' }}>
{JSON.stringify(businessData?.column_values)}
{' '}
,
count:
{' '}
{businessData?.count}
</Typography>
<div>
<BeneficiaryDuplicatesTable
headers={headers}
rows={beneficiaries}
setAdditionalData={setAdditionalData}
beneficiaryUuids={beneficiaryUuids}
/>

</div>
</div>
);
}

const DeduplicationResolutionTaskTableHeaders = () => [];

const DeduplicationResolutionItemFormatters = () => [
(businessData, jsonExt, formatterIndex, setAdditionalData) => (
<BeneficiaryDeduplicationTaskDisplay
businessData={businessData}
setAdditionalData={setAdditionalData}
/>
),
];

export { DeduplicationResolutionTaskTableHeaders, DeduplicationResolutionItemFormatters };
6 changes: 6 additions & 0 deletions src/translations/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,11 @@
"deduplication.deduplicate.button.createDeduplicationReviewTask": "Create Deduplication Review Tasks",
"deduplication.deduplicationSummaryTable.group": "Group",
"deduplication.deduplicationSummaryTable.duplicates": "Duplicates",
<<<<<<< Updated upstream
"deduplication.deduplicate.mutation.createTasks": "Deduplication tasks have been created."
=======
"deduplication.tasks.deduplication.title": "Benefit Plan Deduplication Task",
"deduplication.deduplicate.mutation.createTasks": "Deduplication tasks have been created.",
"deduplication.BeneficiaryDuplicatesTable.checkbox.header": "Select all columns"
>>>>>>> Stashed changes
}

0 comments on commit ec10865

Please sign in to comment.