Skip to content

Commit 5f2012f

Browse files
codemonkey800claudeczi-github-helper[bot]
authored
feat: add dataset and organism filters to deposition page (#1876)
* feat: add reusable dataset and organism filter components - Add DatasetNameOrIdFilter component with search and multi-select - Add OrganismNameFilter component extracted from SampleAndExperimentFilterSection - Both components use SelectFilter with consistent styling 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com> * refactor: extract OrganismNameFilter from SampleAndExperimentFilterSection - Replace inline organism filter logic with reusable OrganismNameFilter component - Simplify SampleAndExperimentFilterSection by using the extracted component - Use useI18n hook for internationalization consistency 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com> * feat: add dataset and organism filters to deposition page - Add DatasetNameOrIdFilter and OrganismNameFilter to DepositionFilters - Add visual divider and "Filter by:" section for better organization - Maintain consistent spacing and styling with other filter sections 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com> * chore: Updated [rdev] values.yaml image tags to sha-24314f0 * add missing padding above filter chips * chore: Updated [rdev] values.yaml image tags to sha-b628ed0 --------- Co-authored-by: Claude <noreply@anthropic.com> Co-authored-by: czi-github-helper[bot] <+czi-github-helper[bot]@users.noreply.github.com>
1 parent 79293cf commit 5f2012f

File tree

8 files changed

+166
-43
lines changed

8 files changed

+166
-43
lines changed

.infra/rdev/values.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ stack:
22
services:
33
frontend:
44
image:
5-
tag: sha-01d81cb
5+
tag: sha-b628ed0
66
replicaCount: 1
77
env:
88
- name: API_URL_V2
Lines changed: 6 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,39 +1,13 @@
1-
import { useMemo } from 'react'
2-
3-
import { FilterSection, SelectFilter } from 'app/components/Filters'
4-
import { QueryParams } from 'app/constants/query'
5-
import { useDatasetsFilterData } from 'app/hooks/useDatasetsFilterData'
6-
import { useFilter } from 'app/hooks/useFilter'
7-
import { i18n } from 'app/i18n'
8-
import { BaseFilterOption } from 'app/types/filter'
1+
import { FilterSection } from 'app/components/Filters'
2+
import { OrganismNameFilter } from 'app/components/Filters/OrganismNameFilter'
3+
import { useI18n } from 'app/hooks/useI18n'
94

105
export function SampleAndExperimentFilterSection() {
11-
const {
12-
updateValue,
13-
sampleAndExperimentConditions: { organismNames },
14-
} = useFilter()
15-
const { organismNames: allOrganismNames } = useDatasetsFilterData()
16-
17-
const organismNameOptions = useMemo(
18-
() => allOrganismNames.map<BaseFilterOption>((name) => ({ value: name })),
19-
[allOrganismNames],
20-
)
21-
22-
const organismNameValue = useMemo(
23-
() => organismNames.map<BaseFilterOption>((value) => ({ value })),
24-
[organismNames],
25-
)
6+
const { t } = useI18n()
267

278
return (
28-
<FilterSection title={i18n.sampleAndExperimentConditions}>
29-
<SelectFilter
30-
multiple
31-
search
32-
options={organismNameOptions}
33-
value={organismNameValue}
34-
label={i18n.organismName}
35-
onChange={(options) => updateValue(QueryParams.Organism, options)}
36-
/>
9+
<FilterSection title={t('sampleAndExperimentConditions')}>
10+
<OrganismNameFilter />
3711
</FilterSection>
3812
)
3913
}

frontend/packages/data-portal/app/components/Deposition/DepositionFilters.tsx

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,13 @@
1+
import Divider from '@mui/material/Divider'
12
import { useMemo } from 'react'
23

4+
import { OrganismNameFilter } from 'app/components/Filters/OrganismNameFilter'
35
import { useDepositionById } from 'app/hooks/useDepositionById'
46
import { useI18n } from 'app/hooks/useI18n'
57
import { cns } from 'app/utils/cns'
68
import { getDataContents } from 'app/utils/deposition'
79

10+
import { DatasetNameOrIdFilter } from '../Filters/DatasetNameOrIdFilter'
811
import { DepositionTabs } from './DepositionTabs'
912

1013
export function DepositionFilters() {
@@ -64,6 +67,25 @@ export function DepositionFilters() {
6467
</div>
6568
))}
6669
</div>
70+
71+
<Divider className="bg-light-sds-color-semantic-base-divider h-[3px] !mt-[60px] !mb-sds-xl" />
72+
73+
<div>
74+
<h3
75+
className={cns(
76+
'text-sds-header-m-600-wide font-semibold',
77+
'tracking-sds-header-m-600-wide leading-sds-header-m',
78+
'px-sds-xl mb-sds-s',
79+
)}
80+
>
81+
{t('filterBy')}:
82+
</h3>
83+
84+
<div className="px-sds-l flex flex-col gap-sds-xxs">
85+
<DatasetNameOrIdFilter />
86+
<OrganismNameFilter />
87+
</div>
88+
</div>
6789
</div>
6890
)
6991
}
Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
import { useMemo } from 'react'
2+
3+
import { SelectFilter } from 'app/components/Filters'
4+
import { IdPrefix } from 'app/constants/idPrefixes'
5+
import { QueryParams } from 'app/constants/query'
6+
import { useFilter } from 'app/hooks/useFilter'
7+
import { useI18n } from 'app/hooks/useI18n'
8+
import { type BaseFilterOption } from 'app/types/filter'
9+
10+
const MOCK_DATA = [
11+
{
12+
id: 10301,
13+
title: 'Dataset Name A',
14+
},
15+
{
16+
id: 10302,
17+
title: 'Dataset Name B',
18+
},
19+
{
20+
id: 10303,
21+
title: 'Dataset Name C',
22+
},
23+
{
24+
id: 10304,
25+
title: 'Dataset Name D',
26+
},
27+
{
28+
id: 10305,
29+
title: 'Dataset Name E',
30+
},
31+
{
32+
id: 10306,
33+
title: 'Dataset Name F',
34+
},
35+
{
36+
id: 10307,
37+
title: 'Dataset Name G',
38+
},
39+
{
40+
id: 10308,
41+
title: 'Dataset Name H',
42+
},
43+
]
44+
45+
export function DatasetNameOrIdFilter() {
46+
const {
47+
updateValue,
48+
ids: { datasets: datasetIds },
49+
} = useFilter()
50+
const { t } = useI18n()
51+
const datasets = MOCK_DATA
52+
53+
const allDatasetOptions = useMemo<BaseFilterOption[]>(
54+
() =>
55+
datasets.map((dataset) => ({
56+
value: String(dataset.id),
57+
label: dataset.title,
58+
details: `${IdPrefix.Dataset}-${dataset.id}`,
59+
})),
60+
[datasets],
61+
)
62+
63+
const datasetValue = useMemo<BaseFilterOption[]>(
64+
() =>
65+
datasetIds.map((id) => {
66+
const dataset = datasets.find((d) => String(d.id) === id)
67+
return {
68+
value: id,
69+
label: dataset?.title ?? `Dataset ${id}`,
70+
details: `${IdPrefix.Dataset}-${id}`,
71+
}
72+
}),
73+
[datasetIds, datasets],
74+
)
75+
76+
return (
77+
<SelectFilter
78+
multiple
79+
search
80+
options={allDatasetOptions}
81+
value={datasetValue}
82+
label={t('datasetName')}
83+
onChange={(options) => {
84+
updateValue(QueryParams.DatasetId, options)
85+
}}
86+
popperClassName="max-w-[368px]"
87+
/>
88+
)
89+
}

frontend/packages/data-portal/app/components/Filters/Filters.module.css

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@
3939
padding: 5px theme('padding.sds-s');
4040

4141
~ div {
42-
@apply pl-sds-s;
42+
@apply pl-sds-s pt-sds-xxxs;
4343
@apply mt-0;
4444

4545
&:empty {
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
import { useMemo } from 'react'
2+
3+
import { SelectFilter } from 'app/components/Filters'
4+
import { QueryParams } from 'app/constants/query'
5+
import { useDatasetsFilterData } from 'app/hooks/useDatasetsFilterData'
6+
import { useFilter } from 'app/hooks/useFilter'
7+
import { useI18n } from 'app/hooks/useI18n'
8+
import { BaseFilterOption } from 'app/types/filter'
9+
10+
export function OrganismNameFilter() {
11+
const {
12+
updateValue,
13+
sampleAndExperimentConditions: { organismNames },
14+
} = useFilter()
15+
const { organismNames: allOrganismNames } = useDatasetsFilterData()
16+
17+
const organismNameOptions = useMemo(
18+
() => allOrganismNames.map<BaseFilterOption>((name) => ({ value: name })),
19+
[allOrganismNames],
20+
)
21+
22+
const organismNameValue = useMemo(
23+
() => organismNames.map<BaseFilterOption>((value) => ({ value })),
24+
[organismNames],
25+
)
26+
27+
const { t } = useI18n()
28+
29+
return (
30+
<SelectFilter
31+
multiple
32+
search
33+
options={organismNameOptions}
34+
value={organismNameValue}
35+
label={t('organismName')}
36+
onChange={(options) => updateValue(QueryParams.Organism, options)}
37+
/>
38+
)
39+
}

frontend/packages/data-portal/app/graphql/common.ts

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -134,14 +134,13 @@ export function getDatasetsFilter({
134134

135135
// NAME/ID SECTION
136136
// Dataset IDs
137-
const datasetId =
138-
filterState.ids.dataset !== null
139-
? parseInt(filterState.ids.dataset)
140-
: undefined
141-
if (Number.isInteger(datasetId)) {
142-
where.id = {
143-
_eq: datasetId,
144-
}
137+
const datasetIds = filterState.ids.datasets
138+
.map((id) => parseInt(id))
139+
.filter((id) => Number.isInteger(id))
140+
141+
if (datasetIds.length > 0) {
142+
where.id =
143+
datasetIds.length === 1 ? { _eq: datasetIds[0] } : { _in: datasetIds }
145144
}
146145
const empiarId = filterState.ids.empiar
147146
const emdbId = filterState.ids.emdb

frontend/packages/data-portal/app/hooks/useFilter.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ export function getFilterState(searchParams: URLSearchParams) {
2727
},
2828

2929
ids: {
30-
dataset: searchParams.get(QueryParams.DatasetId),
30+
datasets: searchParams.getAll(QueryParams.DatasetId),
3131
deposition: searchParams.get(QueryParams.DepositionId),
3232
empiar: searchParams.get(QueryParams.EmpiarId),
3333
emdb: searchParams.get(QueryParams.EmdbId),

0 commit comments

Comments
 (0)