From b578eb228df7cf05aee5dc27115eec67128a6444 Mon Sep 17 00:00:00 2001 From: Ben Silverman Date: Tue, 12 Jan 2021 19:08:13 -0500 Subject: [PATCH] #23 New search logic --- .../Search/SearchResults/SearchResults.js | 43 +++++- src/components/Search/utils.js | 145 +++++------------- 2 files changed, 72 insertions(+), 116 deletions(-) diff --git a/src/components/Search/SearchResults/SearchResults.js b/src/components/Search/SearchResults/SearchResults.js index 1496486..a45940a 100644 --- a/src/components/Search/SearchResults/SearchResults.js +++ b/src/components/Search/SearchResults/SearchResults.js @@ -20,19 +20,50 @@ const loadingResults = Object.keys([...Array(3)]); const getFormattedTitle = (title, searchQuery) => { const titleLowercased = title.toLowerCase(); const searchQueryLowercased = searchQuery.toLowerCase(); - const index = titleLowercased.indexOf(searchQueryLowercased); let formattedTitle = title; - if (index >= 0) { + const sqArray = searchQueryLowercased.split(' '); + if (sqArray.length > 1) { + const highlights = sqArray + .map((sqPart) => { + const index = titleLowercased.indexOf(sqPart); + return { + text: sqPart, + start: index, + end: index + sqPart.length, + }; + }) + .filter((highlight) => highlight.start >= 0); + let cursor = 0; + highlights.sort((a, b) => ((a.start > b.start) ? 1 : -1)); formattedTitle = ( - {title.substring(0, index)} - {title.substring(index, index + searchQuery.length)} - {title.substring(index + searchQuery.length)} + {highlights.map((highlight) => { + const start = cursor; + cursor = highlight.end; + return ( + <> + {title.substring(start, highlight.start)} + {title.substring(highlight.start, highlight.end)} + + ); + })} + {title.substring(cursor)} ); - } + } else { + const index = titleLowercased.indexOf(searchQueryLowercased); + if (index >= 0) { + formattedTitle = ( + + {title.substring(0, index)} + {title.substring(index, index + searchQuery.length)} + {title.substring(index + searchQuery.length)} + + ); + } + } return {formattedTitle}; }; diff --git a/src/components/Search/utils.js b/src/components/Search/utils.js index 3e6b411..50bbaa1 100644 --- a/src/components/Search/utils.js +++ b/src/components/Search/utils.js @@ -1,7 +1,7 @@ import gql from 'graphql-tag'; import { - sortBy, - prop, + // sortBy, + // prop, propEq, findIndex, } from 'ramda'; @@ -15,102 +15,26 @@ import { withRouter } from 'react-router-dom'; import { withLoading, withErrors } from '../../utils/hocUtil'; export const getSearchQuery = (limit) => { - const getEventsQuery = (suffix = '') => `events${suffix}( - where: { - OR: [ - { eventTitle: { - contains: $searchQuery - mode: insensitive - } - } - { eventDescription: { - contains: $searchQuery - mode: insensitive - } - } - { eventStakeholders: { - some: { - Stakeholder: { - stakeholderFullName: { - contains: $searchQuery - mode: insensitive - } - } - } - } - } - ] - } - ${(limit && suffix !== 'Count') ? `first: ${limit}` : ''} + const getQuery = (suffix = '') => `searchQuery${suffix}( + searchQuery: $searchQuery + ${(limit && suffix !== 'Count') ? `limit: ${limit}` : ''} )`; - const getDocumentsQuery = (suffix = '') => `documents${suffix}( - where: { - OR: [ - { documentTitle: { - contains: $searchQuery - mode: insensitive - } + return gql` + query Search($searchQuery: String!) { + ${getQuery()} { + events { + id + eventTitle } - { documentDescription: { - contains: $searchQuery - mode: insensitive - } + documents { + id + documentTitle } - { documentTranscript: { - contains: $searchQuery - mode: insensitive - } + stakeholders { + id + stakeholderFullName } - { mentionedStakeholders: { - some: { - Stakeholder: { - stakeholderFullName: { - contains: $searchQuery - mode: insensitive - } - } - } - } - } - ] - } - ${(limit && suffix !== 'Count') ? `first: ${limit}` : ''} - )`; - const getStakeholderQuery = (suffix = '') => `stakeholders${suffix}( - where: { - OR: [ - { stakeholderFullName: { - contains: $searchQuery - mode: insensitive - } - } - { stakeholderDescription: { - contains: $searchQuery - mode: insensitive - } - } - ] - } - ${(limit && suffix !== 'Count') ? `first: ${limit}` : ''} - )`; - - return gql` - query Search($searchQuery: String!) { - ${getEventsQuery()} { - id - eventTitle - } - ${getDocumentsQuery()} { - id - documentTitle - } - ${getStakeholderQuery()} { - id - stakeholderFullName } - ${getEventsQuery('Count')} - ${getDocumentsQuery('Count')} - ${getStakeholderQuery('Count')} } `; }; @@ -128,29 +52,30 @@ const contains = (container, containment) => container.toLowerCase() .includes(containment.toLowerCase()); export const handleSearchResults = (props, value) => ({ data }) => { - const { stopLoading, setCounts, setSearchResults } = props; - const documents = parseDocuments(data.documents); - const events = parseEvents(data.events); - const stakeholders = parseStakeholders(data.stakeholders); - const unorderedSearchResults = [...stakeholders, ...documents, ...events]; - const allSearchResults = sortBy(prop('title'), unorderedSearchResults); + const { stopLoading, setSearchResults } = props; + // const { stopLoading, setCounts, setSearchResults } = props; + const documents = parseDocuments(data.searchQuery.documents); + const events = parseEvents(data.searchQuery.events); + const stakeholders = parseStakeholders(data.searchQuery.stakeholders); + const allSearchResults = [...stakeholders, ...documents, ...events]; + // const allSearchResults = sortBy(prop('title'), unorderedSearchResults); const withHighlights = allSearchResults.filter(({ title }) => contains(title, value)); const withoutHighlights = allSearchResults.filter(({ title }) => !contains(title, value)); const searchResults = [...withHighlights, ...withoutHighlights]; - const documentCount = data.documentsCount; - const eventCount = data.eventsCount; - const stakeholderCount = data.stakeholdersCount; + // const documentCount = data.documentsCount; + // const eventCount = data.eventsCount; + // const stakeholderCount = data.stakeholdersCount; stopLoading(); setSearchResults(searchResults); - setCounts({ - all: eventCount - + documentCount - + stakeholderCount, - event: eventCount, - document: documentCount, - stakeholder: stakeholderCount, - }); + // setCounts({ + // all: eventCount + // + documentCount + // + stakeholderCount, + // event: eventCount, + // document: documentCount, + // stakeholder: stakeholderCount, + // }); }; export const withSearch = compose(