diff --git a/env.template.sh b/env.template.sh index ab05de7..c740641 100644 --- a/env.template.sh +++ b/env.template.sh @@ -1,5 +1,5 @@ -VITE_OPENSEARCH_URL="http://opensearch:9200" -VITE_OPENSEARCH_CREDENTIALS="admin:password" +VITE_OPENSEARCH_URL="https://opensearch.discovery.dor.lib.umich.edu" +VITE_OPENSEARCH_CREDENTIALS="admin:CHANGEME" VITE_REACTIVESEARCH_URL="http://reactivesearch:8000" VITE_REACTIVESEARCH_CREDENTIALS="admin:password" VITE_SEARCH_PARSER_URL="http://search-parser:4567" diff --git a/eslint.config.js b/eslint.config.js index cee1e2c..fd8a3d3 100644 --- a/eslint.config.js +++ b/eslint.config.js @@ -5,7 +5,7 @@ import reactRefresh from 'eslint-plugin-react-refresh' import { defineConfig, globalIgnores } from 'eslint/config' export default defineConfig([ - globalIgnores(['dist']), + globalIgnores(['dist', 'mlibrary_search_parser/**', 'search-parser-service/**']), { files: ['**/*.{js,jsx}'], extends: [ diff --git a/src/apps/OsDorDcApp/index.jsx b/src/apps/OsDorDcApp/index.jsx index 626df66..51bf020 100644 --- a/src/apps/OsDorDcApp/index.jsx +++ b/src/apps/OsDorDcApp/index.jsx @@ -19,9 +19,13 @@ function OsDorDcApp() { const [loading, setLoading] = useState(false); const [searchQuery, setSearchQuery] = useState(""); const [collectionFilter, setCollectionFilter] = useState(COLLECTION_OPTIONS.ALL); + // eslint-disable-next-line no-unused-vars const [minPrice, setMinPrice] = useState(PRICE_RANGE.DEFAULT_MIN); + // eslint-disable-next-line no-unused-vars const [maxPrice, setMaxPrice] = useState(PRICE_RANGE.DEFAULT_MAX); + // eslint-disable-next-line no-unused-vars const [actualMinPrice, setActualMinPrice] = useState(PRICE_RANGE.DEFAULT_MIN); + // eslint-disable-next-line no-unused-vars const [actualMaxPrice, setActualMaxPrice] = useState(PRICE_RANGE.DEFAULT_MAX); const [error, setError] = useState(null); const [connectionStatus, setConnectionStatus] = useState('checking'); @@ -86,7 +90,8 @@ function OsDorDcApp() { if (actualMaxPrice > 0) { fetchThings("", COLLECTION_OPTIONS.ALL, {min: actualMinPrice, max: actualMaxPrice}); } - }, [actualMaxPrice]); // Fetch things once we have price stats + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [actualMaxPrice]); // Fetch things once we have price stats (actualMinPrice intentionally omitted) const handleSearch = () => { fetchThings(searchQuery, collectionFilter, {min: minPrice, max: maxPrice}); diff --git a/src/apps/OsDorDcApp/services/openSearchService.js b/src/apps/OsDorDcApp/services/openSearchService.js index b3f2441..d946390 100644 --- a/src/apps/OsDorDcApp/services/openSearchService.js +++ b/src/apps/OsDorDcApp/services/openSearchService.js @@ -120,6 +120,7 @@ export const getCollections = async () => { // }; // }; +// eslint-disable-next-line no-unused-vars export const searchThings = async (query, collection, priceRange = null, size = 50) => { // Build the base query let queryObj; diff --git a/src/apps/RsDorDcApp/index.jsx b/src/apps/RsDorDcApp/index.jsx index 481d0ba..0d989b5 100644 --- a/src/apps/RsDorDcApp/index.jsx +++ b/src/apps/RsDorDcApp/index.jsx @@ -7,6 +7,7 @@ import { ResultList, SearchBox, SelectedFilters, + StateProvider, } from '@appbaseio/reactivesearch'; // console.log(Object.keys(ReactiveSearch)); @@ -52,11 +53,15 @@ function RsDorDcApp() { collection: [], subject: [], date: [], - coverage: [] + coverage: [], + group: [], + type: [], + HLB: [], }); const latestDataRef = useRef([]); const searchQueryRef = useRef(''); const parsedQueryRef = useRef(''); + const setSearchStateRef = useRef(null); useEffect(() => { // Test connections to ReactiveSearch and Search Parser @@ -121,6 +126,15 @@ function RsDorDcApp() { if (filters.coverage.length > 0) { filterParts.push(`Coverage: ${filters.coverage.join(', ')}`); } + if (filters.group.length > 0) { + filterParts.push(`Group: ${filters.group.join(', ')}`); + } + if (filters.type.length > 0) { + filterParts.push(`Type: ${filters.type.join(', ')}`); + } + if (filters.HLB.length > 0) { + filterParts.push(`Subject Area: ${filters.HLB.join(', ')}`); + } if (filterParts.length > 0) { if (fullQuery) { @@ -138,10 +152,10 @@ function RsDorDcApp() { const resultsData = latestDataRef.current; if (resultsData && resultsData.length > 0) { const top5Results = resultsData.slice(0, 5).map((item, index) => { - // Handle dc_ti as either string or array + // Handle dc_title as either string or array let title = 'Untitled'; - if (item.dc_ti) { - const titleRaw = Array.isArray(item.dc_ti) ? item.dc_ti.join(', ') : item.dc_ti; + if (item.dc_title) { + const titleRaw = Array.isArray(item.dc_title) ? item.dc_title.join(', ') : item.dc_title; title = titleRaw.replace(/<[^>]*>/g, ''); } return `${index + 1}. ${title}`; @@ -170,6 +184,18 @@ function RsDorDcApp() { setFilters(prev => ({ ...prev, coverage: value || [] })); }, []); + const handleGroupChange = useCallback((value) => { + setFilters(prev => ({ ...prev, group: value || [] })); + }, []); + + const handleTypeChange = useCallback((value) => { + setFilters(prev => ({ ...prev, type: value || [] })); + }, []); + + const handleHLBChange = useCallback((value) => { + setFilters(prev => ({ ...prev, HLB: value || [] })); + }, []); + const handleSearchChange = useCallback(async (value) => { // Store raw query in ref searchQueryRef.current = value || ''; @@ -206,8 +232,14 @@ function RsDorDcApp() { collection: [], subject: [], date: [], - coverage: [] + coverage: [], + group: [], + type: [], + HLB: [], }); + if (setSearchStateRef.current) { + setSearchStateRef.current({}); + } }, []); return ( @@ -234,7 +266,7 @@ function RsDorDcApp() { /> )} + { + setSearchStateRef.current = setSearchState; + return null; + }} + /> @@ -264,15 +301,14 @@ function RsDorDcApp() { @@ -280,15 +316,14 @@ function RsDorDcApp() { @@ -296,29 +331,72 @@ function RsDorDcApp() { + + + + + + + + + { if (!value) return null; @@ -367,14 +445,16 @@ function RsDorDcApp() { "multi_match": { "query": queryToUse, "fields": [ - "dc_ti^5", - "dc_ti.strict^7", - "dc_cr^3", - "dc_de^2", - "dc_su^3", - "dc_ge", - "dc_pu", - "dc_so" + "dc_title^5", + "dc_title.strict^7", + "dc_creator^3", + "dc_description^2", + "dc_subject^3", + "dc_genre", + "dc_publisher", + "dc_source", + "hlb^3", + "groupName^2" ], "type": "best_fields", "tie_breaker": 0.3 @@ -385,11 +465,11 @@ function RsDorDcApp() { "query": queryToUse, "type": "phrase", "fields": [ - "dc_ti^8", - "dc_ti.strict^10", - "dc_cr^5", - "dc_de^3", - "dc_su^5" + "dc_title^8", + "dc_title.strict^10", + "dc_creator^5", + "dc_description^3", + "dc_subject^5" ], "tie_breaker": 0.3 } @@ -428,7 +508,7 @@ function RsDorDcApp() { size={9} pagination={true} react={{ - and: ["search", "collection", "subject", "date", "coverage"], + and: ["search", "collection", "subject", "date", "coverage", "group", "type", "HLB"], }} render={({data}) => { // Store latest data in ref for feedback form @@ -439,12 +519,12 @@ function RsDorDcApp() { {data.map((item) => ( - - -
- {item.dc_cr && ( -
)} + + +
+ {item.dc_creator && ( +
)} {item.collection_id && item.item_id && item.media_id && item.media_id !== "NOFILE" && (
- {item.XXX_dc_de && ( - <> -
XXX_dc_de:
-
{Array.isArray(item.XXX_dc_de) ? item.XXX_dc_de.join(', ') : item.XXX_dc_de}
- - )} - {item.dc_co && ( - <> -
dc_co:
-
{Array.isArray(item.dc_co) ? item.dc_co.join(', ') : item.dc_co}
- - )} - {item.dc_cov && ( - <> -
dc_cov:
-
{Array.isArray(item.dc_cov) ? item.dc_cov.join(', ') : item.dc_cov}
- - )} - {item.dc_cr && ( - <> -
dc_cr:
-
{Array.isArray(item.dc_cr) ? item.dc_cr.join(', ') : item.dc_cr}
- - )} - {item.dc_da && ( + {item.collection_name && ( <> -
dc_da:
-
{Array.isArray(item.dc_da) ? item.dc_da.join(', ') : item.dc_da}
+
collection_name:
+
{Array.isArray(item.collection_name) ? item.collection_name.join(', ') : item.collection_name}
)} - {item.dc_de && ( + {item.hlb && ( <> -
dc_de:
-
{Array.isArray(item.dc_de) ? item.dc_de.join(', ') : item.dc_de}
+
hlb:
+
{Array.isArray(item.hlb) ? item.hlb.join(', ') : item.hlb}
)} - {item.dc_fo && ( + {item.groupName && ( <> -
dc_fo:
-
{Array.isArray(item.dc_fo) ? item.dc_fo.join(', ') : item.dc_fo}
+
groupName:
+
{Array.isArray(item.groupName) ? item.groupName.join(', ') : item.groupName}
)} - {item.dc_ge && ( + {item.dc_contributor && ( <> -
dc_ge:
-
{Array.isArray(item.dc_ge) ? item.dc_ge.join(', ') : item.dc_ge}
+
dc_contributor:
+
{Array.isArray(item.dc_contributor) ? item.dc_contributor.join(', ') : item.dc_contributor}
)} - {item.dc_la && ( + {item.dc_coverage && ( <> -
dc_la:
-
{Array.isArray(item.dc_la) ? item.dc_la.join(', ') : item.dc_la}
+
dc_coverage:
+
{Array.isArray(item.dc_coverage) ? item.dc_coverage.join(', ') : item.dc_coverage}
)} - {item.dc_lo && ( + {item.dc_creator && ( <> -
dc_lo:
-
{Array.isArray(item.dc_lo) ? item.dc_lo.join(', ') : item.dc_lo}
+
dc_creator:
+
{Array.isArray(item.dc_creator) ? item.dc_creator.join(', ') : item.dc_creator}
)} - {item.dc_pu && ( + {item.dc_date && ( <> -
dc_pu:
-
{Array.isArray(item.dc_pu) ? item.dc_pu.join(', ') : item.dc_pu}
+
dc_date:
+
{Array.isArray(item.dc_date) ? item.dc_date.join(', ') : item.dc_date}
)} - {item.dc_re && ( + {item.dc_description && ( <> -
dc_re:
-
{Array.isArray(item.dc_re) ? item.dc_re.join(', ') : item.dc_re}
+
dc_description:
+
{Array.isArray(item.dc_description) ? item.dc_description.join(', ') : item.dc_description}
)} - {item.dc_rel && ( + {item.dc_format && ( <> -
dc_rel:
-
{Array.isArray(item.dc_rel) ? item.dc_rel.join(', ') : item.dc_rel}
+
dc_format:
+
{Array.isArray(item.dc_format) ? item.dc_format.join(', ') : item.dc_format}
)} - {item.dc_so && ( + {item.dc_genre && ( <> -
dc_so:
-
{Array.isArray(item.dc_so) ? item.dc_so.join(', ') : item.dc_so}
+
dc_genre:
+
{Array.isArray(item.dc_genre) ? item.dc_genre.join(', ') : item.dc_genre}
)} - {item.dc_su && ( + {item.dc_language && ( <> -
dc_su:
-
{Array.isArray(item.dc_su) ? item.dc_su.join(', ') : item.dc_su}
+
dc_language:
+
{Array.isArray(item.dc_language) ? item.dc_language.join(', ') : item.dc_language}
)} - {item.dc_ty && ( + {item.dc_location && ( <> -
dc_ty:
-
{Array.isArray(item.dc_ty) ? item.dc_ty.join(', ') : item.dc_ty}
+
dc_location:
+
{Array.isArray(item.dc_location) ? item.dc_location.join(', ') : item.dc_location}
)} - {item.dc_type && ( + {item.dc_publisher && ( <> -
dc_type:
-
{Array.isArray(item.dc_type) ? item.dc_type.join(', ') : item.dc_type}
+
dc_publisher:
+
{Array.isArray(item.dc_publisher) ? item.dc_publisher.join(', ') : item.dc_publisher}
)} - {item.xx_dc_co && ( + {item.dc_rights && ( <> -
xx_dc_co:
-
{Array.isArray(item.xx_dc_co) ? item.xx_dc_co.join(', ') : item.xx_dc_co}
+
dc_rights:
+
{Array.isArray(item.dc_rights) ? item.dc_rights.join(', ') : item.dc_rights}
)} - {item.xx_dc_cr && ( + {item.dc_relation && ( <> -
xx_dc_cr:
-
{Array.isArray(item.xx_dc_cr) ? item.xx_dc_cr.join(', ') : item.xx_dc_cr}
+
dc_relation:
+
{Array.isArray(item.dc_relation) ? item.dc_relation.join(', ') : item.dc_relation}
)} - {item.xx_dc_cv && ( + {item.dc_source && ( <> -
xx_dc_cv:
-
{Array.isArray(item.xx_dc_cv) ? item.xx_dc_cv.join(', ') : item.xx_dc_cv}
+
dc_source:
+
{Array.isArray(item.dc_source) ? item.dc_source.join(', ') : item.dc_source}
)} - {item.xx_dc_fo && ( + {item.dc_subject && ( <> -
xx_dc_fo:
-
{Array.isArray(item.xx_dc_fo) ? item.xx_dc_fo.join(', ') : item.xx_dc_fo}
+
dc_subject:
+
{Array.isArray(item.dc_subject) ? item.dc_subject.join(', ') : item.dc_subject}
)} - {item.xx_dc_so && ( + {item.dc_type && ( <> -
xx_dc_so:
-
{Array.isArray(item.xx_dc_so) ? item.xx_dc_so.join(', ') : item.xx_dc_so}
+
dc_type:
+
{Array.isArray(item.dc_type) ? item.dc_type.join(', ') : item.dc_type}
)} diff --git a/vite.config.js b/vite.config.js index bc84e99..2b434b3 100644 --- a/vite.config.js +++ b/vite.config.js @@ -2,7 +2,7 @@ import { defineConfig } from 'vite' import react from '@vitejs/plugin-react' // https://vite.dev/config/ -export default defineConfig(({ mode }) => { +export default defineConfig(() => { return { plugins: [react()], server: {