-
Notifications
You must be signed in to change notification settings - Fork 9
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
single dataset metadata drawer (#103)
## Description Implements the metadata drawer for the single dataset page. This PR introduces the following changes: - Extract Drawer component and remove global usage in favor of features using it locally. - Extract Tabs component for reuse in the metadata drawer. - Add typed convenience hook for getting the dataset by ID GraphQL response. - Refactored drawer state to be consumed through hooks - Updated GraphQL query to include new properties for the metadata drawer - New components: - Accordion - MetadataTable ## Demos ### Dataset drawer <img width="1722" alt="image" src="https://github.com/chanzuckerberg/cryoet-data-portal/assets/2176050/9e20bad5-61bd-4a4a-be47-65bd6e97daef"> <img width="480" alt="image" src="https://github.com/chanzuckerberg/cryoet-data-portal/assets/2176050/bcd52122-eb34-4ee0-bff0-2e6706c6e012"> <img width="484" alt="image" src="https://github.com/chanzuckerberg/cryoet-data-portal/assets/2176050/d657dcda-08df-46a7-867a-64b3b1c239dd"> <img width="458" alt="image" src="https://github.com/chanzuckerberg/cryoet-data-portal/assets/2176050/8b96ea83-6649-4722-8d02-094938fb8c2d"> ### Really long title clamped at 3 lines <img width="508" alt="image" src="https://github.com/chanzuckerberg/cryoet-data-portal/assets/2176050/4d5b380f-43c7-41a3-8cf1-96285b4a88c2">
- Loading branch information
1 parent
e82082c
commit 8bacebd
Showing
20 changed files
with
682 additions
and
103 deletions.
There are no files selected for viewing
33 changes: 33 additions & 0 deletions
33
frontend/packages/data-portal/app/components/Accordion.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
import { | ||
Accordion as SDSAccordion, | ||
AccordionDetails, | ||
AccordionHeader, | ||
} from '@czi-sds/components' | ||
import { ReactNode, useState } from 'react' | ||
|
||
export function Accordion({ | ||
children, | ||
header, | ||
id, | ||
initialOpen, | ||
}: { | ||
children: ReactNode | ||
header: ReactNode | ||
id: string | ||
initialOpen?: boolean | ||
}) { | ||
const [expanded, setExpanded] = useState(initialOpen) | ||
|
||
return ( | ||
<SDSAccordion | ||
id={id} | ||
elevation={0} | ||
expanded={expanded} | ||
onChange={(_, nextExpanded) => setExpanded(nextExpanded)} | ||
> | ||
<AccordionHeader>{header}</AccordionHeader> | ||
|
||
<AccordionDetails>{children}</AccordionDetails> | ||
</SDSAccordion> | ||
) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
24 changes: 24 additions & 0 deletions
24
frontend/packages/data-portal/app/components/Dataset/AccordionMetadataTable.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
import { ComponentProps } from 'react' | ||
|
||
import { Accordion } from 'app/components/Accordion' | ||
import { MetadataTable } from 'app/components/MetadataTable' | ||
|
||
type AccordionProps = Pick<ComponentProps<typeof Accordion>, 'id' | 'header'> | ||
type MetadataTableProps = Pick<ComponentProps<typeof MetadataTable>, 'data'> | ||
|
||
export function AccordionMetadataTable({ | ||
data, | ||
header, | ||
id, | ||
}: AccordionProps & MetadataTableProps) { | ||
return ( | ||
<Accordion id={id} header={header} initialOpen> | ||
<MetadataTable | ||
data={data} | ||
tableCellProps={{ | ||
loadingSkeleton: false, | ||
}} | ||
/> | ||
</Accordion> | ||
) | ||
} |
50 changes: 50 additions & 0 deletions
50
frontend/packages/data-portal/app/components/Dataset/DatasetHeader.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
import { Icon } from '@czi-sds/components' | ||
import { useSearchParams } from '@remix-run/react' | ||
|
||
import { Link } from 'app/components/Link' | ||
import { useDatasetById } from 'app/hooks/useDatasetById' | ||
import { i18n } from 'app/i18n' | ||
import { cns } from 'app/utils/cns' | ||
|
||
export function DatasetHeader() { | ||
const [params] = useSearchParams() | ||
const previousUrl = params.get('prev') | ||
const dataset = useDatasetById() | ||
|
||
return ( | ||
<header className="flex flex-col items-center justify-center w-full min-h-[48px]"> | ||
<div | ||
className={cns( | ||
'flex items-center', | ||
'px-sds-xl py-sds-l', | ||
'w-full max-w-content', | ||
previousUrl ? 'justify-between' : 'justify-end', | ||
)} | ||
> | ||
{previousUrl && ( | ||
<Link className="flex items-center gap-1" to={previousUrl}> | ||
<Icon | ||
sdsIcon="chevronLeft" | ||
sdsSize="xs" | ||
sdsType="iconButton" | ||
className="!w-[10px] !h-[10px] !fill-sds-primary-400" | ||
/> | ||
<span className="text-sds-primary-400 font-semibold text-sm"> | ||
Back to results | ||
</span> | ||
</Link> | ||
)} | ||
|
||
<div className="flex items-center gap-sds-xs text-xs text-sds-gray-600"> | ||
<p>{i18n.releaseDate(dataset.release_date)}</p> | ||
<div className="h-3 w-px bg-sds-gray-400" /> | ||
<p> | ||
{i18n.lastModified( | ||
dataset.last_modified_date ?? dataset.deposition_date, | ||
)} | ||
</p> | ||
</div> | ||
</div> | ||
</header> | ||
) | ||
} |
122 changes: 122 additions & 0 deletions
122
frontend/packages/data-portal/app/components/Dataset/DatasetMetadataDrawer.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,122 @@ | ||
import { ButtonIcon } from '@czi-sds/components' | ||
import { useSearchParams } from '@remix-run/react' | ||
import { useEffect, useRef } from 'react' | ||
|
||
import { Demo } from 'app/components/Demo' | ||
import { Drawer } from 'app/components/Drawer' | ||
import { TabData, Tabs } from 'app/components/Tabs' | ||
import { useDatasetById } from 'app/hooks/useDatasetById' | ||
import { i18n } from 'app/i18n' | ||
import { useDatasetDrawer } from 'app/state/drawer' | ||
import { cns } from 'app/utils/cns' | ||
|
||
import { DatasetMetadataTable } from './DatasetMetadataTable' | ||
import { SampleAndExperimentConditionsTable } from './SampleAndExperimentConditionsTable' | ||
import { TiltSeriesTable } from './TiltSeriesTable' | ||
|
||
enum MetadataTab { | ||
Metadata = 'metadata', | ||
HowToCite = 'howToCite', | ||
} | ||
|
||
const TAB_OPTIONS: TabData<MetadataTab>[] = [ | ||
{ | ||
label: i18n.metadata, | ||
value: MetadataTab.Metadata, | ||
}, | ||
{ | ||
label: i18n.howToCite, | ||
value: MetadataTab.HowToCite, | ||
}, | ||
] | ||
|
||
const ACTIVE_TAB_PARAM = 'tab' | ||
|
||
export function DatasetMetadataDrawer() { | ||
const drawer = useDatasetDrawer() | ||
const dataset = useDatasetById() | ||
|
||
const [searchParams, setSearchParams] = useSearchParams() | ||
const activeTab = (searchParams.get(ACTIVE_TAB_PARAM) ?? | ||
MetadataTab.Metadata) as MetadataTab | ||
|
||
const initialLoadRef = useRef(true) | ||
if (initialLoadRef.current && searchParams.has(ACTIVE_TAB_PARAM)) { | ||
initialLoadRef.current = false | ||
drawer.setOpen(true) | ||
} | ||
|
||
useEffect(() => { | ||
if (drawer.open && searchParams.get(ACTIVE_TAB_PARAM) !== activeTab) { | ||
setSearchParams((params) => { | ||
params.set(ACTIVE_TAB_PARAM, activeTab) | ||
return params | ||
}) | ||
} else if (!drawer.open) { | ||
setSearchParams((params) => { | ||
params.delete(ACTIVE_TAB_PARAM) | ||
return params | ||
}) | ||
} | ||
}, [activeTab, drawer.open, searchParams, setSearchParams]) | ||
|
||
return ( | ||
<Drawer open={drawer.open} onClose={() => drawer.setOpen(false)}> | ||
<div className="flex flex-col flex-auto"> | ||
<header className="flex items-start justify-between px-sds-xl pt-sds-xl pb-sds-xxl"> | ||
<div className="flex flex-col gap-sds-s"> | ||
<p className="text-xs text-sds-gray-600 font-semibold uppercase"> | ||
{i18n.datasetDetails} | ||
</p> | ||
|
||
<p className="text-sds-header-xl font-semibold text-black leading-[30px] line-clamp-3"> | ||
{dataset.title} | ||
</p> | ||
</div> | ||
|
||
<ButtonIcon | ||
onClick={() => drawer.setOpen(false)} | ||
sdsIcon="xMark" | ||
sdsIconProps={{ | ||
color: 'gray', | ||
}} | ||
/> | ||
</header> | ||
|
||
<div className="px-sds-xl border-b-2 border-sds-gray-200"> | ||
<Tabs | ||
className="!m-0" | ||
tabs={TAB_OPTIONS} | ||
value={activeTab} | ||
onChange={(tab) => | ||
setSearchParams((params) => { | ||
params.set(ACTIVE_TAB_PARAM, tab) | ||
return params | ||
}) | ||
} | ||
/> | ||
</div> | ||
|
||
<div | ||
className={cns( | ||
'flex flex-col flex-auto', | ||
'px-sds-xl pt-sds-xl pb-sds-xxl', | ||
|
||
activeTab === MetadataTab.Metadata && | ||
'divide-y divide-sds-gray-300', | ||
)} | ||
> | ||
{activeTab === MetadataTab.Metadata && ( | ||
<> | ||
<DatasetMetadataTable /> | ||
<SampleAndExperimentConditionsTable /> | ||
<TiltSeriesTable /> | ||
</> | ||
)} | ||
|
||
{activeTab === MetadataTab.HowToCite && <Demo>How to cite</Demo>} | ||
</div> | ||
</div> | ||
</Drawer> | ||
) | ||
} |
51 changes: 51 additions & 0 deletions
51
frontend/packages/data-portal/app/components/Dataset/DatasetMetadataTable.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
import { useDatasetById } from 'app/hooks/useDatasetById' | ||
import { i18n } from 'app/i18n' | ||
|
||
import { AccordionMetadataTable } from './AccordionMetadataTable' | ||
import { getTableData } from './utils' | ||
|
||
export function DatasetMetadataTable() { | ||
const dataset = useDatasetById() | ||
const datasetMetadata = getTableData( | ||
{ | ||
label: i18n.depositionDate, | ||
values: [dataset.deposition_date], | ||
}, | ||
{ | ||
label: i18n.affiliationName, | ||
values: dataset.authors | ||
.map((author) => author.affiliation_name) | ||
.filter((value): value is string => !!value), | ||
}, | ||
{ | ||
label: i18n.fundingAgency, | ||
values: dataset.funding_sources.map( | ||
(source) => source.funding_agency_name, | ||
), | ||
}, | ||
{ | ||
label: i18n.relatedDatabases, | ||
values: dataset.funding_sources.map( | ||
(source) => source.funding_agency_name, | ||
), | ||
}, | ||
{ | ||
label: i18n.relatedDatabases, | ||
// TODO implement when data is available | ||
values: ['TBD'], | ||
}, | ||
{ | ||
label: i18n.citations, | ||
// TODO implement when data is available | ||
values: ['TBD'], | ||
}, | ||
) | ||
|
||
return ( | ||
<AccordionMetadataTable | ||
id="dataset-metadata" | ||
header={i18n.datasetMetadata} | ||
data={datasetMetadata} | ||
/> | ||
) | ||
} |
Oops, something went wrong.