Skip to content

Commit

Permalink
[WEB-1230] -> Input Caching in typesense search (#470)
Browse files Browse the repository at this point in the history
  • Loading branch information
Santhosh-testsigma authored Aug 1, 2024
1 parent 2b67626 commit c08e26d
Show file tree
Hide file tree
Showing 5 changed files with 69 additions and 38 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 @@ -23,10 +23,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} className="shadow sm:rounded-lg">
<Link to={hit.fields.slug}>
<Link to={hit?.slug}>
<span className="search-title" dangerouslySetInnerHTML={{ __html: hit._highlightResult.title.value }} />
<p dangerouslySetInnerHTML={{ __html: hit._snippetResult.excerpt.value }} />
</Link>
Expand Down
6 changes: 3 additions & 3 deletions src/components/SearchHits.scss
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ ais-highlight-0000000000 {

.style {
list-style: none;
padding-top: 20px;
padding-top: 14px;
li {
margin-bottom: 6px;
background-color: #fff;
Expand All @@ -35,15 +35,15 @@ ais-highlight-0000000000 {
}
p {
margin: 6px 0;
font-size: 16px;
font-size: 14px;
line-height: 20px;
overflow-wrap: break-word;
}
}

.search-title {
font-weight: 700;
font-size: 14px;
font-size: 16px;
overflow-wrap: break-word;
color: #0E5AD9;
}
Expand Down
61 changes: 38 additions & 23 deletions src/components/SearchInputBox.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,16 +13,11 @@ 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 +38,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 +57,46 @@ 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,
});

/* eslint-enabe class-methods-use-this */
this.setState({ searchQuery: '' }, () => {
this.debouncedSearch(query);
});
}

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

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,9 +106,8 @@ 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">
<svg
width="15"
Expand All @@ -97,7 +118,6 @@ class SearchInputBox extends React.Component {
>
<path d="M8 16C9.77498 15.9996 11.4988 15.4054 12.897 14.312L17.293 18.708L18.707 17.294L14.311 12.898C15.405 11.4997 15.9996 9.77544 16 8C16 3.589 12.411 0 8 0C3.589 0 0 3.589 0 8C0 12.411 3.589 16 8 16ZM8 2C11.309 2 14 4.691 14 8C14 11.309 11.309 14 8 14C4.691 14 2 11.309 2 8C2 4.691 4.691 2 8 2Z" fill="black"/>
</svg>

</div>
<SearchBox
className="w-full pl-2"
Expand All @@ -107,30 +127,25 @@ 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' : 'absolute bg-white search_results border'}>
<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>
</div>
</InstantSearch>
</ClickOutHandler>

</div>
</>
);
Expand Down
23 changes: 17 additions & 6 deletions src/templates/page.scss
Original file line number Diff line number Diff line change
Expand Up @@ -350,22 +350,27 @@ body {
}
.float-searchBox {
position: fixed;
top: 0;
right: 0;
top: 30px;
right: 30px;
z-index: 3;
padding: 1.6rem 1rem;
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: 767px) {
width: 85% !important;
height: 90vh !important;
}
@media (min-width: 768px) {
width: 34%;
width: 45%;
height: 90vh !important;
}
@media (min-width: 1024px) {
width: 28%;
width: 35%;
}
@media (min-width: 1280px) {
width: 24.1%;
Expand All @@ -391,6 +396,7 @@ body {
border-left: 0;
background-color: #f5f5f5;
overflow-y: auto;
border-radius: 8px;
@media (max-width: 767px) {
top: 71px;
}
Expand All @@ -409,6 +415,11 @@ body {
}
}
}
.ais-SearchBox-input{
font-size: 18px;
border-radius: 5px;
padding: .5rem 1rem;
}
}
.ais-SearchBox-input{
outline: none!important;
Expand Down

0 comments on commit c08e26d

Please sign in to comment.