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

feat: add filter panel to single deposition page #1030

Merged
merged 1 commit into from
Aug 16, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,23 +1,36 @@
import { GeneOntologyFilter } from 'app/components/AnnotationFilter/GeneOntologyFilter'
import {
AnnotatedObjectNameFilter,
AnnotatedObjectShapeTypeFilter,
FilterSection,
} from 'app/components/Filters'
import { useDatasets } from 'app/hooks/useDatasets'
import { useDatasetsFilterData } from 'app/hooks/useDatasetsFilterData'
import { useI18n } from 'app/hooks/useI18n'

export function AnnotationMetadataFilterSection() {
const { objectNames, objectShapeTypes } = useDatasets()
export function AnnotationMetadataFilterSection({
depositionPageVariant,
}: {
depositionPageVariant?: boolean
}) {
const { objectNames, objectShapeTypes } = useDatasetsFilterData()

const { t } = useI18n()

return (
<FilterSection title={t('annotationMetadata')} border={false}>
{depositionPageVariant && (
<p className="text-sds-body-xxs leading-sds-body-xxs text-sds-gray-500 pl-sds-s">
{t('depositionAnnotationsOnly')}
</p>
)}

<AnnotatedObjectNameFilter
allObjectNames={objectNames}
label={t('objectName')}
/>

{depositionPageVariant && <GeneOntologyFilter />}

<AnnotatedObjectShapeTypeFilter allObjectShapeTypes={objectShapeTypes} />
</FilterSection>
)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { ErrorBoundary } from 'app/components/ErrorBoundary'
import { FilterPanel } from 'app/components/Filters'

import { ErrorBoundary } from '../ErrorBoundary'
import { AnnotationMetadataFilterSection } from './AnnotationMetadataFilterSection'
import { HardwareFilterSection } from './HardwareFilterSection'
import { IncludedContentsFilterSection } from './IncludedContentsFilterSection'
Expand All @@ -9,11 +9,19 @@ import { SampleAndExperimentFilterSection } from './SampleAndExperimentFilterSec
import { TiltSeriesMetadataFilterSection } from './TiltSeriesMetadataFilterSection'
import { TomogramMetadataFilterSection } from './TomogramMetadataFilterSection'

export function DatasetFilter() {
export function DatasetFilter({
depositionPageVariant,
}: {
depositionPageVariant?: boolean
}) {
const filters = [
{
logId: 'included-contents-filter',
filter: <IncludedContentsFilterSection />,
filter: (
<IncludedContentsFilterSection
depositionPageVariant={depositionPageVariant}
/>
),
},
{
logId: 'name-or-id-filter',
Expand All @@ -37,7 +45,11 @@ export function DatasetFilter() {
},
{
logId: 'annotation-metadata-filter',
filter: <AnnotationMetadataFilterSection />,
filter: (
<AnnotationMetadataFilterSection
depositionPageVariant={depositionPageVariant}
/>
),
},
]

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,13 @@ import { useMemo } from 'react'

import { FilterSection, SelectFilter } from 'app/components/Filters'
import { QueryParams } from 'app/constants/query'
import { useDatasets } from 'app/hooks/useDatasets'
import { useDatasetsFilterData } from 'app/hooks/useDatasetsFilterData'
import { useFilter } from 'app/hooks/useFilter'
import { i18n } from 'app/i18n'
import { BaseFilterOption } from 'app/types/filter'

export function HardwareFilterSection() {
const { cameraManufacturers } = useDatasets()
const { cameraManufacturers } = useDatasetsFilterData()

const cameraManufacturerOptions = useMemo(
() => cameraManufacturers.map<BaseFilterOption>((value) => ({ value })),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,11 @@ const NUMBER_OF_RUN_OPTIONS: NumberOfRunsFilterOption[] = [
const AVAILABLE_FILES_CLASS_NAME = 'select-available-files'
const MEETS_ALL_LABEL_ID = 'meets-all'

export function IncludedContentsFilterSection() {
export function IncludedContentsFilterSection({
depositionPageVariant,
}: {
depositionPageVariant?: boolean
}) {
const {
updateValue,
includedContents: { availableFiles, numberOfRuns },
Expand Down Expand Up @@ -95,7 +99,9 @@ export function IncludedContentsFilterSection() {

return (
<FilterSection title={i18n.includedContents}>
<GroundTruthAnnotationFilter />
<GroundTruthAnnotationFilter
depositionPageVariant={depositionPageVariant}
/>

<SelectFilter
multiple
Expand All @@ -121,6 +127,13 @@ export function IncludedContentsFilterSection() {
option ? JSON.stringify(option.value) : null,
)
}
details={
depositionPageVariant ? (
<p className="text-sds-body-xxs leading-sds-body-xxs text-sds-gray-500">
{t('withDepositionData')}
</p>
) : undefined
}
/>
</FilterSection>
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { useMemo } from 'react'

import { FilterSection, SelectFilter } from 'app/components/Filters'
import { QueryParams } from 'app/constants/query'
import { useDatasets } from 'app/hooks/useDatasets'
import { useDatasetsFilterData } from 'app/hooks/useDatasetsFilterData'
import { useFilter } from 'app/hooks/useFilter'
import { i18n } from 'app/i18n'
import { BaseFilterOption } from 'app/types/filter'
Expand All @@ -12,7 +12,7 @@ export function SampleAndExperimentFilterSection() {
updateValue,
sampleAndExperimentConditions: { organismNames },
} = useFilter()
const { organismNames: allOrganismNames } = useDatasets()
const { organismNames: allOrganismNames } = useDatasetsFilterData()

const organismNameOptions = useMemo(
() => allOrganismNames.map<BaseFilterOption>((name) => ({ value: name })),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { useMemo } from 'react'

import { FilterSection, SelectFilter } from 'app/components/Filters'
import { QueryParams } from 'app/constants/query'
import { useDatasets } from 'app/hooks/useDatasets'
import { useDatasetsFilterData } from 'app/hooks/useDatasetsFilterData'
import { useFilter } from 'app/hooks/useFilter'
import { i18n } from 'app/i18n'
import {
Expand Down Expand Up @@ -36,7 +36,8 @@ export function TomogramMetadataFilterSection() {
)!
}, [fiducialAlignmentStatus])

const { reconstructionMethods, reconstructionSoftwares } = useDatasets()
const { reconstructionMethods, reconstructionSoftwares } =
useDatasetsFilterData()

const reconstructionMethodOptions = useMemo(
() => reconstructionMethods.map<BaseFilterOption>((value) => ({ value })),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,12 @@ import { cns } from 'app/utils/cns'
import styles from './Filters.module.css'

export function BooleanFilter({
caption,
label,
onChange,
value,
}: {
caption?: string
label: string
onChange(value: boolean): void
value: boolean
Expand All @@ -19,6 +21,7 @@ export function BooleanFilter({
checked={value}
onChange={(event) => onChange(event.target.checked)}
label={label}
caption={caption}
/>
</div>
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,20 +4,36 @@ import { useI18n } from 'app/hooks/useI18n'

import { BooleanFilter } from './BooleanFilter'

export function GroundTruthAnnotationFilter() {
export function GroundTruthAnnotationFilter({
depositionPageVariant,
}: {
depositionPageVariant?: boolean
}) {
const { t } = useI18n()
const {
updateValue,
includedContents: { isGroundTruthEnabled },
} = useFilter()

return (
<BooleanFilter
label={t('groundTruthAnnotation')}
onChange={(value) =>
updateValue(QueryParams.GroundTruthAnnotation, value ? 'true' : null)
}
value={isGroundTruthEnabled}
/>
<>
<BooleanFilter
label={t('groundTruthAnnotation')}
onChange={(value) =>
updateValue(QueryParams.GroundTruthAnnotation, value ? 'true' : null)
}
value={isGroundTruthEnabled}
// FIXME: once sds upgraded to 0.20.x uncomment this
// caption={
// depositionPageVariant ? t('depositionAnnotationsOnly') : undefined
// }
/>
{/* FIXME: once sds upgraded to 0.20.x delete below line and remove fragment wrapper */}
{depositionPageVariant && (
<p className="pl-[32px] text-sds-body-xxs leading-sds-body-xxs text-sds-gray-500">
{t('depositionAnnotationsOnly')}
</p>
)}
</>
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import {
Value,
} from '@czi-sds/components'
import { isArray, isEqual } from 'lodash-es'
import { useCallback, useMemo } from 'react'
import { ReactNode, useCallback, useMemo } from 'react'

import { BaseFilterOption } from 'app/types/filter'
import { cns } from 'app/utils/cns'
Expand All @@ -20,6 +20,7 @@ export function SelectFilter<
Multiple extends boolean = false,
>({
className,
details,
groupBy: groupByProp,
label,
multiple,
Expand All @@ -31,6 +32,7 @@ export function SelectFilter<
value,
}: {
className?: string
details?: ReactNode
groupBy?: (option: Value<Option, Multiple>) => string
label: string
multiple?: Multiple
Expand Down Expand Up @@ -109,6 +111,15 @@ export function SelectFilter<
className: cns(popperClassName, multiple && styles.popper),
},
}}
InputDropdownProps={
details
? {
value: details,
sdsStyle: 'minimal',
sdsType: 'label',
}
: undefined
}
onChange={(nextOptions) => {
if (isEqual(nextOptions, sdsValue)) {
return
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,30 +63,6 @@ const GET_DATASETS_DATA_QUERY = gql(`
count
}
}

organism_names: datasets(distinct_on: organism_name) {
organism_name
}

camera_manufacturers: tiltseries(distinct_on: camera_manufacturer) {
camera_manufacturer
}

reconstruction_methods: tomograms(distinct_on: reconstruction_method) {
reconstruction_method
}

reconstruction_softwares: tomograms(distinct_on: reconstruction_software) {
reconstruction_software
}

object_names: annotations(distinct_on: object_name) {
object_name
}

object_shape_types: annotation_files(distinct_on: shape_type) {
shape_type
}
}
`)

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import type { ApolloClient, NormalizedCacheObject } from '@apollo/client'

import { gql } from 'app/__generated__'
import { Datasets_Bool_Exp } from 'app/__generated__/graphql'

const GET_DATASETS_FILTER_DATA_QUERY = gql(`
Copy link
Contributor

Choose a reason for hiding this comment

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

Is it possible to just make this a fragment? https://www.apollographql.com/docs/react/data/fragments/ That way any query can add this just by concatenating the string. It should generate the type too, hopefully that would work with useTypedLoaderData()?

const TEST_FRAGMENT = gql(`
  fragment TestFragment on query_root {
    datasets {
      organism_name
    }
  }  
`)
useTypedLoaderData<TestFragmentFragment>()

Copy link
Member Author

Choose a reason for hiding this comment

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

yes i think so. a lot of the codebase could actually benefit from fragments (for example authors)

how important do you think this is? since i have low bandwidth i would prefer to keep this as-is and make the refactor along with the other places we should be using fragments

Copy link
Contributor

Choose a reason for hiding this comment

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

I don't think it's too important! Maybe file a ticket?

query GetDatasetsFilterData(
$filter: datasets_bool_exp,
) {
organism_names: datasets(where: $filter, distinct_on: organism_name) {
organism_name
}

camera_manufacturers: tiltseries(distinct_on: camera_manufacturer) {
camera_manufacturer
}

reconstruction_methods: tomograms(distinct_on: reconstruction_method) {
reconstruction_method
}

reconstruction_softwares: tomograms(distinct_on: reconstruction_software) {
reconstruction_software
}

object_names: annotations(distinct_on: object_name) {
object_name
}

object_shape_types: annotation_files(distinct_on: shape_type) {
shape_type
}
}
`)

export async function getDatasetsFilterData({
client,
filter = {},
}: {
client: ApolloClient<NormalizedCacheObject>
filter: Datasets_Bool_Exp
}) {
const start = performance.now()

const results = await client.query({
query: GET_DATASETS_FILTER_DATA_QUERY,
variables: {
filter,
},
})

const end = performance.now()
// eslint-disable-next-line no-console
console.log(`getDatasetsFilterData query perf: ${end - start}ms`)

return results
}
Loading
Loading