Skip to content

Commit

Permalink
Merge pull request #109 from PDCMFinder/dev
Browse files Browse the repository at this point in the history
Version 2.0
  • Loading branch information
ficolo authored Aug 22, 2022
2 parents 83b5044 + 20ae55f commit 55e3fb9
Show file tree
Hide file tree
Showing 20 changed files with 695 additions and 227 deletions.
2 changes: 0 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@
"@types/react": "^17.0.38",
"@types/react-bootstrap-typeahead": "^5.1.5",
"@types/react-dom": "^17.0.0",
"@yaireo/tagify": "^4.3.1",
"bootstrap": "5.1.3",
"dagre": "^0.8.5",
"node-sass": "^6.0.0",
Expand Down Expand Up @@ -95,7 +94,6 @@
"@types/react-router": "^5.1.17",
"@types/react-router-dom": "^5.3.2",
"@types/storybook-react-router": "^1.0.1",
"@types/yaireo__tagify": "^4.3.0",
"css-loader": "^5.2.5",
"fetch-mock": "^9.11.0",
"mini-css-extract-plugin": "^1.6.0",
Expand Down
Binary file not shown.
62 changes: 49 additions & 13 deletions src/apis/Details.api.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { IEngraftment } from "../components/details/ModelEngraftmentTable";
import { IMolecularCharacterization } from "../components/details/MolecularDataTable";
import { Treatment } from "../models/PDCModel.model";
import { Publication, Treatment } from "../models/PDCModel.model";
import { camelCase } from "./Utils.api";

export interface IModelExtLinks {
Expand All @@ -21,6 +21,44 @@ export async function getModelDetailsMetadata(
return response.json().then((d) => camelCase(d[0]));
}

export async function getModelPubmedIds(pdcmModelId: string): Promise<any> {
if (!pdcmModelId) {
return [];
}
let response = await fetch(
`${process.env.REACT_APP_API_URL}/model_information?id=eq.${pdcmModelId}&select=publication_group(pubmed_ids)`
);
if (!response.ok) {
throw new Error("Network response was not ok");
}

const jsonContent = await response.json();

const publicationGroup = jsonContent[0]["publication_group"] || {};

const pubmedIds: string = publicationGroup["pubmed_ids"] || "";
return pubmedIds.replaceAll(" ", "").split(",");
}

export async function getPublicationData(
pubmedId: string
): Promise<Publication> {
let response = await fetch(
`https://www.ebi.ac.uk/europepmc/webservices/rest/article/MED/${pubmedId.replace(
"PMID:",
""
)}?resultType=lite&format=json`
);
if (!response.ok) {
throw new Error("Network response was not ok");
}
return response.json().then((d) => {
console.log(d);

return camelCase(d["result"]);
});
}

export async function getModelExtLinks(
pdcmModelId: string,
modelId: string
Expand Down Expand Up @@ -227,19 +265,17 @@ export async function getPatientTreatment(
if (!response.ok) {
throw new Error("Network response was not ok");
}
return response.json().then((d) => {
return d.flatMap((item: any) => {
return response.json().then((d) =>
d.map((item: any) => {
const itemCamelCase: any = camelCase(item);

return itemCamelCase.treatment.split(" And ").map((name: string) => {
return {
treatmentName: name,
treatmentDose: itemCamelCase.dose,
treatmentResponse: itemCamelCase.response,
};
});
});
});
let treatment: Treatment = {
treatmentName: itemCamelCase.treatment.replaceAll(" And ", ", "),
treatmentDose: itemCamelCase.dose,
treatmentResponse: itemCamelCase.response,
};
return treatment;
})
);
}

export async function getModelDrugDosing(
Expand Down
2 changes: 1 addition & 1 deletion src/apis/Search.api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,7 @@ export async function getSearchResults(
let response = await fetch(
`${API_URL}/search_index?${query}&limit=${pageSize}&offset=${
(page - 1) * pageSize
}&select=patient_age,patient_sex,external_model_id,model_type,data_source,histology,primary_site,collection_site,tumour_type,dataset_available&order=external_model_id.asc`,
}&select=patient_age,patient_sex,external_model_id,model_type,data_source,histology,primary_site,collection_site,tumour_type,dataset_available&order=model_dataset_type_count.desc.nullslast`,
{ headers: { Prefer: "count=exact" } }
);
if (!response.ok) {
Expand Down
4 changes: 4 additions & 0 deletions src/apis/Utils.api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,7 @@ export function camelCase(obj: any) {
}
return newObj;
}

export function capitalizeFirstLetter(text: string) {
return text ? text.charAt(0).toUpperCase() + text.slice(1) : "";
}
16 changes: 16 additions & 0 deletions src/components/details/AnchorLink.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { FC } from "react";

export const AnchorLink: FC<{disabled: boolean, label: string, href?: string}> = ({ disabled, label, href}) => {
return <li className="py-3">
<a
href={href}
className={
disabled
? "disabled text-muted text-decoration-none"
: ""
}
>
{label}
</a>
</li>
}
20 changes: 20 additions & 0 deletions src/components/details/MetadataItem.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { FunctionComponent } from "react";

export interface MetadataItemProps {
value: string;
label: string;
}

export const MetadataItem: FunctionComponent<MetadataItemProps> = ({
value,
label,
}) => {
return (
<>
<dt style={{ fontWeight: "400" }} className="text-capitalize">
{value || "N/A"}
</dt>
<dl className="text-muted fw-lighter">{label}</dl>
</>
);
};
1 change: 1 addition & 0 deletions src/components/details/PatientMetadata.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ export interface IPatientMetadataProps {
cancerStage: string;
cancerStagingSystem: string;
collectionSite: string;
primarySite: string;
}

export const PatientMetadata: FunctionComponent<IPatientMetadataProps> = ({
Expand Down
43 changes: 43 additions & 0 deletions src/components/details/PublicationTable.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import React, { FunctionComponent } from "react";
import { Card, ListGroup, ListGroupItem, Table } from "react-bootstrap";
import { Publication, Treatment } from "../../models/PDCModel.model";

export interface IPublicationsTableProps {
publications: Array<Publication>;
}

export const PublicationTable: FunctionComponent<IPublicationsTableProps> = ({
publications,
}) => {
return (
<>
{publications.map((publication: Publication) => (
<Card className="my-4">
<Card.Body>
<Card.Title>{publication.title}</Card.Title>
<Card.Subtitle className="mb-2 text-muted">
{publication.authorString}
</Card.Subtitle>
<Card.Text>
{publication.journalTitle} - {publication.pubYear}
</Card.Text>
<Card.Link
href={`https://europepmc.org/article/MED/${publication.pmid}`}
target="_blank"
rel="noreferrer"
>
View at EuropePMC
</Card.Link>
<Card.Link
href={`https://doi.org/${publication.doi}`}
target="_blank"
rel="noreferrer"
>
DOI:{publication.doi}
</Card.Link>
</Card.Body>
</Card>
))}
</>
);
};
116 changes: 116 additions & 0 deletions src/components/details/TableOfContent.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
import {
faEnvelope,
faExternalLinkAlt,
} from "@fortawesome/free-solid-svg-icons";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { FC } from "react";
import { Button } from "react-bootstrap";
import { IDetailsTemplateProps } from "../../templates/DetailsTemplate";

export const TableOfContent: FC<IDetailsTemplateProps> = ({
modelType,
engraftments,
qualityChecks,
molecularCharacterizations,
dosingStudies,
patientTreatments,
contactLink,
sourceDatabaseUrl,
providerId,
}) => {
return (
<>
<h6 className="text-muted my-4">Data available</h6>
<ul className="list-unstyled">
{modelType === "xenograft" ? (
<li className="py-3">
<a
href="#quality-control"
className={
engraftments.length > 0
? ""
: "disabled text-muted text-decoration-none"
}
>
PDX model engraftment
</a>
</li>
) : null}
<li className="py-3">
<a
href="#quality-control"
className={
qualityChecks.length > 0
? ""
: "disabled text-muted text-decoration-none"
}
>
Quality control
</a>
</li>
<li className="py-3">
<a
href="#molecular-data"
className={
molecularCharacterizations.length > 0
? ""
: "disabled text-muted text-decoration-none"
}
>
Molecular data
</a>
</li>
<li className="py-3">
<a
href="#dosing-studies"
className={
dosingStudies.length > 0
? ""
: "disabled text-muted text-decoration-none"
}
>
Dosing studies
</a>
</li>
<li className="py-3">
<a
href="#patient-treatment"
className={
patientTreatments.length > 0
? ""
: "disabled text-muted text-decoration-none"
}
>
Patient treatment
</a>
</li>
{/* <li className="py-3"><a href="#publications" className={qualityChecks.length > 0 ? "" : "disabled text-muted text-decoration-none"}>Publications</a></li> */}
<li className="py-3">
<Button
variant="outline-primary"
href={contactLink}
target="_blank"
className="w-100"
>
<FontAwesomeIcon icon={faEnvelope} />
&nbsp; Contact provider
</Button>
</li>

{sourceDatabaseUrl && (
<li className="py-3">
<Button
variant="outline-primary"
href={sourceDatabaseUrl}
target="_blank"
className="w-100"
>
<FontAwesomeIcon icon={faExternalLinkAlt} />
&nbsp; View data at {providerId}
</Button>
</li>
)}
</ul>
</>
);
};
Loading

0 comments on commit 55e3fb9

Please sign in to comment.