diff --git a/apps/platform/src/pages/CredibleSetPage/ProfileHeader.tsx b/apps/platform/src/pages/CredibleSetPage/ProfileHeader.tsx
index ad4091c35..f92061eaf 100644
--- a/apps/platform/src/pages/CredibleSetPage/ProfileHeader.tsx
+++ b/apps/platform/src/pages/CredibleSetPage/ProfileHeader.tsx
@@ -12,6 +12,7 @@ import {
DetailPopover,
SummaryStatsTable,
DisplaySampleSize,
+ StudyPublication,
} from "ui";
import { Box, Typography } from "@mui/material";
import CREDIBLE_SET_PROFILE_HEADER_FRAGMENT from "./ProfileHeader.gql";
@@ -248,8 +249,11 @@ function ProfileHeader() {
)}
{study?.publicationFirstAuthor && (
- {study?.publicationFirstAuthor} et al. {study?.publicationJournal} (
- {study?.publicationDate?.slice(0, 4)})
+
)}
{study?.pubmedId && (
diff --git a/apps/platform/src/pages/SearchPage/SearchContainer.jsx b/apps/platform/src/pages/SearchPage/SearchContainer.jsx
index 45320f937..3fae24531 100644
--- a/apps/platform/src/pages/SearchPage/SearchContainer.jsx
+++ b/apps/platform/src/pages/SearchPage/SearchContainer.jsx
@@ -229,7 +229,6 @@ function SearchContainer({ q, page, entities, data, onPageChange, onSetEntity })
md={6}
sx={{
display: "flex",
- alignItems: "center",
justifyContent: "center",
}}
>
diff --git a/apps/platform/src/pages/SearchPage/StudyResult.jsx b/apps/platform/src/pages/SearchPage/StudyResult.jsx
index 71e88c722..dbb0d8782 100644
--- a/apps/platform/src/pages/SearchPage/StudyResult.jsx
+++ b/apps/platform/src/pages/SearchPage/StudyResult.jsx
@@ -1,7 +1,7 @@
-import { makeStyles, useTheme } from "@mui/styles";
+import { makeStyles } from "@mui/styles";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { faChartBar } from "@fortawesome/free-solid-svg-icons";
-import { Highlights, Link } from "ui";
+import { Highlights, Link, StudyPublication } from "ui";
import { Box, Typography } from "@mui/material";
import { getStudyItemMetaData } from "@ot/utils";
@@ -20,7 +20,6 @@ const useStyles = makeStyles(theme => ({
function StudyResult({ data, highlights }) {
const classes = useStyles();
- const theme = useTheme();
return (
@@ -42,12 +41,11 @@ function StudyResult({ data, highlights }) {
{" "}
- {data.publicationFirstAuthor && (
- <>
- {data.publicationFirstAuthor} et al. {data.publicationJournal} (
- {data.publicationDate?.slice(0, 4)})
- >
- )}
+
diff --git a/apps/platform/src/pages/StudyPage/StudyProfileHeader.tsx b/apps/platform/src/pages/StudyPage/StudyProfileHeader.tsx
index a55679b1a..4968036c6 100644
--- a/apps/platform/src/pages/StudyPage/StudyProfileHeader.tsx
+++ b/apps/platform/src/pages/StudyPage/StudyProfileHeader.tsx
@@ -9,6 +9,7 @@ import {
LabelChip,
DisplaySampleSize,
PublicationsDrawer,
+ StudyPublication,
} from "ui";
import { Box } from "@mui/material";
import { populationMap } from "@ot/constants";
@@ -106,8 +107,11 @@ function ProfileHeader() {
)}
{publicationFirstAuthor && (
- {publicationFirstAuthor} et al. {publicationJournal} (
- {publicationDate?.slice(0, 4)})
+
)}
{pubmedId && (
diff --git a/packages/ui/src/components/GlobalSearch/GlobalSearchListItem.jsx b/packages/ui/src/components/GlobalSearch/GlobalSearchListItem.jsx
index f30091d29..ea33ac4e1 100644
--- a/packages/ui/src/components/GlobalSearch/GlobalSearchListItem.jsx
+++ b/packages/ui/src/components/GlobalSearch/GlobalSearchListItem.jsx
@@ -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",
@@ -215,12 +216,11 @@ function TopHitListItem({ item, onItemClick }) {
{item.symbol && item.name}
- {item.publicationFirstAuthor && (
- <>
- {item.publicationFirstAuthor} et al. {item.publicationJournal} (
- {item.publicationDate?.slice(0, 4)})
- >
- )}
+
diff --git a/packages/ui/src/components/Navigate.tsx b/packages/ui/src/components/Navigate.tsx
index d4df3b0c6..3aea1e300 100644
--- a/packages/ui/src/components/Navigate.tsx
+++ b/packages/ui/src/components/Navigate.tsx
@@ -1,13 +1,7 @@
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;
@@ -15,7 +9,7 @@ type NavigateProps = {
export default function Navigate({ to }: NavigateProps) {
return (
-
+
View
diff --git a/packages/ui/src/components/OtAsyncTooltip/OtAsyncTooltip.tsx b/packages/ui/src/components/OtAsyncTooltip/OtAsyncTooltip.tsx
index 0109dbb8a..d638ada4b 100644
--- a/packages/ui/src/components/OtAsyncTooltip/OtAsyncTooltip.tsx
+++ b/packages/ui/src/components/OtAsyncTooltip/OtAsyncTooltip.tsx
@@ -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;
@@ -56,8 +61,10 @@ function OtAsyncTooltip({ children, entity, id }: OtAsyncTooltipProps): ReactEle
});
function getTooltipContent() {
+ let entityAccessor = entity;
if (loading || !data) return ;
- return ;
+ if (entity === "credible-set") entityAccessor = "credibleSet";
+ return ;
}
function abortApiCall() {
@@ -119,41 +126,33 @@ function AsyncTooltipDataView({
entity: string;
data: Record;
}): 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 = (
+
+ );
return finalSubText;
}
- const showSubText = !!data?.mostSevereConsequence?.label;
+ function getLabel() {
+ if (entity === "credible-set") return "Credible set";
+ return data?.name || data?.id || naLabel;
+ }
return (
@@ -184,7 +183,7 @@ function AsyncTooltipDataView({
{getLabel()}
{" "}
theme.palette.grey[800] }}>
- {getDescription()}
+ {getEntityDescription(entity, data)}
diff --git a/packages/ui/src/components/OtAsyncTooltip/queries/CredibleSetsTooltipQuery.gql b/packages/ui/src/components/OtAsyncTooltip/queries/CredibleSetsTooltipQuery.gql
index e69de29bb..f3e7320c9 100644
--- a/packages/ui/src/components/OtAsyncTooltip/queries/CredibleSetsTooltipQuery.gql
+++ b/packages/ui/src/components/OtAsyncTooltip/queries/CredibleSetsTooltipQuery.gql
@@ -0,0 +1,12 @@
+query CredibleSetsTooltipQuery($studyLocusId: String!) {
+ credibleSet(studyLocusId: $studyLocusId) {
+ id: studyLocusId
+ variant {
+ id
+ }
+ study {
+ id
+ studyType
+ }
+ }
+}
diff --git a/packages/ui/src/components/OtAsyncTooltip/queries/StudyTooltipQuery.gql b/packages/ui/src/components/OtAsyncTooltip/queries/StudyTooltipQuery.gql
index 0090fb719..33036a8cb 100644
--- a/packages/ui/src/components/OtAsyncTooltip/queries/StudyTooltipQuery.gql
+++ b/packages/ui/src/components/OtAsyncTooltip/queries/StudyTooltipQuery.gql
@@ -7,5 +7,8 @@ query StudyTooltipQuery($studyId: String!) {
credibleSets {
credibleSetsCount: count
}
+ publicationFirstAuthor
+ publicationDate
+ publicationJournal
}
}
diff --git a/packages/ui/src/components/OtAsyncTooltip/utils/asyncTooltipUtil.ts b/packages/ui/src/components/OtAsyncTooltip/utils/asyncTooltipUtil.ts
index 89434102d..5df8064af 100644
--- a/packages/ui/src/components/OtAsyncTooltip/utils/asyncTooltipUtil.ts
+++ b/packages/ui/src/components/OtAsyncTooltip/utils/asyncTooltipUtil.ts
@@ -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 {
switch (entity) {
@@ -24,6 +27,8 @@ export function getQueryVariables(entity: string, id: string): Record {
return TARGET_TOOLTIP_QUERY;
case "variant":
return VARIANT_TOOLTIP_QUERY;
+ case "credible-set":
+ return CREDIBLE_SETS_TOOLTIP_QUERY;
default:
return;
}
@@ -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;
+};
diff --git a/packages/ui/src/components/StudyPublication.tsx b/packages/ui/src/components/StudyPublication.tsx
new file mode 100644
index 000000000..a53706ad5
--- /dev/null
+++ b/packages/ui/src/components/StudyPublication.tsx
@@ -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} et al. {publicationJournal} (
+ {publicationDate?.slice(0, 4)})
+ >
+ )}
+ >
+ );
+}
+export default StudyPublication;
diff --git a/packages/ui/src/index.tsx b/packages/ui/src/index.tsx
index f951563f4..25abf101a 100644
--- a/packages/ui/src/index.tsx
+++ b/packages/ui/src/index.tsx
@@ -48,6 +48,7 @@ export { default as OtScoreLinearBar } from "./components/OtScoreLinearBar";
export { default as OtTableSSP } from "./components/OtTable/OtTableSSP";
export { default as EntityPanel } from "./components/EntityPanel/EntityPanel";
export { default as Page } from "./pages/Page";
+export { default as StudyPublication } from "./components/StudyPublication";
export * as summaryUtils from "./components/Summary/utils";
export * from "./components/Footer";