mirror of
https://github.com/elastic/kibana.git
synced 2025-04-23 09:19:04 -04:00
[Serverless Search] Add Indexing API Page (#160343)
## Summary
Adds the indexing API page as a plugin application and registers it's
deep link. This intentionally only implements the empty / no indices
state. Fetching indices and giving a combobox to select an index will be
done in another PR.
### Screenshots
<img width="1840" alt="image"
src="dc62c816
-34b3-47be-ba24-e5e0a06d1533">
This commit is contained in:
parent
a1d02824f1
commit
738f0cdc4d
9 changed files with 196 additions and 14 deletions
|
@ -7,3 +7,4 @@
|
|||
*/
|
||||
|
||||
export const SERVERLESS_ES_APP_ID = 'serverlessElasticsearch';
|
||||
export const SERVERLESS_ES_INDEXING_API_ID = 'serverlessIndexingApi';
|
||||
|
|
|
@ -6,8 +6,9 @@
|
|||
* Side Public License, v 1.
|
||||
*/
|
||||
|
||||
import { SERVERLESS_ES_APP_ID } from './constants';
|
||||
import { SERVERLESS_ES_APP_ID, SERVERLESS_ES_INDEXING_API_ID } from './constants';
|
||||
|
||||
export type AppId = typeof SERVERLESS_ES_APP_ID;
|
||||
export type IndexingApiId = typeof SERVERLESS_ES_INDEXING_API_ID;
|
||||
|
||||
export type DeepLinkId = AppId;
|
||||
export type DeepLinkId = AppId | IndexingApiId;
|
||||
|
|
|
@ -6,6 +6,6 @@
|
|||
* Side Public License, v 1.
|
||||
*/
|
||||
|
||||
export { SERVERLESS_ES_APP_ID } from './constants';
|
||||
export { SERVERLESS_ES_APP_ID, SERVERLESS_ES_INDEXING_API_ID } from './constants';
|
||||
|
||||
export type { AppId, DeepLinkId } from './deep_links';
|
||||
|
|
|
@ -0,0 +1,123 @@
|
|||
/*
|
||||
* 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, { useState } from 'react';
|
||||
|
||||
import {
|
||||
EuiFlexGroup,
|
||||
EuiFlexItem,
|
||||
EuiLink,
|
||||
EuiPageTemplate,
|
||||
EuiSpacer,
|
||||
EuiText,
|
||||
} from '@elastic/eui';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import { FormattedMessage } from '@kbn/i18n-react';
|
||||
|
||||
import { CodeBox } from './code_box';
|
||||
import { javascriptDefinition } from './languages/javascript';
|
||||
import { languageDefinitions } from './languages/languages';
|
||||
import { LanguageDefinition } from './languages/types';
|
||||
|
||||
import { OverviewPanel } from './overview_panels/overview_panel';
|
||||
import { LanguageClientPanel } from './overview_panels/language_client_panel';
|
||||
|
||||
const NoIndicesContent = () => (
|
||||
<>
|
||||
<EuiSpacer />
|
||||
<EuiText>
|
||||
<FormattedMessage
|
||||
id="xpack.serverlessSearch.content.indexingApi.clientPanel.noIndices.helpText"
|
||||
defaultMessage="Don't have an index yet? {getStartedLink}"
|
||||
values={{
|
||||
getStartedLink: (
|
||||
<EuiLink href="#" external>
|
||||
{i18n.translate(
|
||||
'xpack.serverlessSearch.content.indexingApi.clientPanel.noIndices.getStartedLink',
|
||||
{ defaultMessage: 'Get started' }
|
||||
)}
|
||||
</EuiLink>
|
||||
),
|
||||
}}
|
||||
/>
|
||||
</EuiText>
|
||||
</>
|
||||
);
|
||||
|
||||
export const ElasticsearchIndexingApi = () => {
|
||||
const [selectedLanguage, setSelectedLanguage] =
|
||||
useState<LanguageDefinition>(javascriptDefinition);
|
||||
|
||||
return (
|
||||
<EuiPageTemplate offset={0} grow restrictWidth data-test-subj="svlSearchIndexingApiPage">
|
||||
<EuiPageTemplate.Header
|
||||
pageTitle={i18n.translate('xpack.serverlessSearch.content.indexingApi.header.title', {
|
||||
defaultMessage: 'Indexing API',
|
||||
})}
|
||||
description={i18n.translate(
|
||||
'xpack.serverlessSearch.content.indexingApi.header.description',
|
||||
{
|
||||
defaultMessage:
|
||||
'Add data to your data stream or index to make it searchable. Choose an ingestion method that fits your application and workflow.',
|
||||
}
|
||||
)}
|
||||
bottomBorder="extended"
|
||||
/>
|
||||
<EuiPageTemplate.Section color="subdued" bottomBorder="extended">
|
||||
<OverviewPanel
|
||||
title={i18n.translate('xpack.serverlessSearch.content.indexingApi.clientPanel.title', {
|
||||
defaultMessage: 'Ingest data for the first time',
|
||||
})}
|
||||
description={i18n.translate(
|
||||
'xpack.serverlessSearch.content.indexingApi.clientPanel.description',
|
||||
{ defaultMessage: 'Adding documents to your already created index using the API' }
|
||||
)}
|
||||
leftPanelContent={
|
||||
<>
|
||||
<EuiFlexGroup direction="column">
|
||||
<EuiFlexItem>
|
||||
<EuiText size="s">
|
||||
<strong>
|
||||
{i18n.translate(
|
||||
'xpack.serverlessSearch.content.indexingApi.clientPanel.selectClient.heading',
|
||||
{
|
||||
defaultMessage: 'Choose one',
|
||||
}
|
||||
)}
|
||||
</strong>
|
||||
</EuiText>
|
||||
</EuiFlexItem>
|
||||
</EuiFlexGroup>
|
||||
<EuiSpacer size="s" />
|
||||
<EuiFlexGroup gutterSize="xs" direction="row">
|
||||
{languageDefinitions.map((language, index) => (
|
||||
<EuiFlexItem key={`panelItem.${index}`}>
|
||||
<LanguageClientPanel
|
||||
language={language}
|
||||
setSelectedLanguage={setSelectedLanguage}
|
||||
isSelectedLanguage={selectedLanguage === language}
|
||||
/>
|
||||
</EuiFlexItem>
|
||||
))}
|
||||
</EuiFlexGroup>
|
||||
<EuiSpacer />
|
||||
<CodeBox
|
||||
code="ingestData"
|
||||
codeArgs={{ url: '', apiKey: '' }}
|
||||
languages={languageDefinitions}
|
||||
selectedLanguage={selectedLanguage}
|
||||
setSelectedLanguage={setSelectedLanguage}
|
||||
/>
|
||||
</>
|
||||
}
|
||||
>
|
||||
<NoIndicesContent />
|
||||
</OverviewPanel>
|
||||
</EuiPageTemplate.Section>
|
||||
</EuiPageTemplate>
|
||||
);
|
||||
};
|
|
@ -18,9 +18,9 @@ import React from 'react';
|
|||
import { LEARN_MORE_LABEL } from '../../../../common/i18n_string';
|
||||
|
||||
interface OverviewPanelProps {
|
||||
description: React.ReactNode | string;
|
||||
description?: React.ReactNode | string;
|
||||
leftPanelContent: React.ReactNode;
|
||||
links: Array<{ label: string; href: string }>;
|
||||
links?: Array<{ label: string; href: string }>;
|
||||
title: string;
|
||||
}
|
||||
|
||||
|
@ -42,9 +42,9 @@ export const OverviewPanel: React.FC<OverviewPanelProps> = ({
|
|||
<h2>{title}</h2>
|
||||
</EuiTitle>
|
||||
<EuiSpacer />
|
||||
<EuiText>{description}</EuiText>
|
||||
{description && <EuiText>{description}</EuiText>}
|
||||
{children}
|
||||
{links.length > 0 ? (
|
||||
{links && links.length > 0 ? (
|
||||
<>
|
||||
<EuiSpacer />
|
||||
<EuiTitle size="xxs">
|
||||
|
|
|
@ -0,0 +1,38 @@
|
|||
/*
|
||||
* 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 ReactDOM from 'react-dom';
|
||||
import { CoreStart } from '@kbn/core/public';
|
||||
import { KibanaContextProvider, KibanaThemeProvider } from '@kbn/kibana-react-plugin/public';
|
||||
import { I18nProvider } from '@kbn/i18n-react';
|
||||
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
|
||||
import { ReactQueryDevtools } from '@tanstack/react-query-devtools';
|
||||
import { ServerlessSearchContext } from './hooks/use_kibana';
|
||||
|
||||
export async function renderApp(
|
||||
element: HTMLElement,
|
||||
core: CoreStart,
|
||||
services: ServerlessSearchContext
|
||||
) {
|
||||
const { ElasticsearchIndexingApi } = await import('./components/indexing_api');
|
||||
const queryClient = new QueryClient();
|
||||
ReactDOM.render(
|
||||
<KibanaThemeProvider theme$={core.theme.theme$}>
|
||||
<KibanaContextProvider services={{ ...core, ...services }}>
|
||||
<QueryClientProvider client={queryClient}>
|
||||
<ReactQueryDevtools initialIsOpen={false} />
|
||||
<I18nProvider>
|
||||
<ElasticsearchIndexingApi />
|
||||
</I18nProvider>
|
||||
</QueryClientProvider>
|
||||
</KibanaContextProvider>
|
||||
</KibanaThemeProvider>,
|
||||
element
|
||||
);
|
||||
return () => ReactDOM.unmountComponentAtNode(element);
|
||||
}
|
|
@ -71,19 +71,18 @@ const navigationTree: NavigationTreeDefinition = {
|
|||
link: 'management:index_management',
|
||||
},
|
||||
{
|
||||
title: i18n.translate('xpack.serverlessSearch.nav.content.transforms', {
|
||||
defaultMessage: 'Transforms',
|
||||
title: i18n.translate('xpack.serverlessSearch.nav.content.pipelines', {
|
||||
defaultMessage: 'Pipelines',
|
||||
}),
|
||||
// TODO: this will be updated to a new Transforms page
|
||||
// TODO: this will be updated to a new Pipelines page
|
||||
link: 'management:ingest_pipelines',
|
||||
},
|
||||
{
|
||||
id: 'content_indexing_api',
|
||||
link: 'serverlessIndexingApi',
|
||||
title: i18n.translate('xpack.serverlessSearch.nav.content.indexingApi', {
|
||||
defaultMessage: 'Indexing API',
|
||||
}),
|
||||
// TODO: this page does not exist yet, linking to getting started for now
|
||||
link: 'serverlessElasticsearch',
|
||||
},
|
||||
],
|
||||
},
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
*/
|
||||
|
||||
import { AppMountParameters, CoreSetup, CoreStart, Plugin } from '@kbn/core/public';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import { createServerlessSearchSideNavComponent as createComponent } from './layout/nav';
|
||||
import { docLinks } from '../common/doc_links';
|
||||
import {
|
||||
|
@ -30,10 +31,29 @@ export class ServerlessSearchPlugin
|
|||
): ServerlessSearchPluginSetup {
|
||||
core.application.register({
|
||||
id: 'serverlessElasticsearch',
|
||||
title: 'Elasticsearch',
|
||||
title: i18n.translate('xpack.serverlessSearch.app.elasticsearch.title', {
|
||||
defaultMessage: 'Elasticsearch',
|
||||
}),
|
||||
appRoute: '/app/elasticsearch',
|
||||
async mount({ element }: AppMountParameters) {
|
||||
const { renderApp } = await import('./application');
|
||||
const { renderApp } = await import('./application/elasticsearch');
|
||||
const [coreStart, services] = await core.getStartServices();
|
||||
const { security } = services;
|
||||
docLinks.setDocLinks(coreStart.docLinks.links);
|
||||
|
||||
const userProfile = await security.userProfiles.getCurrent();
|
||||
|
||||
return await renderApp(element, coreStart, { userProfile, ...services });
|
||||
},
|
||||
});
|
||||
core.application.register({
|
||||
id: 'serverlessIndexingApi',
|
||||
title: i18n.translate('xpack.serverlessSearch.app.indexingApi.title', {
|
||||
defaultMessage: 'Indexing API',
|
||||
}),
|
||||
appRoute: '/app/indexing_api',
|
||||
async mount({ element }: AppMountParameters) {
|
||||
const { renderApp } = await import('./application/indexing_api');
|
||||
const [coreStart, services] = await core.getStartServices();
|
||||
const { security } = services;
|
||||
docLinks.setDocLinks(coreStart.docLinks.links);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue