in src/main/js/components/query-result/query-result.js [9:236]
function QueryResult({containerUrl, vispanaClient, query, showResults, schema, refreshQuery, defaultPageSize = 15, useTabs = false}) {
// customize theme
createTheme('dark', {
text: {
// primary: '#facc15',
primary: '#fff',
secondary: '#fff',
},
background: {
default: '#1f2a40',
},
highlightOnHover: {
default: '#3b4f77',
text: '#fff',
},
striped: {
default: '#2c3c5a',
text: '#fff',
},
context: {
text: '#facc15',
},
divider: {
default: 'rgb(20 27 45 / var(--tw-bg-opacity))',
},
});
// data state
const [data, setData] = useState({columns: [], content: [], trace: []});
const [loading, setLoading] = useState(true);
const [totalRows, setTotalRows] = useState(0);
// pagination state
const [offset, setOffset] = useState(0);
const [perPage, setPerPage] = useState(defaultPageSize);
const [page, setPage] = useState(1);
// error state
const [error, setError] = useState({
hasError: false,
error: ""
});
const NoDataConst = props => {
if (data.json && data.json.root) {
const root = data.json.root
if (root.coverage && root.coverage.degraded && root.coverage.degraded.timeout) {
return <><span className="text-red-500 m-8">Vespa query timed out.</span></>
} else {
if (root.fields && root.fields.totalCount === 0) {
return <><span className="text-yellow-400 m-8">No fields returned.</span></>
} else {
return <><span className="text-yellow-400 m-8">Unexpected state, please check JSON and report an issue.</span></>
}
}
}
return <><span className="text-yellow-400 m-8">There are no records to display</span></>
}
async function postQuery(offset, perPage) {
try {
const queryObject = JSON.parse(query)
const response = await vispanaClient
.postQuery(containerUrl, queryObject, offset, perPage)
.then(response => {
if (response.status && response.status !== 200) {
const error = response.message ? response.message : "Failed to execute the query"
return {
success: undefined,
error: error
}
} else {
return {
success: response,
error: undefined
}
}
})
.catch(error => {
return {
success: undefined,
error: error.message
}
})
if (response.error) {
setError({
hasError: true,
error: response.error
})
} else {
const vespaState = response.success;
setTotalRows(vespaState.root.fields.totalCount);
const resultData = processResult(vespaState);
setData(resultData);
setError({
hasError: false,
error: undefined
})
}
} catch (exception) {
setError({
hasError: true,
error: exception.message
})
}
}
const load = async () => {
setLoading(true);
await postQuery(offset, perPage);
setLoading(false);
};
const handlePageChange = newPage => {
if (newPage === page) {
return;
}
const offset = (newPage - 1) * perPage
setPage(newPage)
setOffset(offset)
};
const handlePerRowsChange = async (newPerPage, page) => {
if (newPerPage === perPage) {
return;
}
setPerPage(newPerPage);
};
useEffect(() => {
setPage(1)
setPerPage(defaultPageSize)
setError({
hasError: false,
error: ""
})
}, [schema]);
useEffect(() => {
load();
}, [showResults, perPage, page]);
useEffect(() => {
setError({
hasError: false,
error: ""
})
load();
}, [refreshQuery]);
if (error.hasError) {
return (
<VispanaError showLogo={false} errorMessage={{
title: "Failed to execute the query",
description: error.error
}}/>
)
}
const results = (
<DataTable
theme="dark"
customStyles={{
head: {
style: {
color: '#facc15'
}
}
}}
columns={data.columns}
data={data.content}
fixedHeader
expandableRows
expandableRowsComponent={ExpandedComponent}
progressPending={loading}
progressComponent={<Loading centralize={false}/>}
pagination
paginationPerPage={defaultPageSize}
paginationServer
paginationTotalRows={totalRows}
onChangeRowsPerPage={handlePerRowsChange}
onChangePage={handlePageChange}
responsive
striped
highlightOnHover
noDataComponent={<NoDataConst/>}
/>
)
if (!useTabs) {
return results
}
const tabs = [
{
"header": "Results",
"content": results
},
{
"header": "JSON response",
"content": (<SyntaxHighlighter language="json" style={androidstudio}>
{JSON.stringify(data.json, null, 2)}
</SyntaxHighlighter>)
}
]
if (data && data.trace && data.trace.length > 0) {
tabs.push(
{
"header": "Trace",
"content": (
<SyntaxHighlighter language="json" style={androidstudio}>
{JSON.stringify(data.trace, null, 2)}
</SyntaxHighlighter>
)
}
)
}
return (
<TabView tabs={tabs}/>
)
}