From 1efd1917ad9233771eb423c97d953e38803be6c1 Mon Sep 17 00:00:00 2001 From: Derek Ho Date: Fri, 22 Sep 2023 15:37:18 -0400 Subject: [PATCH 1/6] Get most of the workflow working for configure datasource Signed-off-by: Derek Ho --- .../components/configure_datasource.tsx | 117 ++++++++++++++++++ .../components/data_connections_header.tsx | 45 ++++++- .../manage_data_connections_table.tsx | 2 +- .../components/new_datasource.tsx | 84 +++++++++++++ .../components/new_datasource_card_view.tsx | 116 +++++++++++++++++ .../components/new_datasource_description.tsx | 24 ++++ public/components/data_connections/home.tsx | 11 ++ .../icons/apache_spark-icon.svg | 1 + 8 files changed, 396 insertions(+), 4 deletions(-) create mode 100644 public/components/data_connections/components/configure_datasource.tsx create mode 100644 public/components/data_connections/components/new_datasource.tsx create mode 100644 public/components/data_connections/components/new_datasource_card_view.tsx create mode 100644 public/components/data_connections/components/new_datasource_description.tsx create mode 100644 public/components/data_connections/icons/apache_spark-icon.svg diff --git a/public/components/data_connections/components/configure_datasource.tsx b/public/components/data_connections/components/configure_datasource.tsx new file mode 100644 index 000000000..3cd30dece --- /dev/null +++ b/public/components/data_connections/components/configure_datasource.tsx @@ -0,0 +1,117 @@ +/* + * Copyright OpenSearch Contributors + * SPDX-License-Identifier: Apache-2.0 + */ + +import { + EuiFlexGroup, + EuiFlexItem, + EuiPage, + EuiPageBody, + EuiSpacer, + EuiTitle, + EuiText, + EuiLink, + EuiButton, + EuiSteps, + EuiPageSideBar, + EuiPanel, + EuiFormRow, + EuiFieldText, + EuiBottomBar, + EuiButtonEmpty, +} from '@elastic/eui'; +import React from 'react'; +import { OPENSEARCH_DOCUMENTATION_URL } from '../../../../common/constants/data_connections'; + +interface ConfigureDatasourceProps { + type: string; +} + +export function Configure(props: ConfigureDatasourceProps) { + const { type } = props; + const ConfigureDatasourceSteps = [ + { + title: 'Step 1', + children: ( + +

Configure Connection

+
+ ), + }, + { + title: 'Step 2', + children: ( + +

Review Configuration

+
+ ), + }, + ]; + + const ConfigureDatasource = (configurationProps: { datasourceType: string }) => { + const { datasourceType } = configurationProps; + return ( +
+ + +

{`Configure ${datasourceType} Connection`}

+
+ + + {`Connect to ${datasourceType} with OpenSearch and OpenSearch Dashboards `} + + Learn more + + + + +

Connection Details

+
+ + + + + + + + + + + +
+
+ ); + }; + + return ( + + + + + + + + + + + + {}} color="ghost" size="s" iconType="cross"> + Cancel + + + + {}} color="ghost" size="s" iconType="arrowLeft"> + Previous + + + + {}} size="s" iconType="arrowRight" fill> + Review Configuration + + + + + + ); +} diff --git a/public/components/data_connections/components/data_connections_header.tsx b/public/components/data_connections/components/data_connections_header.tsx index 7f071683b..85f204dd9 100644 --- a/public/components/data_connections/components/data_connections_header.tsx +++ b/public/components/data_connections/components/data_connections_header.tsx @@ -8,31 +8,70 @@ import { EuiPageHeader, EuiPageHeaderSection, EuiSpacer, + EuiTab, + EuiTabs, EuiText, EuiTitle, } from '@elastic/eui'; import _ from 'lodash'; -import React from 'react'; +import React, { useState } from 'react'; import { OPENSEARCH_DOCUMENTATION_URL } from '../../../../common/constants/data_connections'; export const DataConnectionsHeader = () => { + const tabs = [ + { + id: 'manage', + name: 'Manage data source', + disabled: false, + }, + { + id: 'new', + name: 'New data source', + disabled: false, + }, + ]; + + const [selectedTabId, setSelectedTabId] = useState( + window.location.hash.substring(2) ? window.location.hash.substring(2) : 'manage' + ); + + const onSelectedTabChanged = (id) => { + setSelectedTabId(id); + window.location.hash = id; + }; + + const renderTabs = () => { + return tabs.map((tab, index) => ( + onSelectedTabChanged(tab.id)} + isSelected={tab.id === selectedTabId} + disabled={tab.disabled} + key={index} + > + {tab.name} + + )); + }; + return (
-

Data connections

+

Data sources

- Connect and manage compatible OpenSearch and OpenSearch Dashboard data connections.{' '} + Connect and manage compatible OpenSearch and OpenSearch Dashboard data sources.{' '} Learn more + {renderTabs()} +
); }; diff --git a/public/components/data_connections/components/manage_data_connections_table.tsx b/public/components/data_connections/components/manage_data_connections_table.tsx index e1950e704..a1b241031 100644 --- a/public/components/data_connections/components/manage_data_connections_table.tsx +++ b/public/components/data_connections/components/manage_data_connections_table.tsx @@ -57,7 +57,7 @@ export const ManageDataConnectionsTable = (props: HomeProps) => { useEffect(() => { chrome.setBreadcrumbs([ { - text: 'Data Connections', + text: 'Data sources', href: '#/', }, ]); diff --git a/public/components/data_connections/components/new_datasource.tsx b/public/components/data_connections/components/new_datasource.tsx new file mode 100644 index 000000000..186749ba5 --- /dev/null +++ b/public/components/data_connections/components/new_datasource.tsx @@ -0,0 +1,84 @@ +/* + * Copyright OpenSearch Contributors + * SPDX-License-Identifier: Apache-2.0 + */ + +import { + EuiFieldSearch, + EuiFilterButton, + EuiFilterGroup, + EuiFilterSelectItem, + EuiFlexGroup, + EuiFlexItem, + EuiIcon, + EuiInMemoryTable, + EuiLink, + EuiOverlayMask, + EuiPage, + EuiPageBody, + EuiPageContent, + EuiPopover, + EuiPopoverTitle, + EuiTableFieldDataColumnType, +} from '@elastic/eui'; +import _ from 'lodash'; +import React, { useEffect, useState } from 'react'; +import { DataConnectionsHeader } from './data_connections_header'; +import { HomeProps } from '../home'; +import { DataConnectionsDescription } from './manage_data_connections_description'; +import { DATACONNECTIONS_BASE, INTEGRATIONS_BASE } from '../../../../common/constants/shared'; +import { useToast } from '../../../../public/components/common/toast'; +import { DeleteModal } from '../../../../public/components/common/helpers/delete_modal'; +import { AvailableIntegrationsList } from '../../../../public/components/integrations/components/available_integration_overview_page'; +import { IntegrationHeader } from '../../../../public/components/integrations/components/integration_header'; +import { AvailableIntegrationsCardView } from '../../../../public/components/integrations/components/available_integration_card_view'; +import { AvailableIntegrationsTable } from '../../../../public/components/integrations/components/available_integration_table'; +import { NewDatasourceCardView } from './new_datasource_card_view'; + +interface DataConnection { + connectionType: 'OPENSEARCH' | 'SPARK'; + name: string; +} + +export const NewDatasource = (props: HomeProps) => { + const { chrome, http } = props; + + const [query, setQuery] = useState(''); + const [isCardView, setCardView] = useState(true); + const [data, setData] = useState({ hits: [] }); + + const [isPopoverOpen, setIsPopoverOpen] = useState(false); + + const onButtonClick = () => { + setIsPopoverOpen(!isPopoverOpen); + }; + + const closePopover = () => { + setIsPopoverOpen(false); + }; + + const [items, setItems] = useState([] as Array<{ name: string; checked: boolean }>); + + useEffect(() => { + chrome.setBreadcrumbs([ + { + text: 'Data sources', + href: '#/', + }, + ]); + }, []); + + // TODO: implement table view + const NewDatasourceTableView = () => { + return null; + }; + + return ( + + + + {isCardView ? : } + + + ); +}; diff --git a/public/components/data_connections/components/new_datasource_card_view.tsx b/public/components/data_connections/components/new_datasource_card_view.tsx new file mode 100644 index 000000000..0981b4d26 --- /dev/null +++ b/public/components/data_connections/components/new_datasource_card_view.tsx @@ -0,0 +1,116 @@ +/* + * Copyright OpenSearch Contributors + * SPDX-License-Identifier: Apache-2.0 + */ + +import { + EuiPanel, + EuiCard, + EuiFlexGroup, + EuiFlexItem, + EuiSpacer, + EuiFieldSearch, + EuiButtonGroup, + EuiIcon, +} from '@elastic/eui'; +import _ from 'lodash'; +import React, { useState } from 'react'; +import { INTEGRATIONS_BASE } from '../../../../common/constants/shared'; +import { NewDatasourceDescription } from './new_datasource_description'; +import { coreRefs } from '../../../../public/framework/core_refs'; +import { MANAGEMENT_APP_ID } from '../../../../../../src/plugins/management/public'; +import sparkSvg from '../icons/apache_spark-icon.svg'; + +export interface DatasourceType { + name: string; + description: string; + displayIcon: JSX.Element; +} + +const Datasources: DatasourceType[] = [ + { + name: 'OpenSearch', + description: 'Connect to self managed OpenSearch clusters', + displayIcon: , + }, + { + name: 'Spark', + description: 'Connect to a self managed instance of Apache Spark', + displayIcon: , + }, +]; + +export function NewDatasourceCardView() { + const { http } = coreRefs; + const [toggleIconIdSelected, setToggleIconIdSelected] = useState('1'); + + const toggleButtonsIcons = [ + { + id: '0', + label: 'list', + iconType: 'list', + }, + { + id: '1', + label: 'grid', + iconType: 'grid', + }, + ]; + + const onChangeIcons = (optionId: string) => { + setToggleIconIdSelected(optionId); + }; + + const renderRows = (datasources: DatasourceType[]) => { + return ( + <> + + {datasources.map((i, v) => { + return ( + + (window.location.hash = `#/configure/${i.name}`)} + /> + + ); + })} + + + + ); + }; + + return ( + + + + + {}} + /> + + + onChangeIcons(id)} + isIconOnly + /> + + + + {renderRows(Datasources)} + + ); +} diff --git a/public/components/data_connections/components/new_datasource_description.tsx b/public/components/data_connections/components/new_datasource_description.tsx new file mode 100644 index 000000000..91f13c666 --- /dev/null +++ b/public/components/data_connections/components/new_datasource_description.tsx @@ -0,0 +1,24 @@ +/* + * Copyright OpenSearch Contributors + * SPDX-License-Identifier: Apache-2.0 + */ + +import { EuiSpacer, EuiText, EuiTitle, EuiHorizontalRule } from '@elastic/eui'; +import React from 'react'; + +export const NewDatasourceDescription = () => { + return ( +
+ +

Create a new data source

+
+ + + + Connect to a compatible data source or compute engine to bring your data into OpenSearch and + OpenSearch Dashboards. + + +
+ ); +}; diff --git a/public/components/data_connections/home.tsx b/public/components/data_connections/home.tsx index 534a71815..0ee1d5c9d 100644 --- a/public/components/data_connections/home.tsx +++ b/public/components/data_connections/home.tsx @@ -9,6 +9,8 @@ import { ChromeBreadcrumb, ChromeStart, HttpStart } from '../../../../../src/cor import { DataConnection } from './components/data_connection'; import { ManageDataConnectionsTable } from './components/manage_data_connections_table'; import { AccelerationIndices } from './components/acceleration_ui/acceleration_indices'; +import { NewDatasource } from './components/new_datasource'; +import { Configure } from './components/configure_datasource'; export interface HomeProps extends RouteComponentProps { pplService: any; @@ -45,6 +47,15 @@ export const Home = (props: HomeProps) => { path={['/', '/manage']} render={(routerProps) => } /> + } /> + + ( + + )} + /> \ No newline at end of file From 93ad0dda60fd0155463c756bc711e4b42bd57634 Mon Sep 17 00:00:00 2001 From: Derek Ho Date: Fri, 22 Sep 2023 15:44:43 -0400 Subject: [PATCH 2/6] Update data connection to datasources in a few more places and update tests Signed-off-by: Derek Ho --- common/constants/shared.ts | 4 +- ...data_connections_description.test.tsx.snap | 4 +- ...anage_data_connections_table.test.tsx.snap | 40 +++++++++++++++++-- .../manage_data_connections_description.tsx | 4 +- 4 files changed, 42 insertions(+), 10 deletions(-) diff --git a/common/constants/shared.ts b/common/constants/shared.ts index f26a59820..b3a08da21 100644 --- a/common/constants/shared.ts +++ b/common/constants/shared.ts @@ -58,8 +58,8 @@ export const observabilityIntegrationsID = 'integrations'; export const observabilityIntegrationsTitle = 'Integrations'; export const observabilityIntegrationsPluginOrder = 9020; -export const observabilityDataConnectionsID = 'dataconnections'; -export const observabilityDataConnectionsTitle = 'Data Connections'; +export const observabilityDataConnectionsID = 'datasources'; +export const observabilityDataConnectionsTitle = 'Data Sources'; export const observabilityDataConnectionsPluginOrder = 9030; // Shared Constants diff --git a/public/components/data_connections/components/__tests__/__snapshots__/manage_data_connections_description.test.tsx.snap b/public/components/data_connections/components/__tests__/__snapshots__/manage_data_connections_description.test.tsx.snap index 2cc84b45b..10c1b2484 100644 --- a/public/components/data_connections/components/__tests__/__snapshots__/manage_data_connections_description.test.tsx.snap +++ b/public/components/data_connections/components/__tests__/__snapshots__/manage_data_connections_description.test.tsx.snap @@ -9,7 +9,7 @@ exports[`Manage Data Connections Description test Renders manage data connection

- Manage existing data connections + Manage existing data sources

- Manage already created data connections. + Manage already created data sources. diff --git a/public/components/data_connections/components/__tests__/__snapshots__/manage_data_connections_table.test.tsx.snap b/public/components/data_connections/components/__tests__/__snapshots__/manage_data_connections_table.test.tsx.snap index 20c847340..6cd9a84f9 100644 --- a/public/components/data_connections/components/__tests__/__snapshots__/manage_data_connections_table.test.tsx.snap +++ b/public/components/data_connections/components/__tests__/__snapshots__/manage_data_connections_table.test.tsx.snap @@ -19,7 +19,7 @@ exports[`Manage Data Connections Table test Renders manage data connections tabl class="euiTitle euiTitle--large" data-test-subj="dataconnections-header" > - Data connections + Data sources @@ -32,7 +32,7 @@ exports[`Manage Data Connections Table test Renders manage data connections tabl
- Connect and manage compatible OpenSearch and OpenSearch Dashboard data connections. + Connect and manage compatible OpenSearch and OpenSearch Dashboard data sources. +
+ + +
+
- Manage existing data connections + Manage existing data sources
- Manage already created data connections. + Manage already created data sources.

{ return (
-

Manage existing data connections

+

Manage existing data sources

- Manage already created data connections. + Manage already created data sources.
From 2bd8c2711e353b920da463e27b0a51bbbf1fc0f7 Mon Sep 17 00:00:00 2001 From: Derek Ho Date: Fri, 22 Sep 2023 16:08:27 -0400 Subject: [PATCH 3/6] Rename and re-organize in folders Signed-off-by: Derek Ho --- public/components/app.tsx | 2 +- .../components/new_datasource.tsx | 84 ------------------- .../data_connection.test.tsx.snap | 0 ...data_connections_description.test.tsx.snap | 0 ...anage_data_connections_table.test.tsx.snap | 0 .../__tests__/data_connection.test.tsx | 2 +- ...nage_data_connections_description.test.tsx | 2 +- .../manage_data_connections_table.test.tsx | 0 .../components/data_connections_header.tsx | 0 .../components/manage}/access_control_tab.tsx | 6 +- .../components/manage}/connection_details.tsx | 8 +- .../manage}/connection_management_callout.tsx | 0 .../components/manage}/data_connection.tsx | 8 +- .../manage_data_connections_description.tsx | 0 .../manage}/manage_data_connections_table.tsx | 4 +- .../components/manage}/query_permissions.tsx | 4 +- .../components/new}/configure_datasource.tsx | 31 +++++-- .../new}/connection_configuration.tsx | 0 .../components/new/new_datasource.tsx | 48 +++++++++++ .../new}/new_datasource_card_view.tsx | 6 +- .../new}/new_datasource_description.tsx | 0 .../components/no_access.tsx | 0 .../components/save_or_cancel.tsx | 0 .../home.tsx | 6 +- .../icons/apache_spark-icon.svg | 0 25 files changed, 96 insertions(+), 115 deletions(-) delete mode 100644 public/components/data_connections/components/new_datasource.tsx rename public/components/{data_connections => datasources}/components/__tests__/__snapshots__/data_connection.test.tsx.snap (100%) rename public/components/{data_connections => datasources}/components/__tests__/__snapshots__/manage_data_connections_description.test.tsx.snap (100%) rename public/components/{data_connections => datasources}/components/__tests__/__snapshots__/manage_data_connections_table.test.tsx.snap (100%) rename public/components/{data_connections => datasources}/components/__tests__/data_connection.test.tsx (94%) rename public/components/{data_connections => datasources}/components/__tests__/manage_data_connections_description.test.tsx (86%) rename public/components/{data_connections => datasources}/components/__tests__/manage_data_connections_table.test.tsx (100%) rename public/components/{data_connections => datasources}/components/data_connections_header.tsx (100%) rename public/components/{data_connections/components => datasources/components/manage}/access_control_tab.tsx (94%) rename public/components/{data_connections/components => datasources/components/manage}/connection_details.tsx (94%) rename public/components/{data_connections/components => datasources/components/manage}/connection_management_callout.tsx (100%) rename public/components/{data_connections/components => datasources/components/manage}/data_connection.tsx (96%) rename public/components/{data_connections/components => datasources/components/manage}/manage_data_connections_description.tsx (100%) rename public/components/{data_connections/components => datasources/components/manage}/manage_data_connections_table.tsx (96%) rename public/components/{data_connections/components => datasources/components/manage}/query_permissions.tsx (94%) rename public/components/{data_connections/components => datasources/components/new}/configure_datasource.tsx (71%) rename public/components/{data_connections/components => datasources/components/new}/connection_configuration.tsx (100%) create mode 100644 public/components/datasources/components/new/new_datasource.tsx rename public/components/{data_connections/components => datasources/components/new}/new_datasource_card_view.tsx (90%) rename public/components/{data_connections/components => datasources/components/new}/new_datasource_description.tsx (100%) rename public/components/{data_connections => datasources}/components/no_access.tsx (100%) rename public/components/{data_connections => datasources}/components/save_or_cancel.tsx (100%) rename public/components/{data_connections => datasources}/home.tsx (88%) rename public/components/{data_connections => datasources}/icons/apache_spark-icon.svg (100%) diff --git a/public/components/app.tsx b/public/components/app.tsx index 7ace523b4..805ebc2e0 100644 --- a/public/components/app.tsx +++ b/public/components/app.tsx @@ -19,7 +19,7 @@ import { EventAnalytics } from './event_analytics'; import { Home as MetricsHome } from './metrics/index'; import { Main as NotebooksHome } from './notebooks/components/main'; import { Home as TraceAnalyticsHome } from './trace_analytics/home'; -import { Home as DataConnectionsHome } from './data_connections/home'; +import { Home as DataConnectionsHome } from './datasources/home'; interface ObservabilityAppDeps { CoreStartProp: CoreStart; diff --git a/public/components/data_connections/components/new_datasource.tsx b/public/components/data_connections/components/new_datasource.tsx deleted file mode 100644 index 186749ba5..000000000 --- a/public/components/data_connections/components/new_datasource.tsx +++ /dev/null @@ -1,84 +0,0 @@ -/* - * Copyright OpenSearch Contributors - * SPDX-License-Identifier: Apache-2.0 - */ - -import { - EuiFieldSearch, - EuiFilterButton, - EuiFilterGroup, - EuiFilterSelectItem, - EuiFlexGroup, - EuiFlexItem, - EuiIcon, - EuiInMemoryTable, - EuiLink, - EuiOverlayMask, - EuiPage, - EuiPageBody, - EuiPageContent, - EuiPopover, - EuiPopoverTitle, - EuiTableFieldDataColumnType, -} from '@elastic/eui'; -import _ from 'lodash'; -import React, { useEffect, useState } from 'react'; -import { DataConnectionsHeader } from './data_connections_header'; -import { HomeProps } from '../home'; -import { DataConnectionsDescription } from './manage_data_connections_description'; -import { DATACONNECTIONS_BASE, INTEGRATIONS_BASE } from '../../../../common/constants/shared'; -import { useToast } from '../../../../public/components/common/toast'; -import { DeleteModal } from '../../../../public/components/common/helpers/delete_modal'; -import { AvailableIntegrationsList } from '../../../../public/components/integrations/components/available_integration_overview_page'; -import { IntegrationHeader } from '../../../../public/components/integrations/components/integration_header'; -import { AvailableIntegrationsCardView } from '../../../../public/components/integrations/components/available_integration_card_view'; -import { AvailableIntegrationsTable } from '../../../../public/components/integrations/components/available_integration_table'; -import { NewDatasourceCardView } from './new_datasource_card_view'; - -interface DataConnection { - connectionType: 'OPENSEARCH' | 'SPARK'; - name: string; -} - -export const NewDatasource = (props: HomeProps) => { - const { chrome, http } = props; - - const [query, setQuery] = useState(''); - const [isCardView, setCardView] = useState(true); - const [data, setData] = useState({ hits: [] }); - - const [isPopoverOpen, setIsPopoverOpen] = useState(false); - - const onButtonClick = () => { - setIsPopoverOpen(!isPopoverOpen); - }; - - const closePopover = () => { - setIsPopoverOpen(false); - }; - - const [items, setItems] = useState([] as Array<{ name: string; checked: boolean }>); - - useEffect(() => { - chrome.setBreadcrumbs([ - { - text: 'Data sources', - href: '#/', - }, - ]); - }, []); - - // TODO: implement table view - const NewDatasourceTableView = () => { - return null; - }; - - return ( - - - - {isCardView ? : } - - - ); -}; diff --git a/public/components/data_connections/components/__tests__/__snapshots__/data_connection.test.tsx.snap b/public/components/datasources/components/__tests__/__snapshots__/data_connection.test.tsx.snap similarity index 100% rename from public/components/data_connections/components/__tests__/__snapshots__/data_connection.test.tsx.snap rename to public/components/datasources/components/__tests__/__snapshots__/data_connection.test.tsx.snap diff --git a/public/components/data_connections/components/__tests__/__snapshots__/manage_data_connections_description.test.tsx.snap b/public/components/datasources/components/__tests__/__snapshots__/manage_data_connections_description.test.tsx.snap similarity index 100% rename from public/components/data_connections/components/__tests__/__snapshots__/manage_data_connections_description.test.tsx.snap rename to public/components/datasources/components/__tests__/__snapshots__/manage_data_connections_description.test.tsx.snap diff --git a/public/components/data_connections/components/__tests__/__snapshots__/manage_data_connections_table.test.tsx.snap b/public/components/datasources/components/__tests__/__snapshots__/manage_data_connections_table.test.tsx.snap similarity index 100% rename from public/components/data_connections/components/__tests__/__snapshots__/manage_data_connections_table.test.tsx.snap rename to public/components/datasources/components/__tests__/__snapshots__/manage_data_connections_table.test.tsx.snap diff --git a/public/components/data_connections/components/__tests__/data_connection.test.tsx b/public/components/datasources/components/__tests__/data_connection.test.tsx similarity index 94% rename from public/components/data_connections/components/__tests__/data_connection.test.tsx rename to public/components/datasources/components/__tests__/data_connection.test.tsx index 995719810..04c1278c2 100644 --- a/public/components/data_connections/components/__tests__/data_connection.test.tsx +++ b/public/components/datasources/components/__tests__/data_connection.test.tsx @@ -8,7 +8,7 @@ import Adapter from 'enzyme-adapter-react-16'; import { act } from '@testing-library/react'; import React from 'react'; import { describeDataConnection, mockRoleData } from '../../../../../test/datasources'; -import { DataConnection } from '../data_connection'; +import { DataConnection } from '../manage/data_connection'; import ReactDOM from 'react-dom'; jest.mock('../../../../../public/framework/core_refs', () => ({ diff --git a/public/components/data_connections/components/__tests__/manage_data_connections_description.test.tsx b/public/components/datasources/components/__tests__/manage_data_connections_description.test.tsx similarity index 86% rename from public/components/data_connections/components/__tests__/manage_data_connections_description.test.tsx rename to public/components/datasources/components/__tests__/manage_data_connections_description.test.tsx index 686230683..3bbfa820e 100644 --- a/public/components/data_connections/components/__tests__/manage_data_connections_description.test.tsx +++ b/public/components/datasources/components/__tests__/manage_data_connections_description.test.tsx @@ -7,7 +7,7 @@ import { configure, mount } from 'enzyme'; import Adapter from 'enzyme-adapter-react-16'; import { waitFor } from '@testing-library/react'; import React from 'react'; -import { DataConnectionsDescription } from '../manage_data_connections_description'; +import { DataConnectionsDescription } from '../manage/manage_data_connections_description'; describe('Manage Data Connections Description test', () => { configure({ adapter: new Adapter() }); diff --git a/public/components/data_connections/components/__tests__/manage_data_connections_table.test.tsx b/public/components/datasources/components/__tests__/manage_data_connections_table.test.tsx similarity index 100% rename from public/components/data_connections/components/__tests__/manage_data_connections_table.test.tsx rename to public/components/datasources/components/__tests__/manage_data_connections_table.test.tsx diff --git a/public/components/data_connections/components/data_connections_header.tsx b/public/components/datasources/components/data_connections_header.tsx similarity index 100% rename from public/components/data_connections/components/data_connections_header.tsx rename to public/components/datasources/components/data_connections_header.tsx diff --git a/public/components/data_connections/components/access_control_tab.tsx b/public/components/datasources/components/manage/access_control_tab.tsx similarity index 94% rename from public/components/data_connections/components/access_control_tab.tsx rename to public/components/datasources/components/manage/access_control_tab.tsx index 58fdffde3..3f588b23b 100644 --- a/public/components/data_connections/components/access_control_tab.tsx +++ b/public/components/datasources/components/manage/access_control_tab.tsx @@ -14,10 +14,10 @@ import { import React, { useEffect, useState } from 'react'; import { EuiPanel } from '@elastic/eui'; import { ConnectionManagementCallout } from './connection_management_callout'; -import { coreRefs } from '../../../../public/framework/core_refs'; +import { coreRefs } from '../../../../framework/core_refs'; import { QueryPermissionsConfiguration } from './query_permissions'; -import { DATACONNECTIONS_BASE } from '../../../../common/constants/shared'; -import { SaveOrCancel } from './save_or_cancel'; +import { DATACONNECTIONS_BASE } from '../../../../../common/constants/shared'; +import { SaveOrCancel } from '../save_or_cancel'; interface AccessControlTabProps { dataConnection: string; diff --git a/public/components/data_connections/components/connection_details.tsx b/public/components/datasources/components/manage/connection_details.tsx similarity index 94% rename from public/components/data_connections/components/connection_details.tsx rename to public/components/datasources/components/manage/connection_details.tsx index 44cd206f4..0ad4eb1b5 100644 --- a/public/components/data_connections/components/connection_details.tsx +++ b/public/components/datasources/components/manage/connection_details.tsx @@ -14,10 +14,10 @@ import { import React, { useState } from 'react'; import { EuiPanel } from '@elastic/eui'; import { ConnectionManagementCallout } from './connection_management_callout'; -import { coreRefs } from '../../../../public/framework/core_refs'; -import { DATACONNECTIONS_BASE } from '../../../../common/constants/shared'; -import { SaveOrCancel } from './save_or_cancel'; -import { ConnectionConfiguration } from './connection_configuration'; +import { coreRefs } from '../../../../framework/core_refs'; +import { DATACONNECTIONS_BASE } from '../../../../../common/constants/shared'; +import { SaveOrCancel } from '../save_or_cancel'; +import { ConnectionConfiguration } from '../new/connection_configuration'; interface ConnectionDetailProps { dataConnection: string; diff --git a/public/components/data_connections/components/connection_management_callout.tsx b/public/components/datasources/components/manage/connection_management_callout.tsx similarity index 100% rename from public/components/data_connections/components/connection_management_callout.tsx rename to public/components/datasources/components/manage/connection_management_callout.tsx diff --git a/public/components/data_connections/components/data_connection.tsx b/public/components/datasources/components/manage/data_connection.tsx similarity index 96% rename from public/components/data_connections/components/data_connection.tsx rename to public/components/datasources/components/manage/data_connection.tsx index d4c87ef49..c8cf014ac 100644 --- a/public/components/data_connections/components/data_connection.tsx +++ b/public/components/datasources/components/manage/data_connection.tsx @@ -21,9 +21,9 @@ import { } from '@elastic/eui'; import React, { useEffect, useState } from 'react'; import { AccessControlTab } from './access_control_tab'; -import { NoAccess } from './no_access'; -import { DATACONNECTIONS_BASE } from '../../../../common/constants/shared'; -import { coreRefs } from '../../../../public/framework/core_refs'; +import { NoAccess } from '../no_access'; +import { DATACONNECTIONS_BASE } from '../../../../../common/constants/shared'; +import { coreRefs } from '../../../../framework/core_refs'; import { ConnectionDetails } from './connection_details'; interface DatasourceDetails { @@ -49,7 +49,7 @@ export const DataConnection = (props: any) => { useEffect(() => { chrome!.setBreadcrumbs([ { - text: 'Data Connections', + text: 'Data sources', href: '#/', }, { diff --git a/public/components/data_connections/components/manage_data_connections_description.tsx b/public/components/datasources/components/manage/manage_data_connections_description.tsx similarity index 100% rename from public/components/data_connections/components/manage_data_connections_description.tsx rename to public/components/datasources/components/manage/manage_data_connections_description.tsx diff --git a/public/components/data_connections/components/manage_data_connections_table.tsx b/public/components/datasources/components/manage/manage_data_connections_table.tsx similarity index 96% rename from public/components/data_connections/components/manage_data_connections_table.tsx rename to public/components/datasources/components/manage/manage_data_connections_table.tsx index a1b241031..2ad6882ef 100644 --- a/public/components/data_connections/components/manage_data_connections_table.tsx +++ b/public/components/datasources/components/manage/manage_data_connections_table.tsx @@ -21,8 +21,8 @@ import { DataConnectionsHeader } from './data_connections_header'; import { HomeProps } from '../home'; import { DataConnectionsDescription } from './manage_data_connections_description'; import { DATACONNECTIONS_BASE } from '../../../../common/constants/shared'; -import { useToast } from '../../../../public/components/common/toast'; -import { DeleteModal } from '../../../../public/components/common/helpers/delete_modal'; +import { useToast } from '../../common/toast'; +import { DeleteModal } from '../../common/helpers/delete_modal'; interface DataConnection { connectionType: 'OPENSEARCH' | 'SPARK'; diff --git a/public/components/data_connections/components/query_permissions.tsx b/public/components/datasources/components/manage/query_permissions.tsx similarity index 94% rename from public/components/data_connections/components/query_permissions.tsx rename to public/components/datasources/components/manage/query_permissions.tsx index eee8312a8..25f43ffac 100644 --- a/public/components/data_connections/components/query_permissions.tsx +++ b/public/components/datasources/components/manage/query_permissions.tsx @@ -17,8 +17,8 @@ import { OPENSEARCH_DOCUMENTATION_URL, QUERY_ALL, QUERY_RESTRICTED, -} from '../../../../common/constants/data_connections'; -import { PermissionsConfigurationProps } from '../../../../common/types/data_connections'; +} from '../../../../../common/constants/data_connections'; +import { PermissionsConfigurationProps } from '../../../../../common/types/data_connections'; export const QueryPermissionsConfiguration = (props: PermissionsConfigurationProps) => { const { roles, selectedRoles, setSelectedRoles } = props; diff --git a/public/components/data_connections/components/configure_datasource.tsx b/public/components/datasources/components/new/configure_datasource.tsx similarity index 71% rename from public/components/data_connections/components/configure_datasource.tsx rename to public/components/datasources/components/new/configure_datasource.tsx index 3cd30dece..82ffe3532 100644 --- a/public/components/data_connections/components/configure_datasource.tsx +++ b/public/components/datasources/components/new/configure_datasource.tsx @@ -20,9 +20,10 @@ import { EuiFieldText, EuiBottomBar, EuiButtonEmpty, + EuiTextArea, } from '@elastic/eui'; -import React from 'react'; -import { OPENSEARCH_DOCUMENTATION_URL } from '../../../../common/constants/data_connections'; +import React, { useState } from 'react'; +import { OPENSEARCH_DOCUMENTATION_URL } from '../../../../../common/constants/data_connections'; interface ConfigureDatasourceProps { type: string; @@ -30,6 +31,9 @@ interface ConfigureDatasourceProps { export function Configure(props: ConfigureDatasourceProps) { const { type } = props; + + const [name, setName] = useState(''); + const [details, setDetails] = useState(''); const ConfigureDatasourceSteps = [ { title: 'Step 1', @@ -66,18 +70,33 @@ export function Configure(props: ConfigureDatasourceProps) { -

Connection Details

+

Data source details

- + - + + Description - optional + + Text that can help identify the data source or share additional details + + + + { + setDetails(e.target.value); + }} + /> + + - +
diff --git a/public/components/data_connections/components/connection_configuration.tsx b/public/components/datasources/components/new/connection_configuration.tsx similarity index 100% rename from public/components/data_connections/components/connection_configuration.tsx rename to public/components/datasources/components/new/connection_configuration.tsx diff --git a/public/components/datasources/components/new/new_datasource.tsx b/public/components/datasources/components/new/new_datasource.tsx new file mode 100644 index 000000000..c504a2c10 --- /dev/null +++ b/public/components/datasources/components/new/new_datasource.tsx @@ -0,0 +1,48 @@ +/* + * Copyright OpenSearch Contributors + * SPDX-License-Identifier: Apache-2.0 + */ + +import { EuiPage, EuiPageBody } from '@elastic/eui'; +import _ from 'lodash'; +import React, { useEffect, useState } from 'react'; +import { DataConnectionsHeader } from '../data_connections_header'; +import { HomeProps } from '../../home'; +import { AvailableIntegrationsList } from '../../../integrations/components/available_integration_overview_page'; +import { NewDatasourceCardView } from './new_datasource_card_view'; + +interface DataConnection { + connectionType: 'OPENSEARCH' | 'SPARK'; + name: string; +} + +export const NewDatasource = (props: HomeProps) => { + const { chrome, http } = props; + + // TODO: implement searching the card view with this + const [query, setQuery] = useState(''); + const [isCardView, setCardView] = useState(true); + + useEffect(() => { + chrome.setBreadcrumbs([ + { + text: 'Data sources', + href: '#/', + }, + ]); + }, []); + + // TODO: implement table view + const NewDatasourceTableView = () => { + return null; + }; + + return ( + + + + {isCardView ? : } + + + ); +}; diff --git a/public/components/data_connections/components/new_datasource_card_view.tsx b/public/components/datasources/components/new/new_datasource_card_view.tsx similarity index 90% rename from public/components/data_connections/components/new_datasource_card_view.tsx rename to public/components/datasources/components/new/new_datasource_card_view.tsx index 0981b4d26..7526aca49 100644 --- a/public/components/data_connections/components/new_datasource_card_view.tsx +++ b/public/components/datasources/components/new/new_datasource_card_view.tsx @@ -15,11 +15,9 @@ import { } from '@elastic/eui'; import _ from 'lodash'; import React, { useState } from 'react'; -import { INTEGRATIONS_BASE } from '../../../../common/constants/shared'; import { NewDatasourceDescription } from './new_datasource_description'; -import { coreRefs } from '../../../../public/framework/core_refs'; -import { MANAGEMENT_APP_ID } from '../../../../../../src/plugins/management/public'; -import sparkSvg from '../icons/apache_spark-icon.svg'; +import { coreRefs } from '../../../../framework/core_refs'; +import sparkSvg from '../../icons/apache_spark-icon.svg'; export interface DatasourceType { name: string; diff --git a/public/components/data_connections/components/new_datasource_description.tsx b/public/components/datasources/components/new/new_datasource_description.tsx similarity index 100% rename from public/components/data_connections/components/new_datasource_description.tsx rename to public/components/datasources/components/new/new_datasource_description.tsx diff --git a/public/components/data_connections/components/no_access.tsx b/public/components/datasources/components/no_access.tsx similarity index 100% rename from public/components/data_connections/components/no_access.tsx rename to public/components/datasources/components/no_access.tsx diff --git a/public/components/data_connections/components/save_or_cancel.tsx b/public/components/datasources/components/save_or_cancel.tsx similarity index 100% rename from public/components/data_connections/components/save_or_cancel.tsx rename to public/components/datasources/components/save_or_cancel.tsx diff --git a/public/components/data_connections/home.tsx b/public/components/datasources/home.tsx similarity index 88% rename from public/components/data_connections/home.tsx rename to public/components/datasources/home.tsx index daa7aff6e..e66301627 100644 --- a/public/components/data_connections/home.tsx +++ b/public/components/datasources/home.tsx @@ -6,10 +6,10 @@ import React from 'react'; import { HashRouter, Route, RouteComponentProps, Switch } from 'react-router-dom'; import { ChromeBreadcrumb, ChromeStart, HttpStart } from '../../../../../src/core/public'; -import { DataConnection } from './components/data_connection'; +import { DataConnection } from './components/manage/data_connection'; import { ManageDataConnectionsTable } from './components/manage_data_connections_table'; -import { NewDatasource } from './components/new_datasource'; -import { Configure } from './components/configure_datasource'; +import { NewDatasource } from './components/new/new_datasource'; +import { Configure } from './components/new/configure_datasource'; export interface HomeProps extends RouteComponentProps { pplService: any; diff --git a/public/components/data_connections/icons/apache_spark-icon.svg b/public/components/datasources/icons/apache_spark-icon.svg similarity index 100% rename from public/components/data_connections/icons/apache_spark-icon.svg rename to public/components/datasources/icons/apache_spark-icon.svg From cc7b1a2e9ee6579d4428c7e43843cdcb16a6c255 Mon Sep 17 00:00:00 2001 From: Derek Ho Date: Fri, 22 Sep 2023 16:26:25 -0400 Subject: [PATCH 4/6] Fix import path in testing file Signed-off-by: Derek Ho --- common/constants/shared.ts | 2 +- .../__tests__/manage_data_connections_table.test.tsx | 2 +- .../{new => manage}/connection_configuration.tsx | 0 .../components/manage/connection_details.tsx | 2 +- .../manage/manage_data_connections_table.tsx | 10 +++++----- public/components/datasources/home.tsx | 2 +- 6 files changed, 9 insertions(+), 9 deletions(-) rename public/components/datasources/components/{new => manage}/connection_configuration.tsx (100%) diff --git a/common/constants/shared.ts b/common/constants/shared.ts index b3a08da21..9bda5d3be 100644 --- a/common/constants/shared.ts +++ b/common/constants/shared.ts @@ -59,7 +59,7 @@ export const observabilityIntegrationsTitle = 'Integrations'; export const observabilityIntegrationsPluginOrder = 9020; export const observabilityDataConnectionsID = 'datasources'; -export const observabilityDataConnectionsTitle = 'Data Sources'; +export const observabilityDataConnectionsTitle = 'Data sources'; export const observabilityDataConnectionsPluginOrder = 9030; // Shared Constants diff --git a/public/components/datasources/components/__tests__/manage_data_connections_table.test.tsx b/public/components/datasources/components/__tests__/manage_data_connections_table.test.tsx index cd5509f1b..dfdb65d85 100644 --- a/public/components/datasources/components/__tests__/manage_data_connections_table.test.tsx +++ b/public/components/datasources/components/__tests__/manage_data_connections_table.test.tsx @@ -7,7 +7,7 @@ import { configure } from 'enzyme'; import Adapter from 'enzyme-adapter-react-16'; import { act } from '@testing-library/react'; import React from 'react'; -import { ManageDataConnectionsTable } from '../manage_data_connections_table'; +import { ManageDataConnectionsTable } from '../manage/manage_data_connections_table'; import { showDataConnectionsData } from '../../../../../test/datasources'; import ReactDOM from 'react-dom'; diff --git a/public/components/datasources/components/new/connection_configuration.tsx b/public/components/datasources/components/manage/connection_configuration.tsx similarity index 100% rename from public/components/datasources/components/new/connection_configuration.tsx rename to public/components/datasources/components/manage/connection_configuration.tsx diff --git a/public/components/datasources/components/manage/connection_details.tsx b/public/components/datasources/components/manage/connection_details.tsx index 0ad4eb1b5..533071960 100644 --- a/public/components/datasources/components/manage/connection_details.tsx +++ b/public/components/datasources/components/manage/connection_details.tsx @@ -17,7 +17,7 @@ import { ConnectionManagementCallout } from './connection_management_callout'; import { coreRefs } from '../../../../framework/core_refs'; import { DATACONNECTIONS_BASE } from '../../../../../common/constants/shared'; import { SaveOrCancel } from '../save_or_cancel'; -import { ConnectionConfiguration } from '../new/connection_configuration'; +import { ConnectionConfiguration } from './connection_configuration'; interface ConnectionDetailProps { dataConnection: string; diff --git a/public/components/datasources/components/manage/manage_data_connections_table.tsx b/public/components/datasources/components/manage/manage_data_connections_table.tsx index 2ad6882ef..5f223ae03 100644 --- a/public/components/datasources/components/manage/manage_data_connections_table.tsx +++ b/public/components/datasources/components/manage/manage_data_connections_table.tsx @@ -17,12 +17,12 @@ import { } from '@elastic/eui'; import _ from 'lodash'; import React, { useEffect, useState } from 'react'; -import { DataConnectionsHeader } from './data_connections_header'; -import { HomeProps } from '../home'; +import { DataConnectionsHeader } from '../data_connections_header'; +import { HomeProps } from '../../home'; import { DataConnectionsDescription } from './manage_data_connections_description'; -import { DATACONNECTIONS_BASE } from '../../../../common/constants/shared'; -import { useToast } from '../../common/toast'; -import { DeleteModal } from '../../common/helpers/delete_modal'; +import { DATACONNECTIONS_BASE } from '../../../../../common/constants/shared'; +import { useToast } from '../../../common/toast'; +import { DeleteModal } from '../../../common/helpers/delete_modal'; interface DataConnection { connectionType: 'OPENSEARCH' | 'SPARK'; diff --git a/public/components/datasources/home.tsx b/public/components/datasources/home.tsx index e66301627..fef07a780 100644 --- a/public/components/datasources/home.tsx +++ b/public/components/datasources/home.tsx @@ -7,7 +7,7 @@ import React from 'react'; import { HashRouter, Route, RouteComponentProps, Switch } from 'react-router-dom'; import { ChromeBreadcrumb, ChromeStart, HttpStart } from '../../../../../src/core/public'; import { DataConnection } from './components/manage/data_connection'; -import { ManageDataConnectionsTable } from './components/manage_data_connections_table'; +import { ManageDataConnectionsTable } from './components/manage/manage_data_connections_table'; import { NewDatasource } from './components/new/new_datasource'; import { Configure } from './components/new/configure_datasource'; From ed8cfc1d69ab1814e41115ff1d652de7a6627494 Mon Sep 17 00:00:00 2001 From: Derek Ho Date: Mon, 25 Sep 2023 10:32:39 -0400 Subject: [PATCH 5/6] Get Initial S3 configuration working Signed-off-by: Derek Ho --- .../components/new/configure_datasource.tsx | 61 +++--------- .../new/configure_s3_datasource.tsx | 92 +++++++++++++++++++ .../new/new_datasource_card_view.tsx | 7 +- .../components/datasources/icons/s3-logo.svg | 7 ++ 4 files changed, 117 insertions(+), 50 deletions(-) create mode 100644 public/components/datasources/components/new/configure_s3_datasource.tsx create mode 100644 public/components/datasources/icons/s3-logo.svg diff --git a/public/components/datasources/components/new/configure_datasource.tsx b/public/components/datasources/components/new/configure_datasource.tsx index 82ffe3532..61cbf5f85 100644 --- a/public/components/datasources/components/new/configure_datasource.tsx +++ b/public/components/datasources/components/new/configure_datasource.tsx @@ -23,7 +23,7 @@ import { EuiTextArea, } from '@elastic/eui'; import React, { useState } from 'react'; -import { OPENSEARCH_DOCUMENTATION_URL } from '../../../../../common/constants/data_connections'; +import { ConfigureS3Datasource } from './configure_s3_datasource'; interface ConfigureDatasourceProps { type: string; @@ -55,52 +55,19 @@ export function Configure(props: ConfigureDatasourceProps) { const ConfigureDatasource = (configurationProps: { datasourceType: string }) => { const { datasourceType } = configurationProps; - return ( -
- - -

{`Configure ${datasourceType} Connection`}

-
- - - {`Connect to ${datasourceType} with OpenSearch and OpenSearch Dashboards `} - - Learn more - - - - -

Data source details

-
- - - - - - - Description - optional - - Text that can help identify the data source or share additional details - - - - { - setDetails(e.target.value); - }} - /> - - - - - - - -
-
- ); + switch (datasourceType) { + case 'S3': + return ( + + ); + default: + return <>; + } }; return ( diff --git a/public/components/datasources/components/new/configure_s3_datasource.tsx b/public/components/datasources/components/new/configure_s3_datasource.tsx new file mode 100644 index 000000000..11d6b7588 --- /dev/null +++ b/public/components/datasources/components/new/configure_s3_datasource.tsx @@ -0,0 +1,92 @@ +/* + * Copyright OpenSearch Contributors + * SPDX-License-Identifier: Apache-2.0 + */ + +import { + EuiPanel, + EuiTitle, + EuiSpacer, + EuiText, + EuiLink, + EuiFormRow, + EuiFieldText, + EuiTextArea, +} from '@elastic/eui'; +import React, { useState } from 'react'; +import { OPENSEARCH_DOCUMENTATION_URL } from '../../../../../common/constants/data_connections'; + +interface ConfigureS3DatasourceProps { + currentName: string; + currentDetails: string; + setNameForRequest: React.Dispatch>; + setDetailsForRequest: React.Dispatch>; +} + +export const ConfigureS3Datasource = (props: ConfigureS3DatasourceProps) => { + const { setNameForRequest, setDetailsForRequest, currentName, currentDetails } = props; + + const [name, setName] = useState(currentName); + const [details, setDetails] = useState(currentDetails); + + return ( +
+ + +

{`Configure S3 Data Source`}

+
+ + + {`Connect to S3with OpenSearch and OpenSearch Dashboards `} + + Learn more + + + + +

Data source details

+
+ + + <> + +

+ This is the name the connection will be referenced by in OpenSearch Dashboards. It + is recommended to make this short yet descriptive to help users when selecting a + connection. +

+
+ { + setName(e.target.value); + }} + onBlur={(e) => { + setNameForRequest(e.target.value); + }} + /> + +
+ + { + setDetailsForRequest(e.target.value); + }} + onChange={(e) => { + setDetails(e.target.value); + }} + /> + + + + +

Glue authentication details

+
+
+
+ ); +}; diff --git a/public/components/datasources/components/new/new_datasource_card_view.tsx b/public/components/datasources/components/new/new_datasource_card_view.tsx index 7526aca49..727975a5c 100644 --- a/public/components/datasources/components/new/new_datasource_card_view.tsx +++ b/public/components/datasources/components/new/new_datasource_card_view.tsx @@ -18,6 +18,7 @@ import React, { useState } from 'react'; import { NewDatasourceDescription } from './new_datasource_description'; import { coreRefs } from '../../../../framework/core_refs'; import sparkSvg from '../../icons/apache_spark-icon.svg'; +import s3Svg from '../../icons/s3-logo.svg'; export interface DatasourceType { name: string; @@ -32,9 +33,9 @@ const Datasources: DatasourceType[] = [ displayIcon: , }, { - name: 'Spark', - description: 'Connect to a self managed instance of Apache Spark', - displayIcon: , + name: 'S3', + description: 'Connect to Amazon S3 via Amazon Glue', + displayIcon: , }, ]; diff --git a/public/components/datasources/icons/s3-logo.svg b/public/components/datasources/icons/s3-logo.svg new file mode 100644 index 000000000..39b0fc099 --- /dev/null +++ b/public/components/datasources/icons/s3-logo.svg @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file From 0b84fab3f00fe95a5b8efdacf523dc176f6072b2 Mon Sep 17 00:00:00 2001 From: Derek Ho Date: Mon, 25 Sep 2023 13:05:51 -0400 Subject: [PATCH 6/6] Configure S3 Data Source Working Signed-off-by: Derek Ho --- .../components/manage/access_control_tab.tsx | 9 +- .../components/manage/data_connection.tsx | 10 +- .../components/new/configure_datasource.tsx | 134 ++++++++++++++++-- .../new/configure_s3_datasource.tsx | 114 ++++++++++++++- .../review_s3_datasource_configuration.tsx | 103 ++++++++++++++ server/adaptors/ppl_plugin.ts | 8 ++ .../data_connections_router.ts | 37 +++++ 7 files changed, 395 insertions(+), 20 deletions(-) create mode 100644 public/components/datasources/components/new/review_s3_datasource_configuration.tsx diff --git a/public/components/datasources/components/manage/access_control_tab.tsx b/public/components/datasources/components/manage/access_control_tab.tsx index 3f588b23b..d35f3876f 100644 --- a/public/components/datasources/components/manage/access_control_tab.tsx +++ b/public/components/datasources/components/manage/access_control_tab.tsx @@ -23,6 +23,7 @@ interface AccessControlTabProps { dataConnection: string; connector: string; properties: unknown; + allowedRoles: string[]; } export const AccessControlTab = (props: AccessControlTabProps) => { @@ -30,7 +31,11 @@ export const AccessControlTab = (props: AccessControlTabProps) => { const [roles, setRoles] = useState>([]); const [selectedQueryPermissionRoles, setSelectedQueryPermissionRoles] = useState< Array<{ label: string }> - >([]); + >( + props.allowedRoles.map((role) => { + return { label: role }; + }) + ); const { http } = coreRefs; useEffect(() => { @@ -51,7 +56,7 @@ export const AccessControlTab = (props: AccessControlTabProps) => { Query access - {[].length ? `Restricted` : '-'} + {selectedQueryPermissionRoles.length ? `Restricted` : '-'} diff --git a/public/components/datasources/components/manage/data_connection.tsx b/public/components/datasources/components/manage/data_connection.tsx index c8cf014ac..a0527e7bc 100644 --- a/public/components/datasources/components/manage/data_connection.tsx +++ b/public/components/datasources/components/manage/data_connection.tsx @@ -59,15 +59,15 @@ export const DataConnection = (props: any) => { ]); http! .get(`${DATACONNECTIONS_BASE}/${dataSource}`) - .then((data) => + .then((data) => { setDatasourceDetails({ allowedRoles: data.allowedRoles, name: data.name, cluster: data.properties['emr.cluster'], connector: data.connector, properties: data.properties, - }) - ) + }); + }) .catch((err) => { setHasAccess(false); }); @@ -80,9 +80,11 @@ export const DataConnection = (props: any) => { disabled: false, content: ( ), }, @@ -200,7 +202,7 @@ export const DataConnection = (props: any) => { - + diff --git a/public/components/datasources/components/new/configure_datasource.tsx b/public/components/datasources/components/new/configure_datasource.tsx index 61cbf5f85..ed44498c8 100644 --- a/public/components/datasources/components/new/configure_datasource.tsx +++ b/public/components/datasources/components/new/configure_datasource.tsx @@ -22,8 +22,12 @@ import { EuiButtonEmpty, EuiTextArea, } from '@elastic/eui'; -import React, { useState } from 'react'; +import React, { useCallback, useEffect, useState } from 'react'; import { ConfigureS3Datasource } from './configure_s3_datasource'; +import { coreRefs } from '../../../../../public/framework/core_refs'; +import { DATACONNECTIONS_BASE } from '../../../../../common/constants/shared'; +import { ReviewS3Datasource } from './review_s3_datasource_configuration'; +import { useToast } from '../../../../../public/components/common/toast'; interface ConfigureDatasourceProps { type: string; @@ -31,9 +35,18 @@ interface ConfigureDatasourceProps { export function Configure(props: ConfigureDatasourceProps) { const { type } = props; + const { http } = coreRefs; + const { setToast } = useToast(); const [name, setName] = useState(''); const [details, setDetails] = useState(''); + const [arn, setArn] = useState(''); + const [store, setStore] = useState(''); + const [roles, setRoles] = useState>([]); + const [selectedQueryPermissionRoles, setSelectedQueryPermissionRoles] = useState< + Array<{ label: string }> + >([]); + const [page, setPage] = useState<'configure' | 'review'>('configure'); const ConfigureDatasourceSteps = [ { title: 'Step 1', @@ -53,6 +66,16 @@ export function Configure(props: ConfigureDatasourceProps) { }, ]; + useEffect(() => { + http!.get('/api/v1/configuration/roles').then((data) => + setRoles( + Object.keys(data.data).map((key) => { + return { label: key }; + }) + ) + ); + }, []); + const ConfigureDatasource = (configurationProps: { datasourceType: string }) => { const { datasourceType } = configurationProps; switch (datasourceType) { @@ -63,6 +86,13 @@ export function Configure(props: ConfigureDatasourceProps) { currentDetails={details} setNameForRequest={setName} setDetailsForRequest={setDetails} + currentArn={arn} + setArnForRequest={setArn} + currentStore={store} + setStoreForRequest={setStore} + roles={roles} + selectedQueryPermissionRoles={selectedQueryPermissionRoles} + setSelectedQueryPermissionRoles={setSelectedQueryPermissionRoles} /> ); default: @@ -70,34 +100,112 @@ export function Configure(props: ConfigureDatasourceProps) { } }; - return ( - - - - - - - + const ReviewDatasourceConfiguration = (configurationProps: { datasourceType: string }) => { + const { datasourceType } = configurationProps; + switch (datasourceType) { + case 'S3': + return ( + + ); + default: + return <>; + } + }; + const ReviewSaveOrCancel = useCallback(() => { + return ( - {}} color="ghost" size="s" iconType="cross"> + { + window.location.hash = '#/new'; + }} + color="ghost" + size="s" + iconType="cross" + > Cancel - {}} color="ghost" size="s" iconType="arrowLeft"> + setPage('configure') : () => {}} + color="ghost" + size="s" + iconType="arrowLeft" + > Previous - {}} size="s" iconType="arrowRight" fill> - Review Configuration + createDatasource() + : () => { + setPage('review'); + } + } + size="s" + iconType="arrowRight" + fill + > + {page === 'configure' ? `Review Configuration` : `Connect to ${type}`} + ); + }, [page]); + + const createDatasource = () => { + http! + .post(`${DATACONNECTIONS_BASE}`, { + body: JSON.stringify({ + name, + allowedRoles: selectedQueryPermissionRoles.map((role) => role.label), + connector: 's3glue', + properties: { + 'glue.auth.type': 'iam_role', + 'glue.auth.role_arn': arn, + 'glue.indexstore.opensearch.uri': store, + 'glue.indexstore.opensearch.auth': false, + 'glue.indexstore.opensearch.region': 'us-west-2', + }, + }), + }) + .then(() => { + setToast(`Data source ${name} created successfully!`); + window.location.hash = '#/manage'; + }) + .catch((err) => { + setToast(`Data source ${name} created successfully!`); + window.location.hash = '#/manage'; + }); + }; + + return ( + + + + + + {page === 'configure' ? ( + + ) : ( + + )} + + + + ); } diff --git a/public/components/datasources/components/new/configure_s3_datasource.tsx b/public/components/datasources/components/new/configure_s3_datasource.tsx index 11d6b7588..155d29d40 100644 --- a/public/components/datasources/components/new/configure_s3_datasource.tsx +++ b/public/components/datasources/components/new/configure_s3_datasource.tsx @@ -12,22 +12,45 @@ import { EuiFormRow, EuiFieldText, EuiTextArea, + EuiButton, } from '@elastic/eui'; import React, { useState } from 'react'; import { OPENSEARCH_DOCUMENTATION_URL } from '../../../../../common/constants/data_connections'; +import { QueryPermissionsConfiguration } from '../manage/query_permissions'; interface ConfigureS3DatasourceProps { + roles: Array<{ label: string }>; + selectedQueryPermissionRoles: Array<{ label: string }>; + setSelectedQueryPermissionRoles: React.Dispatch>>; currentName: string; currentDetails: string; + currentArn: string; + currentStore: string; + setStoreForRequest: React.Dispatch>; setNameForRequest: React.Dispatch>; setDetailsForRequest: React.Dispatch>; + setArnForRequest: React.Dispatch>; } export const ConfigureS3Datasource = (props: ConfigureS3DatasourceProps) => { - const { setNameForRequest, setDetailsForRequest, currentName, currentDetails } = props; + const { + setNameForRequest, + setDetailsForRequest, + setArnForRequest, + setStoreForRequest, + currentStore, + currentName, + currentDetails, + currentArn, + roles, + selectedQueryPermissionRoles, + setSelectedQueryPermissionRoles, + } = props; const [name, setName] = useState(currentName); const [details, setDetails] = useState(currentDetails); + const [arn, setArn] = useState(currentArn); + const [store, setStore] = useState(currentStore); return (
@@ -86,6 +109,95 @@ export const ConfigureS3Datasource = (props: ConfigureS3DatasourceProps) => {

Glue authentication details

+ + + + <> + +

+ This parameters provides the authentication type information required for execution + engine to connect to glue. +

+
+ + +
+ + + <> + +

This should be the IAM role ARN

+
+ { + setArn(e.target.value); + }} + onBlur={(e) => { + setArnForRequest(e.target.value); + }} + /> + +
+ + + + +

Glue index store details

+
+ + + + <> + +

+ This parameters provides the OpenSearch cluster host information for glue. This + OpenSearch instance is used for writing index data back. +

+
+ { + setStore(e.target.value); + }} + onBlur={(e) => { + setStoreForRequest(e.target.value); + }} + /> + +
+ + + <> + +

Lorem ipsum.

+
+ + +
+ + + <> + +

Lorem ipsum.

+
+ + +
+ + Test connection + + + +
); diff --git a/public/components/datasources/components/new/review_s3_datasource_configuration.tsx b/public/components/datasources/components/new/review_s3_datasource_configuration.tsx new file mode 100644 index 000000000..ede85f204 --- /dev/null +++ b/public/components/datasources/components/new/review_s3_datasource_configuration.tsx @@ -0,0 +1,103 @@ +/* + * Copyright OpenSearch Contributors + * SPDX-License-Identifier: Apache-2.0 + */ + +import { + EuiPanel, + EuiTitle, + EuiSpacer, + EuiText, + EuiLink, + EuiFormRow, + EuiFieldText, + EuiTextArea, + EuiButton, + EuiFlexGroup, + EuiHorizontalRule, + EuiFlexItem, +} from '@elastic/eui'; +import React, { useState } from 'react'; +import { OPENSEARCH_DOCUMENTATION_URL } from '../../../../../common/constants/data_connections'; +import { QueryPermissionsConfiguration } from '../manage/query_permissions'; + +interface ConfigureS3DatasourceProps { + selectedQueryPermissionRoles: Array<{ label: string }>; + currentName: string; + currentDetails: string; + currentArn: string; + currentStore: string; +} + +export const ReviewS3Datasource = (props: ConfigureS3DatasourceProps) => { + const { + currentStore, + currentName, + currentDetails, + currentArn, + selectedQueryPermissionRoles, + } = props; + + return ( +
+ + +

{`Review S3 Data Source Configuration`}

+
+ + + +

Data source configuration

+
+ + + + + + + Data source name + + {currentName} + + + + Description + + {currentDetails} + + + + + + + + Glue authentication ARN + + {currentArn} + + + + Glue index store URI + + {currentStore} + + + + + + + + Query Permissions + + {selectedQueryPermissionRoles + ? `Restricted - ${JSON.stringify(selectedQueryPermissionRoles)}` + : 'Everyone'} + + + + + +
+
+ ); +}; diff --git a/server/adaptors/ppl_plugin.ts b/server/adaptors/ppl_plugin.ts index 563c43672..6007f913f 100644 --- a/server/adaptors/ppl_plugin.ts +++ b/server/adaptors/ppl_plugin.ts @@ -68,6 +68,14 @@ export const PPLPlugin = function (Client, config, components) { method: 'DELETE', }); + ppl.createDataSource = ca({ + url: { + fmt: `${OPENSEARCH_DATACONNECTIONS_API.DATACONNECTION}`, + }, + needBody: true, + method: 'POST', + }); + ppl.modifyDataConnection = ca({ url: { fmt: `${OPENSEARCH_DATACONNECTIONS_API.DATACONNECTION}`, diff --git a/server/routes/data_connections/data_connections_router.ts b/server/routes/data_connections/data_connections_router.ts index a65660ba4..2c996ddcc 100644 --- a/server/routes/data_connections/data_connections_router.ts +++ b/server/routes/data_connections/data_connections_router.ts @@ -103,6 +103,43 @@ export function registerDataConnectionsRoute(router: IRouter) { } ); + router.post( + { + path: `${DATACONNECTIONS_BASE}`, + validate: { + body: schema.object({ + name: schema.string(), + connector: schema.string(), + allowedRoles: schema.arrayOf(schema.string()), + properties: schema.any(), + }), + }, + }, + async (context, request, response): Promise => { + try { + const dataConnectionsresponse = await context.observability_plugin.observabilityClient + .asScoped(request) + .callAsCurrentUser('ppl.createDataSource', { + body: { + name: request.body.name, + connector: request.body.connector, + allowedRoles: request.body.allowedRoles, + properties: request.body.properties, + }, + }); + return response.ok({ + body: dataConnectionsresponse, + }); + } catch (error: any) { + console.error('Issue in creating data source:', error); + return response.custom({ + statusCode: error.statusCode || 500, + body: error.message, + }); + } + } + ); + router.get( { path: `${DATACONNECTIONS_BASE}`,