Skip to content

Commit

Permalink
[Search] Add a search guide selector to index onboarding (elastic#206810
Browse files Browse the repository at this point in the history
)

## Summary

This adds a guide selector to the Kibana index management onboarding
experience.

It also fixes a bug where useQuery was causing us to re-render the page
unnecessarily.

<img width="1284" alt="Screenshot 2025-01-15 at 16 11 48"
src="https://github.com/user-attachments/assets/19abe86f-3148-442a-8e1e-8b6b8eeb2ba1"
/>

### Checklist
Check the PR satisfies following conditions. 

Reviewers should verify this PR satisfies this list as well.

- [x] 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/src/platform/packages/shared/kbn-i18n/README.md)
- [x] [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
- [x] The PR description includes the appropriate Release Notes section,
and the correct `release_note:*` label is applied per the
[guidelines](https://www.elastic.co/guide/en/kibana/master/contributing.html#kibana-release-notes-process)

---------

Co-authored-by: Rodney Norris <[email protected]>
  • Loading branch information
sphilipse and TattdCodeMonkey authored Jan 17, 2025
1 parent ba0aa3f commit 63fc1ea
Show file tree
Hide file tree
Showing 29 changed files with 663 additions and 235 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,15 @@ export enum AnalyticsEvents {
startPageShowCreateIndexUIClick = 'start_page_show_create_index_ui',
startCreateIndexPageModifyIndexName = 'start_modify_index_name',
startCreateIndexClick = 'start_create_index',
startCreateIndexWorkflowSelect = 'start_workflow_select',
startCreateIndexLanguageSelect = 'start_code_lang_select',
startCreateIndexRunInConsole = 'start_cta_run_in_console',
startCreateIndexCodeCopyInstall = 'start_code_copy_install',
startCreateIndexCodeCopy = 'start_code_copy',
startCreateIndexCreatedRedirect = 'start_index_created_api',
startFileUploadClick = 'start_file_upload',
indexDetailsCodeLanguageSelect = 'index_details_code_lang_select',
indexDetailsWorkflowSelect = 'index_details_workflow_select',
indexDetailsInstallCodeCopy = 'index_details_code_copy_install',
indexDetailsAddMappingsCodeCopy = 'index_details_add_mappings_code_copy',
indexDetailsIngestDocumentsCodeCopy = 'index_details_ingest_documents_code_copy',
Expand All @@ -29,6 +32,7 @@ export enum AnalyticsEvents {
createIndexPageModifyIndexName = 'create_index_modify_index_name',
createIndexCreateIndexClick = 'create_index_click_create',
createIndexLanguageSelect = 'create_index_code_lang_select',
createIndexWorkflowSelect = 'create_index_workflow_select',
createIndexRunInConsole = 'create_index_run_in_console',
createIndexCodeCopyInstall = 'create_index_copy_install',
createIndexCodeCopy = 'create_index_code_copy',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,3 +34,31 @@ export const CONNECT_CREATE_VECTOR_INDEX_CMD_DESCRIPTION = i18n.translate(
defaultMessage: 'Use the Elasticsearch client to create an index with dense vector fields',
}
);

export const CONNECT_CREATE_DEFAULT_INDEX_CMD_TITLE = i18n.translate(
'xpack.searchIndices.code.createIndexCommand.title',
{
defaultMessage: 'Create an index with text fields',
}
);

export const CONNECT_CREATE_DEFAULT_INDEX_CMD_DESCRIPTION = i18n.translate(
'xpack.searchIndices.code.createIndexCommand.description',
{
defaultMessage: 'Use the Elasticsearch client to create an index with text fields',
}
);

export const CONNECT_CREATE_SEMANTIC_INDEX_CMD_TITLE = i18n.translate(
'xpack.searchIndices.code.createIndexCommand.title',
{
defaultMessage: 'Create an index with semantic fields',
}
);

export const CONNECT_CREATE_SEMANTIC_INDEX_CMD_DESCRIPTION = i18n.translate(
'xpack.searchIndices.code.createIndexCommand.description',
{
defaultMessage: 'Use the Elasticsearch client to create an index with semantic fields',
}
);
Original file line number Diff line number Diff line change
Expand Up @@ -7,37 +7,53 @@

import { CreateIndexCodeExamples } from '../types';
import {
CONNECT_CREATE_DEFAULT_INDEX_CMD_DESCRIPTION,
CONNECT_CREATE_DEFAULT_INDEX_CMD_TITLE,
CONNECT_CREATE_SEMANTIC_INDEX_CMD_DESCRIPTION,
CONNECT_CREATE_SEMANTIC_INDEX_CMD_TITLE,
CONNECT_CREATE_VECTOR_INDEX_CMD_DESCRIPTION,
CONNECT_CREATE_VECTOR_INDEX_CMD_TITLE,
INSTALL_INSTRUCTIONS_DESCRIPTION,
INSTALL_INSTRUCTIONS_TITLE,
} from './constants';

import { CurlCreateIndexExamples } from './curl';
import { JavascriptServerlessCreateIndexExamples } from './javascript';
import { PythonServerlessCreateIndexExamples } from './python';
import { JavascriptCreateIndexExamples } from './javascript';
import { PythonCreateIndexExamples } from './python';
import { ConsoleCreateIndexExamples } from './sense';

export const DefaultServerlessCodeExamples: CreateIndexCodeExamples = {
export const DefaultCodeExamples: CreateIndexCodeExamples = {
exampleType: 'search',
installTitle: INSTALL_INSTRUCTIONS_TITLE,
installDescription: INSTALL_INSTRUCTIONS_DESCRIPTION,
createIndexTitle: CONNECT_CREATE_VECTOR_INDEX_CMD_TITLE,
createIndexDescription: CONNECT_CREATE_VECTOR_INDEX_CMD_DESCRIPTION,
createIndexTitle: CONNECT_CREATE_DEFAULT_INDEX_CMD_TITLE,
createIndexDescription: CONNECT_CREATE_DEFAULT_INDEX_CMD_DESCRIPTION,
sense: ConsoleCreateIndexExamples.default,
curl: CurlCreateIndexExamples.default,
python: PythonServerlessCreateIndexExamples.default,
javascript: JavascriptServerlessCreateIndexExamples.default,
python: PythonCreateIndexExamples.default,
javascript: JavascriptCreateIndexExamples.default,
};

export const DenseVectorSeverlessCodeExamples: CreateIndexCodeExamples = {
export const DenseVectorCodeExamples: CreateIndexCodeExamples = {
exampleType: 'vector',
installTitle: INSTALL_INSTRUCTIONS_TITLE,
installDescription: INSTALL_INSTRUCTIONS_DESCRIPTION,
createIndexTitle: CONNECT_CREATE_VECTOR_INDEX_CMD_TITLE,
createIndexDescription: CONNECT_CREATE_VECTOR_INDEX_CMD_DESCRIPTION,
sense: ConsoleCreateIndexExamples.dense_vector,
curl: CurlCreateIndexExamples.dense_vector,
python: PythonServerlessCreateIndexExamples.dense_vector,
javascript: JavascriptServerlessCreateIndexExamples.dense_vector,
python: PythonCreateIndexExamples.dense_vector,
javascript: JavascriptCreateIndexExamples.dense_vector,
};

export const SemanticCodeExamples: CreateIndexCodeExamples = {
exampleType: 'semantic',
installTitle: INSTALL_INSTRUCTIONS_TITLE,
installDescription: INSTALL_INSTRUCTIONS_DESCRIPTION,
createIndexTitle: CONNECT_CREATE_SEMANTIC_INDEX_CMD_TITLE,
createIndexDescription: CONNECT_CREATE_SEMANTIC_INDEX_CMD_DESCRIPTION,
sense: ConsoleCreateIndexExamples.semantic,
curl: CurlCreateIndexExamples.semantic,
python: PythonCreateIndexExamples.semantic,
javascript: JavascriptCreateIndexExamples.semantic,
};
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,16 @@ export const CurlCreateIndexExamples: CreateIndexLanguageExamples = {
indexName ?? INDEX_PLACEHOLDER
}' \
--header 'Authorization: ApiKey ${apiKey ?? API_KEY_PLACEHOLDER}' \
--header 'Content-Type: application/json'`,
--header 'Content-Type: application/json
--data-raw '{
"mappings": {
"properties":{
"text":{
"type":"text"
}
}
}
}'`,
},
dense_vector: {
createIndex: ({ elasticsearchURL, apiKey, indexName }) => `curl PUT '${elasticsearchURL}/${
Expand All @@ -43,11 +52,27 @@ export const CurlCreateIndexExamples: CreateIndexLanguageExamples = {
}
}
}
}'`,
},
semantic: {
createIndex: ({ elasticsearchURL, apiKey, indexName }) => `curl PUT '${elasticsearchURL}/${
indexName ?? INDEX_PLACEHOLDER
}' \
--header 'Authorization: ApiKey ${apiKey ?? API_KEY_PLACEHOLDER}' \
--header 'Content-Type: application/json
--data-raw '{
"mappings": {
"properties":{
"text":{
"type":"semantic_text"
}
}
}
}'`,
},
};

export const CurlVectorsIngestDataExample: IngestDataCodeDefinition = {
export const CurlIngestDataExample: IngestDataCodeDefinition = {
ingestCommand: ({ elasticsearchURL, apiKey, indexName, sampleDocuments }) => {
let result = `curl -X POST "${elasticsearchURL}/_bulk?pretty" \
--header 'Authorization: ApiKey ${apiKey ?? API_KEY_PLACEHOLDER}' \
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,21 +8,43 @@
import { i18n } from '@kbn/i18n';
import { IngestDataCodeExamples } from '../types';

import { JSServerlessIngestVectorDataExample } from './javascript';
import { PythonServerlessVectorsIngestDataExample } from './python';
import { ConsoleVectorsIngestDataExample } from './sense';
import { CurlVectorsIngestDataExample } from './curl';
import { JSIngestDataExample } from './javascript';
import { PythonIngestDataExample } from './python';
import { ConsoleIngestDataExample } from './sense';
import { CurlIngestDataExample } from './curl';
import { INSTALL_INSTRUCTIONS_TITLE, INSTALL_INSTRUCTIONS_DESCRIPTION } from './constants';

export const DenseVectorServerlessCodeExamples: IngestDataCodeExamples = {
const addMappingsTitle = i18n.translate(
'xpack.searchIndices.codeExamples.serverless.denseVector.mappingsTitle',
{
defaultMessage: 'Define field mappings',
}
);

export const DefaultIngestDataCodeExamples: IngestDataCodeExamples = {
installTitle: INSTALL_INSTRUCTIONS_TITLE,
installDescription: INSTALL_INSTRUCTIONS_DESCRIPTION,
addMappingsTitle: i18n.translate(
'xpack.searchIndices.codeExamples.serverless.denseVector.mappingsTitle',
addMappingsTitle,
addMappingsDescription: i18n.translate(
'xpack.searchIndices.codeExamples.serverless.default.mappingsDescription',
{
defaultMessage: 'Define field mappings',
defaultMessage:
'This example defines one field: a text field that will provide full-text search capabilities. You can add more field types by modifying the mappings in your API call, or in the mappings tab.',
}
),
defaultMapping: {
text: { type: 'text' },
},
sense: ConsoleIngestDataExample,
curl: CurlIngestDataExample,
python: PythonIngestDataExample,
javascript: JSIngestDataExample,
};

export const DenseVectorIngestDataCodeExamples: IngestDataCodeExamples = {
installTitle: INSTALL_INSTRUCTIONS_TITLE,
installDescription: INSTALL_INSTRUCTIONS_DESCRIPTION,
addMappingsTitle,
addMappingsDescription: i18n.translate(
'xpack.searchIndices.codeExamples.serverless.denseVector.mappingsDescription',
{
Expand All @@ -34,8 +56,29 @@ export const DenseVectorServerlessCodeExamples: IngestDataCodeExamples = {
vector: { type: 'dense_vector', dims: 3 },
text: { type: 'text' },
},
sense: ConsoleVectorsIngestDataExample,
curl: CurlVectorsIngestDataExample,
python: PythonServerlessVectorsIngestDataExample,
javascript: JSServerlessIngestVectorDataExample,
sense: ConsoleIngestDataExample,
curl: CurlIngestDataExample,
python: PythonIngestDataExample,
javascript: JSIngestDataExample,
};

export const SemanticIngestDataCodeExamples: IngestDataCodeExamples = {
installTitle: INSTALL_INSTRUCTIONS_TITLE,
installDescription: INSTALL_INSTRUCTIONS_DESCRIPTION,
addMappingsTitle,
addMappingsDescription: i18n.translate(
'xpack.searchIndices.codeExamples.serverless.denseVector.mappingsDescription',
{
defaultMessage:
'This example defines one field: a semantic text field that will provide vector search capabilities using the default ELSER model. You can add more field types by modifying the mappings in your API call, or in the mappings tab.',
}
),
defaultMapping: {
// @ts-expect-error - our types don't understand yet that we can have semantic_text fields without inference ids
text: { type: 'semantic_text' },
},
sense: ConsoleIngestDataExample,
curl: CurlIngestDataExample,
python: PythonIngestDataExample,
javascript: JSIngestDataExample,
};
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,11 @@ export const JAVASCRIPT_INFO: CodeLanguage = {
codeBlockLanguage: 'javascript',
};

const SERVERLESS_INSTALL_CMD = `npm install @elastic/elasticsearch`;
const INSTALL_CMD = `npm install @elastic/elasticsearch`;

export const JavascriptServerlessCreateIndexExamples: CreateIndexLanguageExamples = {
export const JavascriptCreateIndexExamples: CreateIndexLanguageExamples = {
default: {
installCommand: SERVERLESS_INSTALL_CMD,
installCommand: INSTALL_CMD,
createIndex: ({
elasticsearchURL,
apiKey,
Expand All @@ -39,10 +39,15 @@ const client = new Client({
client.indices.create({
index: "${indexName ?? INDEX_PLACEHOLDER}",
mappings: {
properties: {
text: { type: "text"}
},
},
});`,
},
dense_vector: {
installCommand: SERVERLESS_INSTALL_CMD,
installCommand: INSTALL_CMD,
createIndex: ({
elasticsearchURL,
apiKey,
Expand All @@ -64,12 +69,36 @@ client.indices.create({
text: { type: "text"}
},
},
});`,
},
semantic: {
installCommand: INSTALL_CMD,
createIndex: ({
elasticsearchURL,
apiKey,
indexName,
}) => `import { Client } from "@elastic/elasticsearch"
const client = new Client({
node: '${elasticsearchURL}',
auth: {
apiKey: "${apiKey ?? API_KEY_PLACEHOLDER}"
}
});
client.indices.create({
index: "${indexName ?? INDEX_PLACEHOLDER}",
mappings: {
properties: {
text: { type: "semantic_text"}
},
},
});`,
},
};

export const JSServerlessIngestVectorDataExample: IngestDataCodeDefinition = {
installCommand: SERVERLESS_INSTALL_CMD,
export const JSIngestDataExample: IngestDataCodeDefinition = {
installCommand: INSTALL_CMD,
ingestCommand: ({
apiKey,
elasticsearchURL,
Expand Down
Loading

0 comments on commit 63fc1ea

Please sign in to comment.