diff --git a/src/main/js/components/query-result/query-result.js b/src/main/js/components/query-result/query-result.js index 04b83bb..9a13d5d 100644 --- a/src/main/js/components/query-result/query-result.js +++ b/src/main/js/components/query-result/query-result.js @@ -4,8 +4,9 @@ import {androidstudio} from "react-syntax-highlighter/dist/cjs/styles/hljs"; import SyntaxHighlighter from "react-syntax-highlighter"; import Loading from "../../routes/loading/loading"; import VispanaError from "../../routes/error/vispana-error"; +import TabView from "../tabs/tab-view"; -function QueryResult({containerUrl, vispanaClient, query, showResults, schema, refreshQuery, defaultPageSize = 15}) { +function QueryResult({containerUrl, vispanaClient, query, showResults, schema, refreshQuery, defaultPageSize = 15, useTabs = false}) { // customize theme createTheme('dark', { text: { @@ -25,7 +26,7 @@ function QueryResult({containerUrl, vispanaClient, query, showResults, schema, r }); // data state - const [data, setData] = useState({columns: [], content: []}); + const [data, setData] = useState({columns: [], content: [], trace: []}); const [loading, setLoading] = useState(true); const [totalRows, setTotalRows] = useState(0); @@ -75,8 +76,8 @@ function QueryResult({containerUrl, vispanaClient, query, showResults, schema, r const vespaState = response.success; setTotalRows(vespaState.root.fields.totalCount); - const gridData = processResult(vespaState); - setData(gridData); + const resultData = processResult(vespaState); + setData(resultData); setError({ hasError: false, @@ -135,36 +136,67 @@ function QueryResult({containerUrl, vispanaClient, query, showResults, schema, r load(); }, [refreshQuery]); - return ( - <> - {!error.hasError && } - pagination - paginationPerPage={defaultPageSize} - paginationServer - paginationTotalRows={totalRows} - onChangeRowsPerPage={handlePerRowsChange} - onChangePage={handlePageChange} - />} - {error.hasError && ()} - + }}/> + ) + } + + const results = ( + } + pagination + paginationPerPage={defaultPageSize} + paginationServer + paginationTotalRows={totalRows} + onChangeRowsPerPage={handlePerRowsChange} + onChangePage={handlePageChange} + /> + ) + + if (!useTabs) { + return results + } + + const tabs = [ + { + "header": "Results", + "content": results + } + ] + + if (data.trace.length > 0) { + tabs.push( + { + "header": "Trace", + "content": ( + + {JSON.stringify(data.trace, null, 2)} + + ) + } + ) + } + + return ( + ) } @@ -211,9 +243,12 @@ function processResult(result) { return fields }) + const trace = "trace" in result ? result.trace.children : [] + return { columns: columns, - content: data + content: data, + trace: trace } } diff --git a/src/main/js/routes/schema/query.js b/src/main/js/routes/schema/query.js index 8b9d8f1..7767dc8 100644 --- a/src/main/js/routes/schema/query.js +++ b/src/main/js/routes/schema/query.js @@ -23,6 +23,22 @@ function Query({containerUrl, schema}) { } } + function addTrace() { + try { + const parsed = JSON.parse(query) + if ("trace" in parsed) { + return // don't overwrite if it's already there + } + parsed["trace"] = { + "level": 5, + "explainLevel": 1, + "timestamps": true + } + setQuery(JSON.stringify(parsed, null, 2)) + } catch (_) { + } + } + const vispanaClient = new VispanaApiClient() const [query, setQuery] = useState(defaultQuery(schema)) const [showResults, setShowResults] = useState(false) @@ -56,6 +72,14 @@ function Query({containerUrl, schema}) { onClick={prettifyJsonQuery}> +