Commit 27dd9978 authored by Muneeb Saeed's avatar Muneeb Saeed

Filtering work added

parent ea3a31b1
# This file specifies files that are *not* uploaded to Google Cloud
# using gcloud. It follows the same syntax as .gitignore, with the addition of
# "#!include" directives (which insert the entries of the given .gitignore-style
# file at that point).
#
# For more information, run:
# $ gcloud topic gcloudignore
#
.gcloudignore
# If you would like to upload your .git directory, .gitignore file or files
# from your .gitignore file, remove the corresponding line
# below:
.git
.gitignore
# Node.js dependencies:
node_modules/
\ No newline at end of file
......@@ -31,8 +31,8 @@ async function main(searchQuery, facets, filters) {
// Raw search query.
const query = searchQuery; //TRY DIFFERENT QUERY PHRASES
const facetSpecs = facets ? facets : [];
// const filter = filters; // TRY DIFFERENT FILTER EXPRESSIONS
const filter = '(availability: ANY("OUT_OF_STOCK") AND brands: ANY("Google"))'; // TRY DIFFERENT FILTER EXPRESSIONS
const filter = filters; /// TRY DIFFERENT FILTER EXPRESSIONS
// const filter = '(colors: ANY("Cool gray" ,"Light gray"))'; // TRY DIFFERENT FILTER EXPRESSIONS
// A unique identifier for tracking visitors.
const visitorId = '12345';
......@@ -52,7 +52,7 @@ async function main(searchQuery, facets, filters) {
placement,
query,
facetSpecs,
// filter,
filter,
visitorId,
pageSize,
};
......
......@@ -11,10 +11,17 @@ app.use(bodyParser.json());
const searchService = require('./samples/interactive-tutorials/search/search-simple-query');
app.get('/search', (req, res) => {
const { text, facets } = req.query
const facetArray= facets && facets.split(',') || [];
const facetObj = facetArray.map((facet) => ({ facetKey: { key: facet }}));
searchService(text, facetObj)
const { text, facets, filters } = req.query;
const facetsObj = facets && JSON.parse(facets).map((facet) => ({ facetKey: { key: facet }}));
const filterObj = filters && JSON.parse(filters) || [];
let filterString = '';
Object.keys(filterObj).forEach((key, i, arr) => {
filterString = filterString + `${key}: ANY("${filterObj[key].join('","')}")${i == arr.length -1 ? '' : ' AND '}`;
});
filterString = filterString && `(${filterString})`;
searchService(text, facetsObj, filterString)
.then(result => {
return res.send(result);
})
......
import React, { useState } from 'react';
import React, { useEffect, useState } from 'react';
import './search-results.css';
import { Typography, Col, Row, Card, Select, Checkbox, Collapse } from 'antd';
......@@ -6,12 +6,12 @@ import { LinkOutlined, FilterFilled } from '@ant-design/icons';
const { Meta } = Card;
const { Panel } = Collapse;
const SearchResults = ({ searchResults, facets, onSelectFacet }) => {
const SearchResults = ({ searchResults, facets, onSelectFacet, onSelectFilter }) => {
const availabilityMap = new Map();
availabilityMap.set('IN_STOCK', 'In Stock');
availabilityMap.set('OUT_OF_STOCK', 'Out of Stock');
// const [filters, setFilters] = useState('()');
const [filters, setFilters] = useState(null);
const facetOptions = [
{
......@@ -35,17 +35,27 @@ const SearchResults = ({ searchResults, facets, onSelectFacet }) => {
facetOptions.forEach(facet => facetMap.set(facet.value, facet.label));
const onChangeHandler = (value) => {
if (value) {
onSelectFacet(value)
}
onSelectFacet(value);
};
const onChangeCheckboxHandler = (filterValue, filterKey) => {
console.log('filterValue', filterValue);
console.log('filterKey', filterKey);
if (filterValue && filterValue.length) {
setFilters((prevState) => ({
...prevState,
[filterKey]: filterValue
}));
} else {
const tempVal = { ...filters }
delete tempVal[`${filterKey}`];
setFilters(tempVal);
}
};
useEffect(() => {
if (filters != null)
onSelectFilter(filters);
}, [filters]);
return (
<>
{searchResults.length > 0 &&
......@@ -73,7 +83,7 @@ const SearchResults = ({ searchResults, facets, onSelectFacet }) => {
{ facets.length > 0 && facets.map((facet, i) =>
<Collapse ghost>
<Panel header={facetMap.get(facet.key)} key={i} style={{ fontSize: '0.9rem', color: '#000000 ' }}>
<Checkbox.Group class="verticalCheckBox" options={[...facet.values.map((f) => ({label: f.value, value: f.value}) )]}
<Checkbox.Group className="verticalCheckBox" options={[...facet.values.map((f) => ({label: f.value, value: f.value}) )]}
onChange={(val) => onChangeCheckboxHandler(val, facet.key)} />
</Panel>
</Collapse>
......
import React, { useState } from 'react';
import React, { useEffect, useState } from 'react';
import SearchResults from './search-results';
import { Button, Input, Col, Row } from 'antd';
......@@ -6,38 +6,66 @@ import { SearchOutlined } from '@ant-design/icons';
const Search = () => {
const [searchText, setSearchText] = useState({ text: '' });
const INITIAL_STATE = { searchQuery: '', facets: [], filters: null };
const [payload, setPayload] = useState(INITIAL_STATE);
const [searchResults, setSearchResults] = useState([]);
const [facets, setfacets] = useState([]);
const handleOnChange = (e) => {
setSearchText(prevState => ({
setPayload(prevState => ({
...prevState,
text: e.target.value,
searchQuery: e.target.value,
filters: null
}));
};
const handleOnSearch = async (value) => {
const { text, facets } = value;
if (text) {
const url = `https://api-dot-abs-poc-np-prj-01-3f2a.uc.r.appspot.com/search?text=${text}${facets && facets.length? `&facets=${facets}` : ''}`;
const handleOnSearch = async () => {
const { searchQuery, facets, filters } = payload;
if (searchQuery) {
const apiEndpoint = 'https://api-dot-abs-poc-np-prj-01-3f2a.uc.r.appspot.com';
// const apiEndpoint = 'http://localhost:8080';
const url = `${apiEndpoint}/search?text=${searchQuery}${facets.length? `&facets=${JSON.stringify(facets)}` : ''}${filters && Object.keys(filters).length? `&filters=${JSON.stringify(filters)}` : ''}`;
const searchResults = await fetch(url)
.then(res => res.json())
.catch(err => console.log(err));
setSearchResults(searchResults.results.length ? [...searchResults.results] : []);
setfacets(searchResults.facets.length ? [...searchResults.facets] : []);
}
setSearchResults(searchResults.results?.length ? [...searchResults.results] : []);
!Object.keys(filters || {}).length && setfacets(searchResults.facets?.length ? [...searchResults.facets] : []); // for not updating facets while filtering
}
};
const handleImageClick = () => {
setSearchText(prevState => ({
...prevState,
text: ''
}));
setPayload(INITIAL_STATE);
setSearchResults([]);
setfacets([]);
};
const onSelectFacet = (val) => {
setPayload(prevState => ({
...prevState,
facets: val,
}));
}
const onSelectFilter = (val) => {
setPayload(prevState => ({
...prevState,
filters: val,
}));
}
useEffect(() => {
if (payload.filters != null) {
handleOnSearch();
}
}, [payload.filters])
useEffect(() => {
payload.facets.length ? handleOnSearch() : setfacets([]);
}, [payload.facets])
return (
<>
{searchResults.length > 0 &&
......@@ -53,13 +81,11 @@ const Search = () => {
>
<span style={{
margin: '1rem 0',
// width: '7rem',
height: 'auto',
}}
onClick={() => handleImageClick()}
>
<img src='ultabeauty.png' alt="google" style={{
// width: '100%'
}}
/>
</span>
......@@ -71,16 +97,19 @@ const Search = () => {
<Input
size='large'
placeholder="Input Search Text"
value={searchText.text}
value={payload.searchQuery}
allowClear
prefix={<SearchOutlined style={{ color: "#d9d9d9", margin: '0 0.5rem' }} />}
onChange={handleOnChange}
onPressEnter={() => handleOnSearch(searchText, 2)}
onPressEnter={() => handleOnSearch()}
/>
</Col>
</Row>
</div>
<SearchResults searchResults={searchResults} facets={facets} onSelectFacet={(val) => handleOnSearch({ text: searchText.text, facets: val } )} />
<SearchResults searchResults={searchResults} facets={facets}
onSelectFacet={(val) => onSelectFacet(val)}
onSelectFilter={(val) => onSelectFilter(val)}
/>
</>
}
{searchResults.length === 0 &&
......@@ -92,10 +121,6 @@ const Search = () => {
<Row>
<Col span={12} offset={6}>
<div className='App'>
{/* <Typography.Title
style={{ fontSize: '3rem', color: '#000000 ' }}>
{CONFIGS.title}
</Typography.Title> */}
<span>
<img src='ultabeauty.png' alt="google" style={{
width: '12rem',
......@@ -108,11 +133,11 @@ const Search = () => {
<Input
size='large'
placeholder="Input Search Text"
value={searchText.text}
value={payload.searchQuery}
allowClear
prefix={<SearchOutlined style={{ color: "#d9d9d9", margin: '0 0.5rem' }} />}
onChange={handleOnChange}
onPressEnter={() => handleOnSearch(searchText)}
onPressEnter={() => handleOnSearch()}
/>
<Button type='primary' style={{
margin: '2rem 1rem',
......@@ -120,7 +145,7 @@ const Search = () => {
minHeight: '2.5rem',
background: '#b5904a'
}}
onClick={() => handleOnSearch(searchText)}
onClick={() => handleOnSearch()}
> Search </Button>
</div>
</Col>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment