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 };