Skip to content

Commit

Permalink
[Serverless] Playground in Serverless (elastic#181474)
Browse files Browse the repository at this point in the history
## Summary

This PR:

- Integrate Playground into Serverless
- Redesign of Navigation Menu
- Refactor Playground docs

## UI changes:
### Playground in Serverless

![img-1](https://github.com/elastic/kibana/assets/150824886/772d5812-e8ea-41ee-a875-4204fff3e948)

### Playground with docs and indices

![img-2](https://github.com/elastic/kibana/assets/150824886/5545dc3e-bf7d-45c0-9f4a-250dd9c63f75)

### Playground in action


![img-3](https://github.com/elastic/kibana/assets/150824886/a7088863-6dd9-4c4a-9760-e168d37f16c2)


### Checklist

Delete any items that are not applicable to this PR.

- [ ] Any text added follows [EUI's writing
guidelines](https://elastic.github.io/eui/#/guidelines/writing), uses
sentence case text and includes [i18n
support](https://github.com/elastic/kibana/blob/main/packages/kbn-i18n/README.md)
- [ ]
[Documentation](https://www.elastic.co/guide/en/kibana/master/development-documentation.html)
was added for features that require explanation or tutorials
- [ ] [Unit or functional
tests](https://www.elastic.co/guide/en/kibana/master/development-tests.html)
were updated or added to match the most common scenarios
- [ ] [Flaky Test
Runner](https://ci-stats.kibana.dev/trigger_flaky_test_runner/1) was
used on any tests changed
- [ ] Any UI touched in this PR is usable by keyboard only (learn more
about [keyboard accessibility](https://webaim.org/techniques/keyboard/))
- [ ] Any UI touched in this PR does not create any new axe failures
(run axe in browser:
[FF](https://addons.mozilla.org/en-US/firefox/addon/axe-devtools/),
[Chrome](https://chrome.google.com/webstore/detail/axe-web-accessibility-tes/lhdoppojpmngadmnindnejefpokejbdd?hl=en-US))
- [ ] If a plugin configuration key changed, check if it needs to be
allowlisted in the cloud and added to the [docker
list](https://github.com/elastic/kibana/blob/main/src/dev/build/tasks/os_packages/docker_generator/resources/base/bin/kibana-docker)
- [ ] This renders correctly on smaller devices using a responsive
layout. (You can test this [in your
browser](https://www.browserstack.com/guide/responsive-testing-on-local-server))
- [ ] This was checked for [cross-browser
compatibility](https://www.elastic.co/support/matrix#matrix_browsers)


### For maintainers

- [ ] This was checked for breaking API changes and was [labeled
appropriately](https://www.elastic.co/guide/en/kibana/master/contributing.html#kibana-release-notes-process)

---------

Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com>
  • Loading branch information
Samiul-TheSoccerFan and kibanamachine authored Apr 26, 2024
1 parent 438f623 commit 41fd643
Show file tree
Hide file tree
Showing 47 changed files with 500 additions and 145 deletions.
8 changes: 6 additions & 2 deletions config/serverless.es.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,9 @@ xpack.serverless.plugin.developer.projectSwitcher.currentType: 'search'
# Specify in telemetry the project type
telemetry.labels.serverless: search

# Alerts config
xpack.actions.enabledActionTypes: ['.email', '.index', '.slack', '.jira', '.webhook', '.teams']
# Alerts and LLM config
xpack.actions.enabledActionTypes:
['.email', '.index', '.slack', '.jira', '.webhook', '.teams', '.gen-ai', '.bedrock']

# Customize empty page state for analytics apps
no_data_page.analyticsNoDataPageFlavor: 'serverless_search'
Expand All @@ -43,3 +44,6 @@ xpack.ml.nlp.enabled: true
xpack.ml.compatibleModuleType: 'search'

data_visualizer.resultLinks.fileBeat.enabled: false

# Search Playground
xpack.searchPlayground.ui.enabled: false
1 change: 1 addition & 0 deletions packages/deeplinks/search/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,4 @@ export const ENTERPRISE_SEARCH_APPSEARCH_APP_ID = 'appSearch';
export const ENTERPRISE_SEARCH_WORKPLACESEARCH_APP_ID = 'workplaceSearch';
export const SERVERLESS_ES_APP_ID = 'serverlessElasticsearch';
export const SERVERLESS_ES_CONNECTORS_ID = 'serverlessConnectors';
export const SERVERLESS_ES_SEARCH_PLAYGROUND_ID = 'searchPlayground';
3 changes: 3 additions & 0 deletions packages/deeplinks/search/deep_links.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import {
ENTERPRISE_SEARCH_ANALYTICS_APP_ID,
ENTERPRISE_SEARCH_APPSEARCH_APP_ID,
ENTERPRISE_SEARCH_WORKPLACESEARCH_APP_ID,
SERVERLESS_ES_SEARCH_PLAYGROUND_ID,
} from './constants';

export type EnterpriseSearchApp = typeof ENTERPRISE_SEARCH_APP_ID;
Expand All @@ -25,6 +26,7 @@ export type EnterpriseSearchAppsearchApp = typeof ENTERPRISE_SEARCH_APPSEARCH_AP
export type EnterpriseSearchWorkplaceSearchApp = typeof ENTERPRISE_SEARCH_WORKPLACESEARCH_APP_ID;
export type ServerlessSearchApp = typeof SERVERLESS_ES_APP_ID;
export type ConnectorsId = typeof SERVERLESS_ES_CONNECTORS_ID;
export type SearchPlaygroundId = typeof SERVERLESS_ES_SEARCH_PLAYGROUND_ID;

export type ContentLinkId = 'searchIndices' | 'connectors' | 'webCrawlers';

Expand All @@ -41,6 +43,7 @@ export type DeepLinkId =
| EnterpriseSearchWorkplaceSearchApp
| ServerlessSearchApp
| ConnectorsId
| SearchPlaygroundId
| `${EnterpriseSearchContentApp}:${ContentLinkId}`
| `${EnterpriseSearchApplicationsApp}:${ApplicationsLinkId}`
| `${EnterpriseSearchAppsearchApp}:${AppsearchLinkId}`;
4 changes: 3 additions & 1 deletion packages/kbn-doc-links/src/get_doc_links.ts
Original file line number Diff line number Diff line change
Expand Up @@ -206,7 +206,6 @@ export const getDocLinks = ({ kibanaBranch, buildFlavor }: GetDocLinkOptions): D
licenseManagement: `${ENTERPRISE_SEARCH_DOCS}license-management.html`,
machineLearningStart: `${ELASTICSEARCH_DOCS}nlp-example.html`,
mailService: `${ENTERPRISE_SEARCH_DOCS}mailer-configuration.html`,
playground: `${KIBANA_DOCS}playground.html`,
mlDocumentEnrichment: `${ELASTICSEARCH_DOCS}ingest-pipeline-search-inference.html`,
searchApplicationsTemplates: `${ELASTICSEARCH_DOCS}search-application-api.html`,
searchApplicationsSearchApi: `${ELASTICSEARCH_DOCS}search-application-security.html`,
Expand Down Expand Up @@ -939,5 +938,8 @@ export const getDocLinks = ({ kibanaBranch, buildFlavor }: GetDocLinkOptions): D
telemetry: {
settings: `${KIBANA_DOCS}telemetry-settings-kbn.html`,
},
playground: {
chatPlayground: `${KIBANA_DOCS}playground.html`,
},
});
};
4 changes: 3 additions & 1 deletion packages/kbn-doc-links/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,6 @@ export interface DocLinks {
readonly languageClients: string;
readonly licenseManagement: string;
readonly machineLearningStart: string;
readonly playground: string;
readonly mailService: string;
readonly mlDocumentEnrichment: string;
readonly searchApplicationsTemplates: string;
Expand Down Expand Up @@ -648,6 +647,9 @@ export interface DocLinks {
readonly telemetry: {
readonly settings: string;
};
readonly playground: {
readonly chatPlayground: string;
};
}

export type BuildFlavor = 'serverless' | 'traditional';
Original file line number Diff line number Diff line change
Expand Up @@ -311,6 +311,7 @@ export default function ({ getService }: PluginFunctionalProviderContext) {
// 'xpack.reporting.poll.jobsRefresh.intervalErrorMultiplier (number)',
'xpack.rollup.ui.enabled (boolean)',
'xpack.saved_object_tagging.cache_refresh_interval (duration)',
'xpack.searchPlayground.ui.enabled (boolean)',
'xpack.security.loginAssistanceMessage (string)',
'xpack.security.sameSiteCookies (alternatives)',
'xpack.security.showInsecureClusterWarning (boolean)',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,25 +7,21 @@

import React from 'react';

import { EuiButtonEmpty } from '@elastic/eui';
import { useValues } from 'kea';

import { i18n } from '@kbn/i18n';
import { KibanaLogic } from '../../../shared/kibana';

import { docLinks } from '../../../shared/doc_links';
import { EndpointsHeaderAction } from '../../../shared/layout/endpoints_header_action';

export const PlaygroundHeaderDocsAction: React.FC = () => (
<EndpointsHeaderAction>
<EuiButtonEmpty
data-telemetry-id="entSearchApplications-playground-documentationLink"
data-test-subj="playground-documentation-link"
href={docLinks.playground}
target="_blank"
iconType="documents"
>
{i18n.translate('xpack.enterpriseSearch.content.playground.header.docLink', {
defaultMessage: 'Playground Docs',
})}
</EuiButtonEmpty>
</EndpointsHeaderAction>
);
export const PlaygroundHeaderDocsAction: React.FC = () => {
const { searchPlayground } = useValues(KibanaLogic);

if (!searchPlayground) {
return null;
}
return (
<EndpointsHeaderAction>
<searchPlayground.PlaygroundHeaderDocs />
</EndpointsHeaderAction>
);
};
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,6 @@ class DocLinks {
public licenseManagement: string;
public machineLearningStart: string;
public mlDocumentEnrichment: string;
public playground: string;
public pluginsIngestAttachment: string;
public queryDsl: string;
public restApis: string;
Expand Down Expand Up @@ -302,7 +301,6 @@ class DocLinks {
this.licenseManagement = '';
this.machineLearningStart = '';
this.mlDocumentEnrichment = '';
this.playground = '';
this.pluginsIngestAttachment = '';
this.queryDsl = '';
this.restApis = '';
Expand Down Expand Up @@ -482,7 +480,6 @@ class DocLinks {
this.licenseManagement = docLinks.links.enterpriseSearch.licenseManagement;
this.machineLearningStart = docLinks.links.enterpriseSearch.machineLearningStart;
this.mlDocumentEnrichment = docLinks.links.enterpriseSearch.mlDocumentEnrichment;
this.playground = docLinks.links.enterpriseSearch.playground;
this.pluginsIngestAttachment = docLinks.links.plugins.ingestAttachment;
this.queryDsl = docLinks.links.query.queryDsl;
this.restApis = docLinks.links.apis.restApis;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ const createStartMock = (): Start => {
PlaygroundProvider: jest.fn(),
PlaygroundToolbar: jest.fn(),
Playground: jest.fn(),
PlaygroundHeaderDocs: jest.fn(),
};

return startContract;
Expand Down
20 changes: 20 additions & 0 deletions x-pack/plugins/search_playground/common/doc_links.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
/*
* 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 { DocLinks } from '@kbn/doc-links';

class PlaygroundDocLinks {
public chatPlayground: string = '';

constructor() {}

setDocLinks(newDocLinks: DocLinks) {
this.chatPlayground = newDocLinks.playground.chatPlayground;
}
}

export const docLinks = new PlaygroundDocLinks();
10 changes: 10 additions & 0 deletions x-pack/plugins/search_playground/common/is_not_nullish.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
/*
* 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.
*/

export function isNotNullish<T>(value: T | null | undefined): value is T {
return value !== null && value !== undefined;
}
7 changes: 7 additions & 0 deletions x-pack/plugins/search_playground/common/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ export enum APIRoutes {
POST_API_KEY = '/internal/search_playground/api_key',
POST_CHAT_MESSAGE = '/internal/search_playground/chat',
POST_QUERY_SOURCE_FIELDS = '/internal/search_playground/query_source_fields',
GET_INDICES = '/internal/search_playground/indices',
}

export enum LLMs {
Expand All @@ -43,3 +44,9 @@ export interface ChatRequestData {
source_fields: string;
doc_size: number;
}

export interface SearchPlaygroundConfigType {
ui: {
enabled: boolean;
};
}
1 change: 1 addition & 0 deletions x-pack/plugins/search_playground/kibana.jsonc
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
"actions",
"encryptedSavedObjects",
"navigation",
"share",
"security",
"stackConnectors",
"triggersActionsUi",
Expand Down
41 changes: 7 additions & 34 deletions x-pack/plugins/search_playground/public/application.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,53 +7,26 @@

import React from 'react';
import ReactDOM from 'react-dom';
import { CoreStart, AppMountParameters } from '@kbn/core/public';
import { CoreStart } from '@kbn/core/public';
import { KibanaRenderContextProvider } from '@kbn/react-kibana-context-render';
import { KibanaContextProvider } from '@kbn/kibana-react-plugin/public';
import { I18nProvider } from '@kbn/i18n-react';
import { BrowserRouter as Router } from '@kbn/shared-ux-router';
import { i18n } from '@kbn/i18n';
import { KibanaPageTemplate } from '@kbn/shared-ux-page-kibana-template';
import { PLUGIN_ID } from '../common';
import { Router } from '@kbn/shared-ux-router';
import { AppPluginStartDependencies } from './types';
import { App } from './components/app';
import { PlaygroundProvider } from './providers/playground_provider';

export const renderApp = (
export const renderApp = async (
core: CoreStart,
services: AppPluginStartDependencies,
{ appBasePath, element }: AppMountParameters
element: HTMLElement
) => {
const navigation = services.navigation;
const { PlaygroundRouter } = await import('./playground_router');

ReactDOM.render(
<KibanaRenderContextProvider {...core}>
<KibanaContextProvider services={{ ...core, ...services }}>
<I18nProvider>
<Router basename={appBasePath}>
<navigation.ui.TopNavMenu appName={PLUGIN_ID} />
<PlaygroundProvider
defaultValues={{
indices: [],
}}
>
<KibanaPageTemplate
pageChrome={[
i18n.translate('xpack.searchPlayground.breadcrumb', {
defaultMessage: 'Playground',
}),
]}
pageHeader={{
pageTitle: i18n.translate('xpack.searchPlayground.pageTitle', {
defaultMessage: 'Playground',
}),
}}
bottomBorder="extended"
restrictWidth={false}
>
<App />
</KibanaPageTemplate>
</PlaygroundProvider>
<Router history={services.history}>
<PlaygroundRouter />
</Router>
</I18nProvider>
</KibanaContextProvider>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
/*
* 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 { i18n } from '@kbn/i18n';
import React from 'react';
import { EuiPageTemplate } from '@elastic/eui';
import { PlaygroundProvider } from './providers/playground_provider';

import { App } from './components/app';
import { PlaygroundToolbar } from './embeddable';
import { PlaygroundHeaderDocs } from './components/playground_header_docs';

export const ChatPlaygroundOverview: React.FC = () => {
return (
<PlaygroundProvider
defaultValues={{
indices: [],
}}
>
<EuiPageTemplate offset={0} grow restrictWidth data-test-subj="svlPlaygroundPage">
<EuiPageTemplate.Header
pageTitle={i18n.translate('xpack.searchPlayground.pageTitle', {
defaultMessage: 'Playground',
})}
data-test-subj="svlPlaygroundPageTitle"
restrictWidth
rightSideItems={[<PlaygroundHeaderDocs />, <PlaygroundToolbar />]}
/>
<App />
</EuiPageTemplate>
</PlaygroundProvider>
);
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
/*
* 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 { EuiButtonEmpty } from '@elastic/eui';

import { i18n } from '@kbn/i18n';

import { docLinks } from '../../common/doc_links';

export const PlaygroundHeaderDocs: React.FC = () => (
<EuiButtonEmpty
data-telemetry-id="playground-header-documentationLink"
data-test-subj="playground-documentation-link"
href={docLinks.chatPlayground}
target="_blank"
iconType="documents"
>
{i18n.translate('xpack.searchPlayground.pageTitle.header.docLink', {
defaultMessage: 'Playground Docs',
})}
</EuiButtonEmpty>
);
4 changes: 4 additions & 0 deletions x-pack/plugins/search_playground/public/embeddable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,10 @@ export const PlaygroundProvider = dynamic(async () => ({
default: (await import('./providers/playground_provider')).PlaygroundProvider,
}));

export const PlaygroundHeaderDocs = dynamic(async () => ({
default: (await import('./components/playground_header_docs')).PlaygroundHeaderDocs,
}));

export const getPlaygroundProvider =
(core: CoreStart, services: AppPluginStartDependencies) =>
(props: React.ComponentProps<typeof PlaygroundProvider>) =>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ export const useManagementLink = (connectorId: string) => {
} = useKibana();
const managementLocator = useMemo(
() => share.url.locators.get('MANAGEMENT_APP_LOCATOR'),
[share]
[share.url.locators]
);
const [managementLink, setManagementLink] = useState('');
useEffect(() => {
Expand Down
Loading

0 comments on commit 41fd643

Please sign in to comment.