Skip to content

Commit d5a1aed

Browse files
author
Jonah Paten
authored
feat: added bionetworks column and filter (#3342) (#4141)
* feat: added bionetworks column and filter (#3342) * feat: made suggested corrections to the bionetworks cell (#3342)
1 parent 8c3e797 commit d5a1aed

29 files changed

+201
-2
lines changed

explorer/app/apis/azul/hca-dcp/common/entities.ts

+3
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import { NetworkKey } from "app/components/Index/common/entities";
2+
13
/**
24
* Model of accession value in the response from index/projects API endpoints.
35
*/
@@ -82,6 +84,7 @@ export interface ProjectMatrixFileResponse {
8284
export interface ProjectResponse {
8385
accessible: boolean;
8486
accessions: AccessionResponse[];
87+
bionetworkName: (NetworkKey | null)[];
8588
contributedAnalyses: ProjectResponseContributedAnalyses;
8689
contributors: ContributorResponse[];
8790
estimatedCellCount: number | null;

explorer/app/components/Index/common/constants.ts

+45-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { AzulSummaryResponse } from "@databiosphere/findable-ui/lib/apis/azul/common/entities";
2-
import { METADATA_KEY, SUMMARY } from "./entities";
2+
import { METADATA_KEY, NetworkKey, SUMMARY } from "./entities";
33
import {
44
calculateSummaryFileFormatsCount,
55
calculateSummaryTotalCellCount,
@@ -9,6 +9,7 @@ import {
99
// Template constants
1010
const {
1111
ANATOMICAL_ENTITY,
12+
BIONETWORK_NAME,
1213
BIOSAMPLE_TYPE,
1314
CONSENT_CODE,
1415
CONTENT_DESCRIPTION,
@@ -71,11 +72,54 @@ export const BIND_SUMMARY_RESPONSE = {
7172
getSummaryCount(r, SUMMARY_KEY.SPECIMENS),
7273
};
7374

75+
export const NETWORK_KEYS = [
76+
"Adipose",
77+
"Breast",
78+
"Development",
79+
"Eye",
80+
"Genetic-diversity",
81+
"Gut",
82+
"Heart",
83+
"Immune",
84+
"Kidney",
85+
"Liver",
86+
"Lung",
87+
"Musculoskeletal",
88+
"Nervous-system",
89+
"Oral",
90+
"Organoid",
91+
"Pancreas",
92+
"Reproduction",
93+
"Skin",
94+
] as const;
95+
96+
export const NETWORK_ICONS: { [key in NetworkKey]: string } = {
97+
Adipose: "/images/icons/hca-bio-networks/adipose.png",
98+
Breast: "/images/icons/hca-bio-networks/breast.png",
99+
Development: "/images/icons/hca-bio-networks/development.png",
100+
Eye: "/images/icons/hca-bio-networks/eye.png",
101+
"Genetic-diversity": "/images/icons/hca-bio-networks/genetic-diversity.png",
102+
Gut: "/images/icons/hca-bio-networks/gut.png",
103+
Heart: "/images/icons/hca-bio-networks/heart.png",
104+
Immune: "/images/icons/hca-bio-networks/immune.png",
105+
Kidney: "/images/icons/hca-bio-networks/kidney.png",
106+
Liver: "/images/icons/hca-bio-networks/liver.png",
107+
Lung: "/images/icons/hca-bio-networks/lung.png",
108+
Musculoskeletal: "/images/icons/hca-bio-networks/musculoskeletal.png",
109+
"Nervous-system": "/images/icons/hca-bio-networks/nervous-system.png",
110+
Oral: "/images/icons/hca-bio-networks/oral-and-craniofacial.png",
111+
Organoid: "/images/icons/hca-bio-networks/organoid.png",
112+
Pancreas: "/images/icons/hca-bio-networks/pancreas.png",
113+
Reproduction: "/images/icons/hca-bio-networks/reproduction.png",
114+
Skin: "/images/icons/hca-bio-networks/skin.png",
115+
};
116+
74117
/**
75118
* Value for displaying pluralized metadata labels, for example, "tissues" or "diseases".
76119
*/
77120
export const PLURALIZED_METADATA_LABEL = {
78121
[ANATOMICAL_ENTITY]: "anatomical entities",
122+
[BIONETWORK_NAME]: "networks",
79123
[BIOSAMPLE_TYPE]: "biosample types",
80124
[CONSENT_CODE]: "consent codes",
81125
[CONTENT_DESCRIPTION]: "content descriptions",

explorer/app/components/Index/common/entities.ts

+5
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,11 @@
1+
import { NETWORK_KEYS } from "./constants";
2+
13
/**
24
* Set of possible metadata keys.
35
*/
46
export enum METADATA_KEY {
57
ANATOMICAL_ENTITY = "ANATOMICAL_ENTITY",
8+
BIONETWORK_NAME = "BIONETWORK_NAME",
69
BIOSAMPLE_TYPE = "BIOSAMPLE_TYPE",
710
CONSENT_CODE = "CONSENT_CODE",
811
CONTENT_DESCRIPTION = "CONTENT_DESCRIPTION",
@@ -39,6 +42,8 @@ export enum METADATA_KEY {
3942
WORKSPACE_NAME = "WORKSPACE_NAME",
4043
}
4144

45+
export type NetworkKey = (typeof NETWORK_KEYS)[number];
46+
4247
/**
4348
* Set of possible summary counts and other summary values as part of summary response.
4449
*/
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
import styled from "@emotion/styled";
2+
import { Typography } from "@mui/material";
3+
4+
export const Cell = styled.div`
5+
align-content: center;
6+
display: grid;
7+
gap: 8px;
8+
`;
9+
10+
export const Network = styled(Typography)`
11+
align-items: center;
12+
display: grid;
13+
gap: 8px;
14+
grid-auto-flow: column;
15+
justify-content: flex-start;
16+
17+
img {
18+
margin: 0;
19+
}
20+
` as typeof Typography;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
import { LABEL } from "@databiosphere/findable-ui/lib/apis/azul/common/entities";
2+
import { TypographyProps } from "@databiosphere/findable-ui/lib/components/common/Typography/common/entities";
3+
import { NTagCell } from "../../../../components/index";
4+
import { NetworkIcon } from "../../../common/NetworkIcon/networkIcon";
5+
import { NetworkKey } from "../../common/entities";
6+
import { Cell, Network } from "./bioNetworkCell.styles";
7+
8+
const MAX_DISPLAYABLE_VALUES = 1;
9+
10+
export interface BioNetworkCellProps {
11+
label: string;
12+
networkKeys: NetworkKey[];
13+
TypographyProps?: TypographyProps;
14+
}
15+
16+
export const BioNetworkCell = ({
17+
label,
18+
networkKeys,
19+
TypographyProps,
20+
}: BioNetworkCellProps): JSX.Element => {
21+
const showNTag = networkKeys.length > MAX_DISPLAYABLE_VALUES;
22+
if (networkKeys.length === 0) {
23+
return <span>{LABEL.UNSPECIFIED}</span>;
24+
}
25+
return (
26+
<>
27+
{showNTag ? (
28+
<NTagCell
29+
label={label}
30+
TypographyProps={TypographyProps}
31+
values={networkKeys}
32+
/>
33+
) : (
34+
<Cell>
35+
{networkKeys.map((networkKey) => (
36+
<Network component="div" key={networkKey} {...TypographyProps}>
37+
<NetworkIcon networkKey={networkKey} />
38+
<div>{networkKey}</div>
39+
</Network>
40+
))}
41+
</Cell>
42+
)}
43+
</>
44+
);
45+
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
import {
2+
StaticImage,
3+
StaticImageProps,
4+
} from "@databiosphere/findable-ui/lib/components/common/StaticImage/staticImage";
5+
import { NETWORK_ICONS } from "../../Index/common/constants";
6+
import { NetworkKey } from "../../Index/common/entities";
7+
8+
export interface NetworkIconProps
9+
extends Pick<StaticImageProps, "height" | "width"> {
10+
networkKey: NetworkKey;
11+
}
12+
13+
export const NetworkIcon = ({
14+
height = 24,
15+
networkKey,
16+
...props
17+
}: NetworkIconProps): JSX.Element => {
18+
return (
19+
<StaticImage
20+
alt={networkKey}
21+
height={height}
22+
src={NETWORK_ICONS[networkKey]}
23+
{...props}
24+
/>
25+
);
26+
};

explorer/app/components/index.tsx

+1
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,7 @@ export { FileLocationDownload } from "./Detail/components/GeneratedMatricesTable
9292
export { FileNameCell } from "./Detail/components/GeneratedMatricesTables/components/FileNameCell/fileNameCell";
9393
export { GeneratedMatricesTables } from "./Detail/components/GeneratedMatricesTables/generatedMatricesTables";
9494
export { ManifestDownloadEntity as AnVILManifestDownloadEntity } from "./Export/components/AnVILExplorer/components/ManifestDownload/components/ManifestDownloadEntity/manifestDownloadEntity";
95+
export { BioNetworkCell } from "./Index/components/BioNetworkCell/bioNetworkCell";
9596
export { ConsentCodesCell } from "./Index/components/ConsentCodesCell/consentCodesCell";
9697
export { CopyCell } from "./Index/components/CopyCell/copyCell";
9798
export { ANVILBranding } from "./Layout/components/Footer/components/Branding/components/ANVILBranding/anvilBranding";

explorer/app/viewModelBuilders/azul/hca-dcp/common/viewModelBuilders.ts

+41-1
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ import {
5050
FadeProps as MFadeProps,
5151
} from "@mui/material";
5252
import { ColumnDef } from "@tanstack/react-table";
53+
import { NETWORK_KEYS } from "app/components/Index/common/constants";
5354
import React, { ElementType, Fragment, ReactElement } from "react";
5455
import {
5556
HCA_DCP_CATEGORY_KEY,
@@ -79,7 +80,10 @@ import {
7980
} from "../../../../apis/azul/hca-dcp/common/responses";
8081
import * as C from "../../../../components";
8182
import * as MDX from "../../../../components/common/MDXContent/hca-dcp";
82-
import { METADATA_KEY } from "../../../../components/Index/common/entities";
83+
import {
84+
METADATA_KEY,
85+
NetworkKey,
86+
} from "../../../../components/Index/common/entities";
8387
import { getPluralizedMetadataLabel } from "../../../../components/Index/common/indexTransformer";
8488
import { humanFileSize } from "../../../../utils/fileSize";
8589
import { DATE_TIME_FORMAT_OPTIONS } from "../../../common/contants";
@@ -537,6 +541,22 @@ export const buildBatchCorrectionWarning = (): React.ComponentProps<
537541
};
538542
};
539543

544+
/**
545+
* Build props for the bio network cell component.
546+
* @param projectsResponse - Response model return from projects API.
547+
* @returns model to be used as props to be used for the BionetworkCell component.
548+
*/
549+
export const buildBioNetwork = (
550+
projectsResponse: ProjectsResponse
551+
): React.ComponentProps<typeof C.BioNetworkCell> => {
552+
const project = getProjectResponse(projectsResponse);
553+
const networkKeys = filterBioNetworks(project.bionetworkName ?? []);
554+
return {
555+
label: getPluralizedMetadataLabel(METADATA_KEY.BIONETWORK_NAME),
556+
networkKeys: networkKeys,
557+
};
558+
};
559+
540560
/**
541561
* Build props for project Citation component from the given projects response.
542562
* @param projectsResponse - Response model return from projects API.
@@ -1453,6 +1473,17 @@ function calculateEstimatedCellCount(
14531473
return rollUpTotalCells(projectsResponse);
14541474
}
14551475

1476+
/**
1477+
* Returns an array of bionetworks with null values and non-bionetworks filtered out.
1478+
* @param responseValues - an array containing bionetworks and null values
1479+
* @returns a filtered array containing only bionetworks
1480+
*/
1481+
export function filterBioNetworks(
1482+
responseValues: (NetworkKey | null)[]
1483+
): NetworkKey[] {
1484+
return responseValues.filter(isBioNetwork);
1485+
}
1486+
14561487
/**
14571488
* Returns age and age unit object values.
14581489
* @param donorOrganisms - Donor organisms.
@@ -2183,6 +2214,15 @@ function isAccessibleTransitionIn(projectsResponse: ProjectsResponse): boolean {
21832214
return isAccessible || isReady;
21842215
}
21852216

2217+
/**
2218+
* Returns true if the given value is a bionetwork, otherwise returns false.
2219+
* @param value - a value that may or may not be a bionetwork
2220+
* @returns a boolean indicating whether the value is a bionetwork
2221+
*/
2222+
export function isBioNetwork(value: unknown): value is NetworkKey {
2223+
return NETWORK_KEYS.includes(value as NetworkKey);
2224+
}
2225+
21862226
/**
21872227
* Returns true if the "accessible" file facet has a term value of "true".
21882228
* @param fileManifestState - File manifest state.
Loading
Loading
Loading
Loading
Loading
Loading
Loading
Loading
Loading
Loading
Loading
Loading
Loading
Loading
Loading
Loading
Loading
Loading

explorer/site-config/hca-dcp/category.ts

+2
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ export const HCA_DCP_CATEGORY_KEY = {
66
ANATOMICAL_ENTITY: "specimenOrgan",
77
AZUL_FILE_DOWNLOAD: "azulFileDownload",
88
BIOLOGICAL_SEX: "biologicalSex",
9+
BIONETWORK_NAME: "bionetworkName",
910
CELL_COUNT: "cellCount",
1011
CONTACT_NAME: "contactName",
1112
CONTENT_DESCRIPTION: "contentDescription",
@@ -52,6 +53,7 @@ export const HCA_DCP_CATEGORY_LABEL = {
5253
ANATOMICAL_ENTITY: "Anatomical Entity",
5354
AZUL_FILE_DOWNLOAD: " ",
5455
BIOLOGICAL_SEX: "Biological Sex",
56+
BIONETWORK_NAME: "Biological Network",
5557
CELL_COUNT: "Cell Count Estimate",
5658
CONTACT_NAME: "Contributor Name",
5759
CONTENT_DESCRIPTION: "Content Description",

explorer/site-config/hca-dcp/dev/config.ts

+4
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,10 @@ export function makeConfig(
6565
key: HCA_DCP_CATEGORY_KEY.INSTITUTION,
6666
label: HCA_DCP_CATEGORY_LABEL.INSTITUTION,
6767
},
68+
{
69+
key: HCA_DCP_CATEGORY_KEY.BIONETWORK_NAME,
70+
label: HCA_DCP_CATEGORY_LABEL.BIONETWORK_NAME,
71+
},
6872
],
6973
label: "Project",
7074
},

explorer/site-config/hca-dcp/dev/index/projectsEntityConfig.ts

+9
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,15 @@ export const projectsEntityConfig: EntityConfig = {
9090
id: HCA_DCP_CATEGORY_KEY.PROJECT_TITLE,
9191
width: { max: "2fr", min: "374px" },
9292
},
93+
{
94+
componentConfig: {
95+
component: C.BioNetworkCell,
96+
viewBuilder: V.buildBioNetwork,
97+
} as ComponentConfig<typeof C.BioNetworkCell, ProjectsResponse>,
98+
header: HCA_DCP_CATEGORY_LABEL.BIONETWORK_NAME,
99+
id: HCA_DCP_CATEGORY_KEY.BIONETWORK_NAME,
100+
width: { max: "1fr", min: "126px" },
101+
},
93102
{
94103
componentConfig: {
95104
component: C.NTagCell,

0 commit comments

Comments
 (0)