Skip to content

Commit

Permalink
add single run metadata table (#124)
Browse files Browse the repository at this point in the history
  • Loading branch information
kne42 authored Nov 9, 2023
1 parent 745b75d commit e4fb291
Show file tree
Hide file tree
Showing 30 changed files with 1,109 additions and 357 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import { ComponentProps } from 'react'

import { Accordion } from 'app/components/Accordion'
import { MetadataTable } from 'app/components/Table'

type AccordionProps = Pick<
ComponentProps<typeof Accordion>,
'id' | 'header' | 'initialOpen'
>
type MetadataTableProps = Pick<
ComponentProps<typeof MetadataTable>,
'data' | 'tableCellProps' | 'tableHeaderProps'
>

export function AccordionMetadataTable({
data,
header,
id,
initialOpen = true,
tableCellProps,
tableHeaderProps,
}: AccordionProps & MetadataTableProps) {
return (
<Accordion id={id} header={header} initialOpen={initialOpen}>
<MetadataTable
data={data}
tableHeaderProps={{
renderLoadingSkeleton: false,
...tableHeaderProps,
}}
tableCellProps={{
renderLoadingSkeleton: false,
...tableCellProps,
}}
/>
</Accordion>
)
}
51 changes: 51 additions & 0 deletions frontend/packages/data-portal/app/components/DatabaseEntry.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import { Link } from 'app/components/Link'
import {
DatabaseType,
LABEL_MAP,
REGEX_MAP,
URL_MAP,
} from 'app/constants/external-dbs'
import { cns } from 'app/utils/cns'

interface DatabaseEntryProps {
entry: string
inline?: boolean
}

export function DatabaseEntry(props: DatabaseEntryProps) {
const { entry, inline } = props
let dbtype: DatabaseType | undefined
let id: string = ''

for (const [dbt, pattern] of REGEX_MAP) {
const match = pattern.exec(entry)
if (match !== null) {
dbtype = dbt
// eslint-disable-next-line prefer-destructuring
id = match[1]
break
}
}

if (dbtype === undefined) {
return <p>{entry}</p>
}

return (
<p className="flex flex-row gap-sds-xs">
{(!inline || dbtype === DatabaseType.DOI) && (
<span
className={cns('text-sds-gray-black', !inline && 'font-semibold')}
>
{LABEL_MAP.get(dbtype)}:
</span>
)}
<Link
className={cns('text-sds-info-400', inline && 'truncate')}
to={URL_MAP.get(dbtype) + id}
>
{entry}
</Link>
</p>
)
}

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
import { Dataset_Authors } from 'app/__generated__/graphql'
import { EnvelopeIcon } from 'app/components/icons'
import { Link } from 'app/components/Link'

export type AuthorInfo = Pick<
Dataset_Authors,
'name' | 'primary_author_status' | 'corresponding_author_status' | 'email'
>

export function DatasetAuthors({
authors,
className,
}: {
authors: AuthorInfo[]
className?: string
}) {
// TODO: make the below grouping more efficient and/or use GraphQL ordering
const authorsPrimary = authors.filter(
(author) => author.primary_author_status,
)
const authorsCorresponding = authors.filter(
(author) => author.corresponding_author_status,
)
const authorsOther = authors.filter(
(author) =>
!(author.primary_author_status || author.corresponding_author_status),
)

const envelopeIcon = (
<EnvelopeIcon className="text-sds-gray-400 mx-sds-xxxs align-top inline-block h-sds-icon-xs w-sds-icon-xs" />
)

// TODO: let's find a better way of doing this
return (
<p className={className}>
<span className="font-semibold">
{authorsPrimary.map((author, i, arr) => (
<>
{author.name}
{!(
authorsOther.length + authorsCorresponding.length === 0 &&
arr.length - 1 === i
) && '; '}
</>
))}
</span>
<span className="text-sds-gray-600">
{authorsOther.map((author, i, arr) => (
<>
{author.name}
{!(authorsCorresponding.length === 0 && arr.length - 1 === i) &&
'; '}
</>
))}
{authorsCorresponding.map((author, i, arr) => (
<>
{author.name}
{author.email ? (
<Link to={`mailto:${author.email}`}>{envelopeIcon}</Link>
) : (
envelopeIcon
)}
{!(arr.length - 1 === i) && '; '}
</>
))}
</span>
</p>
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,60 +2,20 @@ import { Button } from '@czi-sds/components'
import clsx from 'clsx'
import { useState } from 'react'

import { EnvelopeIcon } from 'app/components/icons'
import { Link } from 'app/components/Link'
import {
DatabaseType,
DOI_ID,
LABEL_MAP,
REGEX_MAP,
URL_MAP,
} from 'app/constants/external-dbs'
import { DatabaseEntry } from 'app/components/DatabaseEntry'
import { DOI_ID } from 'app/constants/external-dbs'
import { useDatasetById } from 'app/hooks/useDatasetById'
import { i18n } from 'app/i18n'

import { DatasetAuthors } from './DatasetAuthors'

// use clsx here instead of cns since it erroneously merges text-sds-gray-500 and text-sds-caps-xxxs
const sectionHeaderStyles = clsx(
'font-semibold uppercase',
'text-sds-gray-500',
'text-sds-caps-xxxs leading-sds-caps-xxxs tracking-sds-caps',
)

interface DatabaseEntryProps {
entry: string
}

function DatabaseEntry(props: DatabaseEntryProps) {
const { entry } = props
let dbtype: DatabaseType | undefined
let id: string = ''

for (const [dbt, pattern] of REGEX_MAP) {
const match = pattern.exec(entry)
if (match !== null) {
dbtype = dbt
// eslint-disable-next-line prefer-destructuring
id = match[1]
break
}
}

if (dbtype === undefined) {
return <p>{entry}</p>
}

return (
<p className="text-sds-body-xxs leading-sds-body-xxs flex flex-row gap-sds-xs">
<span className="text-sds-gray-black font-semibold">
{LABEL_MAP.get(dbtype)}:
</span>
<Link className="text-sds-primary-400" to={URL_MAP.get(dbtype) + id}>
{entry}
</Link>
</p>
)
}

interface DatabaseListProps {
title: string
entries?: string[]
Expand All @@ -76,16 +36,11 @@ function DatabaseList(props: DatabaseListProps) {
<div className={clsx(className, 'flex flex-col gap-sds-xs')}>
<h3 className={sectionHeaderStyles}>{title}</h3>
{entries ? (
<ul
className={clsx(
'flex flex-col gap-sds-xxs',
collapsible && 'transition-[max-height_0.2s_ease-out]',
)}
>
<ul className="flex flex-col gap-sds-xxs">
{entries.map(
(e, i) =>
!(collapsible && collapsed && i + 1 > collapseAfter) && (
<li key={e}>
<li className="text-sds-body-xxs leading-sds-body-xxs" key={e}>
<DatabaseEntry entry={e} />
</li>
),
Expand Down Expand Up @@ -118,18 +73,6 @@ function DatabaseList(props: DatabaseListProps) {
export function DatasetDescription() {
const { dataset } = useDatasetById()

// TODO: make the below grouping more efficient and/or use GraphQL ordering
const authorsPrimary = dataset.authors.filter(
(author) => author.primary_author_status,
)
const authorsCorresponding = dataset.authors.filter(
(author) => author.corresponding_author_status,
)
const authorsOther = dataset.authors.filter(
(author) =>
!(author.primary_author_status || author.corresponding_author_status),
)

// clean up entries into lists
const publicationEntries = dataset.dataset_publications
?.split(',')
Expand All @@ -140,51 +83,17 @@ export function DatasetDescription() {
?.split(',')
.map((e) => e.trim())

const envelopeIcon = (
<EnvelopeIcon className="text-sds-gray-400 mx-sds-xxxs align-top inline-block h-sds-icon-xs w-sds-icon-xs" />
)

return (
<div className="flex flex-col gap-sds-xl">
<p className="text-sds-body-m leading-sds-body-m">
{dataset.description}
</p>
<div className="flex flex-col gap-sds-xs">
<h3 className={sectionHeaderStyles}>{i18n.authors}</h3>
{/* TODO: let's find a better way of doing this */}
<p className="text-sds-body-xxs leading-sds-body-xxs">
<span className="font-semibold">
{authorsPrimary.map((author, i, arr) => (
<>
{author.name}
{!(
authorsOther.length + authorsCorresponding.length === 0 &&
arr.length - 1 === i
) && '; '}
</>
))}
</span>
<span className="text-sds-gray-600">
{authorsOther.map((author, i, arr) => (
<>
{author.name}
{!(authorsCorresponding.length === 0 && arr.length - 1 === i) &&
'; '}
</>
))}
{authorsCorresponding.map((author, i, arr) => (
<>
{author.name}
{author.email ? (
<Link to={`mailto:${author.email}`}>{envelopeIcon}</Link>
) : (
envelopeIcon
)}
{!(arr.length - 1 === i) && '; '}
</>
))}
</span>
</p>
<DatasetAuthors
authors={dataset.authors}
className="text-sds-body-xxs leading-sds-body-xxs"
/>
</div>
<div className="flex flex-row gap-sds-xxl">
<DatabaseList
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,14 @@ import { KeyPhoto } from 'app/components/KeyPhoto'
import { Link } from 'app/components/Link'
import { useDatasetById } from 'app/hooks/useDatasetById'
import { i18n } from 'app/i18n'
import { useDatasetDrawer } from 'app/state/drawer'
import { useDrawer } from 'app/state/drawer'
import { cns } from 'app/utils/cns'

export function DatasetHeader() {
const [params] = useSearchParams()
const previousUrl = params.get('prev')
const { dataset } = useDatasetById()
const drawer = useDatasetDrawer()
const drawer = useDrawer()

return (
<div className="flex flex-auto justify-center px-sds-xl pt-sds-l pb-sds-xxl">
Expand Down Expand Up @@ -66,7 +66,7 @@ export function DatasetHeader() {
{/* portal ID */}
<div className="flex flex-row items-center justify-left gap-sds-xxs text-sds-gray-500">
<p className="font-semibold uppercase text-sds-caps-xxs leading-sds-caps-xxs tracking-sds-caps">
{i18n.portalIdBlank}
{i18n.portalIdBlank}:
</p>
<p className="text-sds-body-s leading-sds-body-s">
{dataset.id}
Expand Down
Loading

0 comments on commit e4fb291

Please sign in to comment.