Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Enterprise Search] Reuse serverless panels on Enterprise Search #163179

Merged
Merged
Show file tree
Hide file tree
Changes from 13 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/CODEOWNERS
Validating CODEOWNERS rules …
Original file line number Diff line number Diff line change
Expand Up @@ -588,6 +588,7 @@ examples/screenshot_mode_example @elastic/kibana-app-services
src/plugins/screenshot_mode @elastic/appex-sharedux
x-pack/examples/screenshotting_example @elastic/appex-sharedux
x-pack/plugins/screenshotting @elastic/kibana-reporting-services
packages/kbn-search-api-panels @elastic/enterprise-search-frontend
examples/search_examples @elastic/kibana-data-discovery
x-pack/plugins/searchprofiler @elastic/platform-deployment-management
x-pack/test/security_api_integration/packages/helpers @elastic/kibana-core
Expand Down
1 change: 1 addition & 0 deletions .i18nrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@
"server": "src/legacy/server",
"share": "src/plugins/share",
"sharedUXPackages": "packages/shared-ux",
"searchApiPanels": "packages/kbn-search-api-panels/",
"securitySolutionPackages": "x-pack/packages/security-solution",
"serverlessPackages": "packages/serverless",
"coloring": "packages/kbn-coloring/src",
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -591,6 +591,7 @@
"@kbn/screenshot-mode-plugin": "link:src/plugins/screenshot_mode",
"@kbn/screenshotting-example-plugin": "link:x-pack/examples/screenshotting_example",
"@kbn/screenshotting-plugin": "link:x-pack/plugins/screenshotting",
"@kbn/search-api-panels": "link:packages/kbn-search-api-panels",
"@kbn/search-examples-plugin": "link:examples/search_examples",
"@kbn/searchprofiler-plugin": "link:x-pack/plugins/searchprofiler",
"@kbn/security-plugin": "link:x-pack/plugins/security",
Expand Down
3 changes: 3 additions & 0 deletions packages/kbn-search-api-panels/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# @kbn/search-api-panels

Empty package generated by @kbn/generate
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
/*
* 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.
* 2.0 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/

import React, { useState } from 'react';

import {
EuiButtonEmpty,
EuiCodeBlock,
Expand All @@ -19,49 +22,46 @@ import {
EuiThemeProvider,
} from '@elastic/eui';
import { i18n } from '@kbn/i18n';
import React, { useState } from 'react';
import { PLUGIN_ID } from '../../../common';
import { useKibanaServices } from '../hooks/use_kibana';
import { consoleDefinition } from './languages/console';
import { LanguageDefinition, LanguageDefinitionSnippetArguments } from './languages/types';
import type { HttpStart } from '@kbn/core-http-browser';
import type { ApplicationStart } from '@kbn/core-application-browser';
import type { SharePluginStart } from '@kbn/share-plugin/public';

import { LanguageDefinition } from '../types';
import { TryInConsoleButton } from './try_in_console_button';
import './code_box.scss';

interface CodeBoxProps {
languages: LanguageDefinition[];
code: keyof LanguageDefinition;
codeArgs: LanguageDefinitionSnippetArguments;
codeSnippet: string;
// overrides the language type for syntax highlighting
languageType?: string;
selectedLanguage: LanguageDefinition;
setSelectedLanguage: (language: LanguageDefinition) => void;
http: HttpStart;
pluginId: string;
application?: ApplicationStart;
sharePlugin: SharePluginStart;
showTryInConsole: boolean;
}

const getCodeSnippet = (
language: Partial<LanguageDefinition>,
key: keyof LanguageDefinition,
args: LanguageDefinitionSnippetArguments
): string => {
const snippetVal = language[key];
if (snippetVal === undefined) return '';
if (typeof snippetVal === 'string') return snippetVal;
return snippetVal(args);
};

export const CodeBox: React.FC<CodeBoxProps> = ({
code,
codeArgs,
languages,
application,
codeSnippet,
http,
languageType,
languages,
pluginId,
selectedLanguage,
setSelectedLanguage,
sharePlugin,
showTryInConsole,
}) => {
const [isPopoverOpen, setIsPopoverOpen] = useState<boolean>(false);
const { http } = useKibanaServices();

const items = languages.map((language) => (
<EuiContextMenuItem
key={language.id}
icon={http.basePath.prepend(`/plugins/${PLUGIN_ID}/assets/${language.iconType}`)}
icon={http.basePath.prepend(`/plugins/${pluginId}/assets/${language.iconType}`)}
onClick={() => {
setSelectedLanguage(language);
setIsPopoverOpen(false);
Expand All @@ -74,7 +74,7 @@ export const CodeBox: React.FC<CodeBoxProps> = ({
const button = (
<EuiThemeProvider colorMode="dark">
<EuiButtonEmpty
aria-label={i18n.translate('xpack.serverlessSearch.codeBox.selectAriaLabel', {
aria-label={i18n.translate('searchApiPanels.welcomeBanner.codeBox.selectAriaLabel', {
defaultMessage: 'Select a programming language',
})}
color="text"
Expand All @@ -86,8 +86,6 @@ export const CodeBox: React.FC<CodeBoxProps> = ({
</EuiButtonEmpty>
</EuiThemeProvider>
);
const codeSnippet = getCodeSnippet(selectedLanguage, code, codeArgs);
const showTryInConsole = code in consoleDefinition;

return (
<EuiThemeProvider colorMode="dark">
Expand All @@ -110,7 +108,7 @@ export const CodeBox: React.FC<CodeBoxProps> = ({
<EuiCopy textToCopy={codeSnippet}>
{(copy) => (
<EuiButtonEmpty color="text" iconType="copy" size="s" onClick={copy}>
{i18n.translate('xpack.serverlessSearch.codeBox.copyButtonLabel', {
{i18n.translate('searchApiPanels.welcomeBanner.codeBox.copyButtonLabel', {
defaultMessage: 'Copy',
})}
</EuiButtonEmpty>
Expand All @@ -119,7 +117,11 @@ export const CodeBox: React.FC<CodeBoxProps> = ({
</EuiFlexItem>
{showTryInConsole && (
<EuiFlexItem grow={false}>
<TryInConsoleButton request={getCodeSnippet(consoleDefinition, code, codeArgs)} />
<TryInConsoleButton
request={codeSnippet}
application={application}
sharePlugin={sharePlugin}
/>
</EuiFlexItem>
)}
</EuiFlexGroup>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,21 +1,26 @@
/*
* 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.
* 2.0 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/

import { EuiFlexGroup, EuiFlexItem, EuiIcon, EuiText, EuiLink } from '@elastic/eui';
import React from 'react';
import { PLUGIN_ID } from '../../../../common';
import { useKibanaServices } from '../../hooks/use_kibana';

export const GithubLink: React.FC<{ label: string; href: string }> = ({ label, href }) => {
const { http } = useKibanaServices();
import { EuiFlexGroup, EuiFlexItem, EuiIcon, EuiText, EuiLink } from '@elastic/eui';
import { HttpStart } from '@kbn/core-http-browser';

export const GithubLink: React.FC<{
label: string;
href: string;
http: HttpStart;
pluginId: string;
}> = ({ label, href, http, pluginId }) => {
return (
<EuiFlexGroup alignItems="center" gutterSize="xs" justifyContent="flexEnd">
<EuiFlexItem grow={false}>
<EuiIcon size="s" type={http.basePath.prepend(`/plugins/${PLUGIN_ID}/assets/github.svg`)} />
<EuiIcon size="s" type={http.basePath.prepend(`/plugins/${pluginId}/assets/github.svg`)} />
</EuiFlexItem>
<EuiFlexItem grow={false}>
<EuiText size="s">
Expand Down
Original file line number Diff line number Diff line change
@@ -1,59 +1,80 @@
/*
* 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.
* 2.0 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/

import React, { useState } from 'react';

import { EuiCheckableCard, EuiFormFieldset, EuiSpacer, EuiText, EuiTitle } from '@elastic/eui';
import { i18n } from '@kbn/i18n';
import React, { useState } from 'react';
import { docLinks } from '../../../../common/doc_links';
import { CodeBox } from '../code_box';
import { languageDefinitions } from '../languages/languages';
import { LanguageDefinition, LanguageDefinitionSnippetArguments } from '../languages/types';
import type { HttpStart } from '@kbn/core-http-browser';
import type { ApplicationStart } from '@kbn/core-application-browser';
import type { SharePluginStart } from '@kbn/share-plugin/public';
import { CodeBox } from './code_box';
import { LanguageDefinition } from '../types';
import { OverviewPanel } from './overview_panel';
import { IntegrationsPanel } from './integrations_panel';

interface IngestDataProps {
codeArguments: LanguageDefinitionSnippetArguments;
codeSnippet: string;
selectedLanguage: LanguageDefinition;
setSelectedLanguage: (language: LanguageDefinition) => void;
docLinks: any;
http: HttpStart;
pluginId: string;
application?: ApplicationStart;
sharePlugin: SharePluginStart;
languages: LanguageDefinition[];
showTryInConsole: boolean;
}

export const IngestData: React.FC<IngestDataProps> = ({
codeArguments,
codeSnippet,
selectedLanguage,
setSelectedLanguage,
docLinks,
http,
pluginId,
application,
sharePlugin,
languages,
showTryInConsole,
}) => {
const [selectedIngestMethod, setSelectedIngestMethod] = useState<
'ingestViaApi' | 'ingestViaIntegration'
>('ingestViaApi');
return (
<OverviewPanel
description={i18n.translate('xpack.serverlessSearch.ingestData.description', {
description={i18n.translate('searchApiPanels.welcomeBanner.ingestData.description', {
defaultMessage:
'Add data to your data stream or index to make it searchable. Choose an ingestion method that fits your application and workflow.',
})}
leftPanelContent={
selectedIngestMethod === 'ingestViaApi' ? (
<CodeBox
code="ingestData"
codeArgs={codeArguments}
languages={languageDefinitions}
showTryInConsole={showTryInConsole}
codeSnippet={codeSnippet}
languages={languages}
selectedLanguage={selectedLanguage}
setSelectedLanguage={setSelectedLanguage}
http={http}
pluginId={pluginId}
application={application}
sharePlugin={sharePlugin}
/>
) : (
<IntegrationsPanel />
<IntegrationsPanel docLinks={docLinks} http={http} pluginId={pluginId} />
)
}
links={[
...(selectedLanguage.apiReference
? [
{
href: selectedLanguage.apiReference,
label: i18n.translate('xpack.serverlessSearch.ingestData.clientDocLink', {
label: i18n.translate('searchApiPanels.welcomeBanner.ingestData.clientDocLink', {
defaultMessage: '{languageName} API reference',
values: { languageName: selectedLanguage.name },
}),
Expand All @@ -62,18 +83,18 @@ export const IngestData: React.FC<IngestDataProps> = ({
: []),
{
href: docLinks.integrations,
label: i18n.translate('xpack.serverlessSearch.ingestData.integrationsLink', {
label: i18n.translate('searchApiPanels.welcomeBanner.ingestData.integrationsLink', {
defaultMessage: 'About Integrations',
}),
},
]}
title={i18n.translate('xpack.serverlessSearch.ingestData.title', {
title={i18n.translate('searchApiPanels.welcomeBanner.ingestData.title', {
defaultMessage: 'Ingest data',
})}
>
<EuiFormFieldset
legend={{
children: i18n.translate('xpack.serverlessSearch.ingestData.ingestLegendLabel', {
children: i18n.translate('searchApiPanels.welcomeBanner.ingestData.ingestLegendLabel', {
defaultMessage: 'Select an ingestion method',
}),
display: 'hidden',
Expand All @@ -85,7 +106,7 @@ export const IngestData: React.FC<IngestDataProps> = ({
label={
<EuiTitle size="xs">
<h3>
{i18n.translate('xpack.serverlessSearch.ingestData.ingestApiLabel', {
{i18n.translate('searchApiPanels.welcomeBanner.ingestData.ingestApiLabel', {
defaultMessage: 'Ingest via API',
})}
</h3>
Expand All @@ -96,7 +117,7 @@ export const IngestData: React.FC<IngestDataProps> = ({
onChange={() => setSelectedIngestMethod('ingestViaApi')}
>
<EuiText>
{i18n.translate('xpack.serverlessSearch.ingestData.ingestApiDescription', {
{i18n.translate('searchApiPanels.welcomeBanner.ingestData.ingestApiDescription', {
defaultMessage:
'The most flexible way to index data, enabling full control over your customization and optimization options.',
})}
Expand All @@ -109,7 +130,7 @@ export const IngestData: React.FC<IngestDataProps> = ({
label={
<EuiTitle size="xs">
<h3>
{i18n.translate('xpack.serverlessSearch.ingestData.ingestIntegrationLabel', {
{i18n.translate('searchApiPanels.welcomeBanner.ingestData.ingestIntegrationLabel', {
defaultMessage: 'Ingest via integration',
})}
</h3>
Expand All @@ -120,10 +141,13 @@ export const IngestData: React.FC<IngestDataProps> = ({
onChange={() => setSelectedIngestMethod('ingestViaIntegration')}
>
<EuiText>
{i18n.translate('xpack.serverlessSearch.ingestData.ingestIntegrationDescription', {
defaultMessage:
'Specialized ingestion tools optimized for transforming data and shipping it to Elasticsearch.',
})}
{i18n.translate(
'searchApiPanels.welcomeBanner.ingestData.ingestIntegrationDescription',
{
defaultMessage:
'Specialized ingestion tools optimized for transforming data and shipping it to Elasticsearch.',
}
)}
</EuiText>
</EuiCheckableCard>
</EuiFormFieldset>
Expand Down
Loading