From b37db79e23d15470981cfdd6ffdfe701269b5693 Mon Sep 17 00:00:00 2001
From: Lauri Himanen <lauri.himanen@gmail.com>
Date: Thu, 27 Feb 2025 08:12:31 +0000
Subject: [PATCH] Fixed issue with setting and reading boolean values in
 queries.

Changelog: Fixed
---
 gui/src/components/search/Filter.js           |  4 +---
 gui/src/components/search/FilterRegistry.js   |  3 ++-
 gui/src/components/search/input/InputTerms.js | 21 ++++++++++++++++---
 3 files changed, 21 insertions(+), 7 deletions(-)

diff --git a/gui/src/components/search/Filter.js b/gui/src/components/search/Filter.js
index dd4d4782e0..a7f863ea7c 100644
--- a/gui/src/components/search/Filter.js
+++ b/gui/src/components/search/Filter.js
@@ -144,9 +144,7 @@ export class Filter {
     this.parent = parent
     this.group = params.group
     this.placeholder = params?.placeholder
-    this.multiple = params?.multiple === undefined
-      ? multiTypes.has(this.dtype)
-      : params?.multiple
+    this.multiple = params?.multiple ?? multiTypes.has(this.dtype)
     this.exclusive = params?.exclusive === undefined ? true : params?.exclusive
     this.queryMode = params?.queryMode || (this.multiple ? 'any' : undefined)
     this.options = params?.options || getEnumOptions(this.quantity)
diff --git a/gui/src/components/search/FilterRegistry.js b/gui/src/components/search/FilterRegistry.js
index 4d91c63e73..cfe9f46e9a 100644
--- a/gui/src/components/search/FilterRegistry.js
+++ b/gui/src/components/search/FilterRegistry.js
@@ -143,7 +143,7 @@ const termQuantityAll = {aggs: {terms: {size: 5}}, exclusive: false, multiple: t
 const termQuantityAllNonExclusive = {...termQuantityNonExclusive, queryMode: 'all'}
 const noAggQuantity = {}
 const nestedQuantity = {}
-const noQueryQuantity = {multiple: false, global: true}
+const noQueryQuantity = {global: true}
 const numberHistogramQuantity = {multiple: false, exclusive: false}
 
 // Filters that directly correspond to a metainfo value
@@ -587,6 +587,7 @@ registerFilter(
   'combine',
   {
     ...noQueryQuantity,
+    dtype: DType.Boolean,
     default: true,
     description: 'If selected, your filters may be matched from several entries that contain the same material. When unchecked, the material has to have a single entry that matches all your filters.'
   }
diff --git a/gui/src/components/search/input/InputTerms.js b/gui/src/components/search/input/InputTerms.js
index 690e04920b..e71af11697 100644
--- a/gui/src/components/search/input/InputTerms.js
+++ b/gui/src/components/search/input/InputTerms.js
@@ -28,10 +28,24 @@ import InputUnavailable from './InputUnavailable'
 import Placeholder from '../../visualization/Placeholder'
 import { useSearchContext } from '../SearchContext'
 import { isNil, isNumber } from 'lodash'
+import { DType } from '../../../utils'
 import Pagination from '../../visualization/Pagination'
 import { guiState } from '../../GUIMenu'
 import { InputTextQuantity } from './InputText'
 
+/**
+ * Converts a string value to its appropriate type based on the provided dtype.
+ * Needed for converting booleans used as object keys (object keys are always
+ * strings).
+ *
+ * @param {string} value - The value to be converted.
+ * @param {DType} dtype - The data type to convert the value to.
+ * @returns {boolean|string} - The converted value.
+ */
+function getFinalKey(value, dtype) {
+  return dtype === DType.Boolean ? value === 'true' : value
+}
+
 /**
  * Generic input component that can be configured to fit several use cases. The
  * most typical configufations are:
@@ -152,6 +166,7 @@ const InputTerms = React.memo(({
   // results or change in the available options.
   useEffect(() => {
     let options = Object.entries(finalOptions).reduce((opt, [key, value]) => {
+      key = getFinalKey(key, filterData[searchQuantity]?.dtype)
       const selected = filter?.has(key) || false
       opt[key] = {
         checked: selected,
@@ -184,7 +199,7 @@ const InputTerms = React.memo(({
     }
 
     setVisibleOptions(options)
-  }, [agg?.data, filter, finalOptions, fixedOptions, isStatisticsEnabled, showStatistics, sortStatic])
+  }, [agg?.data, filter, filterData, finalOptions, fixedOptions, isStatisticsEnabled, searchQuantity, showStatistics, sortStatic])
 
   // Show more values
   const handleShowMore = useCallback(() => {
@@ -214,9 +229,9 @@ const InputTerms = React.memo(({
     newOptions[key].checked = selected
     const checked = Object.entries(newOptions)
       .filter(([key, value]) => value.checked)
-      .map(([key, value]) => key)
+      .map(([key, value]) => getFinalKey(key, filterData[searchQuantity]?.dtype))
     setFilter(new Set(checked))
-  }, [setFilter, visibleOptions])
+  }, [setFilter, visibleOptions, filterData, searchQuantity])
 
   // Create the search component
   const searchComponent = useMemo(() => {
-- 
GitLab