Skip to content

Commit

Permalink
uxr minor updates (#229)
Browse files Browse the repository at this point in the history
#157

- Adds new tooltips + Tooltip component and utils
- Adds survey banner
- Add redundant more info button

## Demos

### Tooltips

<img width="343" alt="image"
src="https://github.com/chanzuckerberg/cryoet-data-portal/assets/2176050/3cb3d186-8135-49f9-ad27-898418aa35a1">

<img width="338" alt="image"
src="https://github.com/chanzuckerberg/cryoet-data-portal/assets/2176050/12a29396-77b9-4a5f-81eb-d47db4caae89">

<img width="354" alt="image"
src="https://github.com/chanzuckerberg/cryoet-data-portal/assets/2176050/45d2034c-cce0-4f4f-bc8e-ce6d953f0fdc">

<img width="343" alt="image"
src="https://github.com/chanzuckerberg/cryoet-data-portal/assets/2176050/14dccb62-f293-43d6-8da7-e814e2a25fbc">

<img width="354" alt="image"
src="https://github.com/chanzuckerberg/cryoet-data-portal/assets/2176050/4755f672-de1d-4918-837e-0fca06bca3c2">

<img width="350" alt="image"
src="https://github.com/chanzuckerberg/cryoet-data-portal/assets/2176050/5c90f44e-7c9f-474b-914c-5b93f31cff32">

<img width="331" alt="image"
src="https://github.com/chanzuckerberg/cryoet-data-portal/assets/2176050/c52e57f5-b23c-46ff-95ef-3e15b873bed4">

### Survey Banner

<img width="1728" alt="image"
src="https://github.com/chanzuckerberg/cryoet-data-portal/assets/2176050/ab7e1152-eac7-4334-8da3-fd67160f01a1">

### Redundant more info button

<img width="510" alt="image"
src="https://github.com/chanzuckerberg/cryoet-data-portal/assets/2176050/9ac256f4-a694-4b07-b6a2-60ec9201cef1">


<img width="687" alt="image"
src="https://github.com/chanzuckerberg/cryoet-data-portal/assets/2176050/3cb42f7e-4c95-4cae-a4cb-fbfb31e9de22">
  • Loading branch information
codemonkey800 authored Dec 8, 2023
1 parent 77b620a commit 8b21d8a
Show file tree
Hide file tree
Showing 23 changed files with 529 additions and 162 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -9,23 +9,31 @@ type AccordionProps = Pick<
>
type MetadataTableProps = Pick<
ComponentProps<typeof MetadataTable>,
'data' | 'tableCellProps'
'data' | 'tableCellLabelProps' | 'tableCellValueProps'
>

export function AccordionMetadataTable({
data,
header,
id,
initialOpen = true,
tableCellProps,
tableCellLabelProps,
tableCellValueProps,
}: AccordionProps & MetadataTableProps) {
return (
<Accordion id={id} header={header} initialOpen={initialOpen}>
<MetadataTable
data={data}
tableCellProps={{
tableCellLabelProps={{
renderLoadingSkeleton: false,
...tableCellProps,
minWidth: 170,
maxWidth: 170,
...tableCellLabelProps,
}}
tableCellValueProps={{
renderLoadingSkeleton: false,
minWidth: 170,
...tableCellValueProps,
}}
/>
</Accordion>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,23 +1,23 @@
/* eslint-disable react/no-unstable-nested-components */

import { CellHeader, CellHeaderDirection } from '@czi-sds/components'
import { CellHeaderDirection } from '@czi-sds/components'
import Skeleton from '@mui/material/Skeleton'
import { useLocation, useSearchParams } from '@remix-run/react'
import { ColumnDef, createColumnHelper } from '@tanstack/react-table'
import { range } from 'lodash-es'
import { useMemo } from 'react'

import { AnnotatedObjectsList } from 'app/components/AnnotatedObjectsList'
import { I18n } from 'app/components/I18n'
import { KeyPhoto } from 'app/components/KeyPhoto'
import { Link } from 'app/components/Link'
import { PageTable, TableCell } from 'app/components/Table'
import { CellHeader, PageTable, TableCell } from 'app/components/Table'
import { EMPIAR_ID, EMPIAR_URL } from 'app/constants/external-dbs'
import { ANNOTATED_OBJECTS_MAX, MAX_PER_PAGE } from 'app/constants/pagination'
import { Dataset, useDatasets } from 'app/hooks/useDatasets'
import { useI18n } from 'app/hooks/useI18n'
import { useIsLoading } from 'app/hooks/useIsLoading'

import { AnnotatedObjectsList } from '../AnnotatedObjectsList'

/**
* Max number of authors to show for dataset.
*/
Expand Down Expand Up @@ -188,7 +188,16 @@ export function DatasetTable() {
columnHelper.accessor(
(dataset) => dataset.runs_aggregate.aggregate?.count,
{
header: t('runs'),
id: 'runs',
header: () => (
<CellHeader
hideSortIcon
tooltip={<I18n i18nKey="runsTooltip" />}
arrowPadding={{ right: 270 }}
>
{t('runs')}
</CellHeader>
),
cell: ({ getValue }) => (
<TableCell
primaryText={String(getValue() ?? 0).padStart(4, '0')}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import { Fragment } from 'react'

import { Dataset_Authors } from 'app/__generated__/graphql'
import { EnvelopeIcon } from 'app/components/icons'
import { Link } from 'app/components/Link'
Expand All @@ -7,6 +9,10 @@ export type AuthorInfo = Pick<
'name' | 'primary_author_status' | 'corresponding_author_status' | 'email'
>

function getAuthorKey(author: AuthorInfo) {
return author.name + author.email
}

export function DatasetAuthors({
authors,
className,
Expand Down Expand Up @@ -35,33 +41,33 @@ export function DatasetAuthors({
<p className={className}>
<span className="font-semibold">
{authorsPrimary.map((author, i, arr) => (
<>
<Fragment key={getAuthorKey(author)}>
{author.name}
{!(
authorsOther.length + authorsCorresponding.length === 0 &&
arr.length - 1 === i
) && '; '}
</>
</Fragment>
))}
</span>
<span className="text-sds-gray-600">
{authorsOther.map((author, i, arr) => (
<>
<Fragment key={getAuthorKey(author)}>
{author.name}
{!(authorsCorresponding.length === 0 && arr.length - 1 === i) &&
'; '}
</>
</Fragment>
))}
{authorsCorresponding.map((author, i, arr) => (
<>
<Fragment key={getAuthorKey(author)}>
{author.name}
{author.email ? (
<Link to={`mailto:${author.email}`}>{envelopeIcon}</Link>
) : (
envelopeIcon
)}
{!(arr.length - 1 === i) && '; '}
</>
</Fragment>
))}
</span>
</p>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,22 +37,25 @@ export function DatasetHeader() {
onMoreInfoClick={() => drawer.setActiveDrawerId('dataset-metadata')}
releaseDate={dataset.release_date}
title={dataset.title}
>
<div className="flex flex-row justify-between gap-sds-xxl px-sds-xl pb-sds-xxl">
<div className="flex-1 min-w-[300px]">
<DatasetDescription />
</div>
renderHeader={({ moreInfo }) => (
<div className="flex flex-row justify-between gap-sds-xxl px-sds-xl pb-sds-xxl">
<div className="flex flex-col gap-sds-xl flex-1 min-w-[300px]">
<DatasetDescription />

{moreInfo}
</div>

{/* 465 + 38 = 503px */}
<div className="flex-1 max-w-[503px] text-right">
<div className="max-w-[465px] w-full inline-block">
<KeyPhoto
title={dataset.title}
src={dataset.key_photo_url ?? undefined}
/>
{/* 465 + 38 = 503px */}
<div className="flex-1 max-w-[503px] text-right">
<div className="max-w-[465px] w-full inline-block">
<KeyPhoto
title={dataset.title}
src={dataset.key_photo_url ?? undefined}
/>
</div>
</div>
</div>
</div>
</PageHeader>
)}
/>
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -64,12 +64,12 @@ export function DatasetMetadataTable({
},

!!allFields && {
label: t('releaseDateBlank'),
label: t('releaseDate'),
values: [dataset.release_date!],
},

!!allFields && {
label: t('lastModifiedBlank'),
label: t('lastModified'),
values: [dataset.last_modified_date!],
},

Expand Down
27 changes: 21 additions & 6 deletions frontend/packages/data-portal/app/components/Dataset/RunsTable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,19 +8,19 @@ import { range } from 'lodash-es'
import { useMemo } from 'react'

import { GetDatasetByIdQuery } from 'app/__generated__/graphql'
import { AnnotatedObjectsList } from 'app/components/AnnotatedObjectsList'
import { I18n } from 'app/components/I18n'
import { KeyPhoto } from 'app/components/KeyPhoto'
import { Link } from 'app/components/Link'
import { PageTable, TableCell } from 'app/components/Table'
import { CellHeader, PageTable, TableCell } from 'app/components/Table'
import { TiltSeriesQualityScoreBadge } from 'app/components/TiltSeriesQualityScoreBadge'
import { MAX_PER_PAGE } from 'app/constants/pagination'
import { TiltSeriesScore } from 'app/constants/tiltSeries'
import { useDatasetById } from 'app/hooks/useDatasetById'
import { useI18n } from 'app/hooks/useI18n'
import { useIsLoading } from 'app/hooks/useIsLoading'
import { inQualityScoreRange } from 'app/utils/tiltSeries'

import { AnnotatedObjectsList } from '../AnnotatedObjectsList'
import { TiltSeriesQualityScoreBadge } from '../TiltSeriesQualityScoreBadge'

type Run = GetDatasetByIdQuery['datasets'][number]['runs'][number]

const LOADING_RUNS = range(0, MAX_PER_PAGE).map(() => ({}) as Run)
Expand All @@ -37,7 +37,14 @@ export function RunsTable() {

return [
columnHelper.accessor('name', {
header: t('run'),
header: () => (
<CellHeader
tooltip={<I18n i18nKey="runsTooltip" />}
arrowPadding={{ right: 260 }}
>
{t('runs')}
</CellHeader>
),
cell({ row: { original: run } }) {
const previousUrl = `${location.pathname}${location.search}`
const runUrl = `/runs/${run.id}?prev=${encodeURIComponent(
Expand Down Expand Up @@ -75,7 +82,15 @@ export function RunsTable() {
columnHelper.accessor(
(run) => run.tiltseries_aggregate?.aggregate?.avg?.tilt_series_quality,
{
header: t('tiltSeriesQualityScore'),
id: 'tilt-series-quality',
header: () => (
<CellHeader
hideSortIcon
tooltip={<I18n i18nKey="tiltSeriesTooltip" />}
>
{t('tiltSeriesQualityScore')}
</CellHeader>
),
cell: ({ getValue }) => {
const score = getValue() as TiltSeriesScore | null | undefined

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import { ReactNode } from 'react'

import { SurveyBanner } from 'app/components/SurveyBanner'

import { Footer } from './Footer'
import { TopNavigation } from './TopNavigation'

Expand All @@ -9,6 +11,7 @@ export function Layout({ children }: { children: ReactNode }) {
<TopNavigation />
<div className="flex flex-col flex-[1_0_auto]">{children}</div>
<Footer />
<SurveyBanner />
</main>
)
}
59 changes: 41 additions & 18 deletions frontend/packages/data-portal/app/components/PageHeader.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { useSearchParams } from '@remix-run/react'
import { ReactNode } from 'react'

import { Link } from 'app/components/Link'
import { i18n } from 'app/i18n'
import { useI18n } from 'app/hooks/useI18n'
import { cns } from 'app/utils/cns'

interface PageHeaderMetadata {
Expand All @@ -14,25 +14,26 @@ interface PageHeaderMetadata {

export function PageHeader({
actions,
backToResultsLabel = i18n.backToResults,
children,
backToResultsLabel,
lastModifiedDate,
metadata = [],
onMoreInfoClick,
releaseDate,
renderHeader,
title,
}: {
actions?: ReactNode
backToResultsLabel?: string
children?: ReactNode
lastModifiedDate?: string
metadata?: PageHeaderMetadata[]
onMoreInfoClick?(): void
releaseDate?: string
renderHeader?({ moreInfo }: { moreInfo?: ReactNode }): ReactNode
title: ReactNode
}) {
const [params] = useSearchParams()
const previousUrl = params.get('prev')
const { t } = useI18n()

return (
<div className="flex flex-auto justify-center">
Expand Down Expand Up @@ -67,7 +68,7 @@ export function PageHeader({
className="!w-[10px] !h-[10px] !fill-sds-primary-400"
/>
<span className="text-sds-primary-400 font-semibold text-sds-header-s leading-sds-header-s">
{backToResultsLabel}
{backToResultsLabel ?? t('backToResults')}
</span>
</Link>
</div>
Expand Down Expand Up @@ -120,12 +121,18 @@ export function PageHeader({
'my-sds-l',
)}
>
{releaseDate && <p>{i18n.releaseDate(releaseDate)}</p>}
{releaseDate && (
<p>
{t('releaseDate')}: {releaseDate}
</p>
)}

<div className="h-3 w-px bg-sds-gray-400" />

{lastModifiedDate && (
<p>{i18n.lastModified(lastModifiedDate)}</p>
<p>
{t('lastModified')}: {lastModifiedDate}
</p>
)}
</div>
)}
Expand All @@ -134,20 +141,36 @@ export function PageHeader({
<div className="flex flex-row row-start-2 col-start-2 gap-sds-m justify-between min-w-[315px]">
{actions}

<Button
startIcon={
<Icon sdsIcon="infoCircle" sdsType="button" sdsSize="l" />
}
sdsType="secondary"
sdsStyle="rounded"
onClick={onMoreInfoClick}
>
{i18n.moreInfo}
</Button>
{onMoreInfoClick && (
<Button
startIcon={
<Icon sdsIcon="infoCircle" sdsType="button" sdsSize="l" />
}
sdsType="secondary"
sdsStyle="rounded"
onClick={onMoreInfoClick}
>
{t('moreInfo')}
</Button>
)}
</div>
</div>

{children}
{renderHeader?.({
moreInfo: onMoreInfoClick && (
<div className="flex w-full">
<Button
className="flex items-center gap-sds-xxs"
sdsType="primary"
sdsStyle="minimal"
onClick={onMoreInfoClick}
>
<Icon sdsIcon="infoCircle" sdsSize="s" sdsType="button" />
<span>{t('moreInfo')}</span>
</Button>
</div>
),
})}
</div>
</header>
</div>
Expand Down
Loading

0 comments on commit 8b21d8a

Please sign in to comment.