Skip to content

Commit

Permalink
[WEB-1230] -> Input Caching in typesense search (#94)
Browse files Browse the repository at this point in the history
  • Loading branch information
Santhosh-testsigma authored Aug 2, 2024
1 parent 6314b7d commit 5978706
Show file tree
Hide file tree
Showing 5 changed files with 72 additions and 29 deletions.
13 changes: 9 additions & 4 deletions scripts/indexr.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,19 +29,24 @@ const pageQuery = `
fields {
slug
}
excerpt(pruneLength: 6700)
excerpt(pruneLength: 100)
}
}
}
}
`;

function pageToTypesenseRecord({ node }) {
const { id, frontmatter, ...rest } = node;
console.log('node', node);
const { id, frontmatter, fields = {}, headings = [], ...rest } = node;

const formattedHeadings = headings.map(h => h.value || '').filter(Boolean);
return {
objectID: id,
...frontmatter,
title: frontmatter.title || '',
search_keyword: String(frontmatter.search_keyword || ''),
slug: fields.slug || '',
excerpt: frontmatter.excerpt || '',
headings: formattedHeadings,
...rest,
};
}
Expand Down
4 changes: 2 additions & 2 deletions src/components/SearchHits.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,10 @@ export const CustomSearchBox = connectSearchBox(SearchBox);
/* eslint-disable react/no-danger */
const Hits = ({ hits }) => (
<ul className="style">
{hits.length < 1 ? <li>No search results found</li> : ''}
{hits.length < 1 ? <li className='px-5 py-3 rounded-lg text-center'>No search results found</li> : ''}
{hits.map((hit) => (
<li key={hit.title}>
<a href={hit.fields.slug}>
<a href={hit?.slug}>
<span className="search-title" dangerouslySetInnerHTML={{ __html: hit._highlightResult.title.value }} />
<p dangerouslySetInnerHTML={{ __html: hit._snippetResult.excerpt.value }} />
</a>
Expand Down
9 changes: 8 additions & 1 deletion src/components/SearchHits.scss
Original file line number Diff line number Diff line change
Expand Up @@ -19,19 +19,26 @@ ais-highlight-0000000000 {

.style {
list-style: none;
padding-top: 20px;
padding-top: 14px;
a {
color: #757575;
}
a:hover {
color: #fe6c37;
text-decoration: none;
}
p {
margin: 6px 0;
font-size: 14px;
line-height: 20px;
overflow-wrap: break-word;
}
}

.search-title {
font-weight: 700;
color: #0E5AD9;
font-size: 16px;
}

.ais-SearchBox-form {
Expand Down
57 changes: 39 additions & 18 deletions src/components/SearchInputBox.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,16 +13,13 @@ import { SearchHits } from './SearchHits';

import TypesenseInstantsearchAdapter from "typesense-instantsearch-adapter";

// window.$ = $;

/* Algolia Search Bar */
const ClickOutHandler = require('react-onclickout');

// Create the Typesense InstantSearch Adapter instance

// @ts-ignore
console.log(process.env.TYPESENSE_SEARCH_API_KEY);
console.log(process.env.TYPESENSE_HOST);
// console.log(process.env.TYPESENSE_SEARCH_API_KEY);
// console.log(process.env.TYPESENSE_HOST);
const typesenseInstantsearchAdapter = new TypesenseInstantsearchAdapter({
server: {
apiKey: process.env.TYPESENSE_SEARCH_API_KEY, // Use your Typesense search-only API key here
Expand All @@ -43,6 +40,16 @@ const typesenseInstantsearchAdapter = new TypesenseInstantsearchAdapter({

export const searchClient = typesenseInstantsearchAdapter.searchClient;

const debounce = (func, delay) => {
let timer;
return function (...args) {
clearTimeout(timer);
timer = setTimeout(() => {
func.apply(this, args);
}, delay);
};
};

class SearchInputBox extends React.Component {
constructor(props) {
super(props);
Expand All @@ -52,29 +59,47 @@ class SearchInputBox extends React.Component {
cookie: '',
hasInput: false,
refresh: false,
searchQuery: ''
};

this.debouncedSearch = debounce(this.handleSearch, 300);
}

// Algolia - clicking out exits searchbox
onClickOut = (event) => {
const searchInput = document.getElementsByClassName(
'ais-SearchBox-input',
)[0].value;
const domNode = ReactDOM.findDOMNode(this);
if (searchInput === '' || !domNode || !domNode.contains(event.target))
this.setState({ hasInput: false });
} // end onClickOut
}

handleKeyUp = (event) => {
const query = event.currentTarget.value;
this.setState({
hasInput: query.length > 2,
});

this.setState({ searchQuery: '' }, () => {
this.debouncedSearch(query);
});
}

handleSearch = (query) => {
console.log('Searching for:', query);
this.setState({
refresh: !this.state.refresh,
searchQuery: query
});
}

/* eslint-enabe class-methods-use-this */

render() {
const {
refresh, hasInput
refresh, hasInput, searchQuery
} = this.state;
return (
<>

<div className={!hasInput ? 'form-inline flex w-1/5 items-center pl-4' : 'form-inline flex w-1/5 items-center pl-4 float-searchBox'}>
<label htmlFor="search-lc" />

Expand All @@ -84,7 +109,7 @@ class SearchInputBox extends React.Component {
indexName={process.env.TYPESENSE_COLLECTION}
refresh={refresh}
>
<Configure hitsPerPage={5} />
<Configure hitsPerPage={10} />

{/* forcefeed className because component does not accept natively as prop */}
<div className="search-icon">
Expand All @@ -107,23 +132,19 @@ class SearchInputBox extends React.Component {
translations={{
placeholder: 'Search',
}}
onKeyUp={(event) => {
this.setState({
hasInput: event.currentTarget.value.length > 2,
});
}}
onKeyUp={this.handleKeyUp}
/>

<div className={!hasInput ? 'input-empty' : '-mt-1.5 absolute background-white bg-white search_results border h-full top-20 w-2/8'}>
<div className="container">
<div className="row">
<div className="col-12">
<SearchHits hitComponent={Hits} />
{searchQuery && <SearchHits hitComponent={Hits} />}
</div>
</div>
<div className="row">
<div className="col-12">
<Pagination />
{searchQuery && <Pagination />}
</div>
</div>
</div>
Expand Down
18 changes: 14 additions & 4 deletions src/templates/page.scss
Original file line number Diff line number Diff line change
Expand Up @@ -486,17 +486,21 @@ code[class*="language-"] {

.float-searchBox {
position: fixed;
top: 0;
right: 0;
top: 30px;
right: 30px;
z-index: 3;
padding: 1.6rem 1rem;
width: 24.1%;
height: 100%;
max-height: 94vh;
display: block;
border-left: 1px solid rgba(229, 231, 235, var(--tw-border-opacity));
background-color: #fff;
border-radius: 8px;
backdrop-filter: blur(26px);
padding: 0.9rem 1rem;
transition: all 0.25s ease-in;
@media (max-width: 576px) {
width: 85%;
height: 90vh !important;
}
.ais-SearchBox,
.search-icon {
Expand All @@ -519,6 +523,7 @@ code[class*="language-"] {
border-left: 0;
background-color: #f5f5f5;
overflow-y: auto;
border-radius: 8px;
.ais-Pagination-list {
display: flex;
padding: 0.25rem 0 0.5rem;
Expand All @@ -531,6 +536,11 @@ code[class*="language-"] {
}
}
}
.ais-SearchBox-input{
font-size: 18px;
border-radius: 5px;
padding: .5rem 1rem;
}
}

.ais-SearchBox-input{
Expand Down

0 comments on commit 5978706

Please sign in to comment.