diff --git a/CHANGELOG-add-donor-age-messaging.md b/CHANGELOG-add-donor-age-messaging.md new file mode 100644 index 0000000000..dc40eb3b34 --- /dev/null +++ b/CHANGELOG-add-donor-age-messaging.md @@ -0,0 +1 @@ +- Add messaging where donors with ages > 89 are displayed on search and detail pages. \ No newline at end of file diff --git a/context/app/static/js/components/detailPage/MetadataTable/MetadataTable.tsx b/context/app/static/js/components/detailPage/MetadataTable/MetadataTable.tsx index c2885c00f9..2291ff3b56 100644 --- a/context/app/static/js/components/detailPage/MetadataTable/MetadataTable.tsx +++ b/context/app/static/js/components/detailPage/MetadataTable/MetadataTable.tsx @@ -5,9 +5,11 @@ import TableBody from '@mui/material/TableBody'; import TableCell from '@mui/material/TableCell'; import TableHead from '@mui/material/TableHead'; import TableRow from '@mui/material/TableRow'; +import Stack from '@mui/material/Stack'; import { StyledTableContainer, HeaderCell } from 'js/shared-styles/tables'; import IconTooltipCell from 'js/shared-styles/tables/IconTooltipCell'; +import DonorAgeTooltip from 'js/shared-styles/tooltips/DonorAgeTooltip'; import { defaultColumns } from '../MetadataSection/columns'; interface MetadataTableRow { @@ -32,7 +34,12 @@ function MetadataTable({ tableRows = [] as MetadataTableRow[], columns = default {tableRows.map((row) => ( {row.key} - {row.value} + + + {row.value} + {row.key.endsWith('age_value') && } + + ))} diff --git a/context/app/static/js/components/detailPage/entityHeader/EntityHeaderContent/EntityHeaderContent.tsx b/context/app/static/js/components/detailPage/entityHeader/EntityHeaderContent/EntityHeaderContent.tsx index 24248e795c..91c8e14b87 100644 --- a/context/app/static/js/components/detailPage/entityHeader/EntityHeaderContent/EntityHeaderContent.tsx +++ b/context/app/static/js/components/detailPage/entityHeader/EntityHeaderContent/EntityHeaderContent.tsx @@ -18,6 +18,7 @@ import { useFlaskDataContext } from 'js/components/Contexts'; import { Entity, isDataset, isDonor, isPublication, isSample } from 'js/components/types'; import EntityIcon from 'js/shared-styles/icons/EntityIcon'; import { SampleCategoryIcon } from 'js/shared-styles/icons'; +import DonorAgeTooltip from 'js/shared-styles/tooltips/DonorAgeTooltip'; import { getDonorMetadata, getOriginSampleAndMappedOrgan } from '../../utils'; import EntityHeaderItem from '../EntityHeaderItem'; @@ -72,7 +73,10 @@ function DonorItems({ data: { entity } }: EntityHeaderItemsProps) { {race && {race}} {age_unit && age_value && ( - {age_value} {age_unit} + + {age_value} {age_unit} + + )} diff --git a/context/app/static/js/components/entity-tile/EntityTileBody/EntityTileBody.tsx b/context/app/static/js/components/entity-tile/EntityTileBody/EntityTileBody.tsx index b0ae2fbe05..3fa0d02c65 100644 --- a/context/app/static/js/components/entity-tile/EntityTileBody/EntityTileBody.tsx +++ b/context/app/static/js/components/entity-tile/EntityTileBody/EntityTileBody.tsx @@ -1,9 +1,11 @@ import React from 'react'; +import Stack from '@mui/system/Stack'; import Tile from 'js/shared-styles/tiles/Tile'; import EntityTileThumbnail from 'js/components/entity-tile/EntityTileThumbnail'; import { getOriginSamplesOrgan } from 'js/helpers/functions'; import { EntityWithType, isDataset, isDonor, isSample } from 'js/components/types'; +import DonorAgeTooltip from 'js/shared-styles/tooltips/DonorAgeTooltip'; import { Flex, StyledDiv, BodyWrapper } from './style'; const thumbnailDimension = 80; @@ -33,7 +35,10 @@ function EntityTileBody({ entity_type, id, entityData, invertColors }: EntityTil {entityData.mapped_metadata?.sex} - {entityData.mapped_metadata?.age_value} {entityData.mapped_metadata?.age_unit} + + {entityData.mapped_metadata?.age_value} {entityData.mapped_metadata?.age_unit} + + {(entityData.mapped_metadata?.race ?? []).join(', ')} diff --git a/context/app/static/js/components/searchPage/ResultsTable/utils.js b/context/app/static/js/components/searchPage/ResultsTable/utils.jsx similarity index 79% rename from context/app/static/js/components/searchPage/ResultsTable/utils.js rename to context/app/static/js/components/searchPage/ResultsTable/utils.jsx index a0c85b9f0b..b7ba8105db 100644 --- a/context/app/static/js/components/searchPage/ResultsTable/utils.js +++ b/context/app/static/js/components/searchPage/ResultsTable/utils.jsx @@ -1,4 +1,7 @@ +import React from 'react'; +import Stack from '@mui/material/Stack'; import { get } from 'js/helpers/nodash'; +import DonorAgeTooltip from 'js/shared-styles/tooltips/DonorAgeTooltip'; const donorMetadataPath = 'mapped_metadata'; const sampleMetdataPath = 'metadata'; @@ -48,6 +51,14 @@ function getByPath(hitSource, field) { } if (Array.isArray(fieldValue)) { + if (field?.id === 'mapped_metadata.age_value') { + return ( + + {fieldValue.join(' / ')} + {fieldValue.length > 0 && } + + ); + } return fieldValue.join(' / '); } diff --git a/context/app/static/js/components/searchPage/config.js b/context/app/static/js/components/searchPage/config.js index 0b3cd8eb13..06d56b6efd 100644 --- a/context/app/static/js/components/searchPage/config.js +++ b/context/app/static/js/components/searchPage/config.js @@ -12,7 +12,7 @@ function makeDonorMetadataFilters(isDonor) { const labelPrefix = isDonor ? '' : 'Donor '; return [ listFilter(`${pathPrefix}mapped_metadata.sex`, `${labelPrefix}Sex`), - rangeFilter(`${pathPrefix}mapped_metadata.${ageField}`, `${labelPrefix}Age`, 0, 100), + rangeFilter(`${pathPrefix}mapped_metadata.${ageField}`, `${labelPrefix}Age`, 0, 90), listFilter(`${pathPrefix}mapped_metadata.race`, `${labelPrefix}Race`), rangeFilter(`${pathPrefix}mapped_metadata.${bmiField}`, `${labelPrefix}BMI`, 0, 50), ]; diff --git a/context/app/static/js/components/types.ts b/context/app/static/js/components/types.ts index 4d27af84c6..102d1f9a6c 100644 --- a/context/app/static/js/components/types.ts +++ b/context/app/static/js/components/types.ts @@ -58,7 +58,7 @@ export interface Entity { mapped_data_types?: string[]; mapped_data_access_level: 'Public' | 'Protected' | 'Consortium'; status: string; - mapped_metadata: Record; + mapped_metadata?: Record; [key: string]: unknown; } @@ -66,7 +66,7 @@ export type PartialEntity = Partial & Pick + + + + + ); +} +export default DonorAgeTooltip; diff --git a/context/app/static/js/shared-styles/tooltips/DonorAgeTooltip/index.ts b/context/app/static/js/shared-styles/tooltips/DonorAgeTooltip/index.ts new file mode 100644 index 0000000000..9665f81c59 --- /dev/null +++ b/context/app/static/js/shared-styles/tooltips/DonorAgeTooltip/index.ts @@ -0,0 +1,3 @@ +import DonorAgeTooltip from './DonorAgeTooltip'; + +export default DonorAgeTooltip; diff --git a/context/app/static/js/shared-styles/tooltips/DonorAgeTooltip/style.ts b/context/app/static/js/shared-styles/tooltips/DonorAgeTooltip/style.ts new file mode 100644 index 0000000000..ce7bf6c6bc --- /dev/null +++ b/context/app/static/js/shared-styles/tooltips/DonorAgeTooltip/style.ts @@ -0,0 +1,15 @@ +import { Stack } from '@mui/material'; +import { styled } from '@mui/material/styles'; +import { InfoIcon } from 'js/shared-styles/icons'; + +const StyledStack = styled(Stack)(({ theme }) => ({ + marginLeft: theme.spacing(0.5), + justifyContent: 'center', +})); + +const StyledInfoIcon = styled(InfoIcon)(({ theme }) => ({ + color: theme.palette.primary.main, + fontSize: '0.75rem', +})); + +export { StyledStack, StyledInfoIcon };