From 307849fe45b4c60a3f85f459fe313fdce9cf8007 Mon Sep 17 00:00:00 2001 From: Aarohi Nadkarni Date: Mon, 5 Feb 2024 11:42:24 -0500 Subject: [PATCH 01/12] feat: search bar on data library for researcher console --- .../data_search/DatasetSearchTable.js | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/src/components/data_search/DatasetSearchTable.js b/src/components/data_search/DatasetSearchTable.js index 4420d1129..602d7b42c 100644 --- a/src/components/data_search/DatasetSearchTable.js +++ b/src/components/data_search/DatasetSearchTable.js @@ -1,12 +1,14 @@ import * as React from 'react'; import { Button, Link } from '@mui/material'; -import { useEffect, useState } from 'react'; +import { useEffect, useState, useCallback, useRef } from 'react'; import { groupBy, isEmpty } from 'lodash'; import CollapsibleTable from '../CollapsibleTable'; import TableHeaderSection from '../TableHeaderSection'; import { DAR } from '../../libs/ajax'; import DatasetFilterList from './DatasetFilterList'; import { Box } from '@mui/material'; +import SearchBar from '../SearchBar'; +import { getSearchFilterFunctions, Notifications, searchOnFilteredList } from '../../libs/utils'; const studyTableHeader = [ 'Study Name', @@ -34,6 +36,7 @@ export const DatasetSearchTable = (props) => { const [filtered, setFiltered] = useState([]); const [tableData, setTableData] = useState({}); const [selected, setSelected] = useState([]); + const searchRef = useRef(''); const isFiltered = (filter) => filters.indexOf(filter) > -1; @@ -102,6 +105,13 @@ export const DatasetSearchTable = (props) => { history.push(`/dar_application/${darDraft.referenceId}`); }; + const handleSearchChange = useCallback((searchTerms) => searchOnFilteredList( + searchTerms, + datasets, + getSearchFilterFunctions().datasetTerms, + setFiltered + ), [datasets]); + useEffect(() => { if (isEmpty(filtered)) { return; @@ -195,6 +205,11 @@ export const DatasetSearchTable = (props) => { return ( + + + From 724d4229932d97136fe7bc31373e1e504e5b2c21 Mon Sep 17 00:00:00 2001 From: Aarohi Nadkarni Date: Wed, 7 Feb 2024 15:58:19 -0500 Subject: [PATCH 02/12] fix: stop re-rendering of myinstitution page --- src/pages/DatasetSearch.js | 33 +++++++++++++++++++-------------- 1 file changed, 19 insertions(+), 14 deletions(-) diff --git a/src/pages/DatasetSearch.js b/src/pages/DatasetSearch.js index 29b42cbe8..235d2b8a6 100644 --- a/src/pages/DatasetSearch.js +++ b/src/pages/DatasetSearch.js @@ -80,6 +80,7 @@ export const DatasetSearch = (props) => { const { match: { params: { query } } } = props; const [datasets, setDatasets] = useState([]); const [loading, setLoading] = useState(true); + const [loaded, setLoaded] = useState(false); const user = Storage.getCurrentUser(); const isSigningOfficial = user.isSigningOfficial; @@ -193,26 +194,30 @@ export const DatasetSearch = (props) => { const key = query === undefined ? '/datalibrary' : toLower(query); const version = versions[key] === undefined ? versions['/custom'] : versions[key]; const isInstitutionQuery = key === 'myinstitution'; + const fullQuery = assembleFullQuery(isSigningOfficial, isInstitutionQuery, version.query); + const institutionSet = institutionId === undefined && isInstitutionQuery; useEffect(() => { const init = async () => { - if (institutionId === undefined && isInstitutionQuery) { - Notifications.showError({ text: 'You must set an institution in your profile to view the `myinstitution` data library' }); - props.history.push('/profile'); - return; - } - try { - const query = assembleFullQuery(isSigningOfficial, isInstitutionQuery, version.query); - await DataSet.searchDatasetIndex(query).then((datasets) => { - setDatasets(datasets); - setLoading(false); - }); - } catch (error) { - Notifications.showError({ text: 'Failed to load Elasticsearch index' }); + if (!loaded) { + if (institutionSet) { + Notifications.showError({ text: 'You must set an institution in your profile to view the `myinstitution` data library' }); + props.history.push('/profile'); + return; + } + try { + await DataSet.searchDatasetIndex(fullQuery).then((datasets) => { + setDatasets(datasets); + setLoading(false); + }); + } catch (error) { + Notifications.showError({ text: 'Failed to load Elasticsearch index' }); + } + setLoaded(true); } }; init(); - }, [institutionId, isInstitutionQuery, isSigningOfficial, props.history, version.query]); + }, [institutionSet, fullQuery, props.history]); return ( loading ? From 05f886265e08cc8858f134df59055d940aafdc1c Mon Sep 17 00:00:00 2001 From: Aarohi Nadkarni Date: Thu, 8 Feb 2024 09:35:14 -0500 Subject: [PATCH 03/12] refactor: remove unused import --- src/components/data_search/DatasetSearchTable.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/data_search/DatasetSearchTable.js b/src/components/data_search/DatasetSearchTable.js index 602d7b42c..38a7606ff 100644 --- a/src/components/data_search/DatasetSearchTable.js +++ b/src/components/data_search/DatasetSearchTable.js @@ -8,7 +8,7 @@ import { DAR } from '../../libs/ajax'; import DatasetFilterList from './DatasetFilterList'; import { Box } from '@mui/material'; import SearchBar from '../SearchBar'; -import { getSearchFilterFunctions, Notifications, searchOnFilteredList } from '../../libs/utils'; +import { getSearchFilterFunctions, searchOnFilteredList } from '../../libs/utils'; const studyTableHeader = [ 'Study Name', From f88b670b2e83dbf00932cdaf557dd5c769893fd3 Mon Sep 17 00:00:00 2001 From: Aarohi Nadkarni Date: Thu, 8 Feb 2024 12:04:18 -0500 Subject: [PATCH 04/12] refactor: revert useEffect changes? --- src/pages/DatasetSearch.js | 33 ++++++++++++++------------------- 1 file changed, 14 insertions(+), 19 deletions(-) diff --git a/src/pages/DatasetSearch.js b/src/pages/DatasetSearch.js index 235d2b8a6..29b42cbe8 100644 --- a/src/pages/DatasetSearch.js +++ b/src/pages/DatasetSearch.js @@ -80,7 +80,6 @@ export const DatasetSearch = (props) => { const { match: { params: { query } } } = props; const [datasets, setDatasets] = useState([]); const [loading, setLoading] = useState(true); - const [loaded, setLoaded] = useState(false); const user = Storage.getCurrentUser(); const isSigningOfficial = user.isSigningOfficial; @@ -194,30 +193,26 @@ export const DatasetSearch = (props) => { const key = query === undefined ? '/datalibrary' : toLower(query); const version = versions[key] === undefined ? versions['/custom'] : versions[key]; const isInstitutionQuery = key === 'myinstitution'; - const fullQuery = assembleFullQuery(isSigningOfficial, isInstitutionQuery, version.query); - const institutionSet = institutionId === undefined && isInstitutionQuery; useEffect(() => { const init = async () => { - if (!loaded) { - if (institutionSet) { - Notifications.showError({ text: 'You must set an institution in your profile to view the `myinstitution` data library' }); - props.history.push('/profile'); - return; - } - try { - await DataSet.searchDatasetIndex(fullQuery).then((datasets) => { - setDatasets(datasets); - setLoading(false); - }); - } catch (error) { - Notifications.showError({ text: 'Failed to load Elasticsearch index' }); - } - setLoaded(true); + if (institutionId === undefined && isInstitutionQuery) { + Notifications.showError({ text: 'You must set an institution in your profile to view the `myinstitution` data library' }); + props.history.push('/profile'); + return; + } + try { + const query = assembleFullQuery(isSigningOfficial, isInstitutionQuery, version.query); + await DataSet.searchDatasetIndex(query).then((datasets) => { + setDatasets(datasets); + setLoading(false); + }); + } catch (error) { + Notifications.showError({ text: 'Failed to load Elasticsearch index' }); } }; init(); - }, [institutionSet, fullQuery, props.history]); + }, [institutionId, isInstitutionQuery, isSigningOfficial, props.history, version.query]); return ( loading ? From 059df59317002d4b170de4eb0159f7a810d40b74 Mon Sep 17 00:00:00 2001 From: Aarohi Nadkarni Date: Wed, 14 Feb 2024 11:26:25 -0500 Subject: [PATCH 05/12] feat: consolidate filtering & searching --- .../data_search/DatasetFilterList.js | 4 +- .../data_search/DatasetSearchTable.js | 57 +++++++++++++------ 2 files changed, 41 insertions(+), 20 deletions(-) diff --git a/src/components/data_search/DatasetFilterList.js b/src/components/data_search/DatasetFilterList.js index f63ffa395..a45d7b538 100644 --- a/src/components/data_search/DatasetFilterList.js +++ b/src/components/data_search/DatasetFilterList.js @@ -10,7 +10,7 @@ import { Typography } from '@mui/material'; import { Checkbox } from '@mui/material'; export const DatasetFilterList = (props) => { - const { datasets, filters, filterHandler } = props; + const { datasets, filters, filterHandler, searchRef } = props; const accessManagementFilters = ['Controlled', 'Open', 'External']; @@ -31,7 +31,7 @@ export const DatasetFilterList = (props) => { const filter = filterName.toLowerCase(); return ( - filterHandler(event, datasets, filter)}> + filterHandler(event, datasets, filter, searchRef.current.value)}> diff --git a/src/components/data_search/DatasetSearchTable.js b/src/components/data_search/DatasetSearchTable.js index 38a7606ff..a49b22cd0 100644 --- a/src/components/data_search/DatasetSearchTable.js +++ b/src/components/data_search/DatasetSearchTable.js @@ -9,6 +9,7 @@ import DatasetFilterList from './DatasetFilterList'; import { Box } from '@mui/material'; import SearchBar from '../SearchBar'; import { getSearchFilterFunctions, searchOnFilteredList } from '../../libs/utils'; +import { Styles } from '../../libs/theme'; const studyTableHeader = [ 'Study Name', @@ -40,7 +41,7 @@ export const DatasetSearchTable = (props) => { const isFiltered = (filter) => filters.indexOf(filter) > -1; - const filterHandler = (event, data, filter) => { + const filterHandler = (event, data, filter, searchTerm) => { var newFilters = []; if (!isFiltered(filter)) { newFilters = filters.concat(filter); @@ -69,7 +70,15 @@ export const DatasetSearchTable = (props) => { return false; }); } - setFiltered(newFiltered); + console.log('searchTerm: ' + searchTerm); + console.log('filters: ', newFilters) + if (searchTerm) { + const searchFiltered = getSearchFilterFunctions().datasetTerms(searchTerm, newFiltered); + // console.log("Filtered:", newFiltered.filter(value => searchFiltered.includes(value))) + setFiltered(newFiltered.filter(value => searchFiltered.includes(value))); + } else { + setFiltered(newFiltered); + } }; const selectHandler = (event, data, selector) => { @@ -105,13 +114,6 @@ export const DatasetSearchTable = (props) => { history.push(`/dar_application/${darDraft.referenceId}`); }; - const handleSearchChange = useCallback((searchTerms) => searchOnFilteredList( - searchTerms, - datasets, - getSearchFilterFunctions().datasetTerms, - setFiltered - ), [datasets]); - useEffect(() => { if (isEmpty(filtered)) { return; @@ -205,19 +207,38 @@ export const DatasetSearchTable = (props) => { return ( - - + +
+ filterHandler(null, datasets, [], searchRef.current.value)} + ref={searchRef} + /> +
+
- - - + + + - + { isEmpty(datasets) ? - +

No datasets registered for this library.

: From bba763453f24ce7c84b279d4d68a17b2a678da6c Mon Sep 17 00:00:00 2001 From: Aarohi Nadkarni Date: Fri, 16 Feb 2024 02:26:13 -0500 Subject: [PATCH 06/12] fix: try implementing search as a filter --- .../data_search/DatasetSearchTable.js | 71 ++++++++++++++++--- 1 file changed, 61 insertions(+), 10 deletions(-) diff --git a/src/components/data_search/DatasetSearchTable.js b/src/components/data_search/DatasetSearchTable.js index a49b22cd0..3aed81e72 100644 --- a/src/components/data_search/DatasetSearchTable.js +++ b/src/components/data_search/DatasetSearchTable.js @@ -10,6 +10,8 @@ import { Box } from '@mui/material'; import SearchBar from '../SearchBar'; import { getSearchFilterFunctions, searchOnFilteredList } from '../../libs/utils'; import { Styles } from '../../libs/theme'; +import {capitalize, cloneDeep, concat, each, every, filter, find, first, flatten, flow, forEach as lodashFPForEach, get, getOr, includes, isNil, join, map, toLower, uniq} from 'lodash/fp'; + const studyTableHeader = [ 'Study Name', @@ -41,6 +43,40 @@ export const DatasetSearchTable = (props) => { const isFiltered = (filter) => filters.indexOf(filter) > -1; + const datasetFilter = (term, datasetTerm) => { + const loweredTerm = toLower(term); + console.log('loweredTerm: ', loweredTerm); + // Approval status + const status = !isNil(datasetTerm.dacApproval) + ? datasetTerm.dacApproval + ? 'accepted' + : 'rejected' + : 'pending'; + const primaryCodes = datasetTerm.dataUse?.primary.map(du => du.code); + const secondaryCodes = datasetTerm.dataUse?.secondary.map(du => du.code); + const codes = join(', ')(concat(primaryCodes)(secondaryCodes)); + const dataTypes = join(', ')(datasetTerm.study?.dataTypes); + const custodians = join(', ')(datasetTerm.study?.dataCustodianEmail); + // console.log('datasetTerm.datasetName: ', datasetTerm.datasetName); + return includes(loweredTerm, toLower(datasetTerm.datasetName)) || + includes(loweredTerm, toLower(datasetTerm.datasetIdentifier)) || + includes(loweredTerm, toLower(datasetTerm.dac?.dacName)) || + includes(loweredTerm, toLower(datasetTerm.dac?.dacEmail)) || + includes(loweredTerm, toLower(datasetTerm.dataLocation)) || + includes(loweredTerm, toLower(codes)) || + includes(loweredTerm, toLower(datasetTerm.createUserDisplayName)) || + includes(loweredTerm, toLower(datasetTerm.url)) || + includes(loweredTerm, toLower(datasetTerm.study?.description)) || + includes(loweredTerm, toLower(datasetTerm.study?.dataSubmitterEmail)) || + includes(loweredTerm, toLower(dataTypes)) || + includes(loweredTerm, toLower(custodians)) || + includes(loweredTerm, toLower(datasetTerm.study?.phenotype)) || + includes(loweredTerm, toLower(datasetTerm.study?.piName)) || + includes(loweredTerm, toLower(datasetTerm.study?.species)) || + includes(loweredTerm, toLower(datasetTerm.study?.studyName)) || + includes(loweredTerm, toLower(status)); + }; + const filterHandler = (event, data, filter, searchTerm) => { var newFilters = []; if (!isFiltered(filter)) { @@ -55,6 +91,15 @@ export const DatasetSearchTable = (props) => { newFiltered = data; } else { newFiltered = data.filter((dataset) => { + if (newFilters.includes('search') && searchTerm !== '' && datasetFilter(searchTerm, dataset)) { + // console.log("searchTerm", searchTerm); + // console.log("dataset", dataset); + // console.log("result", getSearchFilterFunctions().datasetTerms(searchTerm, dataset)); + // console.log("newFiltered", newFiltered); + // if (getSearchFilterFunctions().datasetTerms(searchTerm, dataset)) { + return true; + // } + } // TODO: remove extra checks when openAccess property is deprecated if (newFilters.includes('open') && (dataset.openAccess || dataset.accessManagement === 'open')) { return true; @@ -67,18 +112,24 @@ export const DatasetSearchTable = (props) => { if (newFilters.includes('external') && dataset.accessManagement === 'external') { return true; } + // console.log("TEST :", getSearchFilterFunctions().datasetTerms(searchTerm, [dataset])) + // add 'search' filter here; if the search box isn't empty & the filter is 'search' & getSearchFilterFunctions().datasetTerms(searchTerm, newFiltered)ISH, return true return false; }); } - console.log('searchTerm: ' + searchTerm); - console.log('filters: ', newFilters) - if (searchTerm) { - const searchFiltered = getSearchFilterFunctions().datasetTerms(searchTerm, newFiltered); - // console.log("Filtered:", newFiltered.filter(value => searchFiltered.includes(value))) - setFiltered(newFiltered.filter(value => searchFiltered.includes(value))); - } else { - setFiltered(newFiltered); - } + + // const searchFiltered = getSearchFilterFunctions().datasetTerms(searchTerm, newFiltered); + // setFiltered(newFiltered.filter(value => searchFiltered.includes(value))); + // console.log('searchTerm: ' + searchTerm); + // console.log('filters: ', newFilters) + // if (searchTerm) { + // const searchFiltered = getSearchFilterFunctions().datasetTerms(searchTerm, newFiltered) ; + // console.log("Filtered:", newFiltered.filter(value => searchFiltered.includes(value))) + // setFiltered(newFiltered.filter(value => searchFiltered.includes(value))); + // } else { + // setFiltered(newFiltered); + // } + setFiltered(newFiltered); }; const selectHandler = (event, data, selector) => { @@ -223,7 +274,7 @@ export const DatasetSearchTable = (props) => { fontFamily: 'Montserrat', fontSize: '1.5rem' }} - onChange={() => filterHandler(null, datasets, [], searchRef.current.value)} + onChange={() => filterHandler(null, datasets, 'search', searchRef.current.value)} ref={searchRef} />
From 1730bd693c6aae25a500497be649b6d031776e6e Mon Sep 17 00:00:00 2001 From: Aarohi Nadkarni Date: Fri, 16 Feb 2024 18:08:01 -0500 Subject: [PATCH 07/12] fix: try chaining filters --- src/components/data_search/DatasetSearchTable.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/components/data_search/DatasetSearchTable.js b/src/components/data_search/DatasetSearchTable.js index 3aed81e72..1e1d53957 100644 --- a/src/components/data_search/DatasetSearchTable.js +++ b/src/components/data_search/DatasetSearchTable.js @@ -99,7 +99,9 @@ export const DatasetSearchTable = (props) => { // if (getSearchFilterFunctions().datasetTerms(searchTerm, dataset)) { return true; // } - } + } + return false; + }).filter((dataset) => { // TODO: remove extra checks when openAccess property is deprecated if (newFilters.includes('open') && (dataset.openAccess || dataset.accessManagement === 'open')) { return true; From e2f498c31b8720d3e4667d6cb7ed7623a4465d34 Mon Sep 17 00:00:00 2001 From: Aarohi Nadkarni Date: Thu, 22 Feb 2024 18:25:17 -0500 Subject: [PATCH 08/12] feat: implement search & filter using elasticsearch --- .../data_search/DatasetSearchTable.js | 198 ++++++++++-------- 1 file changed, 113 insertions(+), 85 deletions(-) diff --git a/src/components/data_search/DatasetSearchTable.js b/src/components/data_search/DatasetSearchTable.js index 1e1d53957..86a3309e9 100644 --- a/src/components/data_search/DatasetSearchTable.js +++ b/src/components/data_search/DatasetSearchTable.js @@ -4,13 +4,12 @@ import { useEffect, useState, useCallback, useRef } from 'react'; import { groupBy, isEmpty } from 'lodash'; import CollapsibleTable from '../CollapsibleTable'; import TableHeaderSection from '../TableHeaderSection'; -import { DAR } from '../../libs/ajax'; +import { DAR, DataSet } from '../../libs/ajax'; import DatasetFilterList from './DatasetFilterList'; import { Box } from '@mui/material'; -import SearchBar from '../SearchBar'; -import { getSearchFilterFunctions, searchOnFilteredList } from '../../libs/utils'; +import { Notifications } from '../../libs/utils'; import { Styles } from '../../libs/theme'; -import {capitalize, cloneDeep, concat, each, every, filter, find, first, flatten, flow, forEach as lodashFPForEach, get, getOr, includes, isNil, join, map, toLower, uniq} from 'lodash/fp'; +import isEqual from 'lodash/isEqual'; const studyTableHeader = [ @@ -40,99 +39,121 @@ export const DatasetSearchTable = (props) => { const [tableData, setTableData] = useState({}); const [selected, setSelected] = useState([]); const searchRef = useRef(''); - const isFiltered = (filter) => filters.indexOf(filter) > -1; - const datasetFilter = (term, datasetTerm) => { - const loweredTerm = toLower(term); - console.log('loweredTerm: ', loweredTerm); - // Approval status - const status = !isNil(datasetTerm.dacApproval) - ? datasetTerm.dacApproval - ? 'accepted' - : 'rejected' - : 'pending'; - const primaryCodes = datasetTerm.dataUse?.primary.map(du => du.code); - const secondaryCodes = datasetTerm.dataUse?.secondary.map(du => du.code); - const codes = join(', ')(concat(primaryCodes)(secondaryCodes)); - const dataTypes = join(', ')(datasetTerm.study?.dataTypes); - const custodians = join(', ')(datasetTerm.study?.dataCustodianEmail); - // console.log('datasetTerm.datasetName: ', datasetTerm.datasetName); - return includes(loweredTerm, toLower(datasetTerm.datasetName)) || - includes(loweredTerm, toLower(datasetTerm.datasetIdentifier)) || - includes(loweredTerm, toLower(datasetTerm.dac?.dacName)) || - includes(loweredTerm, toLower(datasetTerm.dac?.dacEmail)) || - includes(loweredTerm, toLower(datasetTerm.dataLocation)) || - includes(loweredTerm, toLower(codes)) || - includes(loweredTerm, toLower(datasetTerm.createUserDisplayName)) || - includes(loweredTerm, toLower(datasetTerm.url)) || - includes(loweredTerm, toLower(datasetTerm.study?.description)) || - includes(loweredTerm, toLower(datasetTerm.study?.dataSubmitterEmail)) || - includes(loweredTerm, toLower(dataTypes)) || - includes(loweredTerm, toLower(custodians)) || - includes(loweredTerm, toLower(datasetTerm.study?.phenotype)) || - includes(loweredTerm, toLower(datasetTerm.study?.piName)) || - includes(loweredTerm, toLower(datasetTerm.study?.species)) || - includes(loweredTerm, toLower(datasetTerm.study?.studyName)) || - includes(loweredTerm, toLower(status)); + const assembleFullQuery = (searchTerm, filters) => { + const queryChunks = [ + { + 'match': { + '_type': 'dataset' + } + }, + { + 'exists': { + 'field': 'study' + } + } + ]; + + // do not apply search modifier if there is no searchTerm + if (searchTerm !== '') { + const searchModifier = [ + { + "multi_match": { + "query": searchTerm, + "fields": [ + "datasetName", + "dataLocation", + "study.description", + "study.studyName", + "study.species", + "study.piName", + "study.dataCustodianEmail", + "study.dataTypes", + "dataUse.primary.code", + "dataUse.secondary.code", + "dac.dacName", + "datasetIdentifier" + ] + } + } + ]; + queryChunks.push(...searchModifier); + } + + var filterQuery = {}; + if (filters.length > 0) { + const shouldTerms = []; + + filters.forEach(term => { + shouldTerms.push({ + "term": { + "accessManagement": term + } + }); + }); + + if (shouldTerms.length > 0) { + filterQuery = [ + { + "bool": { + "should": shouldTerms + } + } + ]; + } + } + + // do not add filter subquery if no filters are applied + if (filters.length > 0) { + return { + 'from': 0, + 'size': 10000, + 'query': { + 'bool': { + 'must': queryChunks, + 'filter': filterQuery + } + } + }; + } else { + return { + 'from': 0, + 'size': 10000, + 'query': { + 'bool': { + 'must': queryChunks + } + } + }; + } }; const filterHandler = (event, data, filter, searchTerm) => { var newFilters = []; - if (!isFiltered(filter)) { + if (!isFiltered(filter) && filter !== '') { newFilters = filters.concat(filter); } else { newFilters = filters.filter((f) => f !== filter); } setFilters(newFilters); - var newFiltered = []; - if (newFilters.length === 0) { - newFiltered = data; - } else { - newFiltered = data.filter((dataset) => { - if (newFilters.includes('search') && searchTerm !== '' && datasetFilter(searchTerm, dataset)) { - // console.log("searchTerm", searchTerm); - // console.log("dataset", dataset); - // console.log("result", getSearchFilterFunctions().datasetTerms(searchTerm, dataset)); - // console.log("newFiltered", newFiltered); - // if (getSearchFilterFunctions().datasetTerms(searchTerm, dataset)) { - return true; - // } - } - return false; - }).filter((dataset) => { - // TODO: remove extra checks when openAccess property is deprecated - if (newFilters.includes('open') && (dataset.openAccess || dataset.accessManagement === 'open')) { - return true; - } - if (newFilters.includes('controlled') && ( - (!dataset.openAccess && dataset.accessManagement === undefined) || (dataset.openAccess === undefined && dataset.accessManagement === 'controlled') - )) { - return true; - } - if (newFilters.includes('external') && dataset.accessManagement === 'external') { - return true; - } - // console.log("TEST :", getSearchFilterFunctions().datasetTerms(searchTerm, [dataset])) - // add 'search' filter here; if the search box isn't empty & the filter is 'search' & getSearchFilterFunctions().datasetTerms(searchTerm, newFiltered)ISH, return true - return false; - }); - } - - // const searchFiltered = getSearchFilterFunctions().datasetTerms(searchTerm, newFiltered); - // setFiltered(newFiltered.filter(value => searchFiltered.includes(value))); - // console.log('searchTerm: ' + searchTerm); - // console.log('filters: ', newFilters) - // if (searchTerm) { - // const searchFiltered = getSearchFilterFunctions().datasetTerms(searchTerm, newFiltered) ; - // console.log("Filtered:", newFiltered.filter(value => searchFiltered.includes(value))) - // setFiltered(newFiltered.filter(value => searchFiltered.includes(value))); - // } else { - // setFiltered(newFiltered); - // } - setFiltered(newFiltered); + const fullQuery = assembleFullQuery(searchTerm, newFilters); + // console.log("fullQuery", fullQuery); + const search = async () => { + try { + await DataSet.searchDatasetIndex(fullQuery).then((filteredDatasets) => { + // console.log("intersection", datasets.filter(value => filteredDatasets.some(item => isEqual(item, value)))); + setFiltered(datasets.filter(value => filteredDatasets.some(item => isEqual(item, value)))); + }); + } catch (error) { + Notifications.showError({ text: 'Failed to load Elasticsearch index' }); + } + }; + search(); }; + + const selectHandler = (event, data, selector) => { let idsToModify = []; @@ -276,7 +297,7 @@ export const DatasetSearchTable = (props) => { fontFamily: 'Montserrat', fontSize: '1.5rem' }} - onChange={() => filterHandler(null, datasets, 'search', searchRef.current.value)} + onChange={() => filterHandler(null, datasets, '', searchRef.current.value)} ref={searchRef} />
@@ -295,6 +316,13 @@ export const DatasetSearchTable = (props) => {

No datasets registered for this library.

: + isEmpty(filtered) ? + +

There are no datasets that fit these criteria.

+
+ : } From 06d4c6fd669f8324e1ede82b1d649946bbfbf93d Mon Sep 17 00:00:00 2001 From: Aarohi Nadkarni Date: Mon, 26 Feb 2024 11:56:42 -0500 Subject: [PATCH 09/12] feat: specify phrase_prefix multi_match query? --- src/components/data_search/DatasetSearchTable.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/components/data_search/DatasetSearchTable.js b/src/components/data_search/DatasetSearchTable.js index 86a3309e9..df870bda4 100644 --- a/src/components/data_search/DatasetSearchTable.js +++ b/src/components/data_search/DatasetSearchTable.js @@ -61,6 +61,7 @@ export const DatasetSearchTable = (props) => { { "multi_match": { "query": searchTerm, + "type":"phrase_prefix", "fields": [ "datasetName", "dataLocation", From 3348d8b8ea96f07a427773099436d9b1cd6e559f Mon Sep 17 00:00:00 2001 From: Aarohi Nadkarni Date: Mon, 26 Feb 2024 12:20:24 -0500 Subject: [PATCH 10/12] feat: add clear search button --- src/components/data_search/DatasetSearchTable.js | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/components/data_search/DatasetSearchTable.js b/src/components/data_search/DatasetSearchTable.js index df870bda4..12cf83c32 100644 --- a/src/components/data_search/DatasetSearchTable.js +++ b/src/components/data_search/DatasetSearchTable.js @@ -189,6 +189,11 @@ export const DatasetSearchTable = (props) => { history.push(`/dar_application/${darDraft.referenceId}`); }; + const clearSearchRef = () => { + searchRef.current.value = ''; + filterHandler(null, datasets, '', ''); + } + useEffect(() => { if (isEmpty(filtered)) { return; @@ -302,6 +307,11 @@ export const DatasetSearchTable = (props) => { ref={searchRef} />
+ + +
From 267a8aeb1ffd51ea93f4a53a4bafcc17a3c34060 Mon Sep 17 00:00:00 2001 From: Aarohi Nadkarni Date: Mon, 26 Feb 2024 12:26:24 -0500 Subject: [PATCH 11/12] refactor: remove debugging print statements --- src/components/data_search/DatasetSearchTable.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/components/data_search/DatasetSearchTable.js b/src/components/data_search/DatasetSearchTable.js index 12cf83c32..123adedd3 100644 --- a/src/components/data_search/DatasetSearchTable.js +++ b/src/components/data_search/DatasetSearchTable.js @@ -140,11 +140,9 @@ export const DatasetSearchTable = (props) => { setFilters(newFilters); const fullQuery = assembleFullQuery(searchTerm, newFilters); - // console.log("fullQuery", fullQuery); const search = async () => { try { await DataSet.searchDatasetIndex(fullQuery).then((filteredDatasets) => { - // console.log("intersection", datasets.filter(value => filteredDatasets.some(item => isEqual(item, value)))); setFiltered(datasets.filter(value => filteredDatasets.some(item => isEqual(item, value)))); }); } catch (error) { From 8b7ec7c9f03fd326c5a51d02c3523341655c0187 Mon Sep 17 00:00:00 2001 From: Aarohi Nadkarni Date: Mon, 11 Mar 2024 12:42:36 -0400 Subject: [PATCH 12/12] feat: resolve pr comments --- .../data_search/DatasetSearchTable.js | 68 +++++++++---------- 1 file changed, 34 insertions(+), 34 deletions(-) diff --git a/src/components/data_search/DatasetSearchTable.js b/src/components/data_search/DatasetSearchTable.js index 66aae3f0e..b4ad05cad 100644 --- a/src/components/data_search/DatasetSearchTable.js +++ b/src/components/data_search/DatasetSearchTable.js @@ -148,7 +148,8 @@ export const DatasetSearchTable = (props) => { const search = async () => { try { await DataSet.searchDatasetIndex(fullQuery).then((filteredDatasets) => { - setFiltered(datasets.filter(value => filteredDatasets.some(item => isEqual(item, value)))); + var newFiltered = datasets.filter(value => filteredDatasets.some(item => isEqual(item, value))); + setFiltered(newFiltered); }); } catch (error) { Notifications.showError({ text: 'Failed to load Elasticsearch index' }); @@ -362,8 +363,8 @@ export const DatasetSearchTable = (props) => { ref={searchRef} />
- - @@ -374,37 +375,36 @@ export const DatasetSearchTable = (props) => { - { - isEmpty(datasets) ? - -

No datasets registered for this library.

-
- : - isEmpty(filtered) ? - -

There are no datasets that fit these criteria.

-
- : - isEmpty(filtered) ? - -

There are no datasets that fit these criteria.

-
- : - - } + {(() => { + if (isEmpty(datasets)) { + return ( + +

No datasets registered for this library.

+
+ ); + } else if (isEmpty(filtered)) { + return ( + +

There are no datasets that fit these criteria.

+
+ ); + } else { + return ( + + ); + } + })()}