Select Git revision
search.js 4.73 KiB
import React, { useState } from 'react';
import DataGrid, { Scrolling, Sorting, LoadPanel, Column, MasterDetail, Paging } from 'devextreme-react/data-grid';
import TextBox from 'devextreme-react/text-box';
import "./search.css"
import axios from "axios";
import { LoadIndicator } from 'devextreme-react/load-indicator';
import TextArea from 'devextreme-react/text-area';
const PAGE_SIZE = 25
function search(query, startIdx=0, endIdx=PAGE_SIZE+1) {
const config = {
method: 'get',
url: '/api/search?q=' + query + "&startIdx=" + startIdx + "&endIdx=" + endIdx
};
return axios(config);
}
let TextView = function (e) {
let result = e.data.data
return (
<div>
<TextArea
height={350}
value={JSON.stringify(result, null, 4)}
/>
<Scrolling mode="virtual" rowRenderingMode="virtual" />
</div>
)
}
let SearchEngine = function () {
const [queryResult, setQueryResult] = useState([]);
const [query, setQuery] = useState("");
const [isLoading, setIsLoading] = useState(false);
const [prevPage, setPrevPage] = useState(0);
const [maxPage, setMaxPage] = useState(0);
const parseESData = (data) => {
let parsedData = []
for (let row of data) {
let newObj = {}
newObj["id"] = parseInt(row["_id"])
newObj["title"] = row["_source"]["title"]
newObj["authors"] = row["_source"]["authors"]
newObj["score"] = row["_score"]
newObj["country"] = row["_source"]["country"]
newObj["doi"] = row["_source"]["doi"]
newObj["journal"] = row["_source"]["journal"]
newObj["pmid"] = row["_source"]["pmid"]
newObj["published_at"] = row["_source"]["published_at"]
newObj["abstract"] = row["_source"]["abstract"]
parsedData.push(newObj)
}
return parsedData
}
const handleSubmit = (e) => {
e.preventDefault();
setIsLoading(true)
let query = e.target[0].value
search(query).then((res) => { let parsedRes = parseESData(res.data)
setQuery(query)
setQueryResult(parsedRes)
setIsLoading(false)
}).catch((error) => {
console.log(error)
setIsLoading(false)
})
}
const handlePageChange = (e) => {
let curPage = e.component.pageIndex()
if (curPage < prevPage){
setPrevPage(curPage)
return
} else if (curPage > prevPage && curPage > maxPage){
setIsLoading(true)
search(query, curPage*PAGE_SIZE+1, ((curPage+1)*PAGE_SIZE)+1).then((res) => {
let parsedRes = parseESData(res.data)
setQueryResult(queryResult.concat(parsedRes))
setIsLoading(false)
setMaxPage(curPage)
}).catch((error) => {
console.log(error)
setIsLoading(false)
})
setPrevPage(curPage)
}
}
return (
<div className="dx-fieldset">
<div>
<div className='form-box'>
<form onSubmit={handleSubmit}>
<div className="row">
<div className="column"><h3 className='dx-header'>Search COVID Research!</h3></div>
</div>
<div className="row">
<div className="column-left">
<TextBox width={"100%"} className="dx-field-value" />
</div>
<div className="column-right">
<input type="submit" value="Search" />
</div>
<div className="indicator-column">
<LoadIndicator id="medium-indicator" height={20} width={20} visible={isLoading}/>
</div>
</div>
</form>
</div>
<div className="dx-field" style={{"height":"100", "whiteSpace": "normal", "overflowWrap":"break-word"}}>
<DataGrid
dataSource={queryResult}
keyExpr="id"
showBorders={false}
allowColumnResizing={true}
onContentReady={handlePageChange}
>
<MasterDetail
enabled={true}
component={TextView}
/>
<Column dataField="id" width={75}/>
<Column dataField="title" caption={"Title"} dataType="string" />
<Column dataField="authors" caption={"Authors"} dataType="string" />
<Column dataField="score" caption={"Score"} width={75} dataType="string" />
<Sorting mode="none" /> <Paging pageSize={PAGE_SIZE} visible={true}/>
<LoadPanel enabled={true} />
</DataGrid>
</div>
</div>
</div>
)
}
export default SearchEngine;