Skip to content

Commit

Permalink
Merge branch 'main' into nickakhmetov/cat-949-remove-prov-from-donors
Browse files Browse the repository at this point in the history
  • Loading branch information
NickAkhmetov committed Oct 15, 2024
2 parents 3cbf5af + 0428e22 commit 2e87b41
Show file tree
Hide file tree
Showing 25 changed files with 364 additions and 348 deletions.
1 change: 1 addition & 0 deletions CHANGELOG-cat-706.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
- Add title to changelog page.
1 change: 1 addition & 0 deletions CHANGELOG-entity-header-styling.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
- Fix Webkit-specific bugs that caused the entity header to become misaligned.
3 changes: 3 additions & 0 deletions CHANGELOG-fix-metadata-table.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
- Switch to using metadata table with tabs component in the Sample and Donor pages.
- In the metadata sections of Dataset, Sample, and Donor pages, add tabs for any entities in the Provenance section with metadata.
- Update the metadata table component to show unique labels for each tab and to be scrollable when many tabs are present.
1 change: 1 addition & 0 deletions CHANGELOG-remove-qa-workspace-option.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
- Fix issue of Workspaces button being available for protected datasets in the Visualization section.
2 changes: 2 additions & 0 deletions context/app/markdown/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
# Changelog

## v1.12.1 - 2024-10-10

- Prevent collections without a DOI from being counted on the homepage.
Expand Down
5 changes: 3 additions & 2 deletions context/app/static/js/components/Header/Header/Header.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import React from 'react';

import Box from '@mui/material/Box';
import EntityHeader from 'js/components/detailPage/entityHeader/EntityHeader';
import HeaderAppBar from '../HeaderAppBar';
import HeaderContent from '../HeaderContent';
Expand All @@ -9,12 +10,12 @@ function Header() {
const { shouldDisplayHeader, ...props } = useEntityHeaderVisibility();

return (
<>
<Box sx={(theme) => ({ position: 'fixed', width: '100%', zIndex: theme.zIndex.header })}>
<HeaderAppBar {...props}>
<HeaderContent />
</HeaderAppBar>
{shouldDisplayHeader && <EntityHeader />}
</>
</Box>
);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,66 +6,14 @@ import { CollapsibleDetailPageSection } from 'js/components/detailPage/DetailPag
import { useTrackEntityPageEvent } from 'js/components/detailPage/useTrackEntityPageEvent';
import { tableToDelimitedString, createDownloadUrl } from 'js/helpers/functions';
import { useMetadataFieldDescriptions } from 'js/hooks/useUBKG';
import { getMetadata, hasMetadata } from 'js/helpers/metadata';
import { ESEntityType, isDataset } from 'js/components/types';
import { useProcessedDatasets } from 'js/pages/Dataset/hooks';
import { entityIconMap } from 'js/shared-styles/icons/entityIconMap';
import { Dataset, Donor, Sample, isDataset } from 'js/components/types';
import withShouldDisplay from 'js/helpers/withShouldDisplay';
import { sectionIconMap } from 'js/shared-styles/icons/sectionIconMap';
import { getTableEntities } from 'js/components/detailPage/MetadataSection/utils';
import { DownloadIcon, StyledWhiteBackgroundIconButton } from '../MetadataTable/style';
import MetadataTabs from '../multi-assay/MultiAssayMetadataTabs';
import { Columns, defaultTSVColumns } from './columns';
import { SectionDescription } from '../ProcessedData/ProcessedDataset/SectionDescription';
import MetadataTable from '../MetadataTable';
import { nodeIcons } from '../DatasetRelationships/nodeTypes';

export function getDescription(
field: string,
metadataFieldDescriptions: Record<string, string> | Record<string, never>,
) {
const [prefix, stem] = field.split('.');
if (!stem) {
return metadataFieldDescriptions?.[field];
}
const description = metadataFieldDescriptions?.[stem];
if (!description) {
return undefined;
}
if (prefix === 'donor') {
return `For the original donor: ${metadataFieldDescriptions?.[stem]}`;
}
if (prefix === 'sample') {
return `For the original sample: ${metadataFieldDescriptions?.[stem]}`;
}
throw new Error(`Unrecognized metadata field prefix: ${prefix}`);
}

export function buildTableData(
tableData: Record<string, string | object | unknown[]>,
metadataFieldDescriptions: Record<string, string> | Record<string, never>,
extraValues: Record<string, string> = {},
) {
return (
Object.entries(tableData)
// Filter out nested objects, like nested "metadata" for Samples...
// but allow arrays. Remember, in JS: typeof [] === 'object'
.filter((entry) => typeof entry[1] !== 'object' || Array.isArray(entry[1]))
// Filter out fields from TSV that aren't really metadata:
.filter((entry) => !['contributors_path', 'antibodies_path', 'version'].includes(entry[0]))
.map((entry) => ({
...extraValues,
key: entry[0],
// eslint-disable-next-line @typescript-eslint/no-base-to-string
value: Array.isArray(entry[1]) ? entry[1].join(', ') : entry[1].toString(),
description: getDescription(entry[0], metadataFieldDescriptions),
}))
);
}

function useTableData(tableData: Record<string, string>) {
const { data: fieldDescriptions } = useMetadataFieldDescriptions();
return buildTableData(tableData, fieldDescriptions);
}
import { Columns, defaultTSVColumns } from './columns';

interface TableRow {
key: string;
Expand Down Expand Up @@ -124,76 +72,25 @@ function MetadataWrapper({ allTableRows, tsvColumns = defaultTSVColumns, childre
);
}

function SingleMetadata({ metadata }: { metadata: Record<string, string> }) {
const tableRows = useTableData(metadata);

return (
<MetadataWrapper allTableRows={tableRows}>
<MetadataTable tableRows={tableRows} />
</MetadataWrapper>
);
}

function getEntityIcon(entity: { entity_type: ESEntityType; is_component?: boolean; processing?: string }) {
if (isDataset(entity)) {
if (entity.is_component) {
return nodeIcons.componentDataset;
}
if (entity.processing === 'processed') {
return nodeIcons.processedDataset;
}
return nodeIcons.primaryDataset;
}
return entityIconMap[entity.entity_type];
}

interface MetadataProps {
metadata?: Record<string, string>;
entities: (Donor | Dataset | Sample)[];
}

function Metadata({ metadata }: MetadataProps) {
const { searchHits: datasetsWithMetadata, isLoading } = useProcessedDatasets(true);
function Metadata({ entities }: MetadataProps) {
const { data: fieldDescriptions } = useMetadataFieldDescriptions();
const {
entity: { uuid },
} = useFlaskDataContext();

const { entity } = useFlaskDataContext();

if (!isDataset(entity)) {
return <SingleMetadata metadata={metadata!} />;
}

if (isLoading || !datasetsWithMetadata) {
return null;
}

const { donor, source_samples } = entity;

const entities = [entity, ...datasetsWithMetadata.map((d) => d._source), ...source_samples, donor]
.filter((e) => hasMetadata({ targetEntityType: e.entity_type, currentEntity: e }))
.map((e) => {
const label = isDataset(e) ? e.assay_display_name : e.entity_type;
return {
uuid: e.uuid,
label,
icon: getEntityIcon(e),
tableRows: buildTableData(
getMetadata({
targetEntityType: e.entity_type,
currentEntity: e,
}),
fieldDescriptions,
{ hubmap_id: e.hubmap_id, label },
),
};
});

const allTableRows = entities.map((d) => d.tableRows).flat();
const tableEntities = getTableEntities({ entities, uuid, fieldDescriptions });
const allTableRows = tableEntities.map((d) => d.tableRows).flat();

return (
<MetadataWrapper
allTableRows={allTableRows}
tsvColumns={[{ id: 'hubmap_id', label: 'HuBMAP ID' }, { id: 'label', label: 'Entity' }, ...defaultTSVColumns]}
>
<MetadataTabs entities={entities} />
<MetadataTabs entities={tableEntities} />
</MetadataWrapper>
);
}
Expand Down

This file was deleted.

Loading

0 comments on commit 2e87b41

Please sign in to comment.