Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Austenem/CAT-793 unified datasets attribution #3551

Merged
merged 11 commits into from
Oct 2, 2024
1 change: 1 addition & 0 deletions CHANGELOG-unified-datasets-attribution.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
- Remove "Contact" section and add Attribution table with contributors for EPICs and Lab Processed datasets.
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ const tooltips = {
contact: 'This is the contact for this data.',
};

const DatasetAttribution = (
export const DatasetAttributionDescription = (
<SectionDescription>
Below is the information for the individuals who provided this dataset. For questions about this dataset, reach out
to the individuals listed as contacts, either via the email address listed in the table or via contact information
Expand Down Expand Up @@ -44,7 +44,7 @@ function Attribution({ children }: PropsWithChildren) {
return (
<CollapsibleDetailPageSection id="attribution" title="Attribution" icon={sectionIconMap.attribution}>
<Stack spacing={1}>
{isDataset && DatasetAttribution}
{isDataset && DatasetAttributionDescription}
<SummaryPaper>
<Stack direction="row" spacing={10}>
{sections.map((props) => (
Expand Down
Original file line number Diff line number Diff line change
@@ -1,36 +1,43 @@
import React, { useState } from 'react';
import LabelledSectionText from 'js/shared-styles/sections/LabelledSectionText';
import { formatDate } from 'date-fns/format';
import { Tabs, Tab, TabPanel } from 'js/shared-styles/tabs';

import FactCheckRounded from '@mui/icons-material/FactCheckRounded';
import SummarizeRounded from '@mui/icons-material/SummarizeRounded';
import AttributionRoundedIcon from '@mui/icons-material/AttributionRounded';
import InsertDriveFileRounded from '@mui/icons-material/InsertDriveFileRounded';
import Skeleton from '@mui/material/Skeleton';
import Stack from '@mui/material/Stack';

import LabelledSectionText from 'js/shared-styles/sections/LabelledSectionText';
import { Tabs, Tab, TabPanel } from 'js/shared-styles/tabs';
import { VisualizationIcon } from 'js/shared-styles/icons';
import { useVitessceConf } from 'js/pages/Dataset/hooks';
import { isSupport } from 'js/components/types';
import { useFlaskDataContext } from 'js/components/Contexts';
import Skeleton from '@mui/material/Skeleton';
import ContactUsLink from 'js/shared-styles/Links/ContactUsLink';
import Files from '../../files/Files';
import DataProducts from '../../files/DataProducts';
import VisualizationWrapper from '../../visualization/VisualizationWrapper';
import AnalysisDetails from '../../AnalysisDetails';
import Protocol from '../../Protocol';
import ContributorsTable from 'js/components/detailPage/ContributorsTable';
import { DatasetAttributionDescription } from 'js/components/detailPage/Attribution/Attribution';
import Files from 'js/components/detailPage/files/Files';
import DataProducts from 'js/components/detailPage/files/DataProducts';
import VisualizationWrapper from 'js/components/detailPage/visualization/VisualizationWrapper';
import AnalysisDetails from 'js/components/detailPage/AnalysisDetails';
import Protocol from 'js/components/detailPage/Protocol';
import { getDateLabelAndValue } from 'js/components/detailPage/utils';
import { useSelectedVersionStore } from 'js/components/detailPage/VersionSelect/SelectedVersionStore';
import { useVersions } from 'js/components/detailPage/VersionSelect/hooks';
import { useTrackEntityPageEvent } from 'js/components/detailPage/useTrackEntityPageEvent';

import { DatasetTitle } from './DatasetTitle';
import { ProcessedDatasetAccordion } from './ProcessedDatasetAccordion';
import { Subsection } from './Subsection';
import { SectionDescription } from './SectionDescription';
import useProcessedDataStore from '../store';
import { getDateLabelAndValue } from '../../utils';
import {
ProcessedDatasetContextProvider,
useProcessedDatasetContext,
ProcessedDataVisualizationProps,
} from './ProcessedDatasetContext';
import { useSelectedVersionStore } from '../../VersionSelect/SelectedVersionStore';
import { useProcessedDatasetDetails } from './hooks';
import { useVersions } from '../../VersionSelect/hooks';
import { useTrackEntityPageEvent } from '../../useTrackEntityPageEvent';
import { OldVersionAlert } from './OldVersionAlert';

function ProcessedDatasetDescription() {
Expand All @@ -47,12 +54,13 @@ function ProcessedDatasetDescription() {

function Contact() {
const {
dataset: { mapped_consortium },
dataset: { creation_action },
} = useProcessedDatasetContext();

if (mapped_consortium !== 'HuBMAP') {
if (creation_action !== 'Central Process') {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use a constant here as well.

return null;
}

return (
<LabelledSectionText label="Contact" iconTooltipText="This is the contact for this data.">
<ContactUsLink>HuBMAP Help Desk</ContactUsLink>
Expand All @@ -65,12 +73,14 @@ function SummaryAccordion() {
const [dateLabel, dateValue] = getDateLabelAndValue(dataset);
return (
<Subsection title="Summary" icon={<SummarizeRounded />}>
<ProcessedDatasetDescription />
<LabelledSectionText label="Consortium">{dataset.group_name}</LabelledSectionText>
<Contact />
<LabelledSectionText label={dateLabel}>
{dateValue ? formatDate(new Date(dateValue), 'yyyy-MM-dd') : 'N/A'}
</LabelledSectionText>
<Stack spacing={1}>
<ProcessedDatasetDescription />
<LabelledSectionText label="Consortium">{dataset.group_name}</LabelledSectionText>
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is 'Consortium' the right label for group name? Should group_name be mapped_consortium? Do we also want to display the group_name? @tsliaw

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consortium should be the label for mapped_consortium. I didn't include the group field initially since I assumed that the group should be the same for both the raw and processed, but that's probably not true. @austenem Let's add the group field before the consortium field in the summary section. Can you also replace the consortium field in the mini processed data detail section (the pop-up thing on the right) with group instead? That field should be more useful than consortium.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@tsliaw Will do! Would it make sense to also replace the "Consortium" field in the summary view top bar, or to add a "Group" field?

<Contact />
<LabelledSectionText label={dateLabel}>
{dateValue ? formatDate(new Date(dateValue), 'yyyy-MM-dd') : 'N/A'}
</LabelledSectionText>
</Stack>
</Subsection>
);
}
Expand Down Expand Up @@ -182,6 +192,23 @@ function AnalysisDetailsAccordion() {
);
}

function AttributionAccordion() {
const {
dataset: { creation_action, contributors, contacts },
} = useProcessedDatasetContext();

if (creation_action === 'Central Process' || !contributors) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Constant here as well.

austenem marked this conversation as resolved.
Show resolved Hide resolved
return null;
}

return (
<Subsection title="Attribution" idTitleOverride="attribution" icon={<AttributionRoundedIcon />}>
{DatasetAttributionDescription}
<ContributorsTable contributors={contributors} contacts={contacts} />
</Subsection>
);
}

export default function ProcessedDataset({ sectionDataset }: ProcessedDataVisualizationProps) {
const selectedDatasetVersionUUID =
useSelectedVersionStore((state) => state.selectedVersions.get(sectionDataset.uuid))?.uuid ?? sectionDataset.uuid;
Expand Down Expand Up @@ -213,6 +240,7 @@ export default function ProcessedDataset({ sectionDataset }: ProcessedDataVisual
<VisualizationAccordion />
<FilesAccordion />
<AnalysisDetailsAccordion />
<AttributionAccordion />
</ProcessedDatasetAccordion>
</ProcessedDatasetContextProvider>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,8 @@ export function useProcessedDatasetDetails(uuid: string) {
'dataset_type',
'creation_action',
'mapped_consortium',
'contributors',
'contacts',
],
size: 10000,
};
Expand Down
8 changes: 6 additions & 2 deletions context/app/static/js/pages/Dataset/hooks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,8 @@ export type ProcessedDatasetInfo = Pick<
| 'dbgap_sra_experiment_url'
| 'is_component'
| 'visualization'
| 'contributors'
| 'contacts'
>;

type VitessceConf = object | undefined;
Expand Down Expand Up @@ -106,6 +108,7 @@ function useProcessedDatasets(includeComponents?: boolean) {
'dbgap_sra_experiment_url',
'is_component',
'visualization',
'contributors',
],
size: 10000,
};
Expand All @@ -128,13 +131,14 @@ function getProcessedDatasetSection({
hit: Required<SearchHit<ProcessedDatasetInfo>>;
conf?: VitessceConf;
}) {
const { pipeline, hubmap_id, files, metadata, visualization } = hit._source;
const { pipeline, hubmap_id, files, metadata, visualization, creation_action, contributors } = hit._source;

const shouldDisplaySection = {
summary: true,
visualization: visualization || Boolean(conf && 'data' in conf && conf?.data),
files: Boolean(files),
files: Boolean(files?.length !== 0),
austenem marked this conversation as resolved.
Show resolved Hide resolved
analysis: Boolean(metadata?.dag_provenance_list),
attribution: creation_action !== 'Central Process' && Boolean(contributors),
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's introduce constants for creation_action.

  • Create Dataset Activity
  • Central Process
  • Multi-Assay Split
  • Lab Process
  • Create Publication Activity
  • External Process

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good idea - I wrote up a type CreationAction that represents that set of strings. Is that what you had in mind, or would creating individually named constants to represent these strings/an enum be preferable?

austenem marked this conversation as resolved.
Show resolved Hide resolved
};

const sectionsToDisplay = Object.entries(shouldDisplaySection).filter(([_k, v]) => v === true);
Expand Down
Loading