-
+ class="euiPageContentBody"
+ >
-
-
+ class="euiFlexGroup euiFlexGroup--gutterLarge euiFlexGroup--alignItemsCenter euiFlexGroup--directionRow euiFlexGroup--responsive"
+ />
+
+
-
+
-
- Press Enter to start editing.
-
-
- When you're done, press Escape to stop editing.
-
-
-
-
+
+ Press Enter to start editing.
+
+
+ When you're done, press Escape to stop editing.
+
+
-
-
+
+
+
-
+ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
-
-
-
-
-
- XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
-
-
-
-
-
+
-
-
- Run
+
+ Run
+
-
-
-
-
-
+
+
-
- Clear
+
+ Clear
+
-
-
-
-
-
+
+
-
- Explain
+
+ Explain
+
-
-
+
+
-
-
-
+
-
-
-
-
- No result
-
-
+ class="euiSpacer euiSpacer--xxl"
+ />
+
-
- Enter a query in the query editor above to see results.
-
+
+
+ No result
+
+
+
+
+ Enter a query in the query editor above to see results.
+
+
+
+
-
-
diff --git a/public/components/Main/main.test.tsx b/public/components/Main/main.test.tsx
index 8c08e0cc..5a3c2d48 100644
--- a/public/components/Main/main.test.tsx
+++ b/public/components/Main/main.test.tsx
@@ -12,7 +12,8 @@ import {
mockQueryResultJDBCResponse,
mockNotOkQueryResultResponse,
mockQueryTranslationResponse,
- mockResultWithNull
+ mockResultWithNull,
+ mockHttpQuery
} from "../../../test/mocks/mockData";
import Main from "./main";
@@ -20,18 +21,26 @@ const setBreadcrumbsMock = jest.fn();
describe("
spec", () => {
- it("renders the component", () => {
- render(
-
- );
+ it("renders the component", async () => {
+
+ const client = httpClientMock;
+ client.post = jest.fn().mockResolvedValue(mockHttpQuery)
+
+ const asyncTest = () => {
+ render(
+
+ );
+ };
+ await asyncTest();
expect(document.body.children[0]).toMatchSnapshot();
});
+
it("click run button, and response is ok", async () => {
const client = httpClientMock;
client.post = jest.fn().mockResolvedValue(mockQueryResultJDBCResponse);
- const { getByText } = render(
+ const { getByText } = await render(
);
const onRunButton = getByText('Run');
@@ -46,7 +55,7 @@ describe("
spec", () => {
const client = httpClientMock;
client.post = jest.fn().mockResolvedValue(mockResultWithNull);
- const { getByText } = render(
+ const { getByText } = await render(
);
const onRunButton = getByText('Run');
@@ -61,7 +70,7 @@ describe("
spec", () => {
const client = httpClientMock;
client.post = jest.fn().mockRejectedValue('err');
- const { getByText } = render(
+ const { getByText } = await render(
);
const onRunButton = getByText('Run');
@@ -76,7 +85,7 @@ describe("
spec", () => {
const client = httpClientMock;
client.post = jest.fn().mockResolvedValue(mockNotOkQueryResultResponse);
- const { getByText } = render(
+ const { getByText } = await render(
);
const onRunButton = getByText('Run');
@@ -90,7 +99,7 @@ describe("
spec", () => {
it("click translation button, and response is ok", async () => {
const client = httpClientMock;
client.post = jest.fn().mockResolvedValue(mockQueryTranslationResponse);
- const { getByText } = render(
+ const { getByText } = await render(
);
const onTranslateButton = getByText('Explain');
@@ -103,7 +112,7 @@ describe("
spec", () => {
it("click clear button", async () => {
const client = httpClientMock;
- const { getByText } = render(
+ const { getByText } = await render(
);
const onClearButton = getByText('Clear');
@@ -111,7 +120,6 @@ describe("
spec", () => {
fireEvent.click(onClearButton);
};
await asyncTest();
- expect(client.post).not.toHaveBeenCalled();
expect(document.body.children[0]).toMatchSnapshot();
});
});
diff --git a/public/components/Main/main.tsx b/public/components/Main/main.tsx
index 1b458913..a80bdd41 100644
--- a/public/components/Main/main.tsx
+++ b/public/components/Main/main.tsx
@@ -3,7 +3,19 @@
* SPDX-License-Identifier: Apache-2.0
*/
-import { EuiButton, EuiFlexGroup, EuiFlexItem, EuiSpacer, EuiTitle } from '@elastic/eui';
+import {
+ EuiButton,
+ EuiFlexGroup,
+ EuiFlexItem,
+ EuiSpacer,
+ EuiPageSideBar ,
+ EuiPanel,
+ EuiPage,
+ EuiPageContent,
+ EuiPageContentBody,
+ EuiComboBox,
+ EuiText,
+} from '@elastic/eui';
import { IHttpResponse } from 'angular';
import _ from 'lodash';
import React from 'react';
@@ -20,6 +32,7 @@ import { PPLPage } from '../PPLPage/PPLPage';
import Switch from '../QueryLanguageSwitch/Switch';
import QueryResults from '../QueryResults/QueryResults';
import { SQLPage } from '../SQLPage/SQLPage';
+import { TableView } from '../SQLPage/TableView'
interface ResponseData {
ok: boolean;
@@ -87,6 +100,7 @@ interface MainState {
itemIdToExpandedRowMap: ItemIdToExpandedRowMap;
messages: Array
;
isResultFullScreen: boolean;
+ selectedDatasource: string;
}
const SUCCESS_MESSAGE = 'Success';
@@ -218,8 +232,8 @@ export class Main extends React.Component {
itemIdToExpandedRowMap: {},
messages: [],
isResultFullScreen: false,
+ selectedDatasource: ''
};
-
this.httpClient = this.props.httpClient;
this.updateSQLQueries = _.debounce(this.updateSQLQueries, 250).bind(this);
this.updatePPLQueries = _.debounce(this.updatePPLQueries, 250).bind(this);
@@ -611,6 +625,12 @@ export class Main extends React.Component {
});
}
+ handleComboOptionChange = (selectedOption: string) => {
+ this.setState({
+ selectedDatasource: selectedOption });
+ };
+
+
render() {
let page;
let link;
@@ -685,28 +705,67 @@ export class Main extends React.Component {
}
return (
-
-
-
-
-
-
- Query Workbench
-
-
-
-
-
-
-
- {linkTitle}
-
-
-
-
-
-
{page}
-
+ <>
+
+
+ Data Sources
+ {
+ const selectedValue = selectedOptions[0] ? selectedOptions[0].value : '';
+ this.handleComboOptionChange(selectedValue);
+ }}
+ />
+
+
+
+
+
+
+
+ {linkTitle}
+
+
+
+
+ {this.state.language === 'SQL' && (
+
+
+
+
+
+
+ Create
+
+
+
+
+
+
+
+
+
+ )}
+
+
+
+
+
+
+ {page}
{
setIsResultFullScreen={this.setIsResultFullScreen}
/>
-
-
+
+
+
+ >
+
);
}
}
diff --git a/public/components/SQLPage/SQLPage.tsx b/public/components/SQLPage/SQLPage.tsx
index 162d4c70..94808e17 100644
--- a/public/components/SQLPage/SQLPage.tsx
+++ b/public/components/SQLPage/SQLPage.tsx
@@ -105,8 +105,7 @@ export class SQLPage extends React.Component {
}
return (
-
- Query editor
+
{
+ const [tablenames, setTablenames] = useState([]);
+ const [selectedNode, setSelectedNode] = useState(null);
+ const [childData, setChildData] = useState([]);
+ const [selectedChildNode, setSelectedChildNode] = useState(null);
+ const [indexData, setIndexedData] = useState([]);
+
+ const getSidebarContent = () => {
+ const query = { query: ON_LOAD_QUERY }
+ http
+ .post(`/api/sql_console/sqlquery`, {
+ body: JSON.stringify(query),
+ })
+ .then((res) => {
+ const responseObj = res.data.resp
+ ? JSON.parse(res.data.resp)
+ : '';
+ const datarows: any[][] = _.get(responseObj, 'datarows');
+ const fields = datarows.map((data) => {
+ return data[2]
+ })
+ setTablenames(fields)
+ })
+ .catch((err) => {
+ console.error(err);
+ });
+ };
+
+ useEffect(() => {
+
+ getSidebarContent();
+ }, []);
+
+ const handleNodeClick = (nodeLabel: string) => {
+
+ // // will update after new query
+
+ const newData = ["Child 1", "Child 2", "Child 3"];
+ setChildData(newData);
+ setSelectedNode(nodeLabel);
+ };
+
+ const handleChildClick = (nodeLabel1: string) => {
+
+ // will update after new query
+
+ const newData1 = ["Child 4", "Child 5", "Child 6"];
+ setIndexedData(newData1);
+ setSelectedChildNode(nodeLabel1);
+ };
+
+
+ const treeData = tablenames.map((element, index) => ({
+ label: element,
+ icon: ,
+ id: 'element_' + index,
+ callback: () => handleNodeClick(element),
+ isSelectable: true,
+ isExpanded: true,
+ children: dataConnection === 'S3' && selectedNode === element ? childData.map(child => ({
+ label: child,
+ id: `${element}_${child}`,
+ icon: ,
+ callback: () => handleChildClick(child),
+ sSelectable: true,
+ isExpanded: true,
+ children: selectedChildNode === child ? indexData.map(indexChild => ({
+ label: indexChild,
+ id: `${child}_${indexChild}`,
+ icon:
+ })):undefined,
+ })) : undefined,
+ }));
+
+ return (
+ <>
+ {treeData.length > 0 ?
+
+ : Error loading Datasources}
+ />
+ }
+ >
+ )
+}
+
diff --git a/public/components/SQLPage/__snapshots__/SQLPage.test.tsx.snap b/public/components/SQLPage/__snapshots__/SQLPage.test.tsx.snap
index efdbd65e..d2fe7008 100644
--- a/public/components/SQLPage/__snapshots__/SQLPage.test.tsx.snap
+++ b/public/components/SQLPage/__snapshots__/SQLPage.test.tsx.snap
@@ -3,15 +3,8 @@
exports[` spec renders the component 1`] = `
-
@@ -195,15 +188,8 @@ exports[`
spec renders the component 1`] = `
exports[`
spec tests the action buttons 1`] = `
-
diff --git a/public/utils/constants.ts b/public/utils/constants.ts
index 7b93e075..d8791140 100644
--- a/public/utils/constants.ts
+++ b/public/utils/constants.ts
@@ -12,4 +12,4 @@ export const SMALL_COLUMN_WIDTH = '27px';
// Tabs constants
export const TAB_CONTAINER_ID = 'tabsContainer';
-export const MESSAGE_TAB_LABEL = 'Output';
+export const MESSAGE_TAB_LABEL = 'Output';
\ No newline at end of file
diff --git a/test/mocks/mockData.ts b/test/mocks/mockData.ts
index 1418720e..2daadf9d 100644
--- a/test/mocks/mockData.ts
+++ b/test/mocks/mockData.ts
@@ -2334,3 +2334,10 @@ export const mockResultWithNull =
"resp": "{\"schema\":[{\"name\":\"name\",\"type\":\"keyword\"},{\"name\":\"city\",\"type\":\"keyword\"}],\"datarows\":[[\"Hattie\",\"Seattle\"],[\"John\"]]}"
}
}
+export const mockHttpQuery =
+{
+ "data": {
+ "ok": true,
+ resp: "{\"schema\":[{\"name\":\"TABLE_CAT\",\"type\":\"keyword\"}],\"datarows\":[[\"opensearch\",null,\".kibana_1\",\"BASE TABLE\",null,null,null,null,null,null]]}"
+ }
+}
\ No newline at end of file