From 75ea3e229db39dc35dfc307bdf2b781a82432190 Mon Sep 17 00:00:00 2001 From: Rodney Norris Date: Mon, 13 Nov 2023 12:37:18 -0600 Subject: [PATCH] [Serverless Search] connectors callout (#171043) ## Summary Replace console callout with Connectors callout on the Getting started page. ![image](https://github.com/elastic/kibana/assets/1972968/522268ce-62c3-464e-ae77-583a14b8ecdd) ### Notes I had to wrap some things in `

` tags to match the bottom margin on the Icons. This is due to styles from EUI and may get resolved later and we would then remove these `

` tags. --- .../components/select_client.tsx | 44 ++++---- .../components/connectors_callout.tsx | 101 ++++++++++++++++++ .../components/connectors_overview.tsx | 34 +----- .../application/components/overview.tsx | 11 +- .../hooks/api/use_create_connector.tsx | 41 +++++++ 5 files changed, 172 insertions(+), 59 deletions(-) create mode 100644 x-pack/plugins/serverless_search/public/application/components/connectors_callout.tsx create mode 100644 x-pack/plugins/serverless_search/public/application/hooks/api/use_create_connector.tsx diff --git a/packages/kbn-search-api-panels/components/select_client.tsx b/packages/kbn-search-api-panels/components/select_client.tsx index 4b8d1547d35c..8328a32bca75 100644 --- a/packages/kbn-search-api-panels/components/select_client.tsx +++ b/packages/kbn-search-api-panels/components/select_client.tsx @@ -29,6 +29,7 @@ export interface SelectClientPanelProps { http: HttpStart; isPanelLeft?: boolean; overviewPanelProps?: Partial; + callout?: React.ReactNode; } export const SelectClientPanel: React.FC = ({ @@ -37,6 +38,7 @@ export const SelectClientPanel: React.FC = ({ http, isPanelLeft = true, overviewPanelProps, + callout, }) => { const panelContent = ( <> @@ -56,28 +58,30 @@ export const SelectClientPanel: React.FC = ({ {children} - -

- {i18n.translate('searchApiPanels.welcomeBanner.selectClient.callout.description', { - defaultMessage: - 'With Console, you can get started right away with our REST APIs. No installation required.', + {callout || ( + +

+ {i18n.translate('searchApiPanels.welcomeBanner.selectClient.callout.description', { + defaultMessage: + 'With Console, you can get started right away with our REST APIs. No installation required.', + })} - - - {i18n.translate('searchApiPanels.welcomeBanner.selectClient.callout.link', { - defaultMessage: 'Try Console now', - })} - - -

- + + + {i18n.translate('searchApiPanels.welcomeBanner.selectClient.callout.link', { + defaultMessage: 'Try Console now', + })} + + +

+ + )} ); return ( diff --git a/x-pack/plugins/serverless_search/public/application/components/connectors_callout.tsx b/x-pack/plugins/serverless_search/public/application/components/connectors_callout.tsx new file mode 100644 index 000000000000..85d3db211c47 --- /dev/null +++ b/x-pack/plugins/serverless_search/public/application/components/connectors_callout.tsx @@ -0,0 +1,101 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ +import React from 'react'; +import { + EuiButton, + EuiCallOut, + EuiFlexGroup, + EuiFlexItem, + EuiIcon, + EuiText, + EuiToolTip, +} from '@elastic/eui'; +import { i18n } from '@kbn/i18n'; +import { FormattedMessage } from '@kbn/i18n-react'; + +import { useConnectorTypes } from '../hooks/api/use_connector_types'; +import { useCreateConnector } from '../hooks/api/use_create_connector'; + +const CONNECTOR_TYPES_DISPLAY = [ + 'azure_blob_storage', + 'sharepoint_online', + 's3', + 'mongodb', + 'google_cloud_storage', +]; + +export const ConnectorsCallout = () => { + const { data } = useConnectorTypes(); + const { createConnector, isLoading } = useCreateConnector(); + + const allConnectorTypes = data?.connectors; + const connectorTypes = allConnectorTypes + ? CONNECTOR_TYPES_DISPLAY.map( + (type) => allConnectorTypes.find((connType) => connType.serviceType === type)! + ) + : undefined; + const showConnectors = connectorTypes && connectorTypes.length; + return ( + +

+ +

+ + +

+ createConnector()} + isLoading={isLoading} + > + {i18n.translate('xpack.serverlessSearch.selectClient.connectorsCallout.cta', { + defaultMessage: 'Create a connector', + })} + +

+
+ + {showConnectors && + connectorTypes.map((connectorType) => ( + + + + + + ))} + {showConnectors && ( + +

+ + + +

+
+ )} +
+
+ ); +}; diff --git a/x-pack/plugins/serverless_search/public/application/components/connectors_overview.tsx b/x-pack/plugins/serverless_search/public/application/components/connectors_overview.tsx index f79dce303617..ebd7afc288d2 100644 --- a/x-pack/plugins/serverless_search/public/application/components/connectors_overview.tsx +++ b/x-pack/plugins/serverless_search/public/application/components/connectors_overview.tsx @@ -14,49 +14,23 @@ import { EuiPageTemplate, EuiText, } from '@elastic/eui'; -import { Connector } from '@kbn/search-connectors'; import { i18n } from '@kbn/i18n'; import { FormattedMessage } from '@kbn/i18n-react'; -import { useMutation } from '@tanstack/react-query'; -import React, { useEffect } from 'react'; +import React from 'react'; -import { generatePath } from 'react-router-dom'; import { LEARN_MORE_LABEL } from '../../../common/i18n_string'; import { PLUGIN_ID } from '../../../common'; import { useConnectors } from '../hooks/api/use_connectors'; +import { useCreateConnector } from '../hooks/api/use_create_connector'; import { useKibanaServices } from '../hooks/use_kibana'; import { EmptyConnectorsPrompt } from './connectors/empty_connectors_prompt'; import { ConnectorsTable } from './connectors/connectors_table'; -import { EDIT_CONNECTOR_PATH } from './connectors_router'; export const ConnectorsOverview = () => { const { data, isLoading: connectorsLoading } = useConnectors(); - const { - application: { navigateToUrl }, - http, - } = useKibanaServices(); + const { http } = useKibanaServices(); - const { - data: connector, - isLoading, - isSuccess, - mutate, - } = useMutation({ - mutationFn: async () => { - const result = await http.post<{ connector: Connector }>( - '/internal/serverless_search/connectors' - ); - return result.connector; - }, - }); - - useEffect(() => { - if (isSuccess) { - navigateToUrl(generatePath(EDIT_CONNECTOR_PATH, { id: connector?.id || '' })); - } - }, [connector, isSuccess, navigateToUrl]); - - const createConnector = () => mutate(); + const { createConnector, isLoading } = useCreateConnector(); return ( diff --git a/x-pack/plugins/serverless_search/public/application/components/overview.tsx b/x-pack/plugins/serverless_search/public/application/components/overview.tsx index bf66ae62855a..cb32a66cea20 100644 --- a/x-pack/plugins/serverless_search/public/application/components/overview.tsx +++ b/x-pack/plugins/serverless_search/public/application/components/overview.tsx @@ -37,8 +37,6 @@ import type { LanguageDefinition, LanguageDefinitionSnippetArguments, } from '@kbn/search-api-panels'; -import { useQuery } from '@tanstack/react-query'; -import { Connector } from '@kbn/search-connectors'; import { useLocation } from 'react-router-dom'; import { docLinks } from '../../../common/doc_links'; import { PLUGIN_ID } from '../../../common'; @@ -53,6 +51,7 @@ import { languageDefinitions } from './languages/languages'; import { LanguageGrid } from './languages/language_grid'; import './overview.scss'; import { ApiKeyPanel } from './api_key/api_key'; +import { ConnectorsCallout } from './connectors_callout'; export const ElasticsearchOverview = () => { const [selectedLanguage, setSelectedLanguage] = useState(javaDefinition); @@ -82,12 +81,6 @@ export const ElasticsearchOverview = () => { } }, [hash]); - const { data: _data } = useQuery({ - queryKey: ['fetchConnectors'], - queryFn: () => - http.fetch<{ connectors: Connector[] }>('/internal/serverless_search/connectors'), - }); - return ( @@ -100,7 +93,7 @@ export const ElasticsearchOverview = () => { bottomBorder="extended" data-test-subj="select-client-section" > - + }> { + const { + application: { navigateToUrl }, + http, + } = useKibanaServices(); + const { + data: connector, + isLoading, + isSuccess, + mutate, + } = useMutation({ + mutationFn: async () => { + const result = await http.post<{ connector: Connector }>( + '/internal/serverless_search/connectors' + ); + return result.connector; + }, + }); + + useEffect(() => { + if (isSuccess) { + navigateToUrl(generatePath(EDIT_CONNECTOR_PATH, { id: connector?.id || '' })); + } + }, [connector, isSuccess, navigateToUrl]); + + const createConnector = () => mutate(); + return { createConnector, isLoading }; +};