mirror of
https://github.com/elastic/kibana.git
synced 2025-04-25 02:09:32 -04:00
# Backport This will backport the following commits from `main` to `8.12`: - [[Search] Fix API key flyout bugfixes (#173547)](https://github.com/elastic/kibana/pull/173547) <!--- Backport version: 8.9.7 --> ### Questions ? Please refer to the [Backport tool documentation](https://github.com/sqren/backport) <!--BACKPORT [{"author":{"name":"Sander Philipse","email":"94373878+sphilipse@users.noreply.github.com"},"sourceCommit":{"committedDate":"2023-12-18T19:25:48Z","message":"[Search] Fix API key flyout bugfixes (#173547)\n\n## Summary\r\n\r\nThis fixes a couple of API key flyout bugfixes:\r\n\r\n- created API key now shows up regardless of where you opened the flyout\r\nfrom\r\n- Header action has a max width of 256px and wraps the cloud ID and\r\nelasticsearch endpoint\r\n- API key is scrolled into view when created","sha":"7016c042336d154e8e570d268a3031cc170bc0af","branchLabelMapping":{"^v8.13.0$":"main","^v(\\d+).(\\d+).\\d+$":"$1.$2"}},"sourcePullRequest":{"labels":["release_note:skip","Team:EnterpriseSearch","v8.12.0","v8.13.0"],"number":173547,"url":"https://github.com/elastic/kibana/pull/173547","mergeCommit":{"message":"[Search] Fix API key flyout bugfixes (#173547)\n\n## Summary\r\n\r\nThis fixes a couple of API key flyout bugfixes:\r\n\r\n- created API key now shows up regardless of where you opened the flyout\r\nfrom\r\n- Header action has a max width of 256px and wraps the cloud ID and\r\nelasticsearch endpoint\r\n- API key is scrolled into view when created","sha":"7016c042336d154e8e570d268a3031cc170bc0af"}},"sourceBranch":"main","suggestedTargetBranches":["8.12"],"targetPullRequestStates":[{"branch":"8.12","label":"v8.12.0","labelRegex":"^v(\\d+).(\\d+).\\d+$","isSourceBranch":false,"state":"NOT_CREATED"},{"branch":"main","label":"v8.13.0","labelRegex":"^v8.13.0$","isSourceBranch":true,"state":"MERGED","url":"https://github.com/elastic/kibana/pull/173547","number":173547,"mergeCommit":{"message":"[Search] Fix API key flyout bugfixes (#173547)\n\n## Summary\r\n\r\nThis fixes a couple of API key flyout bugfixes:\r\n\r\n- created API key now shows up regardless of where you opened the flyout\r\nfrom\r\n- Header action has a max width of 256px and wraps the cloud ID and\r\nelasticsearch endpoint\r\n- API key is scrolled into view when created","sha":"7016c042336d154e8e570d268a3031cc170bc0af"}}]}] BACKPORT--> Co-authored-by: Sander Philipse <94373878+sphilipse@users.noreply.github.com>
This commit is contained in:
parent
134d51bbdf
commit
34f6840f54
15 changed files with 129 additions and 101 deletions
|
@ -15,18 +15,13 @@ import { i18n } from '@kbn/i18n';
|
||||||
import { LanguageDefinitionSnippetArguments } from '@kbn/search-api-panels';
|
import { LanguageDefinitionSnippetArguments } from '@kbn/search-api-panels';
|
||||||
import { ELASTICSEARCH_URL_PLACEHOLDER } from '@kbn/search-api-panels/constants';
|
import { ELASTICSEARCH_URL_PLACEHOLDER } from '@kbn/search-api-panels/constants';
|
||||||
|
|
||||||
import { Status } from '../../../../../common/types/api';
|
|
||||||
|
|
||||||
import { CreateApiKeyAPILogic } from '../../../enterprise_search_overview/api/create_elasticsearch_api_key_logic';
|
|
||||||
import { FetchApiKeysAPILogic } from '../../../enterprise_search_overview/api/fetch_api_keys_logic';
|
import { FetchApiKeysAPILogic } from '../../../enterprise_search_overview/api/fetch_api_keys_logic';
|
||||||
import { CreateApiKeyFlyout } from '../../../shared/api_key/create_api_key_flyout';
|
import { CreateApiKeyFlyout } from '../../../shared/api_key/create_api_key_flyout';
|
||||||
import { useCloudDetails } from '../../../shared/cloud_details/cloud_details';
|
import { useCloudDetails } from '../../../shared/cloud_details/cloud_details';
|
||||||
import { GettingStarted } from '../../../shared/getting_started/getting_started';
|
import { GettingStarted } from '../../../shared/getting_started/getting_started';
|
||||||
import { KibanaLogic } from '../../../shared/kibana/kibana_logic';
|
|
||||||
import { EnterpriseSearchElasticsearchPageTemplate } from '../layout';
|
import { EnterpriseSearchElasticsearchPageTemplate } from '../layout';
|
||||||
|
|
||||||
export const ElasticsearchGuide = () => {
|
export const ElasticsearchGuide = () => {
|
||||||
const { user } = useValues(KibanaLogic);
|
|
||||||
const cloudContext = useCloudDetails();
|
const cloudContext = useCloudDetails();
|
||||||
const [isFlyoutOpen, setIsFlyoutOpen] = useState(false);
|
const [isFlyoutOpen, setIsFlyoutOpen] = useState(false);
|
||||||
|
|
||||||
|
@ -36,8 +31,6 @@ export const ElasticsearchGuide = () => {
|
||||||
url: cloudContext.elasticsearchUrl || ELASTICSEARCH_URL_PLACEHOLDER,
|
url: cloudContext.elasticsearchUrl || ELASTICSEARCH_URL_PLACEHOLDER,
|
||||||
};
|
};
|
||||||
const { makeRequest } = useActions(FetchApiKeysAPILogic);
|
const { makeRequest } = useActions(FetchApiKeysAPILogic);
|
||||||
const { makeRequest: saveApiKey } = useActions(CreateApiKeyAPILogic);
|
|
||||||
const { error, status } = useValues(CreateApiKeyAPILogic);
|
|
||||||
const { data } = useValues(FetchApiKeysAPILogic);
|
const { data } = useValues(FetchApiKeysAPILogic);
|
||||||
const apiKeys = data?.api_keys || [];
|
const apiKeys = data?.api_keys || [];
|
||||||
|
|
||||||
|
@ -45,15 +38,7 @@ export const ElasticsearchGuide = () => {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<EnterpriseSearchElasticsearchPageTemplate>
|
<EnterpriseSearchElasticsearchPageTemplate>
|
||||||
{isFlyoutOpen && (
|
{isFlyoutOpen && <CreateApiKeyFlyout onClose={() => setIsFlyoutOpen(false)} />}
|
||||||
<CreateApiKeyFlyout
|
|
||||||
error={error?.body?.message}
|
|
||||||
isLoading={status === Status.LOADING}
|
|
||||||
onClose={() => setIsFlyoutOpen(false)}
|
|
||||||
setApiKey={saveApiKey}
|
|
||||||
username={user?.full_name || user?.username || ''}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
<EuiTitle size="l" data-test-subj="elasticsearchGuide">
|
<EuiTitle size="l" data-test-subj="elasticsearchGuide">
|
||||||
<h1>
|
<h1>
|
||||||
{i18n.translate('xpack.enterpriseSearch.content.overview.gettingStarted.pageTitle', {
|
{i18n.translate('xpack.enterpriseSearch.content.overview.gettingStarted.pageTitle', {
|
||||||
|
|
|
@ -30,7 +30,7 @@ import {
|
||||||
INGESTION_METHOD_IDS,
|
INGESTION_METHOD_IDS,
|
||||||
} from '../../../../../common/constants';
|
} from '../../../../../common/constants';
|
||||||
|
|
||||||
import apiLogo from '../../../../assets/images/api_cloud.svg';
|
import apiLogo from '../../../../assets/images/api_image.png';
|
||||||
import fileUploadLogo from '../../../../assets/images/file_upload_logo.svg';
|
import fileUploadLogo from '../../../../assets/images/file_upload_logo.svg';
|
||||||
import sampleDataLogo from '../../../../assets/images/sample_data_logo.svg';
|
import sampleDataLogo from '../../../../assets/images/sample_data_logo.svg';
|
||||||
import connectorLogo from '../../../../assets/images/search_connector.svg';
|
import connectorLogo from '../../../../assets/images/search_connector.svg';
|
||||||
|
|
|
@ -59,7 +59,7 @@ export const ProductSelector: React.FC = () => {
|
||||||
</EuiPageTemplate.Section>
|
</EuiPageTemplate.Section>
|
||||||
|
|
||||||
<EuiPageTemplate.Section color="subdued">
|
<EuiPageTemplate.Section color="subdued">
|
||||||
<ApiKeyPanel user={user} />
|
<ApiKeyPanel />
|
||||||
<EuiSpacer size="xl" />
|
<EuiSpacer size="xl" />
|
||||||
<EuiTitle>
|
<EuiTitle>
|
||||||
<h4>
|
<h4>
|
||||||
|
|
|
@ -26,29 +26,19 @@ import {
|
||||||
import { i18n } from '@kbn/i18n';
|
import { i18n } from '@kbn/i18n';
|
||||||
import { FormattedMessage } from '@kbn/i18n-react';
|
import { FormattedMessage } from '@kbn/i18n-react';
|
||||||
import { ELASTICSEARCH_URL_PLACEHOLDER } from '@kbn/search-api-panels/constants';
|
import { ELASTICSEARCH_URL_PLACEHOLDER } from '@kbn/search-api-panels/constants';
|
||||||
import { AuthenticatedUser } from '@kbn/security-plugin/common';
|
|
||||||
|
|
||||||
import { Status } from '../../../../common/types/api';
|
|
||||||
|
|
||||||
import { CreateApiKeyAPILogic } from '../../enterprise_search_overview/api/create_elasticsearch_api_key_logic';
|
|
||||||
import { FetchApiKeysAPILogic } from '../../enterprise_search_overview/api/fetch_api_keys_logic';
|
import { FetchApiKeysAPILogic } from '../../enterprise_search_overview/api/fetch_api_keys_logic';
|
||||||
import { KibanaLogic } from '../kibana';
|
import { KibanaLogic } from '../kibana';
|
||||||
|
|
||||||
import { CreateApiKeyFlyout } from './create_api_key_flyout';
|
import { CreateApiKeyFlyout } from './create_api_key_flyout';
|
||||||
|
|
||||||
interface ApiKeyPanelProps {
|
|
||||||
user: AuthenticatedUser | null;
|
|
||||||
}
|
|
||||||
|
|
||||||
const COPIED_LABEL = i18n.translate('xpack.enterpriseSearch.overview.apiKey.copied', {
|
const COPIED_LABEL = i18n.translate('xpack.enterpriseSearch.overview.apiKey.copied', {
|
||||||
defaultMessage: 'Copied',
|
defaultMessage: 'Copied',
|
||||||
});
|
});
|
||||||
|
|
||||||
export const ApiKeyPanel: React.FC<ApiKeyPanelProps> = ({ user }) => {
|
export const ApiKeyPanel: React.FC = () => {
|
||||||
const { cloud, navigateToUrl } = useValues(KibanaLogic);
|
const { cloud, navigateToUrl } = useValues(KibanaLogic);
|
||||||
const { makeRequest } = useActions(FetchApiKeysAPILogic);
|
const { makeRequest } = useActions(FetchApiKeysAPILogic);
|
||||||
const { makeRequest: saveApiKey } = useActions(CreateApiKeyAPILogic);
|
|
||||||
const { error, status } = useValues(CreateApiKeyAPILogic);
|
|
||||||
const { data } = useValues(FetchApiKeysAPILogic);
|
const { data } = useValues(FetchApiKeysAPILogic);
|
||||||
const [isFlyoutOpen, setIsFlyoutOpen] = useState(false);
|
const [isFlyoutOpen, setIsFlyoutOpen] = useState(false);
|
||||||
|
|
||||||
|
@ -60,15 +50,7 @@ export const ApiKeyPanel: React.FC<ApiKeyPanelProps> = ({ user }) => {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
{isFlyoutOpen && (
|
{isFlyoutOpen && <CreateApiKeyFlyout onClose={() => setIsFlyoutOpen(false)} />}
|
||||||
<CreateApiKeyFlyout
|
|
||||||
error={error?.body?.message}
|
|
||||||
isLoading={status === Status.LOADING}
|
|
||||||
onClose={() => setIsFlyoutOpen(false)}
|
|
||||||
setApiKey={saveApiKey}
|
|
||||||
username={user?.full_name || user?.username || ''}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
<EuiSplitPanel.Outer>
|
<EuiSplitPanel.Outer>
|
||||||
{Boolean(cloud) && (
|
{Boolean(cloud) && (
|
||||||
<EuiSplitPanel.Inner>
|
<EuiSplitPanel.Inner>
|
||||||
|
|
|
@ -4,10 +4,12 @@
|
||||||
* 2.0; you may not use this file except in compliance with the Elastic License
|
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||||
* 2.0.
|
* 2.0.
|
||||||
*/
|
*/
|
||||||
import React, { useState } from 'react';
|
import React, { useEffect, useRef, useState } from 'react';
|
||||||
|
|
||||||
import { css } from '@emotion/react';
|
import { css } from '@emotion/react';
|
||||||
|
|
||||||
|
import { useValues, useActions } from 'kea';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
useEuiTheme,
|
useEuiTheme,
|
||||||
EuiAccordion,
|
EuiAccordion,
|
||||||
|
@ -31,12 +33,14 @@ import {
|
||||||
EuiText,
|
EuiText,
|
||||||
EuiTitle,
|
EuiTitle,
|
||||||
} from '@elastic/eui';
|
} from '@elastic/eui';
|
||||||
|
|
||||||
import { i18n } from '@kbn/i18n';
|
import { i18n } from '@kbn/i18n';
|
||||||
|
|
||||||
import {
|
import { Status } from '../../../../common/types/api';
|
||||||
CreateAPIKeyArgs,
|
|
||||||
CreateApiKeyResponse,
|
import { CreateApiKeyAPILogic } from '../../enterprise_search_overview/api/create_elasticsearch_api_key_logic';
|
||||||
} from '../../enterprise_search_overview/api/create_elasticsearch_api_key_logic';
|
|
||||||
|
import { KibanaLogic } from '../kibana';
|
||||||
|
|
||||||
import { BasicSetupForm, DEFAULT_EXPIRES_VALUE } from './basic_setup_form';
|
import { BasicSetupForm, DEFAULT_EXPIRES_VALUE } from './basic_setup_form';
|
||||||
import { MetadataForm } from './metadata_form';
|
import { MetadataForm } from './metadata_form';
|
||||||
|
@ -57,12 +61,7 @@ const DEFAULT_METADATA = `{
|
||||||
}`;
|
}`;
|
||||||
|
|
||||||
interface CreateApiKeyFlyoutProps {
|
interface CreateApiKeyFlyoutProps {
|
||||||
createdApiKey?: CreateApiKeyResponse;
|
|
||||||
error?: string;
|
|
||||||
isLoading: boolean;
|
|
||||||
onClose: () => void;
|
onClose: () => void;
|
||||||
setApiKey: (apiKey: CreateAPIKeyArgs) => void;
|
|
||||||
username: string;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export const CANCEL_LABEL: string = i18n.translate('xpack.enterpriseSearch.cancel', {
|
export const CANCEL_LABEL: string = i18n.translate('xpack.enterpriseSearch.cancel', {
|
||||||
|
@ -93,14 +92,7 @@ const INVALID_JSON_ERROR: string = i18n.translate('xpack.enterpriseSearch.invali
|
||||||
defaultMessage: 'Invalid JSON',
|
defaultMessage: 'Invalid JSON',
|
||||||
});
|
});
|
||||||
|
|
||||||
export const CreateApiKeyFlyout: React.FC<CreateApiKeyFlyoutProps> = ({
|
export const CreateApiKeyFlyout: React.FC<CreateApiKeyFlyoutProps> = ({ onClose }) => {
|
||||||
createdApiKey,
|
|
||||||
error,
|
|
||||||
isLoading,
|
|
||||||
onClose,
|
|
||||||
username,
|
|
||||||
setApiKey,
|
|
||||||
}) => {
|
|
||||||
const { euiTheme } = useEuiTheme();
|
const { euiTheme } = useEuiTheme();
|
||||||
const [name, setName] = useState('');
|
const [name, setName] = useState('');
|
||||||
const [expires, setExpires] = useState<string | null>(DEFAULT_EXPIRES_VALUE);
|
const [expires, setExpires] = useState<string | null>(DEFAULT_EXPIRES_VALUE);
|
||||||
|
@ -113,6 +105,14 @@ export const CreateApiKeyFlyout: React.FC<CreateApiKeyFlyoutProps> = ({
|
||||||
const [metadataEnabled, setMetadataEnabled] = useState<boolean>(false);
|
const [metadataEnabled, setMetadataEnabled] = useState<boolean>(false);
|
||||||
const [metadataOpen, setMetadataOpen] = useState<'open' | 'closed'>('closed');
|
const [metadataOpen, setMetadataOpen] = useState<'open' | 'closed'>('closed');
|
||||||
|
|
||||||
|
const { user } = useValues(KibanaLogic);
|
||||||
|
const { makeRequest: saveApiKey, apiReset } = useActions(CreateApiKeyAPILogic);
|
||||||
|
const { data: createdApiKey, error, status } = useValues(CreateApiKeyAPILogic);
|
||||||
|
|
||||||
|
const isLoading = status === Status.LOADING;
|
||||||
|
|
||||||
|
const username = user?.full_name || user?.username || user?.email || '';
|
||||||
|
|
||||||
const togglePrivileges = (e: EuiSwitchEvent) => {
|
const togglePrivileges = (e: EuiSwitchEvent) => {
|
||||||
const enabled = e.target.checked;
|
const enabled = e.target.checked;
|
||||||
setPrivilegesEnabled(enabled);
|
setPrivilegesEnabled(enabled);
|
||||||
|
@ -151,7 +151,7 @@ export const CreateApiKeyFlyout: React.FC<CreateApiKeyFlyoutProps> = ({
|
||||||
if (metadataError) setMetadataError(undefined);
|
if (metadataError) setMetadataError(undefined);
|
||||||
const expiration = expires !== null ? `${expires}d` : undefined;
|
const expiration = expires !== null ? `${expires}d` : undefined;
|
||||||
|
|
||||||
setApiKey({
|
saveApiKey({
|
||||||
expiration,
|
expiration,
|
||||||
metadata: parsedMetadata,
|
metadata: parsedMetadata,
|
||||||
name,
|
name,
|
||||||
|
@ -159,9 +159,22 @@ export const CreateApiKeyFlyout: React.FC<CreateApiKeyFlyoutProps> = ({
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const apiKeyRef = useRef<HTMLDivElement>(null);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (createdApiKey && apiKeyRef) {
|
||||||
|
apiKeyRef.current?.scrollIntoView();
|
||||||
|
}
|
||||||
|
}, [createdApiKey, apiKeyRef]);
|
||||||
|
|
||||||
|
const closeFlyOut = () => {
|
||||||
|
apiReset();
|
||||||
|
onClose();
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<EuiFlyout
|
<EuiFlyout
|
||||||
onClose={onClose}
|
onClose={closeFlyOut}
|
||||||
css={css`
|
css={css`
|
||||||
max-width: calc(${euiTheme.size.xxxxl} * 10);
|
max-width: calc(${euiTheme.size.xxxxl} * 10);
|
||||||
`}
|
`}
|
||||||
|
@ -176,14 +189,11 @@ export const CreateApiKeyFlyout: React.FC<CreateApiKeyFlyoutProps> = ({
|
||||||
</EuiTitle>
|
</EuiTitle>
|
||||||
</EuiFlyoutHeader>
|
</EuiFlyoutHeader>
|
||||||
<EuiFlyoutBody>
|
<EuiFlyoutBody>
|
||||||
|
<div ref={apiKeyRef} />
|
||||||
{createdApiKey && (
|
{createdApiKey && (
|
||||||
<>
|
<>
|
||||||
<EuiPanel
|
<EuiSpacer />
|
||||||
css={css`
|
<EuiPanel color="success" data-test-subj="api-key-create-success-panel">
|
||||||
background-color: transparentize($euiColorSuccess, 0.9);
|
|
||||||
`}
|
|
||||||
data-test-subj="api-key-create-success-panel"
|
|
||||||
>
|
|
||||||
<EuiStep
|
<EuiStep
|
||||||
css={css`
|
css={css`
|
||||||
.euiStep__content {
|
.euiStep__content {
|
||||||
|
@ -221,7 +231,7 @@ export const CreateApiKeyFlyout: React.FC<CreateApiKeyFlyoutProps> = ({
|
||||||
})}
|
})}
|
||||||
data-test-subj="create-api-key-error-callout"
|
data-test-subj="create-api-key-error-callout"
|
||||||
>
|
>
|
||||||
{error}
|
{error.body?.message}
|
||||||
</EuiCallOut>
|
</EuiCallOut>
|
||||||
)}
|
)}
|
||||||
<EuiPanel hasBorder>
|
<EuiPanel hasBorder>
|
||||||
|
@ -384,7 +394,7 @@ export const CreateApiKeyFlyout: React.FC<CreateApiKeyFlyoutProps> = ({
|
||||||
<EuiFlexItem grow={false}>
|
<EuiFlexItem grow={false}>
|
||||||
<EuiButtonEmpty
|
<EuiButtonEmpty
|
||||||
isDisabled={isLoading}
|
isDisabled={isLoading}
|
||||||
onClick={onClose}
|
onClick={closeFlyOut}
|
||||||
data-test-subj="create-api-key-cancel"
|
data-test-subj="create-api-key-cancel"
|
||||||
>
|
>
|
||||||
{CANCEL_LABEL}
|
{CANCEL_LABEL}
|
||||||
|
|
|
@ -7,10 +7,14 @@
|
||||||
|
|
||||||
import { LanguageDefinition } from '@kbn/search-api-panels';
|
import { LanguageDefinition } from '@kbn/search-api-panels';
|
||||||
|
|
||||||
|
import { INDEX_NAME_PLACEHOLDER } from './constants';
|
||||||
|
|
||||||
import { ingestKeysToJSON } from './helpers';
|
import { ingestKeysToJSON } from './helpers';
|
||||||
|
|
||||||
export const consoleDefinition: Partial<LanguageDefinition> = {
|
export const consoleDefinition: Partial<LanguageDefinition> = {
|
||||||
buildSearchQuery: ({ indexName }) => `POST /${indexName ?? 'books'}/_search?pretty
|
buildSearchQuery: ({ indexName = INDEX_NAME_PLACEHOLDER }) => `POST /${
|
||||||
|
indexName ?? 'books'
|
||||||
|
}/_search?pretty
|
||||||
{
|
{
|
||||||
"query": {
|
"query": {
|
||||||
"query_string": {
|
"query_string": {
|
||||||
|
@ -18,7 +22,11 @@ export const consoleDefinition: Partial<LanguageDefinition> = {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}`,
|
}`,
|
||||||
ingestData: ({ indexName, ingestPipeline, extraIngestDocumentValues }) => {
|
ingestData: ({
|
||||||
|
indexName = INDEX_NAME_PLACEHOLDER,
|
||||||
|
ingestPipeline,
|
||||||
|
extraIngestDocumentValues,
|
||||||
|
}) => {
|
||||||
const ingestDocumentKeys = ingestPipeline ? ingestKeysToJSON(extraIngestDocumentValues) : '';
|
const ingestDocumentKeys = ingestPipeline ? ingestKeysToJSON(extraIngestDocumentValues) : '';
|
||||||
return `POST _bulk?pretty${ingestPipeline ? `&pipeline=${ingestPipeline}` : ''}
|
return `POST _bulk?pretty${ingestPipeline ? `&pipeline=${ingestPipeline}` : ''}
|
||||||
{ "index" : { "_index" : "${indexName}" } }
|
{ "index" : { "_index" : "${indexName}" } }
|
||||||
|
|
|
@ -10,10 +10,14 @@ import { Languages, LanguageDefinition } from '@kbn/search-api-panels';
|
||||||
|
|
||||||
import { docLinks } from '../../doc_links';
|
import { docLinks } from '../../doc_links';
|
||||||
|
|
||||||
|
import { INDEX_NAME_PLACEHOLDER } from './constants';
|
||||||
|
|
||||||
import { ingestKeysToJSON } from './helpers';
|
import { ingestKeysToJSON } from './helpers';
|
||||||
|
|
||||||
export const curlDefinition: LanguageDefinition = {
|
export const curlDefinition: LanguageDefinition = {
|
||||||
buildSearchQuery: ({ indexName }) => `curl -X POST "\$\{ES_URL\}/${indexName}/_search?pretty" \\
|
buildSearchQuery: ({
|
||||||
|
indexName = INDEX_NAME_PLACEHOLDER,
|
||||||
|
}) => `curl -X POST "\$\{ES_URL\}/${indexName}/_search?pretty" \\
|
||||||
-H "Authorization: ApiKey "\$\{API_KEY\}"" \\
|
-H "Authorization: ApiKey "\$\{API_KEY\}"" \\
|
||||||
-H "Content-Type: application/json" \\
|
-H "Content-Type: application/json" \\
|
||||||
-d'
|
-d'
|
||||||
|
@ -35,7 +39,11 @@ export API_KEY="${apiKey}"`,
|
||||||
},
|
},
|
||||||
iconType: 'curl.svg',
|
iconType: 'curl.svg',
|
||||||
id: Languages.CURL,
|
id: Languages.CURL,
|
||||||
ingestData: ({ indexName, ingestPipeline, extraIngestDocumentValues }) => {
|
ingestData: ({
|
||||||
|
indexName = INDEX_NAME_PLACEHOLDER,
|
||||||
|
ingestPipeline,
|
||||||
|
extraIngestDocumentValues,
|
||||||
|
}) => {
|
||||||
const ingestDocumentKeys = ingestPipeline ? ingestKeysToJSON(extraIngestDocumentValues) : '';
|
const ingestDocumentKeys = ingestPipeline ? ingestKeysToJSON(extraIngestDocumentValues) : '';
|
||||||
return `curl -X POST "\$\{ES_URL\}/_bulk?pretty${
|
return `curl -X POST "\$\{ES_URL\}/_bulk?pretty${
|
||||||
ingestPipeline ? `&pipeline=${ingestPipeline}` : ''
|
ingestPipeline ? `&pipeline=${ingestPipeline}` : ''
|
||||||
|
@ -67,7 +75,7 @@ brew install curl`,
|
||||||
defaultMessage: 'cURL',
|
defaultMessage: 'cURL',
|
||||||
}),
|
}),
|
||||||
languageStyling: 'shell',
|
languageStyling: 'shell',
|
||||||
testConnection: ({ indexName }) => `curl "\$\{ES_URL\}/${indexName}" \\
|
testConnection: ({ indexName = INDEX_NAME_PLACEHOLDER }) => `curl "\$\{ES_URL\}/${indexName}" \\
|
||||||
-H "Authorization: ApiKey "\$\{API_KEY\}"" \\
|
-H "Authorization: ApiKey "\$\{API_KEY\}"" \\
|
||||||
-H "Content-Type: application/json"`,
|
-H "Content-Type: application/json"`,
|
||||||
};
|
};
|
||||||
|
|
|
@ -10,10 +10,12 @@ import { Languages, LanguageDefinition } from '@kbn/search-api-panels';
|
||||||
|
|
||||||
import { docLinks } from '../../doc_links';
|
import { docLinks } from '../../doc_links';
|
||||||
|
|
||||||
|
import { INDEX_NAME_PLACEHOLDER } from './constants';
|
||||||
|
|
||||||
import { ingestKeysToJSON } from './helpers';
|
import { ingestKeysToJSON } from './helpers';
|
||||||
|
|
||||||
export const goDefinition: LanguageDefinition = {
|
export const goDefinition: LanguageDefinition = {
|
||||||
buildSearchQuery: ({ indexName }) => `searchResp, err := es.Search(
|
buildSearchQuery: ({ indexName = INDEX_NAME_PLACEHOLDER }) => `searchResp, err := es.Search(
|
||||||
es.Search.WithContext(context.Background()),
|
es.Search.WithContext(context.Background()),
|
||||||
es.Search.WithIndex("${indexName}"),
|
es.Search.WithIndex("${indexName}"),
|
||||||
es.Search.WithQuery("snow"),
|
es.Search.WithQuery("snow"),
|
||||||
|
@ -58,7 +60,11 @@ if err != nil {
|
||||||
},
|
},
|
||||||
iconType: 'go.svg',
|
iconType: 'go.svg',
|
||||||
id: Languages.GO,
|
id: Languages.GO,
|
||||||
ingestData: ({ indexName, ingestPipeline, extraIngestDocumentValues }) => {
|
ingestData: ({
|
||||||
|
indexName = INDEX_NAME_PLACEHOLDER,
|
||||||
|
ingestPipeline,
|
||||||
|
extraIngestDocumentValues,
|
||||||
|
}) => {
|
||||||
const ingestDocumentKeys = ingestPipeline ? ingestKeysToJSON(extraIngestDocumentValues) : '';
|
const ingestDocumentKeys = ingestPipeline ? ingestKeysToJSON(extraIngestDocumentValues) : '';
|
||||||
return `buf := bytes.NewBufferString(\`
|
return `buf := bytes.NewBufferString(\`
|
||||||
{"index":{"_id":"9780553351927"}}
|
{"index":{"_id":"9780553351927"}}
|
||||||
|
|
|
@ -10,10 +10,12 @@ import { Languages, LanguageDefinition } from '@kbn/search-api-panels';
|
||||||
|
|
||||||
import { docLinks } from '../../doc_links';
|
import { docLinks } from '../../doc_links';
|
||||||
|
|
||||||
|
import { INDEX_NAME_PLACEHOLDER } from './constants';
|
||||||
|
|
||||||
import { ingestKeysToJSON } from './helpers';
|
import { ingestKeysToJSON } from './helpers';
|
||||||
|
|
||||||
export const javascriptDefinition: LanguageDefinition = {
|
export const javascriptDefinition: LanguageDefinition = {
|
||||||
buildSearchQuery: ({ indexName }) => `// Let's search!
|
buildSearchQuery: ({ indexName = INDEX_NAME_PLACEHOLDER }) => `// Let's search!
|
||||||
const searchResult = await client.search({
|
const searchResult = await client.search({
|
||||||
index: '${indexName}',
|
index: '${indexName}',
|
||||||
q: 'snow'
|
q: 'snow'
|
||||||
|
@ -37,7 +39,11 @@ const client = new Client({
|
||||||
},
|
},
|
||||||
iconType: 'javascript.svg',
|
iconType: 'javascript.svg',
|
||||||
id: Languages.JAVASCRIPT,
|
id: Languages.JAVASCRIPT,
|
||||||
ingestData: ({ indexName, ingestPipeline, extraIngestDocumentValues }) => {
|
ingestData: ({
|
||||||
|
indexName = INDEX_NAME_PLACEHOLDER,
|
||||||
|
ingestPipeline,
|
||||||
|
extraIngestDocumentValues,
|
||||||
|
}) => {
|
||||||
const ingestDocumentKeys = ingestPipeline ? ingestKeysToJSON(extraIngestDocumentValues) : '';
|
const ingestDocumentKeys = ingestPipeline ? ingestKeysToJSON(extraIngestDocumentValues) : '';
|
||||||
return `// Sample data books
|
return `// Sample data books
|
||||||
const dataset = [
|
const dataset = [
|
||||||
|
|
|
@ -10,10 +10,12 @@ import { Languages, LanguageDefinition } from '@kbn/search-api-panels';
|
||||||
|
|
||||||
import { docLinks } from '../../doc_links';
|
import { docLinks } from '../../doc_links';
|
||||||
|
|
||||||
|
import { INDEX_NAME_PLACEHOLDER } from './constants';
|
||||||
|
|
||||||
import { ingestKeysToPHP } from './helpers';
|
import { ingestKeysToPHP } from './helpers';
|
||||||
|
|
||||||
export const phpDefinition: LanguageDefinition = {
|
export const phpDefinition: LanguageDefinition = {
|
||||||
buildSearchQuery: ({ indexName }) => `$params = [
|
buildSearchQuery: ({ indexName = INDEX_NAME_PLACEHOLDER }) => `$params = [
|
||||||
'index' => '${indexName}',
|
'index' => '${indexName}',
|
||||||
'body' => [
|
'body' => [
|
||||||
'q' => 'snow'
|
'q' => 'snow'
|
||||||
|
@ -35,7 +37,11 @@ print_r($response->asArray());`,
|
||||||
},
|
},
|
||||||
iconType: 'php.svg',
|
iconType: 'php.svg',
|
||||||
id: Languages.PHP,
|
id: Languages.PHP,
|
||||||
ingestData: ({ indexName, ingestPipeline, extraIngestDocumentValues }) => {
|
ingestData: ({
|
||||||
|
indexName = INDEX_NAME_PLACEHOLDER,
|
||||||
|
ingestPipeline,
|
||||||
|
extraIngestDocumentValues,
|
||||||
|
}) => {
|
||||||
const ingestDocumentKeys = ingestPipeline ? ingestKeysToPHP(extraIngestDocumentValues) : '';
|
const ingestDocumentKeys = ingestPipeline ? ingestKeysToPHP(extraIngestDocumentValues) : '';
|
||||||
return `$params = [${ingestPipeline ? `\n 'pipeline' => '${ingestPipeline}',` : ''}
|
return `$params = [${ingestPipeline ? `\n 'pipeline' => '${ingestPipeline}',` : ''}
|
||||||
'body' => [
|
'body' => [
|
||||||
|
|
|
@ -10,10 +10,13 @@ import { Languages, LanguageDefinition } from '@kbn/search-api-panels';
|
||||||
|
|
||||||
import { docLinks } from '../../doc_links';
|
import { docLinks } from '../../doc_links';
|
||||||
|
|
||||||
|
import { INDEX_NAME_PLACEHOLDER } from './constants';
|
||||||
|
|
||||||
import { ingestKeysToJSON } from './helpers';
|
import { ingestKeysToJSON } from './helpers';
|
||||||
|
|
||||||
export const pythonDefinition: LanguageDefinition = {
|
export const pythonDefinition: LanguageDefinition = {
|
||||||
buildSearchQuery: ({ indexName }) => `client.search(index="${indexName}", q="snow")`,
|
buildSearchQuery: ({ indexName = INDEX_NAME_PLACEHOLDER }) =>
|
||||||
|
`client.search(index="${indexName}", q="snow")`,
|
||||||
configureClient: ({ url, apiKey }) => `from elasticsearch import Elasticsearch
|
configureClient: ({ url, apiKey }) => `from elasticsearch import Elasticsearch
|
||||||
|
|
||||||
client = Elasticsearch(
|
client = Elasticsearch(
|
||||||
|
@ -29,7 +32,11 @@ client = Elasticsearch(
|
||||||
},
|
},
|
||||||
iconType: 'python.svg',
|
iconType: 'python.svg',
|
||||||
id: Languages.PYTHON,
|
id: Languages.PYTHON,
|
||||||
ingestData: ({ indexName, ingestPipeline, extraIngestDocumentValues }) => {
|
ingestData: ({
|
||||||
|
indexName = INDEX_NAME_PLACEHOLDER,
|
||||||
|
ingestPipeline,
|
||||||
|
extraIngestDocumentValues,
|
||||||
|
}) => {
|
||||||
const ingestDocumentKeys = ingestPipeline ? ingestKeysToJSON(extraIngestDocumentValues) : '';
|
const ingestDocumentKeys = ingestPipeline ? ingestKeysToJSON(extraIngestDocumentValues) : '';
|
||||||
return `documents = [
|
return `documents = [
|
||||||
{ "index": { "_index": "${indexName}", "_id": "9780553351927"}},
|
{ "index": { "_index": "${indexName}", "_id": "9780553351927"}},
|
||||||
|
|
|
@ -10,10 +10,13 @@ import { Languages, LanguageDefinition } from '@kbn/search-api-panels';
|
||||||
|
|
||||||
import { docLinks } from '../../doc_links';
|
import { docLinks } from '../../doc_links';
|
||||||
|
|
||||||
|
import { INDEX_NAME_PLACEHOLDER } from './constants';
|
||||||
|
|
||||||
import { ingestKeysToRuby } from './helpers';
|
import { ingestKeysToRuby } from './helpers';
|
||||||
|
|
||||||
export const rubyDefinition: LanguageDefinition = {
|
export const rubyDefinition: LanguageDefinition = {
|
||||||
buildSearchQuery: ({ indexName }) => `client.search(index: '${indexName}', q: 'snow')`,
|
buildSearchQuery: ({ indexName = INDEX_NAME_PLACEHOLDER }) =>
|
||||||
|
`client.search(index: '${indexName}', q: 'snow')`,
|
||||||
configureClient: ({ url, apiKey, cloudId }) => `client = Elasticsearch::Client.new(
|
configureClient: ({ url, apiKey, cloudId }) => `client = Elasticsearch::Client.new(
|
||||||
api_key: '${apiKey}',
|
api_key: '${apiKey}',
|
||||||
${cloudId ? `cloud_id: ${cloudId},` : `url: '${url}',`}
|
${cloudId ? `cloud_id: ${cloudId},` : `url: '${url}',`}
|
||||||
|
@ -28,7 +31,11 @@ export const rubyDefinition: LanguageDefinition = {
|
||||||
},
|
},
|
||||||
iconType: 'ruby.svg',
|
iconType: 'ruby.svg',
|
||||||
id: Languages.RUBY,
|
id: Languages.RUBY,
|
||||||
ingestData: ({ indexName, ingestPipeline, extraIngestDocumentValues }) => {
|
ingestData: ({
|
||||||
|
indexName = INDEX_NAME_PLACEHOLDER,
|
||||||
|
ingestPipeline,
|
||||||
|
extraIngestDocumentValues,
|
||||||
|
}) => {
|
||||||
const ingestDocumentKeys = ingestPipeline ? ingestKeysToRuby(extraIngestDocumentValues) : '';
|
const ingestDocumentKeys = ingestPipeline ? ingestKeysToRuby(extraIngestDocumentValues) : '';
|
||||||
return `documents = [
|
return `documents = [
|
||||||
{ index: { _index: '${indexName}', data: {name: "Snow Crash", author: "Neal Stephenson", release_date: "1992-06-01", page_count: 470${ingestDocumentKeys}} } },
|
{ index: { _index: '${indexName}', data: {name: "Snow Crash", author: "Neal Stephenson", release_date: "1992-06-01", page_count: 470${ingestDocumentKeys}} } },
|
||||||
|
|
|
@ -37,8 +37,8 @@ export const AddDataPanelContent: React.FC<AddDataPanelContentProps> = ({
|
||||||
return (
|
return (
|
||||||
<CodeBox
|
<CodeBox
|
||||||
languages={languageDefinitions}
|
languages={languageDefinitions}
|
||||||
codeSnippet={getLanguageDefinitionCodeSnippet(selectedLanguage, 'testConnection', codeArgs)}
|
codeSnippet={getLanguageDefinitionCodeSnippet(selectedLanguage, 'ingestData', codeArgs)}
|
||||||
consoleRequest={getConsoleRequest('testConnection')}
|
consoleRequest={getConsoleRequest('ingestData')}
|
||||||
selectedLanguage={selectedLanguage}
|
selectedLanguage={selectedLanguage}
|
||||||
setSelectedLanguage={setSelectedLanguage}
|
setSelectedLanguage={setSelectedLanguage}
|
||||||
assetBasePath={assetBasePath}
|
assetBasePath={assetBasePath}
|
||||||
|
|
|
@ -9,6 +9,7 @@ import React from 'react';
|
||||||
|
|
||||||
import { useState, useEffect } from 'react';
|
import { useState, useEffect } from 'react';
|
||||||
|
|
||||||
|
import { css } from '@emotion/react';
|
||||||
import { useValues, useActions } from 'kea';
|
import { useValues, useActions } from 'kea';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
|
@ -27,15 +28,13 @@ import {
|
||||||
EuiHorizontalRule,
|
EuiHorizontalRule,
|
||||||
EuiButton,
|
EuiButton,
|
||||||
EuiHeaderLinks,
|
EuiHeaderLinks,
|
||||||
|
useEuiTheme,
|
||||||
} from '@elastic/eui';
|
} from '@elastic/eui';
|
||||||
|
|
||||||
import { i18n } from '@kbn/i18n';
|
import { i18n } from '@kbn/i18n';
|
||||||
import { FormattedMessage } from '@kbn/i18n-react';
|
import { FormattedMessage } from '@kbn/i18n-react';
|
||||||
import { ELASTICSEARCH_URL_PLACEHOLDER } from '@kbn/search-api-panels/constants';
|
import { ELASTICSEARCH_URL_PLACEHOLDER } from '@kbn/search-api-panels/constants';
|
||||||
|
|
||||||
import { Status } from '../../../../common/types/api';
|
|
||||||
|
|
||||||
import { CreateApiKeyAPILogic } from '../../enterprise_search_overview/api/create_elasticsearch_api_key_logic';
|
|
||||||
import { FetchApiKeysAPILogic } from '../../enterprise_search_overview/api/fetch_api_keys_logic';
|
import { FetchApiKeysAPILogic } from '../../enterprise_search_overview/api/fetch_api_keys_logic';
|
||||||
import { CreateApiKeyFlyout } from '../api_key/create_api_key_flyout';
|
import { CreateApiKeyFlyout } from '../api_key/create_api_key_flyout';
|
||||||
import { KibanaLogic } from '../kibana';
|
import { KibanaLogic } from '../kibana';
|
||||||
|
@ -48,9 +47,7 @@ export const EndpointsHeaderAction: React.FC = ({ children }) => {
|
||||||
const { makeRequest } = useActions(FetchApiKeysAPILogic);
|
const { makeRequest } = useActions(FetchApiKeysAPILogic);
|
||||||
const { data } = useValues(FetchApiKeysAPILogic);
|
const { data } = useValues(FetchApiKeysAPILogic);
|
||||||
const [isFlyoutOpen, setIsFlyoutOpen] = useState(false);
|
const [isFlyoutOpen, setIsFlyoutOpen] = useState(false);
|
||||||
const { user } = useValues(KibanaLogic);
|
const { euiTheme } = useEuiTheme();
|
||||||
const { makeRequest: saveApiKey } = useActions(CreateApiKeyAPILogic);
|
|
||||||
const { data: apiKey, error, status } = useValues(CreateApiKeyAPILogic);
|
|
||||||
|
|
||||||
useEffect(() => makeRequest({}), []);
|
useEffect(() => makeRequest({}), []);
|
||||||
|
|
||||||
|
@ -75,16 +72,7 @@ export const EndpointsHeaderAction: React.FC = ({ children }) => {
|
||||||
<EuiFlexGroup alignItems="center" gutterSize="s">
|
<EuiFlexGroup alignItems="center" gutterSize="s">
|
||||||
{Boolean(children) && <EuiFlexItem>{children}</EuiFlexItem>}
|
{Boolean(children) && <EuiFlexItem>{children}</EuiFlexItem>}
|
||||||
<EuiFlexItem>
|
<EuiFlexItem>
|
||||||
{isFlyoutOpen && (
|
{isFlyoutOpen && <CreateApiKeyFlyout onClose={() => setIsFlyoutOpen(false)} />}
|
||||||
<CreateApiKeyFlyout
|
|
||||||
createdApiKey={apiKey}
|
|
||||||
error={error?.body?.message}
|
|
||||||
isLoading={status === Status.LOADING}
|
|
||||||
onClose={() => setIsFlyoutOpen(false)}
|
|
||||||
setApiKey={saveApiKey}
|
|
||||||
username={user?.full_name || user?.username || ''}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
<EuiPopover
|
<EuiPopover
|
||||||
button={button}
|
button={button}
|
||||||
isOpen={isPopoverOpen}
|
isOpen={isPopoverOpen}
|
||||||
|
@ -93,6 +81,9 @@ export const EndpointsHeaderAction: React.FC = ({ children }) => {
|
||||||
anchorPosition="downLeft"
|
anchorPosition="downLeft"
|
||||||
>
|
>
|
||||||
<EuiContextMenuPanel
|
<EuiContextMenuPanel
|
||||||
|
css={css`
|
||||||
|
max-width: calc(${euiTheme.size.xxxxl} * 4);
|
||||||
|
`}
|
||||||
items={[
|
items={[
|
||||||
<EuiContextMenuItem key="endpoint">
|
<EuiContextMenuItem key="endpoint">
|
||||||
<EuiText size="s">
|
<EuiText size="s">
|
||||||
|
@ -107,7 +98,13 @@ export const EndpointsHeaderAction: React.FC = ({ children }) => {
|
||||||
|
|
||||||
<EuiFlexGroup gutterSize="s" justifyContent="flexEnd" alignItems="center">
|
<EuiFlexGroup gutterSize="s" justifyContent="flexEnd" alignItems="center">
|
||||||
<EuiFlexItem>
|
<EuiFlexItem>
|
||||||
<EuiCode>{elasticsearchEndpoint}</EuiCode>
|
<EuiCode
|
||||||
|
css={css`
|
||||||
|
overflow-wrap: anywhere;
|
||||||
|
`}
|
||||||
|
>
|
||||||
|
{elasticsearchEndpoint}
|
||||||
|
</EuiCode>
|
||||||
</EuiFlexItem>
|
</EuiFlexItem>
|
||||||
<EuiFlexItem grow={false}>
|
<EuiFlexItem grow={false}>
|
||||||
<EuiCopy textToCopy={elasticsearchEndpoint || ''} afterMessage={COPIED_LABEL}>
|
<EuiCopy textToCopy={elasticsearchEndpoint || ''} afterMessage={COPIED_LABEL}>
|
||||||
|
@ -139,7 +136,13 @@ export const EndpointsHeaderAction: React.FC = ({ children }) => {
|
||||||
|
|
||||||
<EuiFlexGroup gutterSize="s" justifyContent="flexEnd" alignItems="center">
|
<EuiFlexGroup gutterSize="s" justifyContent="flexEnd" alignItems="center">
|
||||||
<EuiFlexItem>
|
<EuiFlexItem>
|
||||||
<EuiCode>{cloudId}</EuiCode>
|
<EuiCode
|
||||||
|
css={css`
|
||||||
|
overflow-wrap: anywhere;
|
||||||
|
`}
|
||||||
|
>
|
||||||
|
{cloudId}
|
||||||
|
</EuiCode>
|
||||||
</EuiFlexItem>
|
</EuiFlexItem>
|
||||||
<EuiFlexItem grow={false}>
|
<EuiFlexItem grow={false}>
|
||||||
<EuiCopy textToCopy={cloudId || ''} afterMessage={COPIED_LABEL}>
|
<EuiCopy textToCopy={cloudId || ''} afterMessage={COPIED_LABEL}>
|
||||||
|
|
Binary file not shown.
After Width: | Height: | Size: 11 KiB |
Loading…
Add table
Add a link
Reference in a new issue