Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 6 additions & 2 deletions apps/platform/src/pages/CredibleSetPage/ProfileHeader.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import { Box, Typography } from "@mui/material";
import CREDIBLE_SET_PROFILE_HEADER_FRAGMENT from "./ProfileHeader.gql";
import { epmcUrl, getSortedAncestries } from "@ot/utils";
import { credsetConfidenceMap, populationMap } from "@ot/constants";
import StudyPublication from "ui/src/components/StudyPublication";

function ProfileHeader() {
const { loading, error, data } = usePlatformApi();
Expand Down Expand Up @@ -248,8 +249,11 @@ function ProfileHeader() {
)}
{study?.publicationFirstAuthor && (
<Field loading={loading} title="Publication">
{study?.publicationFirstAuthor} <i>et al.</i> {study?.publicationJournal} (
{study?.publicationDate?.slice(0, 4)})
<StudyPublication
publicationFirstAuthor={study.publicationFirstAuthor}
publicationDate={study.publicationDate}
publicationJournal={study.publicationJournal}
/>
</Field>
)}
{study?.pubmedId && (
Expand Down
1 change: 0 additions & 1 deletion apps/platform/src/pages/SearchPage/SearchContainer.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -229,7 +229,6 @@ function SearchContainer({ q, page, entities, data, onPageChange, onSetEntity })
md={6}
sx={{
display: "flex",
alignItems: "center",
justifyContent: "center",
}}
>
Expand Down
13 changes: 6 additions & 7 deletions apps/platform/src/pages/SearchPage/StudyResult.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { faChartBar } from "@fortawesome/free-solid-svg-icons";
import { Highlights, Link } from "ui";
import { Box, Typography } from "@mui/material";
import { getStudyItemMetaData } from "@ot/utils";
import StudyPublication from "ui/src/components/StudyPublication";

const useStyles = makeStyles(theme => ({
container: {
Expand All @@ -20,7 +21,6 @@ const useStyles = makeStyles(theme => ({

function StudyResult({ data, highlights }) {
const classes = useStyles();
const theme = useTheme();

return (
<div className={classes.container}>
Expand All @@ -42,12 +42,11 @@ function StudyResult({ data, highlights }) {
<Box sx={{ display: "flex", flexDirection: "row", gap: 1 }}>
<div>
{" "}
{data.publicationFirstAuthor && (
<>
{data.publicationFirstAuthor} <i>et al.</i> {data.publicationJournal} (
{data.publicationDate?.slice(0, 4)})
</>
)}
<StudyPublication
publicationFirstAuthor={data.publicationFirstAuthor}
publicationDate={data.publicationDate}
publicationJournal={data.publicationJournal}
/>
</div>
</Box>
<div>
Expand Down
8 changes: 6 additions & 2 deletions apps/platform/src/pages/StudyPage/StudyProfileHeader.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import { populationMap } from "@ot/constants";
import { getSortedAncestries, getStudyTypeDisplay } from "@ot/utils";

import STUDY_PROFILE_HEADER_FRAGMENT from "./StudyProfileHeader.gql";
import StudyPublication from "ui/src/components/StudyPublication";

function ProfileHeader() {
const { loading, error, data } = usePlatformApi();
Expand Down Expand Up @@ -106,8 +107,11 @@ function ProfileHeader() {
)}
{publicationFirstAuthor && (
<Field loading={loading} title="Publication">
{publicationFirstAuthor} <i>et al.</i> {publicationJournal} (
{publicationDate?.slice(0, 4)})
<StudyPublication
publicationFirstAuthor={publicationFirstAuthor}
publicationDate={publicationDate}
publicationJournal={publicationJournal}
/>
</Field>
)}
{pubmedId && (
Expand Down
12 changes: 6 additions & 6 deletions packages/ui/src/components/GlobalSearch/GlobalSearchListItem.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { faXmark, faClockRotateLeft, faArrowTrendUp } from "@fortawesome/free-so
import { clearRecentItem } from "./utils/searchUtils";
import DisplayVariantId from "../DisplayVariantId";
import { getStudyItemMetaData } from "@ot/utils";
import StudyPublication from "../StudyPublication";

const ListItem = styled("li")(({ theme }) => ({
cursor: "pointer",
Expand Down Expand Up @@ -215,12 +216,11 @@ function TopHitListItem({ item, onItemClick }) {
<Typography variant="subtitle1">
{item.symbol && item.name}

{item.publicationFirstAuthor && (
<>
{item.publicationFirstAuthor} <i>et al.</i> {item.publicationJournal} (
{item.publicationDate?.slice(0, 4)})
</>
)}
<StudyPublication
publicationFirstAuthor={item.publicationFirstAuthor}
publicationDate={item.publicationDate}
publicationJournal={item.publicationJournal}
/>
</Typography>
</Box>
<JustifyBetween>
Expand Down
10 changes: 2 additions & 8 deletions packages/ui/src/components/Navigate.tsx
Original file line number Diff line number Diff line change
@@ -1,21 +1,15 @@
import { Box } from "@mui/material";
import Link from "./Link";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import {
faArrowRight,
faArrowRightToBracket,
faCaretRight,
faChevronRight,
faArrowUpRightFromSquare,
} from "@fortawesome/free-solid-svg-icons";
import { faArrowRightToBracket } from "@fortawesome/free-solid-svg-icons";

type NavigateProps = {
to: string;
};

export default function Navigate({ to }: NavigateProps) {
return (
<Link to={to}>
<Link asyncTooltip to={to}>
<Box display="flex" justifyContent="center" alignItems="center" gap={1}>
View
<FontAwesomeIcon size="sm" icon={faArrowRightToBracket} />
Expand Down
59 changes: 29 additions & 30 deletions packages/ui/src/components/OtAsyncTooltip/OtAsyncTooltip.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,15 @@ import {
TooltipProps,
} from "@mui/material";
import { useLazyQuery } from "@apollo/client";
import { getEntityIcon, getEntityQuery, getQueryVariables } from "./utils/asyncTooltipUtil";
import {
getEntityDescription,
getEntityIcon,
getEntityQuery,
getQueryVariables,
} from "./utils/asyncTooltipUtil";
import { naLabel } from "@ot/constants";

import { getStudyItemMetaData } from "@ot/utils";
import StudyPublication from "../StudyPublication";

const DELAY_REQUEST = 1000;

Expand Down Expand Up @@ -56,8 +61,10 @@ function OtAsyncTooltip({ children, entity, id }: OtAsyncTooltipProps): ReactEle
});

function getTooltipContent() {
let entityAccessor = entity;
if (loading || !data) return <AsyncTooltipLoadingView />;
return <AsyncTooltipDataView entity={entity} data={data?.[entity]} />;
if (entity === "credible-set") entityAccessor = "credibleSet";
return <AsyncTooltipDataView entity={entity} data={data?.[entityAccessor]} />;
}

function abortApiCall() {
Expand Down Expand Up @@ -119,41 +126,33 @@ function AsyncTooltipDataView({
entity: string;
data: Record<string, unknown>;
}): ReactElement {
function getLabel() {
return data?.name || data?.id || naLabel;
}

function getDescription() {
let descText = "";

if (Array.isArray(data.description) && data.description.length)
descText = data?.description[0].substring(0, 150);
else if (Array.isArray(data.description) && !data.description.length) descText = "";
else if (data.description) descText = data?.description.substring(0, 150);

// study subtext
descText += getStudyItemMetaData({
studyType: data?.studyType,
nSamples: data?.nSamples,
credibleSetsCount: data?.credibleSets?.credibleSetsCount,
});

if (!descText) return "No description available.";

return descText;
}
const showSubText = !!data?.mostSevereConsequence?.label || data?.publicationFirstAuthor;

function getSubtext() {
let finalSubText = "";
let finalSubText;

// variant subtext
const mostSevereConsequence = data?.mostSevereConsequence?.label;
if (mostSevereConsequence) finalSubText = `Most severe consequence: ${mostSevereConsequence}`;

if (mostSevereConsequence) finalSubText += `Most severe consequence: ${mostSevereConsequence}`;
// study subtext
const publicationData = data?.publicationFirstAuthor;
if (publicationData)
finalSubText = (
<StudyPublication
publicationDate={data?.publicationDate}
publicationFirstAuthor={data?.publicationFirstAuthor}
publicationJournal={data?.publicationJournal}
/>
);

return finalSubText;
}

const showSubText = !!data?.mostSevereConsequence?.label;
function getLabel() {
if (entity === "credible-set") return "Credible set";
return data?.name || data?.id || naLabel;
}

return (
<Box sx={{ p: 1 }}>
Expand Down Expand Up @@ -184,7 +183,7 @@ function AsyncTooltipDataView({
{getLabel()}
</Box>{" "}
<Box sx={{ typography: "body2", color: theme => theme.palette.grey[800] }}>
{getDescription()}
{getEntityDescription(entity, data)}
</Box>
</Box>
</Box>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
query CredibleSetsTooltipQuery($studyLocusId: String!) {
credibleSet(studyLocusId: $studyLocusId) {
id: studyLocusId
variant {
id
}
study {
id
studyType
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,8 @@ query StudyTooltipQuery($studyId: String!) {
credibleSets {
credibleSetsCount: count
}
publicationFirstAuthor
publicationDate
publicationJournal
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,17 @@ import DISEASE_TOOLTIP_QUERY from "../queries/DiseaseTooltipQuery.gql";
import STUDY_TOOLTIP_QUERY from "../queries/StudyTooltipQuery.gql";
import TARGET_TOOLTIP_QUERY from "../queries/TargetTooltipQuery.gql";
import VARIANT_TOOLTIP_QUERY from "../queries/VariantTooltipQuery.gql";
import CREDIBLE_SETS_TOOLTIP_QUERY from "../queries/CredibleSetsTooltipQuery.gql";
import {
faChartBar,
faDiagramProject,
faDna,
faMapPin,
faPrescriptionBottleAlt,
faStethoscope,
faTag,
} from "@fortawesome/free-solid-svg-icons";
import { getStudyItemMetaData } from "@ot/utils";

export function getQueryVariables(entity: string, id: string): Record<string, string> {
switch (entity) {
Expand All @@ -24,6 +27,8 @@ export function getQueryVariables(entity: string, id: string): Record<string, st
return { variantId: id };
case "study":
return { studyId: id };
case "credible-set":
return { studyLocusId: id };
default:
return { id };
}
Expand All @@ -41,6 +46,8 @@ export const getEntityQuery = (entity: string) => {
return TARGET_TOOLTIP_QUERY;
case "variant":
return VARIANT_TOOLTIP_QUERY;
case "credible-set":
return CREDIBLE_SETS_TOOLTIP_QUERY;
default:
return;
}
Expand All @@ -58,7 +65,48 @@ export const getEntityIcon = (entity: string) => {
return faDna;
case "variant":
return faMapPin;
case "credible-set":
return faDiagramProject;
default:
return faTag;
}
};

export const getEntityDescription = (entity, data) => {
switch (entity) {
case "drug":
return getTrimmedDescription(data?.description);
case "disease":
return getTrimmedDescription(data?.description);
case "study":
return getStudyItemMetaData({
studyType: data?.studyType,
nSamples: data?.nSamples,
credibleSetsCount: data?.credibleSets?.credibleSetsCount,
});
case "target":
return getTrimmedDescription(data?.description[0] || "");
case "variant":
return getTrimmedDescription(data?.description);
case "credible-set":
return getCredibleSetsDescription({
variantId: data?.variant.id,
studyId: data?.study.id,
});
default:
return "No description available.";
}
};

const getTrimmedDescription = (description: string | null) => {
if (!description || description.length < 1) return "No description available.";
return description.substring(0, 150);
};

export const getCredibleSetsDescription = ({ variantId, studyId }): string => {
let metaData = "";
if (variantId) metaData += `Lead Variant: ${variantId}`;
if (studyId) metaData += ` • Study ID: ${studyId}`;

return metaData;
};
26 changes: 26 additions & 0 deletions packages/ui/src/components/StudyPublication.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { ReactNode } from "react";

type StudyPublicationProps = {
publicationFirstAuthor: string;
publicationJournal: string;
publicationDate: string;
};

function StudyPublication({
publicationFirstAuthor,
publicationJournal,
publicationDate,
}: StudyPublicationProps): ReactNode {
if (!publicationFirstAuthor) return "";
return (
<>
{publicationFirstAuthor && (
<>
{publicationFirstAuthor} <i>et al.</i> {publicationJournal} (
{publicationDate?.slice(0, 4)})
</>
)}
</>
);
}
export default StudyPublication;