Skip to content

Commit e89cc72

Browse files
committed
Improve search dropdown config, allow default entry
1 parent 83e8235 commit e89cc72

File tree

4 files changed

+46
-127
lines changed

4 files changed

+46
-127
lines changed

src/components/search/DefaultSorting.tsx

Lines changed: 41 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,18 @@
11
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select"
2-
import { useCallback, useContext } from "react"
2+
import { useCallback, useContext, useEffect, useMemo, useState } from "react"
33
import { SearchContext } from "@elastic/react-search-ui"
44
import { ArrowUpDown } from "lucide-react"
55
import { FairDOSearchContext } from "@/components/FairDOSearchContext"
6+
import { SearchState, SortOption } from "@elastic/search-ui"
67

78
export function DefaultSorting() {
9+
const [value, setValue] = useState("")
810
const search = useContext(SearchContext)
911
const { config } = useContext(FairDOSearchContext)
1012

1113
const handleChange = useCallback(
1214
(value: string) => {
15+
setValue(value)
1316
if (value.startsWith("-")) {
1417
const field = value.replace("-", "")
1518
search.driver.setSort([{ field, direction: "" }], "")
@@ -24,10 +27,45 @@ export function DefaultSorting() {
2427
[search]
2528
)
2629

30+
const makeKey = useCallback((item: SortOption) => {
31+
return `${item.direction}-${item.field}`
32+
}, [])
33+
34+
const defaultSortOption = useMemo(() => {
35+
return config.sortOptions?.find((elem) => elem.default)
36+
}, [config.sortOptions])
37+
38+
// Set default sorting on first load
39+
useEffect(() => {
40+
if (defaultSortOption && value === "") {
41+
const value = makeKey(defaultSortOption)
42+
setValue(value)
43+
// Call to setValue does not trigger onValueChange
44+
handleChange(value)
45+
}
46+
}, [defaultSortOption, handleChange, makeKey, value])
47+
48+
// Update sort dropdown if the sortList changed from the drivers side
49+
useEffect(() => {
50+
const handler = ({ sortList }: SearchState) => {
51+
if (sortList && sortList.length === 1) {
52+
const sorting = sortList[0]
53+
const sortingValue = makeKey(sorting)
54+
setValue(sortingValue)
55+
}
56+
}
57+
58+
search.driver.subscribeToStateChanges(handler)
59+
60+
return () => search.driver.unsubscribeToStateChanges(handler)
61+
}, [makeKey, search.driver])
62+
63+
console.log("haha")
64+
2765
if (!config.sortOptions || config.sortOptions.length === 0) return null
2866

2967
return (
30-
<Select onValueChange={handleChange}>
68+
<Select value={value} onValueChange={handleChange}>
3169
<SelectTrigger className="rfs-max-w-[400px]">
3270
<div className="rfs-flex rfs-items-center rfs-gap-2">
3371
<ArrowUpDown className={"rfs-size-4"} />
@@ -36,11 +74,7 @@ export function DefaultSorting() {
3674
</SelectTrigger>
3775
<SelectContent>
3876
{config.sortOptions.map((item) => (
39-
<SelectItem
40-
className="rfs-flex rfs-items-center"
41-
key={`${item.direction}-${item.field}`}
42-
value={`${item.direction}-${item.field}`}
43-
>
77+
<SelectItem className="rfs-flex rfs-items-center" key={makeKey(item)} value={makeKey(item)}>
4478
{item.label ?? (item.field + " " + item.direction === "asc" ? " (ascending)" : " (descending)")}
4579
</SelectItem>
4680
))}

src/config/FairDOConfig.ts

Lines changed: 2 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ export interface FairDOConfig {
8787
/**
8888
* Configure possible sort options. Fields to sort by must be present in all used indices.
8989
*/
90-
sortOptions?: (SortOption & { label?: string })[]
90+
sortOptions?: (SortOption & { label?: string; default?: boolean })[]
9191
/**
9292
* Disjunctive facets as specified in the elastic search ui documentation
9393
* @link https://www.elastic.co/guide/en/search-ui/current/api-react-components-facet.html#api-react-components-facet-example-of-an-or-based-facet-filter
@@ -117,20 +117,7 @@ export interface FairDOConfig {
117117
imageProxy?: (src: string) => string
118118

119119
/**
120-
* Initialize the internal state. This can be useful to specify the default sorting of the results.
121-
* @example
122-
* initialState: {
123-
* sortList: [
124-
* {
125-
* field: "_score",
126-
* direction: "desc"
127-
* },
128-
* {
129-
* field: "name.keyword",
130-
* direction: "asc"
131-
* }
132-
* ]
133-
* },
120+
* Initialize the internal state. This can be useful to specify some default states.
134121
*/
135122
initialState?: Partial<RequestState>
136123
}

src/stories/0 Getting Started.mdx

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ export default function Home() {
4141
const config: FairDOConfig = useMemo(() => {
4242
return {
4343
alwaysSearchOnInitialLoad: true,
44-
host: <elastic host>,
44+
host: "your elastic host",
4545
indices: [
4646
{
4747
name: "index-name-here",
@@ -63,17 +63,9 @@ export default function Home() {
6363
],
6464
sortOptions: [
6565
{ field: "_score", direction: "desc", label: "Relevance" },
66-
{ field: "name.keyword", direction: "asc", label: "Name (ascending)" },
66+
{ field: "name.keyword", direction: "asc", label: "Name (ascending)", default: true },
6767
{ field: "name.keyword", direction: "desc", label: "Name (descending)" }
6868
],
69-
initialState: {
70-
sortList: [
71-
{
72-
field: "name.keyword",
73-
direction: "asc"
74-
}
75-
]
76-
},
7769
connectionOptions: {
7870
headers: {
7971
// Pass your authentication headers here

src/stories/FairDOElasticSearch.stories.tsx

Lines changed: 1 addition & 95 deletions
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@ const demoConfig: FairDOConfig = {
112112
],
113113
sortOptions: [
114114
{ field: "_score", direction: "desc", label: "Relevance" },
115-
{ field: "name.keyword", direction: "asc", label: "Name (ascending)" },
115+
{ field: "name.keyword", direction: "asc", label: "Name (ascending)", default: true },
116116
{ field: "name.keyword", direction: "desc", label: "Name (descending)" },
117117
{ field: "Compound.Molar_mass", direction: "asc", label: "Molar Mass (ascending)" },
118118
{ field: "Compound.Molar_mass", direction: "desc", label: "Molar Mass (descending)" },
@@ -121,14 +121,6 @@ const demoConfig: FairDOConfig = {
121121
{ field: "dateModified", direction: "asc", label: "Date Modified (ascending)" },
122122
{ field: "dateModified", direction: "desc", label: "Date Modified (descending)" }
123123
],
124-
initialState: {
125-
sortList: [
126-
{
127-
field: "name.keyword",
128-
direction: "asc"
129-
}
130-
]
131-
},
132124
disjunctiveFacets: [
133125
"NMR_Method.keyword",
134126
"resourceType.keyword",
@@ -139,45 +131,6 @@ const demoConfig: FairDOConfig = {
139131
imageProxy: (src) => `https://wsrv.nl/?url=${src}&h=1000&output=webp&ll`
140132
}
141133

142-
// const demoConfigWithCompound: FairDOConfig = {
143-
// debug: false,
144-
// alwaysSearchOnInitialLoad: true,
145-
// // host: "https://matwerk.datamanager.kit.edu/search-proxy/api/v1",
146-
// host: "https://ddaa9283-f114-4496-b6ed-af12ee34b107.ka.bw-cloud-instance.org:9200",
147-
// apiKey: "UGNoTW1KUUJ3WmluUHBTcEVpalo6cGloOUVKZ0tTdnlMYVlpTzV4SXBrUQ==",
148-
// indices: [
149-
// {
150-
// name: "fdo-prod",
151-
// facets: [
152-
// {
153-
// key: "Compound.Molar_mass",
154-
// label: "Compound",
155-
// type: "min-max-slider"
156-
// }
157-
// ],
158-
// resultFields: [], // Leave empty to get all fields
159-
// searchFields: ["name", "pid", "hasMetadata", "isMetadataFor", "NMR_Method"]
160-
// }
161-
// ],
162-
// initialState: {
163-
// sortList: [
164-
// {
165-
// field: "_score",
166-
// direction: "desc"
167-
// },
168-
// {
169-
// field: "name.keyword",
170-
// direction: "asc"
171-
// },
172-
// {
173-
// field: "locationPreview/Sample.keyword",
174-
// direction: "asc"
175-
// }
176-
// ]
177-
// },
178-
// disjunctiveFacets: ["NMR_Method.keyword"]
179-
// }
180-
181134
export const NoResultRenderer: Story = {
182135
args: {
183136
config: demoConfig,
@@ -267,50 +220,3 @@ export const GenericResultRenderer: Story = {
267220
)
268221
}
269222
}
270-
271-
// export const CompoundSlider: Story = {
272-
// args: {
273-
// config: demoConfigWithCompound,
274-
// resultView: (props) => (
275-
// <GenericResultView
276-
// result={props.result}
277-
// invertImageInDarkMode
278-
// tags={[
279-
// {
280-
// icon: <GraduationCap className="rfs-shrink-0 rfs-size-4 rfs-mr-2" />,
281-
// label: "Resource Type",
282-
// field: "resourceType"
283-
// },
284-
// {
285-
// icon: <GlobeIcon className="rfs-shrink-0 rfs-size-4 rfs-mr-2" />,
286-
// field: "hadPrimarySource",
287-
// valueMapper: (v) => tryURLPrettyPrint(v + ""),
288-
// label: "Source"
289-
// },
290-
// {
291-
// icon: <ScaleIcon className="rfs-shrink-0 rfs-size-4 rfs-mr-2" />,
292-
// field: "licenseURL",
293-
// valueMapper: (v) => tryURLPrettyPrint(v + ""),
294-
// label: "License URL"
295-
// },
296-
// {
297-
// icon: <AtomIcon className="rfs-shrink-0 rfs-size-4 rfs-mr-2" />,
298-
// field: "Compound.Molar_mass",
299-
// label: "Molar Mass",
300-
// valueMapper: (v) => v + " g/mol"
301-
// }
302-
// ]}
303-
// titleField="name"
304-
// creationDateField="dateCreatedRfc3339"
305-
// additionalIdentifierField="identifier"
306-
// digitalObjectLocationField="digitalObjectLocation"
307-
// imageField="locationPreview/Sample"
308-
// parentItemPidField="hasMetadata"
309-
// relatedItemPidsField="isMetadataFor"
310-
// pidField="pid"
311-
// relatedItemsPrefetch={{ searchFields: { pid: {} } }}
312-
// showOpenInFairDoScope
313-
// />
314-
// )
315-
// }
316-
// }

0 commit comments

Comments
 (0)