From c65949c3630853f4d776b2a00843566a82baab58 Mon Sep 17 00:00:00 2001 From: Shenoy Pratik Date: Sat, 9 Mar 2024 13:37:38 -0800 Subject: [PATCH 1/2] expose create acceleration flyout, update docs link Signed-off-by: Shenoy Pratik --- common/constants/data_connections.ts | 2 +- .../create_acceleration.test.tsx.snap | 249 +++------------- .../create_acceleration_header.test.tsx.snap | 2 +- .../__tests__/create_acceleration.test.tsx | 14 +- .../create/create_acceleration.tsx | 17 +- .../source_selector.test.tsx.snap | 269 ++---------------- .../__tests__/source_selector.test.tsx | 5 +- .../selectors/index_type_selector.tsx | 2 +- .../selectors/source_selector.tsx | 82 +++--- .../components/manage/data_connection.tsx | 35 ++- public/plugin.tsx | 27 +- 11 files changed, 156 insertions(+), 548 deletions(-) diff --git a/common/constants/data_connections.ts b/common/constants/data_connections.ts index 23fd9a8697..b265b2290d 100644 --- a/common/constants/data_connections.ts +++ b/common/constants/data_connections.ts @@ -12,7 +12,7 @@ export const OPENSEARCH_S3_DOCUMENTATION_URL = 'https://opensearch.org/docs/latest/dashboards/management/S3-data-source/'; export const OPENSEARCH_ACC_DOCUMENTATION_URL = - 'https://opensearch.org/docs/latest/data-acceleration/index'; + 'https://opensearch.org/docs/latest/dashboards/management/accelerate-external-data/'; export const QUERY_RESTRICTED = 'query-restricted'; export const QUERY_ALL = 'query-all'; diff --git a/public/components/datasources/components/manage/accelerations/create/__tests__/__snapshots__/create_acceleration.test.tsx.snap b/public/components/datasources/components/manage/accelerations/create/__tests__/__snapshots__/create_acceleration.test.tsx.snap index 951139f2f0..d77367d91d 100644 --- a/public/components/datasources/components/manage/accelerations/create/__tests__/__snapshots__/create_acceleration.test.tsx.snap +++ b/public/components/datasources/components/manage/accelerations/create/__tests__/__snapshots__/create_acceleration.test.tsx.snap @@ -76,7 +76,7 @@ Array [ @@ -144,102 +144,25 @@ Array [
-
-
- -
-
+
- -
+ my_glue + + +
- flint_{Datasource Name}_{Database Name}_{Table Name}_ + flint_my_glue_{Database Name}_{Table Name}_ @@ -1311,129 +1234,25 @@ Array [
,
, -
-
- -
-
+
-
-
-
-
-

- Select a data source -

-
- -
-
-
-
- -
-
-
-
-
- A data source has to be configured and active to be able to select it and index data from. -
-
-
, + my_glue + + , +
,
- flint_{Datasource Name}_{Database Name}_{Table Name}_ + flint_my_glue_{Database Name}_{Table Name}_ diff --git a/public/components/datasources/components/manage/accelerations/create/__tests__/create_acceleration.test.tsx b/public/components/datasources/components/manage/accelerations/create/__tests__/create_acceleration.test.tsx index 49cd168a3f..165527573c 100644 --- a/public/components/datasources/components/manage/accelerations/create/__tests__/create_acceleration.test.tsx +++ b/public/components/datasources/components/manage/accelerations/create/__tests__/create_acceleration.test.tsx @@ -3,7 +3,6 @@ * SPDX-License-Identifier: Apache-2.0 */ -import { EuiComboBoxOptionOption } from '@elastic/eui'; import { waitFor } from '@testing-library/dom'; import { configure, mount } from 'enzyme'; import Adapter from 'enzyme-adapter-react-16'; @@ -19,19 +18,12 @@ describe('Create acceleration flyout components', () => { configure({ adapter: new Adapter() }); it('renders acceleration flyout component with default options', async () => { - const selectedDatasource: EuiComboBoxOptionOption[] = []; + const selectedDatasource = 'my_glue'; const resetFlyout = jest.fn(); - const updateQueries = jest.fn(); - const client = coreStartMock.http; - client.get = jest.fn().mockResolvedValue(mockDatasourcesQuery); + coreStartMock.http.get = jest.fn().mockResolvedValue(mockDatasourcesQuery); const wrapper = mount( - + ); wrapper.update(); await waitFor(() => { diff --git a/public/components/datasources/components/manage/accelerations/create/create_acceleration.tsx b/public/components/datasources/components/manage/accelerations/create/create_acceleration.tsx index 6ab2805940..08a37a3bf4 100644 --- a/public/components/datasources/components/manage/accelerations/create/create_acceleration.tsx +++ b/public/components/datasources/components/manage/accelerations/create/create_acceleration.tsx @@ -6,7 +6,6 @@ import { EuiButton, EuiButtonEmpty, - EuiComboBoxOptionOption, EuiFlexGroup, EuiFlexItem, EuiFlyout, @@ -17,35 +16,31 @@ import { EuiSpacer, } from '@elastic/eui'; import React, { useState } from 'react'; -import { CoreStart } from '../../../../../../../../../src/core/public'; import { ACCELERATION_DEFUALT_SKIPPING_INDEX_NAME, ACCELERATION_TIME_INTERVAL, } from '../../../../../../../common/constants/data_sources'; import { CreateAccelerationForm } from '../../../../../../../common/types/data_connections'; +import { coreRefs } from '../../../../../../framework/core_refs'; import { DefineIndexOptions } from '../selectors/define_index_options'; import { IndexSettingOptions } from '../selectors/index_setting_options'; import { AccelerationDataSourceSelector } from '../selectors/source_selector'; -import { accelerationQueryBuilder } from '../visual_editors/query_builder'; import { QueryVisualEditor } from '../visual_editors/query_visual_editor'; import { CreateAccelerationHeader } from './create_acceleration_header'; import { formValidator, hasError } from './utils'; export interface CreateAccelerationProps { - http: CoreStart['http']; - selectedDatasource: EuiComboBoxOptionOption[]; + selectedDatasource: string; resetFlyout: () => void; - updateQueries: (query: string) => void; } export const CreateAcceleration = ({ - http, selectedDatasource, resetFlyout, - updateQueries, }: CreateAccelerationProps) => { + const http = coreRefs!.http; const [accelerationFormData, setAccelerationFormData] = useState({ - dataSource: selectedDatasource.length > 0 ? selectedDatasource[0].label : '', + dataSource: selectedDatasource, dataTable: '', database: '', dataTableFields: [], @@ -95,7 +90,7 @@ export const CreateAcceleration = ({ setAccelerationFormData({ ...accelerationFormData, formErrors: errors }); return; } - updateQueries(accelerationQueryBuilder(accelerationFormData)); + // TODO: add -> updateQueries(accelerationQueryBuilder(accelerationFormData)); resetFlyout(); }; @@ -114,7 +109,7 @@ export const CreateAcceleration = ({ id="acceleration-form" >
,
, -
-
- -
-
+
-
-
-
-
-

- Select a data source -

-
- -
-
-
-
- -
-
-
-
-
- A data source has to be configured and active to be able to select it and index data from. -
-
-
, + my_glue + + , +
,
,
, -
-
- -
-
+
-
-
-
-
- - ds - -
- -
-
-
-
- -
-
-
-
-
- A data source has to be configured and active to be able to select it and index data from. -
-
-
, + ds + + , +
,
{ it('renders source selector with default options', async () => { const accelerationFormData = createAccelerationEmptyDataMock; - const selectedDatasource: EuiComboBoxOptionOption[] = []; + const selectedDatasource = 'my_glue'; const setAccelerationFormData = jest.fn(); const client = coreStartMock.http; client.get = jest.fn().mockResolvedValue(mockDatasourcesQuery); @@ -49,7 +48,7 @@ describe('Source selector components', () => { }); it('renders source selector with different options', async () => { - const selectedDatasource: EuiComboBoxOptionOption[] = [{ label: 'ds' }]; + const selectedDatasource = 'ds'; const accelerationFormData: CreateAccelerationForm = { ...createAccelerationEmptyDataMock, dataSource: 'ds', diff --git a/public/components/datasources/components/manage/accelerations/selectors/index_type_selector.tsx b/public/components/datasources/components/manage/accelerations/selectors/index_type_selector.tsx index 1ebd110a68..b710d87794 100644 --- a/public/components/datasources/components/manage/accelerations/selectors/index_type_selector.tsx +++ b/public/components/datasources/components/manage/accelerations/selectors/index_type_selector.tsx @@ -14,7 +14,6 @@ import { AccelerationIndexType, CreateAccelerationForm, } from '../../../../../../../common/types/data_connections'; -// import { executeAsyncQuery } from '../../../../common/utils/async_query_helpers'; interface IndexTypeSelectorProps { accelerationFormData: CreateAccelerationForm; @@ -31,6 +30,7 @@ export const IndexTypeSelector = ({ const [loading, _setLoading] = useState(false); // useEffect(() => { + // TODO: Load table schema from cache // if (accelerationFormData.dataTable !== '') { // setLoading(true); // const idPrefix = htmlIdGenerator()(); diff --git a/public/components/datasources/components/manage/accelerations/selectors/source_selector.tsx b/public/components/datasources/components/manage/accelerations/selectors/source_selector.tsx index ea3859285b..6f44fa94b0 100644 --- a/public/components/datasources/components/manage/accelerations/selectors/source_selector.tsx +++ b/public/components/datasources/components/manage/accelerations/selectors/source_selector.tsx @@ -3,20 +3,29 @@ * SPDX-License-Identifier: Apache-2.0 */ -import { EuiComboBox, EuiComboBoxOptionOption, EuiFormRow, EuiSpacer, EuiText } from '@elastic/eui'; +import { + EuiComboBox, + EuiComboBoxOptionOption, + EuiDescriptionList, + EuiDescriptionListDescription, + EuiDescriptionListTitle, + EuiFormRow, + EuiSpacer, + EuiText, +} from '@elastic/eui'; import producer from 'immer'; import React, { useEffect, useState } from 'react'; -// import { executeAsyncQuery } from '../../../../common/utils/async_query_helpers'; import { CoreStart } from '../../../../../../../../../src/core/public'; +import { DATACONNECTIONS_BASE } from '../../../../../../../common/constants/shared'; import { CreateAccelerationForm } from '../../../../../../../common/types/data_connections'; import { useToast } from '../../../../../common/toast'; -import { hasError, validateDataSource } from '../create/utils'; +import { hasError, validateDataTable, validateDatabase } from '../create/utils'; interface AccelerationDataSourceSelectorProps { http: CoreStart['http']; accelerationFormData: CreateAccelerationForm; setAccelerationFormData: React.Dispatch>; - selectedDatasource: EuiComboBoxOptionOption[]; + selectedDatasource: string; } export const AccelerationDataSourceSelector = ({ @@ -26,12 +35,6 @@ export const AccelerationDataSourceSelector = ({ selectedDatasource, }: AccelerationDataSourceSelectorProps) => { const { setToast } = useToast(); - const [dataConnections, setDataConnections] = useState>>( - [] - ); - const [selectedDataConnection, setSelectedDataConnection] = useState< - Array> - >(selectedDatasource.length > 0 ? [{ label: selectedDatasource[0].label }] : []); const [databases, _setDatabases] = useState>>([]); const [selectedDatabase, setSelectedDatabase] = useState>>( [] @@ -47,23 +50,27 @@ export const AccelerationDataSourceSelector = ({ const loadDataSource = () => { setLoadingComboBoxes({ ...loadingComboBoxes, dataSource: true }); http - .get(`/api/get_datasources`) + .get(DATACONNECTIONS_BASE) .then((res) => { - const data = res.data.resp; - setDataConnections( - data - .filter((connection: any) => connection.connector.toUpperCase() === 'S3GLUE') - .map((connection: any) => ({ label: connection.name })) + const isValidDataSource = res.some( + (connection: any) => + connection.connector.toUpperCase() === 'S3GLUE' && + connection.name === selectedDatasource ); + + if (!isValidDataSource) { + setToast(`Received an invalid datasource in create acceleration flyout`, 'danger'); + } }) .catch((err) => { console.error(err); - setToast(`ERROR: failed to load datasources`, 'danger'); + setToast(`failed to load datasources`, 'danger'); }); setLoadingComboBoxes({ ...loadingComboBoxes, dataSource: false }); }; const loadDatabases = () => { + // TODO: Load databases from cache // setLoadingComboBoxes({ ...loadingComboBoxes, database: true }); // const query = { // lang: 'sql', @@ -93,6 +100,7 @@ export const AccelerationDataSourceSelector = ({ }; const loadTables = () => { + // TODO: Load tables from cache // setLoadingComboBoxes({ ...loadingComboBoxes, dataTable: true }); // const query = { // lang: 'sql', @@ -146,36 +154,12 @@ export const AccelerationDataSourceSelector = ({ Select the data source to accelerate data from. External data sources may take time to load. - - - { - if (dataConnectionOptions.length > 0) { - setAccelerationFormData( - producer((accData) => { - accData.dataSource = dataConnectionOptions[0].label; - accData.formErrors.dataSourceError = validateDataSource( - dataConnectionOptions[0].label - ); - }) - ); - setSelectedDataConnection(dataConnectionOptions); - } - }} - isClearable={false} - isInvalid={hasError(accelerationFormData.formErrors, 'dataSourceError')} - isLoading={loadingComboBoxes.dataSource} - /> - + + + Data source + {selectedDatasource} + + { accData.database = databaseOptions[0].label; - accData.formErrors.databaseError = validateDataSource(databaseOptions[0].label); + accData.formErrors.databaseError = validateDatabase(databaseOptions[0].label); }) ); setSelectedDatabase(databaseOptions); @@ -219,7 +203,7 @@ export const AccelerationDataSourceSelector = ({ setAccelerationFormData( producer((accData) => { accData.dataTable = tableOptions[0].label; - accData.formErrors.dataTableError = validateDataSource(tableOptions[0].label); + accData.formErrors.dataTableError = validateDataTable(tableOptions[0].label); }) ); setSelectedTable(tableOptions); diff --git a/public/components/datasources/components/manage/data_connection.tsx b/public/components/datasources/components/manage/data_connection.tsx index ee10e4a53e..2b8dc5895b 100644 --- a/public/components/datasources/components/manage/data_connection.tsx +++ b/public/components/datasources/components/manage/data_connection.tsx @@ -25,14 +25,14 @@ import { observabilityIntegrationsID, observabilityLogsID, observabilityMetricsID, - queryWorkbenchPluginID, } from '../../../../../common/constants/shared'; +import { DatasourceType } from '../../../../../common/types/data_connections'; import { coreRefs } from '../../../../framework/core_refs'; +import { getRenderCreateAccelerationFlyout } from '../../../../plugin'; import { NoAccess } from '../no_access'; +import { AccelerationTable } from './accelerations/acceleration_table'; import { AccessControlTab } from './access_control_tab'; -import { DatasourceType } from '../../../../../common/types/data_connections'; import { AssociatedObjectsTab } from './associated_objects/associated_objects_tab'; -import { AccelerationTable } from './accelerations/acceleration_table'; import { mockAssociatedObjects } from './associated_objects/utils/associated_objects_tab_utils'; interface DatasourceDetails { @@ -51,6 +51,7 @@ export interface S3GlueProperties { export interface PrometheusProperties { 'prometheus.uri': string; } +const renderCreateAccelerationFlyout = getRenderCreateAccelerationFlyout(); export const DataConnection = (props: any) => { const { dataSource } = props; @@ -82,6 +83,18 @@ export const DataConnection = (props: any) => { }, ]; + const onclickIntegrationsCard = () => { + application!.navigateToApp(observabilityIntegrationsID); + }; + + const onclickAccelerationsCard = () => { + renderCreateAccelerationFlyout(dataSource); + }; + + const onclickDiscoverCard = () => { + application!.navigateToApp(observabilityLogsID); + }; + const DefaultDatasourceCards = () => { return ( @@ -90,9 +103,9 @@ export const DataConnection = (props: any) => { icon={} title={'Configure Integrations'} description="Connect to common application log types using integrations" - onClick={() => application!.navigateToApp(observabilityIntegrationsID)} + onClick={onclickIntegrationsCard} selectable={{ - onClick: () => {}, + onClick: onclickIntegrationsCard, isDisabled: false, children: 'Add Integrations', }} @@ -103,13 +116,9 @@ export const DataConnection = (props: any) => { icon={} title={'Accelerate performance'} description="Accelerate query performance through OpenSearch indexing" - onClick={() => - application!.navigateToApp(queryWorkbenchPluginID, { - path: `#/accelerate/${dataSource}`, - }) - } + onClick={onclickAccelerationsCard} selectable={{ - onClick: () => {}, + onClick: onclickAccelerationsCard, isDisabled: false, children: 'Accelerate Performance', }} @@ -120,9 +129,9 @@ export const DataConnection = (props: any) => { icon={} title={'Query data'} description="Uncover insights from your data or better understand it" - onClick={() => application!.navigateToApp(observabilityLogsID)} + onClick={onclickDiscoverCard} selectable={{ - onClick: () => {}, + onClick: onclickDiscoverCard, isDisabled: false, children: 'Query in Discover', }} diff --git a/public/plugin.tsx b/public/plugin.tsx index ff60e84306..eff8dddc86 100644 --- a/public/plugin.tsx +++ b/public/plugin.tsx @@ -58,6 +58,11 @@ import { import { DirectSearch } from './components/common/search/direct_search'; import { Search } from './components/common/search/search'; import { AccelerationDetailsFlyout } from './components/datasources/components/manage/accelerations/acceleration_details_flyout'; +import { CreateAcceleration } from './components/datasources/components/manage/accelerations/create/create_acceleration'; +import { + AssociatedObjectsDetailsFlyout, + AssociatedObjectsFlyoutProps, +} from './components/datasources/components/manage/associated_objects/associated_objects_details_flyout'; import { convertLegacyNotebooksUrl } from './components/notebooks/components/helpers/legacy_route_helpers'; import { convertLegacyTraceAnalyticsUrl } from './components/trace_analytics/components/common/legacy_route_helpers'; import { registerAsssitantDependencies } from './dependencies/register_assistant'; @@ -84,10 +89,6 @@ import { ObservabilityStart, SetupDependencies, } from './types'; -import { - AssociatedObjectsDetailsFlyout, - AssociatedObjectsFlyoutProps, -} from './components/datasources/components/manage/associated_objects/associated_objects_details_flyout'; interface PublicConfig { query_assist: { @@ -108,6 +109,11 @@ export const [ setRenderAssociatedObjectsDetailsFlyout, ] = createGetterSetter('renderAssociatedObjectsDetailsFlyout'); +export const [ + getRenderCreateAccelerationFlyout, + setRenderCreateAccelerationFlyout, +] = createGetterSetter<(dataSource: string) => void>('renderCreateAccelerationFlyout'); + export class ObservabilityPlugin implements Plugin { @@ -393,10 +399,23 @@ export class ObservabilityPlugin ); setRenderAssociatedObjectsDetailsFlyout(renderAssociatedObjectsDetailsFlyout); + const renderCreateAccelerationFlyout = (selectedDatasource: string) => { + const createAccelerationFlyout = core.overlays.openFlyout( + toMountPoint( + createAccelerationFlyout.close()} + /> + ) + ); + }; + setRenderCreateAccelerationFlyout(renderCreateAccelerationFlyout); + // Export so other plugins can use this flyout return { renderAccelerationDetailsFlyout, renderAssociatedObjectsDetailsFlyout, + renderCreateAccelerationFlyout, }; } From 97a8fc751f9c5f8c02dbba1778774a394db90cca Mon Sep 17 00:00:00 2001 From: Shenoy Pratik Date: Sat, 9 Mar 2024 14:42:09 -0800 Subject: [PATCH 2/2] update test for data_connection page Signed-off-by: Shenoy Pratik --- .../components/__tests__/data_connection.test.tsx | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/public/components/datasources/components/__tests__/data_connection.test.tsx b/public/components/datasources/components/__tests__/data_connection.test.tsx index f17ef2c828..1510a93f13 100644 --- a/public/components/datasources/components/__tests__/data_connection.test.tsx +++ b/public/components/datasources/components/__tests__/data_connection.test.tsx @@ -3,25 +3,22 @@ * SPDX-License-Identifier: Apache-2.0 */ +import { act } from '@testing-library/react'; import { configure } from 'enzyme'; import Adapter from 'enzyme-adapter-react-16'; -import { act } from '@testing-library/react'; import React from 'react'; +import ReactDOM from 'react-dom'; +import { coreRefs } from '../../../../../public/framework/core_refs'; import { describePrometheusDataConnection, describeS3Dataconnection, } from '../../../../../test/datasources'; import { DataConnection } from '../manage/data_connection'; -import ReactDOM from 'react-dom'; -import { coreRefs } from '../../../../../public/framework/core_refs'; jest.mock('../../../../plugin', () => ({ - getRenderAccelerationDetailsFlyout: jest.fn(() => - jest.fn().mockImplementation(() => console.log('Acceleration Details Flyout Rendered')) - ), - getRenderAssociatedObjectsDetailsFlyout: jest.fn(() => - jest.fn().mockImplementation(() => console.log('Associated Objects Details Flyout Rendered')) - ), + getRenderAccelerationDetailsFlyout: jest.fn(), + getRenderAssociatedObjectsDetailsFlyout: jest.fn(), + getRenderCreateAccelerationFlyout: jest.fn(), })); jest.mock('../../../../../public/framework/core_refs', () => ({