mirror of
https://github.com/elastic/kibana.git
synced 2025-04-23 17:28:26 -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 { 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 { CreateApiKeyFlyout } from '../../../shared/api_key/create_api_key_flyout';
|
||||
import { useCloudDetails } from '../../../shared/cloud_details/cloud_details';
|
||||
import { GettingStarted } from '../../../shared/getting_started/getting_started';
|
||||
import { KibanaLogic } from '../../../shared/kibana/kibana_logic';
|
||||
import { EnterpriseSearchElasticsearchPageTemplate } from '../layout';
|
||||
|
||||
export const ElasticsearchGuide = () => {
|
||||
const { user } = useValues(KibanaLogic);
|
||||
const cloudContext = useCloudDetails();
|
||||
const [isFlyoutOpen, setIsFlyoutOpen] = useState(false);
|
||||
|
||||
|
@ -36,8 +31,6 @@ export const ElasticsearchGuide = () => {
|
|||
url: cloudContext.elasticsearchUrl || ELASTICSEARCH_URL_PLACEHOLDER,
|
||||
};
|
||||
const { makeRequest } = useActions(FetchApiKeysAPILogic);
|
||||
const { makeRequest: saveApiKey } = useActions(CreateApiKeyAPILogic);
|
||||
const { error, status } = useValues(CreateApiKeyAPILogic);
|
||||
const { data } = useValues(FetchApiKeysAPILogic);
|
||||
const apiKeys = data?.api_keys || [];
|
||||
|
||||
|
@ -45,15 +38,7 @@ export const ElasticsearchGuide = () => {
|
|||
|
||||
return (
|
||||
<EnterpriseSearchElasticsearchPageTemplate>
|
||||
{isFlyoutOpen && (
|
||||
<CreateApiKeyFlyout
|
||||
error={error?.body?.message}
|
||||
isLoading={status === Status.LOADING}
|
||||
onClose={() => setIsFlyoutOpen(false)}
|
||||
setApiKey={saveApiKey}
|
||||
username={user?.full_name || user?.username || ''}
|
||||
/>
|
||||
)}
|
||||
{isFlyoutOpen && <CreateApiKeyFlyout onClose={() => setIsFlyoutOpen(false)} />}
|
||||
<EuiTitle size="l" data-test-subj="elasticsearchGuide">
|
||||
<h1>
|
||||
{i18n.translate('xpack.enterpriseSearch.content.overview.gettingStarted.pageTitle', {
|
||||
|
|
|
@ -30,7 +30,7 @@ import {
|
|||
INGESTION_METHOD_IDS,
|
||||
} 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 sampleDataLogo from '../../../../assets/images/sample_data_logo.svg';
|
||||
import connectorLogo from '../../../../assets/images/search_connector.svg';
|
||||
|
|
|
@ -59,7 +59,7 @@ export const ProductSelector: React.FC = () => {
|
|||
</EuiPageTemplate.Section>
|
||||
|
||||
<EuiPageTemplate.Section color="subdued">
|
||||
<ApiKeyPanel user={user} />
|
||||
<ApiKeyPanel />
|
||||
<EuiSpacer size="xl" />
|
||||
<EuiTitle>
|
||||
<h4>
|
||||
|
|
|
@ -26,29 +26,19 @@ import {
|
|||
import { i18n } from '@kbn/i18n';
|
||||
import { FormattedMessage } from '@kbn/i18n-react';
|
||||
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 { KibanaLogic } from '../kibana';
|
||||
|
||||
import { CreateApiKeyFlyout } from './create_api_key_flyout';
|
||||
|
||||
interface ApiKeyPanelProps {
|
||||
user: AuthenticatedUser | null;
|
||||
}
|
||||
|
||||
const COPIED_LABEL = i18n.translate('xpack.enterpriseSearch.overview.apiKey.copied', {
|
||||
defaultMessage: 'Copied',
|
||||
});
|
||||
|
||||
export const ApiKeyPanel: React.FC<ApiKeyPanelProps> = ({ user }) => {
|
||||
export const ApiKeyPanel: React.FC = () => {
|
||||
const { cloud, navigateToUrl } = useValues(KibanaLogic);
|
||||
const { makeRequest } = useActions(FetchApiKeysAPILogic);
|
||||
const { makeRequest: saveApiKey } = useActions(CreateApiKeyAPILogic);
|
||||
const { error, status } = useValues(CreateApiKeyAPILogic);
|
||||
const { data } = useValues(FetchApiKeysAPILogic);
|
||||
const [isFlyoutOpen, setIsFlyoutOpen] = useState(false);
|
||||
|
||||
|
@ -60,15 +50,7 @@ export const ApiKeyPanel: React.FC<ApiKeyPanelProps> = ({ user }) => {
|
|||
|
||||
return (
|
||||
<>
|
||||
{isFlyoutOpen && (
|
||||
<CreateApiKeyFlyout
|
||||
error={error?.body?.message}
|
||||
isLoading={status === Status.LOADING}
|
||||
onClose={() => setIsFlyoutOpen(false)}
|
||||
setApiKey={saveApiKey}
|
||||
username={user?.full_name || user?.username || ''}
|
||||
/>
|
||||
)}
|
||||
{isFlyoutOpen && <CreateApiKeyFlyout onClose={() => setIsFlyoutOpen(false)} />}
|
||||
<EuiSplitPanel.Outer>
|
||||
{Boolean(cloud) && (
|
||||
<EuiSplitPanel.Inner>
|
||||
|
|
|
@ -4,10 +4,12 @@
|
|||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
import React, { useState } from 'react';
|
||||
import React, { useEffect, useRef, useState } from 'react';
|
||||
|
||||
import { css } from '@emotion/react';
|
||||
|
||||
import { useValues, useActions } from 'kea';
|
||||
|
||||
import {
|
||||
useEuiTheme,
|
||||
EuiAccordion,
|
||||
|
@ -31,12 +33,14 @@ import {
|
|||
EuiText,
|
||||
EuiTitle,
|
||||
} from '@elastic/eui';
|
||||
|
||||
import { i18n } from '@kbn/i18n';
|
||||
|
||||
import {
|
||||
CreateAPIKeyArgs,
|
||||
CreateApiKeyResponse,
|
||||
} from '../../enterprise_search_overview/api/create_elasticsearch_api_key_logic';
|
||||
import { Status } from '../../../../common/types/api';
|
||||
|
||||
import { CreateApiKeyAPILogic } from '../../enterprise_search_overview/api/create_elasticsearch_api_key_logic';
|
||||
|
||||
import { KibanaLogic } from '../kibana';
|
||||
|
||||
import { BasicSetupForm, DEFAULT_EXPIRES_VALUE } from './basic_setup_form';
|
||||
import { MetadataForm } from './metadata_form';
|
||||
|
@ -57,12 +61,7 @@ const DEFAULT_METADATA = `{
|
|||
}`;
|
||||
|
||||
interface CreateApiKeyFlyoutProps {
|
||||
createdApiKey?: CreateApiKeyResponse;
|
||||
error?: string;
|
||||
isLoading: boolean;
|
||||
onClose: () => void;
|
||||
setApiKey: (apiKey: CreateAPIKeyArgs) => void;
|
||||
username: string;
|
||||
}
|
||||
|
||||
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',
|
||||
});
|
||||
|
||||
export const CreateApiKeyFlyout: React.FC<CreateApiKeyFlyoutProps> = ({
|
||||
createdApiKey,
|
||||
error,
|
||||
isLoading,
|
||||
onClose,
|
||||
username,
|
||||
setApiKey,
|
||||
}) => {
|
||||
export const CreateApiKeyFlyout: React.FC<CreateApiKeyFlyoutProps> = ({ onClose }) => {
|
||||
const { euiTheme } = useEuiTheme();
|
||||
const [name, setName] = useState('');
|
||||
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 [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 enabled = e.target.checked;
|
||||
setPrivilegesEnabled(enabled);
|
||||
|
@ -151,7 +151,7 @@ export const CreateApiKeyFlyout: React.FC<CreateApiKeyFlyoutProps> = ({
|
|||
if (metadataError) setMetadataError(undefined);
|
||||
const expiration = expires !== null ? `${expires}d` : undefined;
|
||||
|
||||
setApiKey({
|
||||
saveApiKey({
|
||||
expiration,
|
||||
metadata: parsedMetadata,
|
||||
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 (
|
||||
<EuiFlyout
|
||||
onClose={onClose}
|
||||
onClose={closeFlyOut}
|
||||
css={css`
|
||||
max-width: calc(${euiTheme.size.xxxxl} * 10);
|
||||
`}
|
||||
|
@ -176,14 +189,11 @@ export const CreateApiKeyFlyout: React.FC<CreateApiKeyFlyoutProps> = ({
|
|||
</EuiTitle>
|
||||
</EuiFlyoutHeader>
|
||||
<EuiFlyoutBody>
|
||||
<div ref={apiKeyRef} />
|
||||
{createdApiKey && (
|
||||
<>
|
||||
<EuiPanel
|
||||
css={css`
|
||||
background-color: transparentize($euiColorSuccess, 0.9);
|
||||
`}
|
||||
data-test-subj="api-key-create-success-panel"
|
||||
>
|
||||
<EuiSpacer />
|
||||
<EuiPanel color="success" data-test-subj="api-key-create-success-panel">
|
||||
<EuiStep
|
||||
css={css`
|
||||
.euiStep__content {
|
||||
|
@ -221,7 +231,7 @@ export const CreateApiKeyFlyout: React.FC<CreateApiKeyFlyoutProps> = ({
|
|||
})}
|
||||
data-test-subj="create-api-key-error-callout"
|
||||
>
|
||||
{error}
|
||||
{error.body?.message}
|
||||
</EuiCallOut>
|
||||
)}
|
||||
<EuiPanel hasBorder>
|
||||
|
@ -384,7 +394,7 @@ export const CreateApiKeyFlyout: React.FC<CreateApiKeyFlyoutProps> = ({
|
|||
<EuiFlexItem grow={false}>
|
||||
<EuiButtonEmpty
|
||||
isDisabled={isLoading}
|
||||
onClick={onClose}
|
||||
onClick={closeFlyOut}
|
||||
data-test-subj="create-api-key-cancel"
|
||||
>
|
||||
{CANCEL_LABEL}
|
||||
|
|
|
@ -7,10 +7,14 @@
|
|||
|
||||
import { LanguageDefinition } from '@kbn/search-api-panels';
|
||||
|
||||
import { INDEX_NAME_PLACEHOLDER } from './constants';
|
||||
|
||||
import { ingestKeysToJSON } from './helpers';
|
||||
|
||||
export const consoleDefinition: Partial<LanguageDefinition> = {
|
||||
buildSearchQuery: ({ indexName }) => `POST /${indexName ?? 'books'}/_search?pretty
|
||||
buildSearchQuery: ({ indexName = INDEX_NAME_PLACEHOLDER }) => `POST /${
|
||||
indexName ?? 'books'
|
||||
}/_search?pretty
|
||||
{
|
||||
"query": {
|
||||
"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) : '';
|
||||
return `POST _bulk?pretty${ingestPipeline ? `&pipeline=${ingestPipeline}` : ''}
|
||||
{ "index" : { "_index" : "${indexName}" } }
|
||||
|
|
|
@ -10,10 +10,14 @@ import { Languages, LanguageDefinition } from '@kbn/search-api-panels';
|
|||
|
||||
import { docLinks } from '../../doc_links';
|
||||
|
||||
import { INDEX_NAME_PLACEHOLDER } from './constants';
|
||||
|
||||
import { ingestKeysToJSON } from './helpers';
|
||||
|
||||
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 "Content-Type: application/json" \\
|
||||
-d'
|
||||
|
@ -35,7 +39,11 @@ export API_KEY="${apiKey}"`,
|
|||
},
|
||||
iconType: 'curl.svg',
|
||||
id: Languages.CURL,
|
||||
ingestData: ({ indexName, ingestPipeline, extraIngestDocumentValues }) => {
|
||||
ingestData: ({
|
||||
indexName = INDEX_NAME_PLACEHOLDER,
|
||||
ingestPipeline,
|
||||
extraIngestDocumentValues,
|
||||
}) => {
|
||||
const ingestDocumentKeys = ingestPipeline ? ingestKeysToJSON(extraIngestDocumentValues) : '';
|
||||
return `curl -X POST "\$\{ES_URL\}/_bulk?pretty${
|
||||
ingestPipeline ? `&pipeline=${ingestPipeline}` : ''
|
||||
|
@ -67,7 +75,7 @@ brew install curl`,
|
|||
defaultMessage: 'cURL',
|
||||
}),
|
||||
languageStyling: 'shell',
|
||||
testConnection: ({ indexName }) => `curl "\$\{ES_URL\}/${indexName}" \\
|
||||
testConnection: ({ indexName = INDEX_NAME_PLACEHOLDER }) => `curl "\$\{ES_URL\}/${indexName}" \\
|
||||
-H "Authorization: ApiKey "\$\{API_KEY\}"" \\
|
||||
-H "Content-Type: application/json"`,
|
||||
};
|
||||
|
|
|
@ -10,10 +10,12 @@ import { Languages, LanguageDefinition } from '@kbn/search-api-panels';
|
|||
|
||||
import { docLinks } from '../../doc_links';
|
||||
|
||||
import { INDEX_NAME_PLACEHOLDER } from './constants';
|
||||
|
||||
import { ingestKeysToJSON } from './helpers';
|
||||
|
||||
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.WithIndex("${indexName}"),
|
||||
es.Search.WithQuery("snow"),
|
||||
|
@ -58,7 +60,11 @@ if err != nil {
|
|||
},
|
||||
iconType: 'go.svg',
|
||||
id: Languages.GO,
|
||||
ingestData: ({ indexName, ingestPipeline, extraIngestDocumentValues }) => {
|
||||
ingestData: ({
|
||||
indexName = INDEX_NAME_PLACEHOLDER,
|
||||
ingestPipeline,
|
||||
extraIngestDocumentValues,
|
||||
}) => {
|
||||
const ingestDocumentKeys = ingestPipeline ? ingestKeysToJSON(extraIngestDocumentValues) : '';
|
||||
return `buf := bytes.NewBufferString(\`
|
||||
{"index":{"_id":"9780553351927"}}
|
||||
|
|
|
@ -10,10 +10,12 @@ import { Languages, LanguageDefinition } from '@kbn/search-api-panels';
|
|||
|
||||
import { docLinks } from '../../doc_links';
|
||||
|
||||
import { INDEX_NAME_PLACEHOLDER } from './constants';
|
||||
|
||||
import { ingestKeysToJSON } from './helpers';
|
||||
|
||||
export const javascriptDefinition: LanguageDefinition = {
|
||||
buildSearchQuery: ({ indexName }) => `// Let's search!
|
||||
buildSearchQuery: ({ indexName = INDEX_NAME_PLACEHOLDER }) => `// Let's search!
|
||||
const searchResult = await client.search({
|
||||
index: '${indexName}',
|
||||
q: 'snow'
|
||||
|
@ -37,7 +39,11 @@ const client = new Client({
|
|||
},
|
||||
iconType: 'javascript.svg',
|
||||
id: Languages.JAVASCRIPT,
|
||||
ingestData: ({ indexName, ingestPipeline, extraIngestDocumentValues }) => {
|
||||
ingestData: ({
|
||||
indexName = INDEX_NAME_PLACEHOLDER,
|
||||
ingestPipeline,
|
||||
extraIngestDocumentValues,
|
||||
}) => {
|
||||
const ingestDocumentKeys = ingestPipeline ? ingestKeysToJSON(extraIngestDocumentValues) : '';
|
||||
return `// Sample data books
|
||||
const dataset = [
|
||||
|
|
|
@ -10,10 +10,12 @@ import { Languages, LanguageDefinition } from '@kbn/search-api-panels';
|
|||
|
||||
import { docLinks } from '../../doc_links';
|
||||
|
||||
import { INDEX_NAME_PLACEHOLDER } from './constants';
|
||||
|
||||
import { ingestKeysToPHP } from './helpers';
|
||||
|
||||
export const phpDefinition: LanguageDefinition = {
|
||||
buildSearchQuery: ({ indexName }) => `$params = [
|
||||
buildSearchQuery: ({ indexName = INDEX_NAME_PLACEHOLDER }) => `$params = [
|
||||
'index' => '${indexName}',
|
||||
'body' => [
|
||||
'q' => 'snow'
|
||||
|
@ -35,7 +37,11 @@ print_r($response->asArray());`,
|
|||
},
|
||||
iconType: 'php.svg',
|
||||
id: Languages.PHP,
|
||||
ingestData: ({ indexName, ingestPipeline, extraIngestDocumentValues }) => {
|
||||
ingestData: ({
|
||||
indexName = INDEX_NAME_PLACEHOLDER,
|
||||
ingestPipeline,
|
||||
extraIngestDocumentValues,
|
||||
}) => {
|
||||
const ingestDocumentKeys = ingestPipeline ? ingestKeysToPHP(extraIngestDocumentValues) : '';
|
||||
return `$params = [${ingestPipeline ? `\n 'pipeline' => '${ingestPipeline}',` : ''}
|
||||
'body' => [
|
||||
|
|
|
@ -10,10 +10,13 @@ import { Languages, LanguageDefinition } from '@kbn/search-api-panels';
|
|||
|
||||
import { docLinks } from '../../doc_links';
|
||||
|
||||
import { INDEX_NAME_PLACEHOLDER } from './constants';
|
||||
|
||||
import { ingestKeysToJSON } from './helpers';
|
||||
|
||||
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
|
||||
|
||||
client = Elasticsearch(
|
||||
|
@ -29,7 +32,11 @@ client = Elasticsearch(
|
|||
},
|
||||
iconType: 'python.svg',
|
||||
id: Languages.PYTHON,
|
||||
ingestData: ({ indexName, ingestPipeline, extraIngestDocumentValues }) => {
|
||||
ingestData: ({
|
||||
indexName = INDEX_NAME_PLACEHOLDER,
|
||||
ingestPipeline,
|
||||
extraIngestDocumentValues,
|
||||
}) => {
|
||||
const ingestDocumentKeys = ingestPipeline ? ingestKeysToJSON(extraIngestDocumentValues) : '';
|
||||
return `documents = [
|
||||
{ "index": { "_index": "${indexName}", "_id": "9780553351927"}},
|
||||
|
|
|
@ -10,10 +10,13 @@ import { Languages, LanguageDefinition } from '@kbn/search-api-panels';
|
|||
|
||||
import { docLinks } from '../../doc_links';
|
||||
|
||||
import { INDEX_NAME_PLACEHOLDER } from './constants';
|
||||
|
||||
import { ingestKeysToRuby } from './helpers';
|
||||
|
||||
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(
|
||||
api_key: '${apiKey}',
|
||||
${cloudId ? `cloud_id: ${cloudId},` : `url: '${url}',`}
|
||||
|
@ -28,7 +31,11 @@ export const rubyDefinition: LanguageDefinition = {
|
|||
},
|
||||
iconType: 'ruby.svg',
|
||||
id: Languages.RUBY,
|
||||
ingestData: ({ indexName, ingestPipeline, extraIngestDocumentValues }) => {
|
||||
ingestData: ({
|
||||
indexName = INDEX_NAME_PLACEHOLDER,
|
||||
ingestPipeline,
|
||||
extraIngestDocumentValues,
|
||||
}) => {
|
||||
const ingestDocumentKeys = ingestPipeline ? ingestKeysToRuby(extraIngestDocumentValues) : '';
|
||||
return `documents = [
|
||||
{ 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 (
|
||||
<CodeBox
|
||||
languages={languageDefinitions}
|
||||
codeSnippet={getLanguageDefinitionCodeSnippet(selectedLanguage, 'testConnection', codeArgs)}
|
||||
consoleRequest={getConsoleRequest('testConnection')}
|
||||
codeSnippet={getLanguageDefinitionCodeSnippet(selectedLanguage, 'ingestData', codeArgs)}
|
||||
consoleRequest={getConsoleRequest('ingestData')}
|
||||
selectedLanguage={selectedLanguage}
|
||||
setSelectedLanguage={setSelectedLanguage}
|
||||
assetBasePath={assetBasePath}
|
||||
|
|
|
@ -9,6 +9,7 @@ import React from 'react';
|
|||
|
||||
import { useState, useEffect } from 'react';
|
||||
|
||||
import { css } from '@emotion/react';
|
||||
import { useValues, useActions } from 'kea';
|
||||
|
||||
import {
|
||||
|
@ -27,15 +28,13 @@ import {
|
|||
EuiHorizontalRule,
|
||||
EuiButton,
|
||||
EuiHeaderLinks,
|
||||
useEuiTheme,
|
||||
} from '@elastic/eui';
|
||||
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import { FormattedMessage } from '@kbn/i18n-react';
|
||||
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 { CreateApiKeyFlyout } from '../api_key/create_api_key_flyout';
|
||||
import { KibanaLogic } from '../kibana';
|
||||
|
@ -48,9 +47,7 @@ export const EndpointsHeaderAction: React.FC = ({ children }) => {
|
|||
const { makeRequest } = useActions(FetchApiKeysAPILogic);
|
||||
const { data } = useValues(FetchApiKeysAPILogic);
|
||||
const [isFlyoutOpen, setIsFlyoutOpen] = useState(false);
|
||||
const { user } = useValues(KibanaLogic);
|
||||
const { makeRequest: saveApiKey } = useActions(CreateApiKeyAPILogic);
|
||||
const { data: apiKey, error, status } = useValues(CreateApiKeyAPILogic);
|
||||
const { euiTheme } = useEuiTheme();
|
||||
|
||||
useEffect(() => makeRequest({}), []);
|
||||
|
||||
|
@ -75,16 +72,7 @@ export const EndpointsHeaderAction: React.FC = ({ children }) => {
|
|||
<EuiFlexGroup alignItems="center" gutterSize="s">
|
||||
{Boolean(children) && <EuiFlexItem>{children}</EuiFlexItem>}
|
||||
<EuiFlexItem>
|
||||
{isFlyoutOpen && (
|
||||
<CreateApiKeyFlyout
|
||||
createdApiKey={apiKey}
|
||||
error={error?.body?.message}
|
||||
isLoading={status === Status.LOADING}
|
||||
onClose={() => setIsFlyoutOpen(false)}
|
||||
setApiKey={saveApiKey}
|
||||
username={user?.full_name || user?.username || ''}
|
||||
/>
|
||||
)}
|
||||
{isFlyoutOpen && <CreateApiKeyFlyout onClose={() => setIsFlyoutOpen(false)} />}
|
||||
<EuiPopover
|
||||
button={button}
|
||||
isOpen={isPopoverOpen}
|
||||
|
@ -93,6 +81,9 @@ export const EndpointsHeaderAction: React.FC = ({ children }) => {
|
|||
anchorPosition="downLeft"
|
||||
>
|
||||
<EuiContextMenuPanel
|
||||
css={css`
|
||||
max-width: calc(${euiTheme.size.xxxxl} * 4);
|
||||
`}
|
||||
items={[
|
||||
<EuiContextMenuItem key="endpoint">
|
||||
<EuiText size="s">
|
||||
|
@ -107,7 +98,13 @@ export const EndpointsHeaderAction: React.FC = ({ children }) => {
|
|||
|
||||
<EuiFlexGroup gutterSize="s" justifyContent="flexEnd" alignItems="center">
|
||||
<EuiFlexItem>
|
||||
<EuiCode>{elasticsearchEndpoint}</EuiCode>
|
||||
<EuiCode
|
||||
css={css`
|
||||
overflow-wrap: anywhere;
|
||||
`}
|
||||
>
|
||||
{elasticsearchEndpoint}
|
||||
</EuiCode>
|
||||
</EuiFlexItem>
|
||||
<EuiFlexItem grow={false}>
|
||||
<EuiCopy textToCopy={elasticsearchEndpoint || ''} afterMessage={COPIED_LABEL}>
|
||||
|
@ -139,7 +136,13 @@ export const EndpointsHeaderAction: React.FC = ({ children }) => {
|
|||
|
||||
<EuiFlexGroup gutterSize="s" justifyContent="flexEnd" alignItems="center">
|
||||
<EuiFlexItem>
|
||||
<EuiCode>{cloudId}</EuiCode>
|
||||
<EuiCode
|
||||
css={css`
|
||||
overflow-wrap: anywhere;
|
||||
`}
|
||||
>
|
||||
{cloudId}
|
||||
</EuiCode>
|
||||
</EuiFlexItem>
|
||||
<EuiFlexItem grow={false}>
|
||||
<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