mirror of
https://github.com/elastic/kibana.git
synced 2025-04-23 01:13:23 -04:00
# Backport This will backport the following commits from `main` to `8.x`: - [[Search] Search Playground - shared rendering (#201302)](https://github.com/elastic/kibana/pull/201302) <!--- Backport version: 8.9.8 --> ### Questions ? Please refer to the [Backport tool documentation](https://github.com/sqren/backport) <!--BACKPORT [{"author":{"name":"Rodney Norris","email":"rodney.norris@elastic.co"},"sourceCommit":{"committedDate":"2024-12-05T21:09:51Z","message":"[Search] Search Playground - shared rendering (#201302)","sha":"434eaa78ad7c045f52b2126cdae0f1d8fa7a00f6","branchLabelMapping":{"^v9.0.0$":"main","^v8.18.0$":"8.x","^v(\\d+).(\\d+).\\d+$":"$1.$2"}},"sourcePullRequest":{"labels":["release_note:skip","v9.0.0","Team:Search","backport:prev-minor","v8.18.0"],"number":201302,"url":"https://github.com/elastic/kibana/pull/201302","mergeCommit":{"message":"[Search] Search Playground - shared rendering (#201302)","sha":"434eaa78ad7c045f52b2126cdae0f1d8fa7a00f6"}},"sourceBranch":"main","suggestedTargetBranches":["8.x"],"targetPullRequestStates":[{"branch":"main","label":"v9.0.0","labelRegex":"^v9.0.0$","isSourceBranch":true,"state":"MERGED","url":"https://github.com/elastic/kibana/pull/201302","number":201302,"mergeCommit":{"message":"[Search] Search Playground - shared rendering (#201302)","sha":"434eaa78ad7c045f52b2126cdae0f1d8fa7a00f6"}},{"branch":"8.x","label":"v8.18.0","labelRegex":"^v8.18.0$","isSourceBranch":false,"state":"NOT_CREATED"}]}] BACKPORT-->
This commit is contained in:
parent
aa59d7acd4
commit
4dd3c9e47b
57 changed files with 485 additions and 420 deletions
|
@ -84,9 +84,6 @@ xpack.ml.compatibleModuleType: 'search'
|
|||
|
||||
data_visualizer.resultLinks.fileBeat.enabled: false
|
||||
|
||||
# Search Playground
|
||||
xpack.searchPlayground.ui.enabled: true
|
||||
|
||||
# Search InferenceEndpoints
|
||||
xpack.searchInferenceEndpoints.ui.enabled: true
|
||||
|
||||
|
|
|
@ -7,6 +7,7 @@ xpack.infra.enabled: true
|
|||
xpack.uptime.enabled: true
|
||||
xpack.securitySolution.enabled: false
|
||||
xpack.search.notebooks.enabled: false
|
||||
xpack.searchPlayground.enabled: false
|
||||
|
||||
## Fine-tune the observability solution feature privileges. Also, refer to `serverless.yml` for the project-agnostic overrides.
|
||||
xpack.features.overrides:
|
||||
|
|
|
@ -8,6 +8,7 @@ xpack.observabilityLogsExplorer.enabled: false
|
|||
xpack.observability.enabled: false
|
||||
xpack.observabilityAIAssistant.enabled: false
|
||||
xpack.search.notebooks.enabled: false
|
||||
xpack.searchPlayground.enabled: false
|
||||
|
||||
## Fine-tune the security solution feature privileges. Also, refer to `serverless.yml` for the project-agnostic overrides.
|
||||
xpack.features.overrides:
|
||||
|
|
|
@ -16,7 +16,7 @@ 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';
|
||||
export const ES_SEARCH_PLAYGROUND_ID = 'searchPlayground';
|
||||
export const SERVERLESS_ES_SEARCH_INFERENCE_ENDPOINTS_ID = 'searchInferenceEndpoints';
|
||||
export const SEARCH_HOMEPAGE = 'searchHomepage';
|
||||
export const SEARCH_INDICES_START = 'elasticsearchStart';
|
||||
|
|
|
@ -17,7 +17,7 @@ import {
|
|||
ENTERPRISE_SEARCH_ANALYTICS_APP_ID,
|
||||
ENTERPRISE_SEARCH_APPSEARCH_APP_ID,
|
||||
ENTERPRISE_SEARCH_WORKPLACESEARCH_APP_ID,
|
||||
SERVERLESS_ES_SEARCH_PLAYGROUND_ID,
|
||||
ES_SEARCH_PLAYGROUND_ID,
|
||||
SERVERLESS_ES_SEARCH_INFERENCE_ENDPOINTS_ID,
|
||||
SEARCH_HOMEPAGE,
|
||||
SEARCH_INDICES_START,
|
||||
|
@ -38,7 +38,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 SearchPlaygroundId = typeof ES_SEARCH_PLAYGROUND_ID;
|
||||
export type SearchInferenceEndpointsId = typeof SERVERLESS_ES_SEARCH_INFERENCE_ENDPOINTS_ID;
|
||||
export type SearchHomepage = typeof SEARCH_HOMEPAGE;
|
||||
export type SearchStart = typeof SEARCH_INDICES_START;
|
||||
|
@ -50,7 +50,7 @@ export type SearchAISearch = typeof SEARCH_AI_SEARCH;
|
|||
|
||||
export type ContentLinkId = 'searchIndices' | 'connectors' | 'webCrawlers';
|
||||
|
||||
export type ApplicationsLinkId = 'searchApplications' | 'playground';
|
||||
export type ApplicationsLinkId = 'searchApplications';
|
||||
|
||||
export type AppsearchLinkId = 'engines';
|
||||
|
||||
|
|
|
@ -21,6 +21,7 @@ export {
|
|||
SEARCH_VECTOR_SEARCH,
|
||||
SEARCH_SEMANTIC_SEARCH,
|
||||
SEARCH_AI_SEARCH,
|
||||
ES_SEARCH_PLAYGROUND_ID,
|
||||
} from './constants';
|
||||
|
||||
export type {
|
||||
|
|
|
@ -137,6 +137,7 @@ export const applicationUsageSchema = {
|
|||
enterpriseSearch: commonSchema,
|
||||
enterpriseSearchContent: commonSchema,
|
||||
searchInferenceEndpoints: commonSchema,
|
||||
searchPlayground: commonSchema,
|
||||
enterpriseSearchAnalytics: commonSchema,
|
||||
enterpriseSearchApplications: commonSchema,
|
||||
enterpriseSearchAISearch: commonSchema,
|
||||
|
|
|
@ -2229,6 +2229,137 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"searchPlayground": {
|
||||
"properties": {
|
||||
"appId": {
|
||||
"type": "keyword",
|
||||
"_meta": {
|
||||
"description": "The application being tracked"
|
||||
}
|
||||
},
|
||||
"viewId": {
|
||||
"type": "keyword",
|
||||
"_meta": {
|
||||
"description": "Always `main`"
|
||||
}
|
||||
},
|
||||
"clicks_total": {
|
||||
"type": "long",
|
||||
"_meta": {
|
||||
"description": "General number of clicks in the application since we started counting them"
|
||||
}
|
||||
},
|
||||
"clicks_7_days": {
|
||||
"type": "long",
|
||||
"_meta": {
|
||||
"description": "General number of clicks in the application over the last 7 days"
|
||||
}
|
||||
},
|
||||
"clicks_30_days": {
|
||||
"type": "long",
|
||||
"_meta": {
|
||||
"description": "General number of clicks in the application over the last 30 days"
|
||||
}
|
||||
},
|
||||
"clicks_90_days": {
|
||||
"type": "long",
|
||||
"_meta": {
|
||||
"description": "General number of clicks in the application over the last 90 days"
|
||||
}
|
||||
},
|
||||
"minutes_on_screen_total": {
|
||||
"type": "float",
|
||||
"_meta": {
|
||||
"description": "Minutes the application is active and on-screen since we started counting them."
|
||||
}
|
||||
},
|
||||
"minutes_on_screen_7_days": {
|
||||
"type": "float",
|
||||
"_meta": {
|
||||
"description": "Minutes the application is active and on-screen over the last 7 days"
|
||||
}
|
||||
},
|
||||
"minutes_on_screen_30_days": {
|
||||
"type": "float",
|
||||
"_meta": {
|
||||
"description": "Minutes the application is active and on-screen over the last 30 days"
|
||||
}
|
||||
},
|
||||
"minutes_on_screen_90_days": {
|
||||
"type": "float",
|
||||
"_meta": {
|
||||
"description": "Minutes the application is active and on-screen over the last 90 days"
|
||||
}
|
||||
},
|
||||
"views": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"properties": {
|
||||
"appId": {
|
||||
"type": "keyword",
|
||||
"_meta": {
|
||||
"description": "The application being tracked"
|
||||
}
|
||||
},
|
||||
"viewId": {
|
||||
"type": "keyword",
|
||||
"_meta": {
|
||||
"description": "The application view being tracked"
|
||||
}
|
||||
},
|
||||
"clicks_total": {
|
||||
"type": "long",
|
||||
"_meta": {
|
||||
"description": "General number of clicks in the application sub view since we started counting them"
|
||||
}
|
||||
},
|
||||
"clicks_7_days": {
|
||||
"type": "long",
|
||||
"_meta": {
|
||||
"description": "General number of clicks in the active application sub view over the last 7 days"
|
||||
}
|
||||
},
|
||||
"clicks_30_days": {
|
||||
"type": "long",
|
||||
"_meta": {
|
||||
"description": "General number of clicks in the active application sub view over the last 30 days"
|
||||
}
|
||||
},
|
||||
"clicks_90_days": {
|
||||
"type": "long",
|
||||
"_meta": {
|
||||
"description": "General number of clicks in the active application sub view over the last 90 days"
|
||||
}
|
||||
},
|
||||
"minutes_on_screen_total": {
|
||||
"type": "float",
|
||||
"_meta": {
|
||||
"description": "Minutes the application sub view is active and on-screen since we started counting them."
|
||||
}
|
||||
},
|
||||
"minutes_on_screen_7_days": {
|
||||
"type": "float",
|
||||
"_meta": {
|
||||
"description": "Minutes the application is active and on-screen active application sub view over the last 7 days"
|
||||
}
|
||||
},
|
||||
"minutes_on_screen_30_days": {
|
||||
"type": "float",
|
||||
"_meta": {
|
||||
"description": "Minutes the application is active and on-screen active application sub view over the last 30 days"
|
||||
}
|
||||
},
|
||||
"minutes_on_screen_90_days": {
|
||||
"type": "float",
|
||||
"_meta": {
|
||||
"description": "Minutes the application is active and on-screen active application sub view over the last 90 days"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"enterpriseSearchAnalytics": {
|
||||
"properties": {
|
||||
"appId": {
|
||||
|
|
|
@ -13,10 +13,8 @@ import {
|
|||
type CreateIndexLocatorParams,
|
||||
} from './create_index_locator';
|
||||
import { SearchInferenceEndpointLocatorDefinition } from './inference_locator';
|
||||
import { PlaygroundLocatorDefinition, type PlaygroundLocatorParams } from './playground_locator';
|
||||
|
||||
export function registerLocators(share: SharePluginSetup) {
|
||||
share.url.locators.create<CreateIndexLocatorParams>(new CreateIndexLocatorDefinition());
|
||||
share.url.locators.create<PlaygroundLocatorParams>(new PlaygroundLocatorDefinition());
|
||||
share.url.locators.create<SerializableRecord>(new SearchInferenceEndpointLocatorDefinition());
|
||||
}
|
||||
|
|
|
@ -1,28 +0,0 @@
|
|||
/*
|
||||
* 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 type { LocatorDefinition } from '@kbn/share-plugin/common';
|
||||
import type { SerializableRecord } from '@kbn/utility-types';
|
||||
|
||||
import { APPLICATIONS_PLUGIN, PLAYGROUND_URL } from '../constants';
|
||||
|
||||
export type PlaygroundLocatorParams = { 'default-index': string } & SerializableRecord;
|
||||
|
||||
export class PlaygroundLocatorDefinition implements LocatorDefinition<PlaygroundLocatorParams> {
|
||||
public readonly getLocation = async (params: PlaygroundLocatorParams) => {
|
||||
const defaultIndex = params['default-index'];
|
||||
const path = `${PLAYGROUND_URL}${defaultIndex ? `?default-index=${defaultIndex}` : ''}`;
|
||||
|
||||
return {
|
||||
app: APPLICATIONS_PLUGIN.ID,
|
||||
path,
|
||||
state: {},
|
||||
};
|
||||
};
|
||||
|
||||
public readonly id = 'PLAYGROUND_LOCATOR_ID';
|
||||
}
|
|
@ -16,7 +16,6 @@ import { dataPluginMock } from '@kbn/data-plugin/public/mocks';
|
|||
|
||||
import { LensPublicStart } from '@kbn/lens-plugin/public';
|
||||
import { mlPluginMock } from '@kbn/ml-plugin/public/mocks';
|
||||
import { searchPlaygroundMock } from '@kbn/search-playground/__mocks__/search_playground_mock';
|
||||
import { securityMock } from '@kbn/security-plugin/public/mocks';
|
||||
import { sharePluginMock } from '@kbn/share-plugin/public/mocks';
|
||||
|
||||
|
@ -67,7 +66,6 @@ export const mockKibanaValues = {
|
|||
},
|
||||
renderHeaderActions: jest.fn(),
|
||||
searchInferenceEndpoints: null,
|
||||
searchPlayground: searchPlaygroundMock.createStart(),
|
||||
security: securityMock.createStart(),
|
||||
setBreadcrumbs: jest.fn(),
|
||||
setChromeIsVisible: jest.fn(),
|
||||
|
|
|
@ -19,14 +19,12 @@ import { SetEnterpriseSearchApplicationsChrome } from '../../../shared/kibana_ch
|
|||
import { EnterpriseSearchPageTemplateWrapper, PageTemplateProps } from '../../../shared/layout';
|
||||
import { useEnterpriseSearchApplicationNav } from '../../../shared/layout';
|
||||
import { SendEnterpriseSearchTelemetry } from '../../../shared/telemetry';
|
||||
import { PlaygroundHeaderDocsAction } from '../playground/header_docs_action';
|
||||
import { SearchApplicationHeaderDocsAction } from '../search_application/header_docs_action';
|
||||
|
||||
export type EnterpriseSearchApplicationsPageTemplateProps = Omit<
|
||||
PageTemplateProps,
|
||||
'useEndpointHeaderActions'
|
||||
> & {
|
||||
docLink?: 'search_application' | 'playground';
|
||||
hasSchemaConflicts?: boolean;
|
||||
restrictWidth?: boolean;
|
||||
searchApplicationName?: string;
|
||||
|
@ -41,7 +39,6 @@ export const EnterpriseSearchApplicationsPageTemplate: React.FC<
|
|||
searchApplicationName,
|
||||
hasSchemaConflicts,
|
||||
restrictWidth = true,
|
||||
docLink = 'search_application',
|
||||
...pageTemplateProps
|
||||
}) => {
|
||||
const alwaysReturnNavItems = true;
|
||||
|
@ -72,11 +69,7 @@ export const EnterpriseSearchApplicationsPageTemplate: React.FC<
|
|||
);
|
||||
|
||||
useLayoutEffect(() => {
|
||||
const docAction = {
|
||||
playground: PlaygroundHeaderDocsAction,
|
||||
search_application: SearchApplicationHeaderDocsAction,
|
||||
}[docLink];
|
||||
renderHeaderActions(docAction);
|
||||
renderHeaderActions(SearchApplicationHeaderDocsAction);
|
||||
|
||||
return () => {
|
||||
renderHeaderActions();
|
||||
|
|
|
@ -1,27 +0,0 @@
|
|||
/*
|
||||
* 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 { useValues } from 'kea';
|
||||
|
||||
import { KibanaLogic } from '../../../shared/kibana';
|
||||
|
||||
import { EndpointsHeaderAction } from '../../../shared/layout/endpoints_header_action';
|
||||
|
||||
export const PlaygroundHeaderDocsAction: React.FC = () => {
|
||||
const { searchPlayground } = useValues(KibanaLogic);
|
||||
|
||||
if (!searchPlayground) {
|
||||
return null;
|
||||
}
|
||||
return (
|
||||
<EndpointsHeaderAction>
|
||||
<searchPlayground.PlaygroundHeaderDocs />
|
||||
</EndpointsHeaderAction>
|
||||
);
|
||||
};
|
|
@ -1,71 +0,0 @@
|
|||
/*
|
||||
* 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, { useLayoutEffect } from 'react';
|
||||
|
||||
import { useValues } from 'kea';
|
||||
|
||||
import useObservable from 'react-use/lib/useObservable';
|
||||
|
||||
import { SEARCH_PRODUCT_NAME } from '../../../../../common/constants';
|
||||
import { KibanaLogic } from '../../../shared/kibana';
|
||||
import { SetSearchPlaygroundChrome } from '../../../shared/kibana_chrome/set_chrome';
|
||||
import { EnterpriseSearchPageTemplateWrapper, PageTemplateProps } from '../../../shared/layout';
|
||||
import { useEnterpriseSearchNav } from '../../../shared/layout';
|
||||
import { SendEnterpriseSearchTelemetry } from '../../../shared/telemetry';
|
||||
|
||||
import { PlaygroundHeaderDocsAction } from './header_docs_action';
|
||||
|
||||
export type SearchPlaygroundPageTemplateProps = Omit<
|
||||
PageTemplateProps,
|
||||
'useEndpointHeaderActions'
|
||||
> & {
|
||||
hasSchemaConflicts?: boolean;
|
||||
restrictWidth?: boolean;
|
||||
searchApplicationName?: string;
|
||||
};
|
||||
|
||||
export const SearchPlaygroundPageTemplate: React.FC<SearchPlaygroundPageTemplateProps> = ({
|
||||
children,
|
||||
pageChrome,
|
||||
pageViewTelemetry,
|
||||
searchApplicationName,
|
||||
hasSchemaConflicts,
|
||||
restrictWidth = true,
|
||||
...pageTemplateProps
|
||||
}) => {
|
||||
const navItems = useEnterpriseSearchNav();
|
||||
|
||||
const { renderHeaderActions, getChromeStyle$ } = useValues(KibanaLogic);
|
||||
const chromeStyle = useObservable(getChromeStyle$(), 'classic');
|
||||
|
||||
useLayoutEffect(() => {
|
||||
renderHeaderActions(PlaygroundHeaderDocsAction);
|
||||
|
||||
return () => {
|
||||
renderHeaderActions();
|
||||
};
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<EnterpriseSearchPageTemplateWrapper
|
||||
{...pageTemplateProps}
|
||||
solutionNav={{
|
||||
items: chromeStyle === 'classic' ? navItems : undefined,
|
||||
name: SEARCH_PRODUCT_NAME,
|
||||
}}
|
||||
restrictWidth={restrictWidth}
|
||||
setPageChrome={pageChrome && <SetSearchPlaygroundChrome trail={pageChrome} />}
|
||||
useEndpointHeaderActions={false}
|
||||
>
|
||||
{pageViewTelemetry && (
|
||||
<SendEnterpriseSearchTelemetry action="viewed" metric={pageViewTelemetry} />
|
||||
)}
|
||||
{children}
|
||||
</EnterpriseSearchPageTemplateWrapper>
|
||||
);
|
||||
};
|
|
@ -1,46 +0,0 @@
|
|||
/*
|
||||
* 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 { useValues } from 'kea';
|
||||
|
||||
import { i18n } from '@kbn/i18n';
|
||||
|
||||
import { KibanaLogic } from '../../../shared/kibana';
|
||||
|
||||
import { SearchPlaygroundPageTemplate } from './page_template';
|
||||
|
||||
interface PlaygroundProps {
|
||||
pageMode?: 'chat' | 'search';
|
||||
}
|
||||
|
||||
export const Playground: React.FC<PlaygroundProps> = ({ pageMode = 'chat' }) => {
|
||||
const { searchPlayground } = useValues(KibanaLogic);
|
||||
|
||||
if (!searchPlayground) {
|
||||
return null;
|
||||
}
|
||||
return (
|
||||
<searchPlayground.PlaygroundProvider>
|
||||
<SearchPlaygroundPageTemplate
|
||||
pageChrome={[
|
||||
i18n.translate('xpack.enterpriseSearch.content.playground.breadcrumb', {
|
||||
defaultMessage: 'Playground',
|
||||
}),
|
||||
]}
|
||||
pageViewTelemetry="Playground"
|
||||
restrictWidth={false}
|
||||
panelled={false}
|
||||
customPageSections
|
||||
bottomBorder="extended"
|
||||
>
|
||||
<searchPlayground.Playground pageMode={pageMode} />
|
||||
</SearchPlaygroundPageTemplate>
|
||||
</searchPlayground.PlaygroundProvider>
|
||||
);
|
||||
};
|
|
@ -1,19 +0,0 @@
|
|||
/*
|
||||
* 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 enum MessageRole {
|
||||
'user' = 'user',
|
||||
'assistant' = 'assistant',
|
||||
'system' = 'system',
|
||||
}
|
||||
|
||||
export interface Message {
|
||||
id: string;
|
||||
content: string | React.ReactNode;
|
||||
createdAt?: Date;
|
||||
role: MessageRole;
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
/*
|
||||
* 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, { useEffect } from 'react';
|
||||
|
||||
import { ES_SEARCH_PLAYGROUND_ID } from '@kbn/deeplinks-search';
|
||||
|
||||
import { useKibana } from '@kbn/kibana-react-plugin/public';
|
||||
|
||||
export const PlaygroundRedirect: React.FC = () => {
|
||||
const { application } = useKibana().services;
|
||||
|
||||
useEffect(() => {
|
||||
application?.navigateToApp(ES_SEARCH_PLAYGROUND_ID);
|
||||
}, [application]);
|
||||
|
||||
return null;
|
||||
};
|
|
@ -6,35 +6,19 @@
|
|||
*/
|
||||
|
||||
import React from 'react';
|
||||
import { Redirect } from 'react-router-dom';
|
||||
|
||||
import { Routes, Route } from '@kbn/shared-ux-router';
|
||||
|
||||
import { NotFound } from './components/not_found';
|
||||
import { Playground } from './components/playground/playground';
|
||||
import { PlaygroundRedirect } from './components/playground_redirect';
|
||||
import { SearchApplicationsRouter } from './components/search_applications/search_applications_router';
|
||||
import {
|
||||
PLAYGROUND_CHAT_PATH,
|
||||
PLAYGROUND_PATH,
|
||||
PLAYGROUND_SEARCH_PATH,
|
||||
ROOT_PATH,
|
||||
SEARCH_APPLICATIONS_PATH,
|
||||
} from './routes';
|
||||
import { ROOT_PATH, SEARCH_APPLICATIONS_PATH } from './routes';
|
||||
|
||||
export const Applications = () => {
|
||||
return (
|
||||
<Routes>
|
||||
<Redirect exact from={ROOT_PATH} to={PLAYGROUND_PATH} />
|
||||
<Route path={SEARCH_APPLICATIONS_PATH}>
|
||||
<SearchApplicationsRouter />
|
||||
</Route>
|
||||
<Redirect exact from={PLAYGROUND_PATH} to={PLAYGROUND_CHAT_PATH} />
|
||||
<Route path={PLAYGROUND_CHAT_PATH}>
|
||||
<Playground pageMode={'chat'} />
|
||||
</Route>
|
||||
<Route path={PLAYGROUND_SEARCH_PATH}>
|
||||
<Playground pageMode={'search'} />
|
||||
</Route>
|
||||
<Route exact path={ROOT_PATH} component={PlaygroundRedirect} />
|
||||
<Route path={SEARCH_APPLICATIONS_PATH} component={SearchApplicationsRouter} />
|
||||
<Route>
|
||||
<NotFound />
|
||||
</Route>
|
||||
|
|
|
@ -17,9 +17,6 @@ export enum SearchApplicationViewTabs {
|
|||
export const SEARCH_APPLICATION_CREATION_PATH = `${SEARCH_APPLICATIONS_PATH}/new`;
|
||||
export const SEARCH_APPLICATION_PATH = `${SEARCH_APPLICATIONS_PATH}/:searchApplicationName`;
|
||||
export const SEARCH_APPLICATION_TAB_PATH = `${SEARCH_APPLICATION_PATH}/:tabId`;
|
||||
export const PLAYGROUND_PATH = `${ROOT_PATH}playground/`;
|
||||
export const PLAYGROUND_CHAT_PATH = `${PLAYGROUND_PATH}chat`;
|
||||
export const PLAYGROUND_SEARCH_PATH = `${PLAYGROUND_PATH}search`;
|
||||
|
||||
export const SEARCH_APPLICATION_CONNECT_PATH = `${SEARCH_APPLICATION_PATH}/${SearchApplicationViewTabs.CONNECT}/:connectTabId`;
|
||||
export enum SearchApplicationConnectTabs {
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
import React, { useCallback } from 'react';
|
||||
|
||||
import { useValues } from 'kea';
|
||||
|
||||
|
@ -25,9 +25,6 @@ import { FormattedMessage } from '@kbn/i18n-react';
|
|||
|
||||
import { ConnectorStatus } from '@kbn/search-connectors';
|
||||
|
||||
import { APPLICATIONS_PLUGIN } from '../../../../../../common/constants';
|
||||
|
||||
import { PLAYGROUND_PATH } from '../../../../applications/routes';
|
||||
import { generateEncodedPath } from '../../../../shared/encode_path_params';
|
||||
import { KibanaLogic } from '../../../../shared/kibana';
|
||||
import { EuiButtonTo } from '../../../../shared/react_router_helpers';
|
||||
|
@ -53,7 +50,14 @@ export const WhatsNextBox: React.FC<WhatsNextBoxProps> = ({
|
|||
isSyncing = false,
|
||||
isWaitingForConnector = false,
|
||||
}) => {
|
||||
const { navigateToUrl } = useValues(KibanaLogic);
|
||||
const { share } = useValues(KibanaLogic);
|
||||
const onStartPlaygroundClick = useCallback(() => {
|
||||
if (!share) return;
|
||||
const playgroundLocator = share.url.locators.get('PLAYGROUND_LOCATOR_ID');
|
||||
if (playgroundLocator) {
|
||||
playgroundLocator.navigate({ 'default-index': connectorIndex });
|
||||
}
|
||||
}, [connectorIndex, share]);
|
||||
const isConfigured = !(
|
||||
connectorStatus === ConnectorStatus.NEEDS_CONFIGURATION ||
|
||||
connectorStatus === ConnectorStatus.CREATED
|
||||
|
@ -84,14 +88,7 @@ export const WhatsNextBox: React.FC<WhatsNextBoxProps> = ({
|
|||
data-test-subj="enterpriseSearchWhatsNextBoxSearchPlaygroundButton"
|
||||
iconType="sparkles"
|
||||
disabled={!connectorIndex || disabled}
|
||||
onClick={() => {
|
||||
navigateToUrl(
|
||||
`${APPLICATIONS_PLUGIN.URL}${PLAYGROUND_PATH}?default-index=${connectorIndex}`,
|
||||
{
|
||||
shouldNotCreateHref: true,
|
||||
}
|
||||
);
|
||||
}}
|
||||
onClick={onStartPlaygroundClick}
|
||||
>
|
||||
<FormattedMessage
|
||||
id="xpack.enterpriseSearch.whatsNextBox.searchPlaygroundButtonLabel"
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import React, { useCallback, useEffect, useState } from 'react';
|
||||
|
||||
import { css } from '@emotion/react';
|
||||
|
||||
|
@ -30,11 +30,10 @@ import { i18n } from '@kbn/i18n';
|
|||
|
||||
import { useKibana } from '@kbn/kibana-react-plugin/public';
|
||||
|
||||
import { APPLICATIONS_PLUGIN, ELASTICSEARCH_PLUGIN } from '../../../../../../common/constants';
|
||||
import { ELASTICSEARCH_PLUGIN } from '../../../../../../common/constants';
|
||||
|
||||
import { KibanaDeps } from '../../../../../../common/types';
|
||||
|
||||
import { PLAYGROUND_PATH } from '../../../../applications/routes';
|
||||
import { generateEncodedPath } from '../../../../shared/encode_path_params';
|
||||
import { HttpLogic } from '../../../../shared/http';
|
||||
import { KibanaLogic } from '../../../../shared/kibana';
|
||||
|
@ -66,7 +65,14 @@ export const FinishUpStep: React.FC<FinishUpStepProps> = ({ title }) => {
|
|||
const isSyncing = isWaitingForSync || isSyncingProp;
|
||||
|
||||
const { http } = useValues(HttpLogic);
|
||||
const { application } = useValues(KibanaLogic);
|
||||
const { application, share } = useValues(KibanaLogic);
|
||||
const onStartPlaygroundClick = useCallback(() => {
|
||||
if (!share) return;
|
||||
const playgroundLocator = share.url.locators.get('PLAYGROUND_LOCATOR_ID');
|
||||
if (playgroundLocator) {
|
||||
playgroundLocator.navigate({ 'default-index': connector?.index_name });
|
||||
}
|
||||
}, [connector, share]);
|
||||
useEffect(() => {
|
||||
setTimeout(() => {
|
||||
window.scrollTo({
|
||||
|
@ -134,14 +140,7 @@ export const FinishUpStep: React.FC<FinishUpStepProps> = ({ title }) => {
|
|||
'xpack.enterpriseSearch.createConnector.finishUpStep.euiButton.startSearchPlaygroundLabel',
|
||||
{ defaultMessage: 'Start Search Playground' }
|
||||
)}
|
||||
onClick={() => {
|
||||
if (connector) {
|
||||
KibanaLogic.values.navigateToUrl(
|
||||
`${APPLICATIONS_PLUGIN.URL}${PLAYGROUND_PATH}?default-index=${connector.index_name}`,
|
||||
{ shouldNotCreateHref: true }
|
||||
);
|
||||
}
|
||||
}}
|
||||
onClick={onStartPlaygroundClick}
|
||||
>
|
||||
{i18n.translate(
|
||||
'xpack.enterpriseSearch.createConnector.finishUpStep.startSearchPlaygroundButtonLabel',
|
||||
|
|
|
@ -5,14 +5,14 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
import React, { useCallback } from 'react';
|
||||
|
||||
import { useValues } from 'kea';
|
||||
|
||||
import { EuiButton } from '@elastic/eui';
|
||||
|
||||
import { i18n } from '@kbn/i18n';
|
||||
|
||||
import { APPLICATIONS_PLUGIN } from '../../../../../../../common/constants';
|
||||
import { PLAYGROUND_PATH } from '../../../../../applications/routes';
|
||||
import { KibanaLogic } from '../../../../../shared/kibana';
|
||||
|
||||
export interface SearchPlaygroundPopoverProps {
|
||||
|
@ -24,18 +24,21 @@ export const SearchPlaygroundPopover: React.FC<SearchPlaygroundPopoverProps> = (
|
|||
indexName,
|
||||
ingestionMethod,
|
||||
}) => {
|
||||
const playgroundUrl = `${APPLICATIONS_PLUGIN.URL}${PLAYGROUND_PATH}?default-index=${indexName}`;
|
||||
const { share } = useValues(KibanaLogic);
|
||||
const onStartPlaygroundClick = useCallback(() => {
|
||||
if (!share) return;
|
||||
const playgroundLocator = share.url.locators.get('PLAYGROUND_LOCATOR_ID');
|
||||
if (playgroundLocator) {
|
||||
playgroundLocator.navigate({ 'default-index': indexName });
|
||||
}
|
||||
}, [indexName, share]);
|
||||
|
||||
return (
|
||||
<EuiButton
|
||||
data-test-subj="enterpriseSearchSearchPlaygroundPopoverViewInPlaygroundButton"
|
||||
data-telemetry-id={`entSearchContent-${ingestionMethod}-header-viewPlayground`}
|
||||
iconType="eye"
|
||||
onClick={() => {
|
||||
KibanaLogic.values.navigateToUrl(playgroundUrl, {
|
||||
shouldNotCreateHref: true,
|
||||
});
|
||||
}}
|
||||
onClick={onStartPlaygroundClick}
|
||||
>
|
||||
{i18n.translate('xpack.enterpriseSearch.content.index.viewPlayground', {
|
||||
defaultMessage: 'View in Playground',
|
||||
|
|
|
@ -129,7 +129,6 @@ export const renderApp = (
|
|||
params.setHeaderActionMenu(
|
||||
HeaderActions ? renderHeaderActions.bind(null, HeaderActions, store, params) : undefined
|
||||
),
|
||||
searchPlayground: plugins.searchPlayground,
|
||||
searchInferenceEndpoints: plugins.searchInferenceEndpoints,
|
||||
security,
|
||||
setBreadcrumbs: chrome.setBreadcrumbs,
|
||||
|
|
|
@ -30,7 +30,6 @@ import { MlPluginStart } from '@kbn/ml-plugin/public';
|
|||
import { ELASTICSEARCH_URL_PLACEHOLDER } from '@kbn/search-api-panels/constants';
|
||||
import { ConnectorDefinition } from '@kbn/search-connectors';
|
||||
import { SearchInferenceEndpointsPluginStart } from '@kbn/search-inference-endpoints/public';
|
||||
import { SearchPlaygroundPluginStart } from '@kbn/search-playground/public';
|
||||
import { AuthenticatedUser, SecurityPluginStart } from '@kbn/security-plugin/public';
|
||||
import { SharePluginStart } from '@kbn/share-plugin/public';
|
||||
|
||||
|
@ -68,7 +67,6 @@ export interface KibanaLogicProps {
|
|||
productFeatures: ProductFeatures;
|
||||
renderHeaderActions(HeaderActions?: FC): void;
|
||||
searchInferenceEndpoints?: SearchInferenceEndpointsPluginStart;
|
||||
searchPlayground?: SearchPlaygroundPluginStart;
|
||||
security?: SecurityPluginStart;
|
||||
setBreadcrumbs(crumbs: ChromeBreadcrumb[]): void;
|
||||
setChromeIsVisible(isVisible: boolean): void;
|
||||
|
@ -103,7 +101,6 @@ export interface KibanaValues {
|
|||
productFeatures: ProductFeatures;
|
||||
renderHeaderActions(HeaderActions?: FC): void;
|
||||
searchInferenceEndpoints: SearchInferenceEndpointsPluginStart | null;
|
||||
searchPlayground: SearchPlaygroundPluginStart | null;
|
||||
security: SecurityPluginStart | null;
|
||||
setBreadcrumbs(crumbs: ChromeBreadcrumb[]): void;
|
||||
setChromeIsVisible(isVisible: boolean): void;
|
||||
|
@ -150,7 +147,6 @@ export const KibanaLogic = kea<MakeLogicType<KibanaValues>>({
|
|||
productFeatures: [props.productFeatures, {}],
|
||||
renderHeaderActions: [props.renderHeaderActions, {}],
|
||||
searchInferenceEndpoints: [props.searchInferenceEndpoints || null, {}],
|
||||
searchPlayground: [props.searchPlayground || null, {}],
|
||||
security: [props.security || null, {}],
|
||||
setBreadcrumbs: [props.setBreadcrumbs, {}],
|
||||
setChromeIsVisible: [props.setChromeIsVisible, {}],
|
||||
|
|
|
@ -88,7 +88,7 @@ export const buildBaseClassicNavItems = ({
|
|||
{
|
||||
'data-test-subj': 'searchSideNav-Playground',
|
||||
deepLink: {
|
||||
link: 'enterpriseSearchApplications:playground',
|
||||
link: 'searchPlayground',
|
||||
shouldShowActiveForSubroutes: true,
|
||||
},
|
||||
id: 'playground',
|
||||
|
|
|
@ -133,7 +133,7 @@ describe('generateSideNavItems', () => {
|
|||
},
|
||||
{
|
||||
deepLink: {
|
||||
link: 'enterpriseSearchApplications:playground',
|
||||
link: 'searchPlayground',
|
||||
},
|
||||
id: 'unit-test-missing',
|
||||
},
|
||||
|
|
|
@ -73,7 +73,7 @@ const baseNavItems = [
|
|||
items: [
|
||||
{
|
||||
'data-test-subj': 'searchSideNav-Playground',
|
||||
href: '/app/enterprise_search/applications/playground',
|
||||
href: '/app/search_playground',
|
||||
id: 'playground',
|
||||
items: undefined,
|
||||
name: 'Playground',
|
||||
|
@ -188,9 +188,9 @@ const mockNavLinks = [
|
|||
url: '/app/enterprise_search/content/crawlers',
|
||||
},
|
||||
{
|
||||
id: 'enterpriseSearchApplications:playground',
|
||||
id: 'searchPlayground',
|
||||
title: 'Playground',
|
||||
url: '/app/enterprise_search/applications/playground',
|
||||
url: '/app/search_playground',
|
||||
},
|
||||
{
|
||||
id: 'enterpriseSearchApplications:searchApplications',
|
||||
|
|
|
@ -24,7 +24,6 @@ import { dataPluginMock } from '@kbn/data-plugin/public/mocks';
|
|||
import { I18nProvider } from '@kbn/i18n-react';
|
||||
import { LensPublicStart } from '@kbn/lens-plugin/public';
|
||||
import { mlPluginMock } from '@kbn/ml-plugin/public/mocks';
|
||||
import { searchPlaygroundMock } from '@kbn/search-playground/__mocks__/search_playground_mock';
|
||||
import { securityMock } from '@kbn/security-plugin/public/mocks';
|
||||
import { sharePluginMock } from '@kbn/share-plugin/public/mocks';
|
||||
|
||||
|
@ -86,7 +85,6 @@ export const mockKibanaProps: KibanaLogicProps = {
|
|||
hasWebCrawler: true,
|
||||
},
|
||||
renderHeaderActions: jest.fn(),
|
||||
searchPlayground: searchPlaygroundMock.createStart(),
|
||||
security: securityMock.createStart(),
|
||||
setBreadcrumbs: jest.fn(),
|
||||
setChromeIsVisible: jest.fn(),
|
||||
|
|
|
@ -151,7 +151,7 @@ export const getNavigationTreeDefinition = ({
|
|||
{
|
||||
children: [
|
||||
{
|
||||
link: 'enterpriseSearchApplications:playground',
|
||||
link: 'searchPlayground',
|
||||
},
|
||||
{
|
||||
getIsActive: ({ pathNameSerialized, prepend }) => {
|
||||
|
|
|
@ -60,7 +60,7 @@ import { ClientConfigType, InitialAppData, ProductAccess } from '../common/types
|
|||
import { hasEnterpriseLicense } from '../common/utils/licensing';
|
||||
|
||||
import { ENGINES_PATH } from './applications/app_search/routes';
|
||||
import { SEARCH_APPLICATIONS_PATH, PLAYGROUND_PATH } from './applications/applications/routes';
|
||||
import { SEARCH_APPLICATIONS_PATH } from './applications/applications/routes';
|
||||
import {
|
||||
CONNECTORS_PATH,
|
||||
SEARCH_INDICES_PATH,
|
||||
|
@ -151,14 +151,6 @@ const relevanceLinks: AppDeepLink[] = [
|
|||
];
|
||||
|
||||
const applicationsLinks: AppDeepLink[] = [
|
||||
{
|
||||
id: 'playground',
|
||||
path: `/${PLAYGROUND_PATH}`,
|
||||
title: i18n.translate('xpack.enterpriseSearch.navigation.contentPlaygroundLinkLabel', {
|
||||
defaultMessage: 'Playground',
|
||||
}),
|
||||
visibleIn: ['sideNav', 'globalSearch'],
|
||||
},
|
||||
{
|
||||
id: 'searchApplications',
|
||||
path: `/${SEARCH_APPLICATIONS_PATH}`,
|
||||
|
@ -281,6 +273,7 @@ export class EnterpriseSearchPlugin implements Plugin {
|
|||
|
||||
return renderApp(EnterpriseSearchOverview, kibanaDeps, pluginData);
|
||||
},
|
||||
order: 0,
|
||||
title: ENTERPRISE_SEARCH_OVERVIEW_PLUGIN.NAV_TITLE,
|
||||
visibleIn: ['home', 'kibanaOverview', 'globalSearch', 'sideNav'],
|
||||
});
|
||||
|
@ -306,6 +299,7 @@ export class EnterpriseSearchPlugin implements Plugin {
|
|||
|
||||
return renderApp(EnterpriseSearchContent, kibanaDeps, pluginData);
|
||||
},
|
||||
order: 1,
|
||||
title: ENTERPRISE_SEARCH_CONTENT_PLUGIN.NAV_TITLE,
|
||||
});
|
||||
|
||||
|
|
|
@ -1,24 +0,0 @@
|
|||
/*
|
||||
* 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 { SearchPlaygroundPluginStart } from '../public';
|
||||
|
||||
export type Start = jest.Mocked<SearchPlaygroundPluginStart>;
|
||||
|
||||
const createStartMock = (): Start => {
|
||||
const startContract: Start = {
|
||||
PlaygroundProvider: jest.fn(),
|
||||
Playground: jest.fn(),
|
||||
PlaygroundHeaderDocs: jest.fn(),
|
||||
};
|
||||
|
||||
return startContract;
|
||||
};
|
||||
|
||||
export const searchPlaygroundMock = {
|
||||
createStart: createStartMock,
|
||||
};
|
|
@ -5,10 +5,13 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import { Pagination } from './types';
|
||||
|
||||
export const PLUGIN_ID = 'searchPlayground';
|
||||
export const PLUGIN_NAME = 'Playground';
|
||||
export const PLUGIN_NAME = i18n.translate('xpack.searchPlayground.plugin.name', {
|
||||
defaultMessage: 'Playground',
|
||||
});
|
||||
export const PLUGIN_PATH = '/app/search_playground';
|
||||
|
||||
export const SEARCH_MODE_FEATURE_FLAG_ID = 'searchPlayground:searchModeEnabled';
|
||||
|
|
|
@ -18,7 +18,9 @@
|
|||
"actions",
|
||||
"data",
|
||||
"encryptedSavedObjects",
|
||||
"licensing",
|
||||
"ml",
|
||||
"features",
|
||||
"navigation",
|
||||
"share",
|
||||
"security",
|
||||
|
@ -29,6 +31,7 @@
|
|||
"cloud",
|
||||
"console",
|
||||
"usageCollection",
|
||||
"searchNavigation",
|
||||
],
|
||||
"requiredBundles": [
|
||||
"kibanaReact",
|
||||
|
|
|
@ -1,34 +0,0 @@
|
|||
/*
|
||||
* 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 { dynamic } from '@kbn/shared-ux-utility';
|
||||
import { KibanaContextProvider } from '@kbn/kibana-react-plugin/public';
|
||||
import { CoreStart } from '@kbn/core-lifecycle-browser';
|
||||
import { AppPluginStartDependencies } from './types';
|
||||
import { AppProps } from './components/app';
|
||||
|
||||
export const Playground = dynamic<React.FC<AppProps>>(async () => ({
|
||||
default: (await import('./components/app')).App,
|
||||
}));
|
||||
|
||||
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>) =>
|
||||
(
|
||||
<KibanaContextProvider services={{ ...core, ...services }}>
|
||||
<PlaygroundProvider {...props} />
|
||||
</KibanaContextProvider>
|
||||
);
|
|
@ -0,0 +1,25 @@
|
|||
/*
|
||||
* 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 { useEffect } from 'react';
|
||||
import { useKibana } from './use_kibana';
|
||||
|
||||
export const usePlaygroundBreadcrumbs = () => {
|
||||
const { searchNavigation } = useKibana().services;
|
||||
|
||||
useEffect(() => {
|
||||
searchNavigation?.breadcrumbs.setSearchBreadCrumbs(
|
||||
[{ text: 'Build' }, { text: 'Playground' }],
|
||||
{ forClassicChromeStyle: true }
|
||||
);
|
||||
|
||||
return () => {
|
||||
// Clear breadcrumbs on unmount;
|
||||
searchNavigation?.breadcrumbs.clearBreadcrumbs();
|
||||
};
|
||||
}, [searchNavigation]);
|
||||
};
|
|
@ -6,12 +6,13 @@
|
|||
*/
|
||||
|
||||
import React, { useMemo } from 'react';
|
||||
import { EuiPageTemplate } from '@elastic/eui';
|
||||
import { KibanaPageTemplate } from '@kbn/shared-ux-page-kibana-template';
|
||||
import { PlaygroundProvider } from './providers/playground_provider';
|
||||
|
||||
import { useKibana } from './hooks/use_kibana';
|
||||
import { PlaygroundPageMode } from './types';
|
||||
import { App } from './components/app';
|
||||
import { usePlaygroundBreadcrumbs } from './hooks/use_playground_breadcrumbs';
|
||||
|
||||
interface PlaygroundOverviewProps {
|
||||
pageMode?: PlaygroundPageMode;
|
||||
|
@ -20,8 +21,9 @@ export const PlaygroundOverview: React.FC<PlaygroundOverviewProps> = ({
|
|||
pageMode = PlaygroundPageMode.chat,
|
||||
}) => {
|
||||
const {
|
||||
services: { console: consolePlugin },
|
||||
services: { history, console: consolePlugin, searchNavigation },
|
||||
} = useKibana();
|
||||
usePlaygroundBreadcrumbs();
|
||||
|
||||
const embeddableConsole = useMemo(
|
||||
() => (consolePlugin?.EmbeddableConsole ? <consolePlugin.EmbeddableConsole /> : null),
|
||||
|
@ -30,16 +32,17 @@ export const PlaygroundOverview: React.FC<PlaygroundOverviewProps> = ({
|
|||
|
||||
return (
|
||||
<PlaygroundProvider>
|
||||
<EuiPageTemplate
|
||||
<KibanaPageTemplate
|
||||
offset={0}
|
||||
restrictWidth={false}
|
||||
data-test-subj="svlPlaygroundPage"
|
||||
grow={false}
|
||||
panelled={false}
|
||||
solutionNav={searchNavigation?.useClassicNavigation(history)}
|
||||
>
|
||||
<App showDocs pageMode={pageMode} />
|
||||
{embeddableConsole}
|
||||
</EuiPageTemplate>
|
||||
</KibanaPageTemplate>
|
||||
</PlaygroundProvider>
|
||||
);
|
||||
};
|
||||
|
|
|
@ -5,17 +5,20 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import type {
|
||||
CoreSetup,
|
||||
import { BehaviorSubject, type Subscription } from 'rxjs';
|
||||
|
||||
import {
|
||||
type CoreSetup,
|
||||
Plugin,
|
||||
CoreStart,
|
||||
AppMountParameters,
|
||||
PluginInitializerContext,
|
||||
type CoreStart,
|
||||
type AppMountParameters,
|
||||
type PluginInitializerContext,
|
||||
DEFAULT_APP_CATEGORIES,
|
||||
AppUpdater,
|
||||
AppStatus,
|
||||
} from '@kbn/core/public';
|
||||
import { PLUGIN_ID, PLUGIN_NAME, PLUGIN_PATH } from '../common';
|
||||
import { docLinks } from '../common/doc_links';
|
||||
import { PlaygroundHeaderDocs } from './components/playground_header_docs';
|
||||
import { Playground, getPlaygroundProvider } from './embeddable';
|
||||
import type {
|
||||
AppPluginSetupDependencies,
|
||||
AppPluginStartDependencies,
|
||||
|
@ -29,6 +32,8 @@ export class SearchPlaygroundPlugin
|
|||
implements Plugin<SearchPlaygroundPluginSetup, SearchPlaygroundPluginStart>
|
||||
{
|
||||
private config: SearchPlaygroundConfigType;
|
||||
private appUpdater$ = new BehaviorSubject<AppUpdater>(() => ({}));
|
||||
private licenseSubscription: Subscription | undefined;
|
||||
|
||||
constructor(initializerContext: PluginInitializerContext) {
|
||||
this.config = initializerContext.config.get<SearchPlaygroundConfigType>();
|
||||
|
@ -43,12 +48,17 @@ export class SearchPlaygroundPlugin
|
|||
core.application.register({
|
||||
id: PLUGIN_ID,
|
||||
appRoute: PLUGIN_PATH,
|
||||
category: DEFAULT_APP_CATEGORIES.enterpriseSearch,
|
||||
euiIconType: 'logoEnterpriseSearch',
|
||||
status: AppStatus.inaccessible,
|
||||
title: PLUGIN_NAME,
|
||||
updater$: this.appUpdater$,
|
||||
async mount({ element, history }: AppMountParameters) {
|
||||
const { renderApp } = await import('./application');
|
||||
const [coreStart, depsStart] = await core.getStartServices();
|
||||
|
||||
coreStart.chrome.docTitle.change(PLUGIN_NAME);
|
||||
depsStart.searchNavigation?.handleOnAppMount();
|
||||
|
||||
const startDeps: AppPluginStartDependencies = {
|
||||
...depsStart,
|
||||
|
@ -57,6 +67,8 @@ export class SearchPlaygroundPlugin
|
|||
|
||||
return renderApp(coreStart, startDeps, element);
|
||||
},
|
||||
visibleIn: ['sideNav', 'globalSearch'],
|
||||
order: 2,
|
||||
});
|
||||
|
||||
registerLocators(deps.share);
|
||||
|
@ -64,14 +76,29 @@ export class SearchPlaygroundPlugin
|
|||
return {};
|
||||
}
|
||||
|
||||
public start(core: CoreStart, deps: AppPluginStartDependencies): SearchPlaygroundPluginStart {
|
||||
public start(
|
||||
core: CoreStart,
|
||||
{ licensing }: AppPluginStartDependencies
|
||||
): SearchPlaygroundPluginStart {
|
||||
docLinks.setDocLinks(core.docLinks.links);
|
||||
return {
|
||||
PlaygroundProvider: getPlaygroundProvider(core, deps),
|
||||
Playground,
|
||||
PlaygroundHeaderDocs,
|
||||
};
|
||||
|
||||
this.licenseSubscription = licensing.license$.subscribe((license) => {
|
||||
const status: AppStatus =
|
||||
license && license.isAvailable && license.isActive && license.hasAtLeast('enterprise')
|
||||
? AppStatus.accessible
|
||||
: AppStatus.inaccessible;
|
||||
|
||||
this.appUpdater$.next(() => ({
|
||||
status,
|
||||
}));
|
||||
});
|
||||
return {};
|
||||
}
|
||||
|
||||
public stop() {}
|
||||
public stop() {
|
||||
if (this.licenseSubscription) {
|
||||
this.licenseSubscription.unsubscribe();
|
||||
this.licenseSubscription = undefined;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,21 +11,19 @@ import {
|
|||
IndicesStatsIndexMetadataState,
|
||||
Uuid,
|
||||
} from '@elastic/elasticsearch/lib/api/typesWithBodyKey';
|
||||
import { NavigationPublicPluginStart } from '@kbn/navigation-plugin/public';
|
||||
import { SecurityPluginStart } from '@kbn/security-plugin/public';
|
||||
import { HttpStart } from '@kbn/core-http-browser';
|
||||
import type { NavigationPublicPluginStart } from '@kbn/navigation-plugin/public';
|
||||
import React, { ComponentType } from 'react';
|
||||
import { SharePluginSetup, SharePluginStart } from '@kbn/share-plugin/public';
|
||||
import { CloudSetup } from '@kbn/cloud-plugin/public';
|
||||
import { TriggersAndActionsUIPublicPluginStart } from '@kbn/triggers-actions-ui-plugin/public';
|
||||
import { AppMountParameters } from '@kbn/core/public';
|
||||
import { UsageCollectionStart } from '@kbn/usage-collection-plugin/public';
|
||||
import type { SharePluginSetup, SharePluginStart } from '@kbn/share-plugin/public';
|
||||
import type { CloudSetup, CloudStart } from '@kbn/cloud-plugin/public';
|
||||
import type { TriggersAndActionsUIPublicPluginStart } from '@kbn/triggers-actions-ui-plugin/public';
|
||||
import type { AppMountParameters, CoreStart } from '@kbn/core/public';
|
||||
import type { UsageCollectionStart } from '@kbn/usage-collection-plugin/public';
|
||||
import type { ConsolePluginStart } from '@kbn/console-plugin/public';
|
||||
import { DataPublicPluginStart } from '@kbn/data-plugin/public';
|
||||
import { ChatRequestData, MessageRole } from '../common/types';
|
||||
import type { App } from './components/app';
|
||||
import type { PlaygroundProvider as PlaygroundProviderComponent } from './providers/playground_provider';
|
||||
import { PlaygroundHeaderDocs } from './components/playground_header_docs';
|
||||
import type { DataPublicPluginStart } from '@kbn/data-plugin/public';
|
||||
import type { SearchNavigationPluginStart } from '@kbn/search-navigation/public';
|
||||
import type { SecurityPluginStart } from '@kbn/security-plugin/public';
|
||||
import type { LicensingPluginStart } from '@kbn/licensing-plugin/public';
|
||||
import type { ChatRequestData, MessageRole } from '../common/types';
|
||||
|
||||
export * from '../common/types';
|
||||
|
||||
|
@ -36,13 +34,11 @@ export enum PlaygroundPageMode {
|
|||
|
||||
// eslint-disable-next-line @typescript-eslint/no-empty-interface
|
||||
export interface SearchPlaygroundPluginSetup {}
|
||||
export interface SearchPlaygroundPluginStart {
|
||||
PlaygroundProvider: React.FC<React.ComponentProps<typeof PlaygroundProviderComponent>>;
|
||||
Playground: React.FC<React.ComponentProps<typeof App>>;
|
||||
PlaygroundHeaderDocs: React.FC<React.ComponentProps<typeof PlaygroundHeaderDocs>>;
|
||||
}
|
||||
// eslint-disable-next-line @typescript-eslint/no-empty-interface
|
||||
export interface SearchPlaygroundPluginStart {}
|
||||
|
||||
export interface AppPluginSetupDependencies {
|
||||
cloud?: CloudSetup;
|
||||
share: SharePluginSetup;
|
||||
}
|
||||
|
||||
|
@ -52,20 +48,15 @@ export interface AppPluginStartDependencies {
|
|||
navigation: NavigationPublicPluginStart;
|
||||
triggersActionsUi: TriggersAndActionsUIPublicPluginStart;
|
||||
share: SharePluginStart;
|
||||
cloud?: CloudStart;
|
||||
console?: ConsolePluginStart;
|
||||
data: DataPublicPluginStart;
|
||||
searchNavigation?: SearchNavigationPluginStart;
|
||||
security: SecurityPluginStart;
|
||||
licensing: LicensingPluginStart;
|
||||
}
|
||||
|
||||
export interface AppServicesContext {
|
||||
http: HttpStart;
|
||||
security: SecurityPluginStart;
|
||||
share: SharePluginStart;
|
||||
cloud?: CloudSetup;
|
||||
triggersActionsUi: TriggersAndActionsUIPublicPluginStart;
|
||||
usageCollection?: UsageCollectionStart;
|
||||
console?: ConsolePluginStart;
|
||||
data: DataPublicPluginStart;
|
||||
}
|
||||
export type AppServicesContext = CoreStart & AppPluginStartDependencies;
|
||||
|
||||
export enum ChatFormFields {
|
||||
question = 'question',
|
||||
|
|
|
@ -13,7 +13,7 @@ export * from './types';
|
|||
const configSchema = schema.object({
|
||||
enabled: schema.boolean({ defaultValue: true }),
|
||||
ui: schema.object({
|
||||
enabled: schema.boolean({ defaultValue: false }),
|
||||
enabled: schema.boolean({ defaultValue: true }),
|
||||
}),
|
||||
});
|
||||
|
||||
|
|
|
@ -5,15 +5,25 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import { PluginInitializerContext, CoreSetup, CoreStart, Plugin, Logger } from '@kbn/core/server';
|
||||
import {
|
||||
PluginInitializerContext,
|
||||
CoreSetup,
|
||||
CoreStart,
|
||||
Plugin,
|
||||
Logger,
|
||||
DEFAULT_APP_CATEGORIES,
|
||||
} from '@kbn/core/server';
|
||||
import { KibanaFeatureScope } from '@kbn/features-plugin/common';
|
||||
|
||||
import { sendMessageEvent } from './analytics/events';
|
||||
import {
|
||||
SearchPlaygroundPluginSetup,
|
||||
SearchPlaygroundPluginSetupDependencies,
|
||||
SearchPlaygroundPluginStart,
|
||||
SearchPlaygroundPluginStartDependencies,
|
||||
} from './types';
|
||||
import { defineRoutes } from './routes';
|
||||
import { PLUGIN_ID, PLUGIN_NAME } from '../common';
|
||||
|
||||
export class SearchPlaygroundPlugin
|
||||
implements
|
||||
|
@ -31,7 +41,8 @@ export class SearchPlaygroundPlugin
|
|||
}
|
||||
|
||||
public setup(
|
||||
core: CoreSetup<SearchPlaygroundPluginStartDependencies, SearchPlaygroundPluginStart>
|
||||
core: CoreSetup<SearchPlaygroundPluginStartDependencies, SearchPlaygroundPluginStart>,
|
||||
{ features }: SearchPlaygroundPluginSetupDependencies
|
||||
) {
|
||||
this.logger.debug('searchPlayground: Setup');
|
||||
const router = core.http.createRouter();
|
||||
|
@ -40,6 +51,37 @@ export class SearchPlaygroundPlugin
|
|||
|
||||
this.registerAnalyticsEvents(core);
|
||||
|
||||
features.registerKibanaFeature({
|
||||
id: PLUGIN_ID,
|
||||
minimumLicense: 'enterprise',
|
||||
name: PLUGIN_NAME,
|
||||
order: 1,
|
||||
category: DEFAULT_APP_CATEGORIES.enterpriseSearch,
|
||||
scope: [KibanaFeatureScope.Spaces, KibanaFeatureScope.Security],
|
||||
app: ['kibana', PLUGIN_ID],
|
||||
catalogue: [PLUGIN_ID],
|
||||
privileges: {
|
||||
all: {
|
||||
app: ['kibana', PLUGIN_ID],
|
||||
api: [PLUGIN_ID],
|
||||
catalogue: [PLUGIN_ID],
|
||||
savedObject: {
|
||||
all: [],
|
||||
read: [],
|
||||
},
|
||||
ui: [],
|
||||
},
|
||||
read: {
|
||||
disabled: true,
|
||||
savedObject: {
|
||||
all: [],
|
||||
read: [],
|
||||
},
|
||||
ui: [],
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
|
|
|
@ -9,6 +9,7 @@ import { schema } from '@kbn/config-schema';
|
|||
import type { Logger } from '@kbn/logging';
|
||||
import { IRouter, StartServicesAccessor } from '@kbn/core/server';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import { PLUGIN_ID } from '../common';
|
||||
import { sendMessageEvent, SendMessageEventData } from './analytics/events';
|
||||
import { fetchFields } from './lib/fetch_query_source_fields';
|
||||
import { AssistClientOptionsWithClient, createAssist as Assist } from './utils/assist';
|
||||
|
@ -53,6 +54,14 @@ export function defineRoutes({
|
|||
router.post(
|
||||
{
|
||||
path: APIRoutes.POST_QUERY_SOURCE_FIELDS,
|
||||
options: {
|
||||
access: 'internal',
|
||||
},
|
||||
security: {
|
||||
authz: {
|
||||
requiredPrivileges: [PLUGIN_ID],
|
||||
},
|
||||
},
|
||||
validate: {
|
||||
body: schema.object({
|
||||
indices: schema.arrayOf(schema.string()),
|
||||
|
@ -74,6 +83,14 @@ export function defineRoutes({
|
|||
router.post(
|
||||
{
|
||||
path: APIRoutes.POST_CHAT_MESSAGE,
|
||||
options: {
|
||||
access: 'internal',
|
||||
},
|
||||
security: {
|
||||
authz: {
|
||||
requiredPrivileges: [PLUGIN_ID],
|
||||
},
|
||||
},
|
||||
validate: {
|
||||
body: schema.object({
|
||||
data: schema.object({
|
||||
|
@ -194,6 +211,14 @@ export function defineRoutes({
|
|||
router.get(
|
||||
{
|
||||
path: APIRoutes.GET_INDICES,
|
||||
options: {
|
||||
access: 'internal',
|
||||
},
|
||||
security: {
|
||||
authz: {
|
||||
requiredPrivileges: [PLUGIN_ID],
|
||||
},
|
||||
},
|
||||
validate: {
|
||||
query: schema.object({
|
||||
search_query: schema.maybe(schema.string()),
|
||||
|
@ -223,6 +248,14 @@ export function defineRoutes({
|
|||
router.post(
|
||||
{
|
||||
path: APIRoutes.POST_SEARCH_QUERY,
|
||||
options: {
|
||||
access: 'internal',
|
||||
},
|
||||
security: {
|
||||
authz: {
|
||||
requiredPrivileges: [PLUGIN_ID],
|
||||
},
|
||||
},
|
||||
validate: {
|
||||
body: schema.object({
|
||||
search_query: schema.string(),
|
||||
|
@ -287,6 +320,14 @@ export function defineRoutes({
|
|||
router.post(
|
||||
{
|
||||
path: APIRoutes.GET_INDEX_MAPPINGS,
|
||||
options: {
|
||||
access: 'internal',
|
||||
},
|
||||
security: {
|
||||
authz: {
|
||||
requiredPrivileges: [PLUGIN_ID],
|
||||
},
|
||||
},
|
||||
validate: {
|
||||
body: schema.object({
|
||||
indices: schema.arrayOf(schema.string()),
|
||||
|
|
|
@ -5,8 +5,9 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import { PluginStartContract as ActionsPluginStartContract } from '@kbn/actions-plugin/server';
|
||||
import { CloudStart } from '@kbn/cloud-plugin/server';
|
||||
import type { PluginStartContract as ActionsPluginStartContract } from '@kbn/actions-plugin/server';
|
||||
import type { CloudSetup, CloudStart } from '@kbn/cloud-plugin/server';
|
||||
import type { FeaturesPluginSetup } from '@kbn/features-plugin/server';
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-empty-interface
|
||||
export interface SearchPlaygroundPluginSetup {}
|
||||
|
@ -14,6 +15,11 @@ export interface SearchPlaygroundPluginSetup {}
|
|||
// eslint-disable-next-line @typescript-eslint/no-empty-interface
|
||||
export interface SearchPlaygroundPluginStart {}
|
||||
|
||||
export interface SearchPlaygroundPluginSetupDependencies {
|
||||
cloud?: CloudSetup;
|
||||
features: FeaturesPluginSetup;
|
||||
}
|
||||
|
||||
export interface SearchPlaygroundPluginStartDependencies {
|
||||
actions: ActionsPluginStartContract;
|
||||
cloud?: CloudStart;
|
||||
|
|
|
@ -17,7 +17,6 @@
|
|||
"@kbn/i18n",
|
||||
"@kbn/i18n-react",
|
||||
"@kbn/kibana-react-plugin",
|
||||
"@kbn/security-plugin",
|
||||
"@kbn/user-profile-components",
|
||||
"@kbn/shared-ux-router",
|
||||
"@kbn/shared-ux-page-kibana-template",
|
||||
|
@ -26,8 +25,6 @@
|
|||
"@kbn/share-plugin",
|
||||
"@kbn/cloud-plugin",
|
||||
"@kbn/actions-plugin",
|
||||
"@kbn/shared-ux-utility",
|
||||
"@kbn/core-lifecycle-browser",
|
||||
"@kbn/stack-connectors-plugin",
|
||||
"@kbn/cases-plugin",
|
||||
"@kbn/triggers-actions-ui-plugin",
|
||||
|
@ -46,6 +43,10 @@
|
|||
"@kbn/discover-utils",
|
||||
"@kbn/data-plugin",
|
||||
"@kbn/search-index-documents",
|
||||
"@kbn/search-navigation",
|
||||
"@kbn/features-plugin",
|
||||
"@kbn/security-plugin",
|
||||
"@kbn/licensing-plugin",
|
||||
],
|
||||
"exclude": [
|
||||
"target/**/*",
|
||||
|
|
|
@ -12,13 +12,17 @@ import type {
|
|||
PluginInitializerContext,
|
||||
ScopedHistory,
|
||||
} from '@kbn/core/public';
|
||||
import type { ChromeStyle } from '@kbn/core-chrome-browser';
|
||||
import type { Subscription } from 'rxjs';
|
||||
import type { ChromeBreadcrumb, ChromeStyle } from '@kbn/core-chrome-browser';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import type { Logger } from '@kbn/logging';
|
||||
import type {
|
||||
SearchNavigationPluginSetup,
|
||||
SearchNavigationPluginStart,
|
||||
ClassicNavItem,
|
||||
ClassicNavigationFactoryFn,
|
||||
SearchNavigationSetBreadcrumbsOptions,
|
||||
AppPluginStartDependencies,
|
||||
} from './types';
|
||||
|
||||
export class SearchNavigationPlugin
|
||||
|
@ -28,8 +32,10 @@ export class SearchNavigationPlugin
|
|||
private currentChromeStyle: ChromeStyle | undefined = undefined;
|
||||
private baseClassicNavItemsFn: (() => ClassicNavItem[]) | undefined = undefined;
|
||||
private coreStart: CoreStart | undefined = undefined;
|
||||
private pluginsStart: AppPluginStartDependencies | undefined = undefined;
|
||||
private classicNavFactory: ClassicNavigationFactoryFn | undefined = undefined;
|
||||
private onAppMountHandlers: Array<() => Promise<void>> = [];
|
||||
private chromeSub: Subscription | undefined;
|
||||
|
||||
constructor(private readonly initializerContext: PluginInitializerContext) {
|
||||
this.logger = this.initializerContext.logger.get();
|
||||
|
@ -39,9 +45,10 @@ export class SearchNavigationPlugin
|
|||
return {};
|
||||
}
|
||||
|
||||
public start(core: CoreStart): SearchNavigationPluginStart {
|
||||
public start(core: CoreStart, plugins: AppPluginStartDependencies): SearchNavigationPluginStart {
|
||||
this.coreStart = core;
|
||||
core.chrome.getChromeStyle$().subscribe((value) => {
|
||||
this.pluginsStart = plugins;
|
||||
this.chromeSub = core.chrome.getChromeStyle$().subscribe((value) => {
|
||||
this.currentChromeStyle = value;
|
||||
});
|
||||
|
||||
|
@ -54,10 +61,19 @@ export class SearchNavigationPlugin
|
|||
registerOnAppMountHandler: this.registerOnAppMountHandler.bind(this),
|
||||
setGetBaseClassicNavItems: this.setGetBaseClassicNavItems.bind(this),
|
||||
useClassicNavigation: this.useClassicNavigation.bind(this),
|
||||
breadcrumbs: {
|
||||
setSearchBreadCrumbs: this.setBreadcrumbs.bind(this),
|
||||
clearBreadcrumbs: this.clearBreadcrumbs.bind(this),
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
public stop() {}
|
||||
public stop() {
|
||||
if (this.chromeSub) {
|
||||
this.chromeSub.unsubscribe();
|
||||
this.chromeSub = undefined;
|
||||
}
|
||||
}
|
||||
|
||||
private async handleOnAppMount() {
|
||||
if (this.onAppMountHandlers.length === 0) return;
|
||||
|
@ -89,4 +105,36 @@ export class SearchNavigationPlugin
|
|||
|
||||
return this.classicNavFactory(this.baseClassicNavItemsFn(), this.coreStart, history);
|
||||
}
|
||||
|
||||
private setBreadcrumbs(
|
||||
breadcrumbs: ChromeBreadcrumb[],
|
||||
{ forClassicChromeStyle = false }: SearchNavigationSetBreadcrumbsOptions = {}
|
||||
) {
|
||||
if (forClassicChromeStyle === true && this.currentChromeStyle !== 'classic') return;
|
||||
|
||||
const searchBreadcrumbs = [this.getSearchHomeBreadcrumb(), ...breadcrumbs];
|
||||
if (this.pluginsStart?.serverless) {
|
||||
this.pluginsStart.serverless.setBreadcrumbs(searchBreadcrumbs);
|
||||
} else {
|
||||
this.coreStart?.chrome.setBreadcrumbs(searchBreadcrumbs);
|
||||
}
|
||||
}
|
||||
|
||||
private clearBreadcrumbs() {
|
||||
if (this.pluginsStart?.serverless) {
|
||||
this.pluginsStart.serverless.setBreadcrumbs([]);
|
||||
} else {
|
||||
this.coreStart?.chrome.setBreadcrumbs([]);
|
||||
}
|
||||
}
|
||||
|
||||
private getSearchHomeBreadcrumb(): ChromeBreadcrumb {
|
||||
// TODO: When search_navigation handles solution nav, use the default
|
||||
// home deep link for this breadcrumb's path.
|
||||
return {
|
||||
text: i18n.translate('xpack.searchNavigation.breadcrumbs.home.title', {
|
||||
defaultMessage: 'Elasticsearch',
|
||||
}),
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
*/
|
||||
|
||||
import type { ReactNode } from 'react';
|
||||
import type { AppDeepLinkId } from '@kbn/core-chrome-browser';
|
||||
import type { AppDeepLinkId, ChromeBreadcrumb } from '@kbn/core-chrome-browser';
|
||||
import type { CoreStart, ScopedHistory } from '@kbn/core/public';
|
||||
import type { ServerlessPluginSetup, ServerlessPluginStart } from '@kbn/serverless/public';
|
||||
import type { SolutionNavProps } from '@kbn/shared-ux-page-solution-nav';
|
||||
|
@ -20,6 +20,13 @@ export interface SearchNavigationPluginStart {
|
|||
// This is temporary until we can migrate building the class nav item list out of `enterprise_search` plugin
|
||||
setGetBaseClassicNavItems: (classicNavItemsFn: () => ClassicNavItem[]) => void;
|
||||
useClassicNavigation: (history: ScopedHistory<unknown>) => SolutionNavProps | undefined;
|
||||
breadcrumbs: {
|
||||
setSearchBreadCrumbs: (
|
||||
breadcrumbs: ChromeBreadcrumb[],
|
||||
options?: SearchNavigationSetBreadcrumbsOptions
|
||||
) => void;
|
||||
clearBreadcrumbs: () => void;
|
||||
};
|
||||
}
|
||||
|
||||
export interface AppPluginSetupDependencies {
|
||||
|
@ -49,3 +56,10 @@ export type ClassicNavigationFactoryFn = (
|
|||
core: CoreStart,
|
||||
history: ScopedHistory<unknown>
|
||||
) => SolutionNavProps | undefined;
|
||||
|
||||
export interface SearchNavigationSetBreadcrumbsOptions {
|
||||
// When set to `true` breadcrumbs are only set when chrome style is set to classic.
|
||||
// This option is for pages who rely on Solution Navigation for breadcrumbs, but still
|
||||
// need to explicitly set the page breadcrumbs for classic solution view.
|
||||
forClassicChromeStyle?: boolean;
|
||||
}
|
||||
|
|
|
@ -4,11 +4,8 @@
|
|||
"outDir": "target/types"
|
||||
},
|
||||
"include": [
|
||||
"__mocks__/**/*",
|
||||
"common/**/*",
|
||||
"public/**/*",
|
||||
"server/**/*",
|
||||
"../../../../typings/**/*"
|
||||
],
|
||||
"kbn_references": [
|
||||
"@kbn/core",
|
||||
|
|
|
@ -35,6 +35,7 @@
|
|||
"indexManagement",
|
||||
"searchConnectors",
|
||||
"searchInferenceEndpoints",
|
||||
"searchPlayground",
|
||||
"usageCollection"
|
||||
],
|
||||
"requiredBundles": ["kibanaReact"]
|
||||
|
|
|
@ -17868,7 +17868,6 @@
|
|||
"xpack.enterpriseSearch.content.overview.gettingStarted.generateApiKeyPanel.panelTitle": "Générer une clé d’API",
|
||||
"xpack.enterpriseSearch.content.overview.gettingStarted.pageDescription": "Configurez votre client de langage de programmation, ingérez des données, et vous serez prêt à commencer vos recherches en quelques minutes.",
|
||||
"xpack.enterpriseSearch.content.overview.gettingStarted.pageTitle": "Clients linguistiques Elasticsearch",
|
||||
"xpack.enterpriseSearch.content.playground.breadcrumb": "Playground",
|
||||
"xpack.enterpriseSearch.content.searchIndex.cancelSync.successMessage": "Annulation réussie de la synchronisation",
|
||||
"xpack.enterpriseSearch.content.searchIndex.cancelSyncs.successMessage": "Annulation réussie des synchronisations",
|
||||
"xpack.enterpriseSearch.content.searchIndex.cannotConnect.body": "Le robot d'indexation Elastic requiert Enterprise Search. {link}",
|
||||
|
@ -18444,7 +18443,6 @@
|
|||
"xpack.enterpriseSearch.navigation.appSearchEnginesLinkLabel": "Moteurs",
|
||||
"xpack.enterpriseSearch.navigation.contentConnectorsLinkLabel": "Connecteurs",
|
||||
"xpack.enterpriseSearch.navigation.contentIndicesLinkLabel": "Index",
|
||||
"xpack.enterpriseSearch.navigation.contentPlaygroundLinkLabel": "Playground",
|
||||
"xpack.enterpriseSearch.navigation.contentWebcrawlersLinkLabel": "Robots d'indexation",
|
||||
"xpack.enterpriseSearch.navigation.relevanceInferenceEndpointsLinkLabel": "Points de terminaison d'inférence",
|
||||
"xpack.enterpriseSearch.noEntSearch.noCrawler": "Le robot d'indexation d'Elastic n'est pas disponible sans Entreprise Search.",
|
||||
|
|
|
@ -17727,7 +17727,6 @@
|
|||
"xpack.enterpriseSearch.content.overview.gettingStarted.generateApiKeyPanel.panelTitle": "APIキーを生成",
|
||||
"xpack.enterpriseSearch.content.overview.gettingStarted.pageDescription": "プログラミング言語のクライアントを設定し、データを取り込めば、数分で検索を開始できます。",
|
||||
"xpack.enterpriseSearch.content.overview.gettingStarted.pageTitle": "Elasticsearch言語クライアント",
|
||||
"xpack.enterpriseSearch.content.playground.breadcrumb": "Playground",
|
||||
"xpack.enterpriseSearch.content.searchIndex.cancelSync.successMessage": "同期が正常にキャンセルされました",
|
||||
"xpack.enterpriseSearch.content.searchIndex.cancelSyncs.successMessage": "同期が正常にキャンセルされました",
|
||||
"xpack.enterpriseSearch.content.searchIndex.cannotConnect.body": "Elastic Webクローラーにはエンタープライズ サーチが必要です。{link}",
|
||||
|
@ -18301,7 +18300,6 @@
|
|||
"xpack.enterpriseSearch.navigation.appSearchEnginesLinkLabel": "エンジン",
|
||||
"xpack.enterpriseSearch.navigation.contentConnectorsLinkLabel": "コネクター",
|
||||
"xpack.enterpriseSearch.navigation.contentIndicesLinkLabel": "インデックス",
|
||||
"xpack.enterpriseSearch.navigation.contentPlaygroundLinkLabel": "Playground",
|
||||
"xpack.enterpriseSearch.navigation.contentWebcrawlersLinkLabel": "Webクローラー",
|
||||
"xpack.enterpriseSearch.navigation.relevanceInferenceEndpointsLinkLabel": "推論エンドポイント",
|
||||
"xpack.enterpriseSearch.noEntSearch.noCrawler": "Elastic Webクローラーはエンタープライズ サーチなしでは利用できません。",
|
||||
|
|
|
@ -17798,7 +17798,6 @@
|
|||
"xpack.enterpriseSearch.content.overview.gettingStarted.generateApiKeyPanel.panelTitle": "生成 API 密钥",
|
||||
"xpack.enterpriseSearch.content.overview.gettingStarted.pageDescription": "设置您的编程语言客户端,采集一些数据,如此即可在数分钟内开始搜索。",
|
||||
"xpack.enterpriseSearch.content.overview.gettingStarted.pageTitle": "Elasticsearch 语言客户端",
|
||||
"xpack.enterpriseSearch.content.playground.breadcrumb": "Playground",
|
||||
"xpack.enterpriseSearch.content.searchIndex.cancelSync.successMessage": "已成功取消同步",
|
||||
"xpack.enterpriseSearch.content.searchIndex.cancelSyncs.successMessage": "已成功取消同步",
|
||||
"xpack.enterpriseSearch.content.searchIndex.cannotConnect.body": "Elastic 网络爬虫需要 Enterprise Search。{link}",
|
||||
|
@ -18374,7 +18373,6 @@
|
|||
"xpack.enterpriseSearch.navigation.appSearchEnginesLinkLabel": "引擎",
|
||||
"xpack.enterpriseSearch.navigation.contentConnectorsLinkLabel": "连接器",
|
||||
"xpack.enterpriseSearch.navigation.contentIndicesLinkLabel": "索引",
|
||||
"xpack.enterpriseSearch.navigation.contentPlaygroundLinkLabel": "Playground",
|
||||
"xpack.enterpriseSearch.navigation.contentWebcrawlersLinkLabel": "网络爬虫",
|
||||
"xpack.enterpriseSearch.navigation.relevanceInferenceEndpointsLinkLabel": "推理终端",
|
||||
"xpack.enterpriseSearch.noEntSearch.noCrawler": "如果没有 Enterprise Search,Elastic 网络爬虫将不可用。",
|
||||
|
|
|
@ -129,6 +129,7 @@ export default function ({ getService }: FtrProviderContext) {
|
|||
'rulesSettings',
|
||||
'uptime',
|
||||
'searchInferenceEndpoints',
|
||||
'searchPlayground',
|
||||
'siem',
|
||||
'slo',
|
||||
'securitySolutionAssistant',
|
||||
|
@ -180,6 +181,7 @@ export default function ({ getService }: FtrProviderContext) {
|
|||
'rulesSettings',
|
||||
'uptime',
|
||||
'searchInferenceEndpoints',
|
||||
'searchPlayground',
|
||||
'siem',
|
||||
'slo',
|
||||
'securitySolutionAssistant',
|
||||
|
|
|
@ -60,6 +60,7 @@ export default function ({ getService }: FtrProviderContext) {
|
|||
],
|
||||
observabilityAIAssistant: ['all', 'read', 'minimal_all', 'minimal_read'],
|
||||
slo: ['all', 'read', 'minimal_all', 'minimal_read'],
|
||||
searchPlayground: ['all', 'read', 'minimal_all', 'minimal_read'],
|
||||
searchInferenceEndpoints: ['all', 'read', 'minimal_all', 'minimal_read'],
|
||||
fleetv2: ['all', 'read', 'minimal_all', 'minimal_read'],
|
||||
fleet: ['all', 'read', 'minimal_all', 'minimal_read'],
|
||||
|
|
|
@ -50,6 +50,7 @@ export default function ({ getService }: FtrProviderContext) {
|
|||
securitySolutionAttackDiscovery: ['all', 'read', 'minimal_all', 'minimal_read'],
|
||||
securitySolutionCases: ['all', 'read', 'minimal_all', 'minimal_read'],
|
||||
securitySolutionCasesV2: ['all', 'read', 'minimal_all', 'minimal_read'],
|
||||
searchPlayground: ['all', 'read', 'minimal_all', 'minimal_read'],
|
||||
searchInferenceEndpoints: ['all', 'read', 'minimal_all', 'minimal_read'],
|
||||
fleetv2: ['all', 'read', 'minimal_all', 'minimal_read'],
|
||||
fleet: ['all', 'read', 'minimal_all', 'minimal_read'],
|
||||
|
@ -146,6 +147,7 @@ export default function ({ getService }: FtrProviderContext) {
|
|||
],
|
||||
observabilityAIAssistant: ['all', 'read', 'minimal_all', 'minimal_read'],
|
||||
slo: ['all', 'read', 'minimal_all', 'minimal_read'],
|
||||
searchPlayground: ['all', 'read', 'minimal_all', 'minimal_read'],
|
||||
searchInferenceEndpoints: ['all', 'read', 'minimal_all', 'minimal_read'],
|
||||
fleetv2: ['all', 'read', 'minimal_all', 'minimal_read'],
|
||||
fleet: ['all', 'read', 'minimal_all', 'minimal_read'],
|
||||
|
|
|
@ -144,15 +144,15 @@ export default function searchSolutionNavigation({
|
|||
// check Build
|
||||
// > Playground
|
||||
await solutionNavigation.sidenav.clickLink({
|
||||
deepLinkId: 'enterpriseSearchApplications:playground',
|
||||
deepLinkId: 'searchPlayground',
|
||||
});
|
||||
await solutionNavigation.sidenav.expectLinkActive({
|
||||
deepLinkId: 'enterpriseSearchApplications:playground',
|
||||
deepLinkId: 'searchPlayground',
|
||||
});
|
||||
await solutionNavigation.breadcrumbs.expectBreadcrumbExists({ text: 'Build' });
|
||||
await solutionNavigation.breadcrumbs.expectBreadcrumbExists({ text: 'Playground' });
|
||||
await solutionNavigation.breadcrumbs.expectBreadcrumbExists({
|
||||
deepLinkId: 'enterpriseSearchApplications:playground',
|
||||
deepLinkId: 'searchPlayground',
|
||||
});
|
||||
// > Search applications
|
||||
await solutionNavigation.sidenav.clickLink({
|
||||
|
@ -293,7 +293,7 @@ export default function searchSolutionNavigation({
|
|||
'enterpriseSearchContent:connectors',
|
||||
'enterpriseSearchContent:webCrawlers',
|
||||
'build',
|
||||
'enterpriseSearchApplications:playground',
|
||||
'searchPlayground',
|
||||
'enterpriseSearchApplications:searchApplications',
|
||||
'enterpriseSearchAnalytics',
|
||||
'relevance',
|
||||
|
|
|
@ -84,6 +84,7 @@ export default function ({ getService }: FtrProviderContext) {
|
|||
apm: 0,
|
||||
enterpriseSearch: 0,
|
||||
searchInferenceEndpoints: 0,
|
||||
searchPlayground: 0,
|
||||
siem: 0,
|
||||
securitySolutionCases: 0,
|
||||
securitySolutionCasesV2: 0,
|
||||
|
|
|
@ -93,6 +93,7 @@ export default function catalogueTests({ getService }: FtrProviderContext) {
|
|||
'enterpriseSearchVectorSearch',
|
||||
'enterpriseSearchSemanticSearch',
|
||||
'enterpriseSearchElasticsearch',
|
||||
'searchPlayground',
|
||||
'searchInferenceEndpoints',
|
||||
'appSearch',
|
||||
'observabilityAIAssistant',
|
||||
|
|
|
@ -64,6 +64,7 @@ export default function navLinksTests({ getService }: FtrProviderContext) {
|
|||
'monitoring',
|
||||
'observabilityAIAssistant',
|
||||
'enterpriseSearch',
|
||||
'searchPlayground',
|
||||
'searchInferenceEndpoints',
|
||||
'guidedOnboardingFeature',
|
||||
'securitySolutionAssistant',
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue