Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Migrate Patients page to using a direct Neo4j query #167

Open
wants to merge 8 commits into
base: master
Choose a base branch
from

Conversation

qu8n
Copy link
Collaborator

@qu8n qu8n commented Nov 1, 2024

For card #1292. This PR migrates the Patients page from OGM to using a direct Neo4j query, improving the performance of the page.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a new version of RecordsList.tsx that's adapted for the Patients page. Because of the new query method, there were several changes made to RecordsList.tsx for the Patients page, so I rewrote it in a new file to make the development process less hairy.

The alternative would have been updating RecordsList.tsx to work for both Patients page and the other pages (Requests & Cohorts), and the RecordsList component's props would end up quite long and confusing.

Meanwhile, you can still see a diff between these files here.

Below, I'm going to clarify only the logic that are new/different (not many), but happy to clarity existing codes as well if you'd like.

Comment on lines +148 to +154
const extraSearchVals = searchInterceptor
? await searchInterceptor(userSearchVal)
: [];
const searchVals = [
...parseUserSearchVal(userSearchVal),
...extraSearchVals,
];
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

searchInterceptor function is a new component prop that runs some logic before the standard search logic kicks in. For the Patients page, this function returns additional values to be searched by: patient IDs corresponding to the MRNs that are entered in the search bar.

Comment on lines +44 to +46
const MAX_ROWS_EXPORT = 10000;
const MAX_ROWS_EXPORT_EXCEED_ALERT =
"You can only download up to 5,000 rows of data at a time. Please refine your search and try again. If you need the full dataset, contact the SMILE team at [email protected].";
"You can only download up to 10,000 rows of data at a time. Please refine your search and try again. If you need the full dataset, contact the SMILE team at [email protected].";
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pavitra requested for this change 1-2 weeks ago (context). I made this quick change to the code running in prod but haven't officially commit-ed it until now.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Most code changes here are simple renames, either to make names more generic for reuse (like DashboardSampleSort to DashboardRecordSort) or follow better JS naming practices (like handleDownload to onDownload).

Comment on lines -22 to -27
// Mirror the field types in the CRDB, where CMO_ID is stored without the "C-" prefix
export type PatientIdsTriplet = {
CMO_ID: string;
PT_MRN: string;
DMP_ID: string | null;
};
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removed because we can pull this type directly from the file generated by the codegen process.

Comment on lines +114 to 143
async function getExtraCmoIdsFromMrnInputs(userSearchVal: string) {
let extraCmoIds: string[] = [];
if (phiEnabled && userSearchVal !== "") {
const parsedSearchVals = parseUserSearchVal(userSearchVal);

if (phiEnabled) {
parsedSearchVals = parsedSearchVals.map((query) =>
query.startsWith("C-") ? query.slice(2) : query
const patientIdsTriplets = await fetchPatientIdsTriplets(
parsedSearchVals
);
setPatientIdsTriplets(patientIdsTriplets);

const customSearchVals = await fetchPatientIdsTriplets(parsedSearchVals);

if (customSearchVals.length > 0) {
setParsedSearchVals(customSearchVals);
if (patientIdsTriplets.length > 0) {
patientIdsTriplets.forEach((triplet) => {
// Add back C- to CMO IDs because they are stored without it in the CRDB
const cmoIdWithCDash = addCDashToCMOId(triplet.CMO_ID);
if (
!parsedSearchVals.includes(cmoIdWithCDash) &&
!parsedSearchVals.includes(triplet.DMP_ID ?? "")
) {
extraCmoIds.push(cmoIdWithCDash);
}
});
} else if (userEmail) {
setAlertModal({
show: true,
...NO_PHI_SEARCH_RESULTS,
});

setParsedSearchVals([]);
}
} else {
setParsedSearchVals(parsedSearchVals);
}
return extraCmoIds;
}
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Renamed this function to be more descriptive. Its logic mostly remains the same. Both functions query the CRDB for the patient IDs corresponding to the MRN inputs.

However, the new function simply returns those patient IDs, whereas the old function triggers the search process as well. The old function used a bad React practice that involves using redundant states.

Comment on lines +158 to +164
if (phiEnabled) {
window.addEventListener("message", handleLogin);
if (!userEmail) openLoginPopup();
return () => {
window.removeEventListener("message", handleLogin);
};
}
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Only listen for the result of the login popup/modal if the "PHI-enabled" toggle is on. Helps us avoid adding listeners excessively and slowing down the page.

Comment on lines +174 to +181
{
field: "totalSampleCount",
headerName: "# Samples",
},
{
field: "cmoSampleIds",
headerName: "Sample IDs",
},
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I moved the "Sample IDs" column to the right-most side because I thought this looks more natural given how wide this column is. Also moved the "# Samples" next to it because they're both samples-related. Happy to move them back if you think otherwise.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Most code changes here are simple renames to follow better JS naming practices (like handleDownload to onDownload).

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Most code changes here are simple renames to follow better JS naming practices (like handleDownload to onDownload).

@qu8n qu8n marked this pull request as ready for review November 4, 2024 20:40
@qu8n qu8n requested a review from ao508 November 4, 2024 20:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant