mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 01:38:56 -04:00
[Guided onboarding] Register config for guides (#146784)
## Summary Fixes https://github.com/elastic/kibana/issues/145878 Fixes https://github.com/elastic/kibana/issues/145880 This PR adds a new function to the guided onboarding server side plugin that allows other plugins to register a guide config. The existing guide configs are also moved to their corresponding solution plugins. Note: we are currently using generic IDs `search`, `security`, `observability` for guides but we will update them to a more specific IDs in a follow up PR (see https://github.com/elastic/kibana/issues/144452). ### Checklist - [ ] [Documentation](https://www.elastic.co/guide/en/kibana/master/development-documentation.html) was added for features that require explanation or tutorials - [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 Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com>
This commit is contained in:
parent
2ef2d249f3
commit
525ad3d6e0
26 changed files with 267 additions and 324 deletions
|
@ -7,5 +7,5 @@
|
|||
*/
|
||||
|
||||
export { PLUGIN_ID, PLUGIN_NAME, API_BASE_PATH } from './constants';
|
||||
export { testGuideConfig } from './test_guide_config';
|
||||
export { testGuideConfig, testGuideId } from './test_guide_config';
|
||||
export type { PluginStatus, PluginState, StepConfig, GuideConfig, GuidesConfig } from './types';
|
||||
|
|
|
@ -6,8 +6,10 @@
|
|||
* Side Public License, v 1.
|
||||
*/
|
||||
|
||||
import type { GuideId } from '@kbn/guided-onboarding';
|
||||
import type { GuideConfig } from './types';
|
||||
|
||||
export const testGuideId: GuideId = 'testGuide';
|
||||
export const testGuideConfig: GuideConfig = {
|
||||
title: 'Test guide for development',
|
||||
description: `This guide is used to test the guided onboarding UI while in development and to run automated tests for the API and UI components.`,
|
||||
|
|
|
@ -16,11 +16,10 @@ import type { HttpSetup } from '@kbn/core/public';
|
|||
import { registerTestBed, TestBed } from '@kbn/test-jest-helpers';
|
||||
|
||||
import type { PluginState } from '../../common';
|
||||
import { API_BASE_PATH, testGuideConfig } from '../../common';
|
||||
import { API_BASE_PATH, testGuideConfig, testGuideId } from '../../common';
|
||||
import { apiService } from '../services/api';
|
||||
import type { GuidedOnboardingApi } from '../types';
|
||||
import {
|
||||
testGuide,
|
||||
testGuideStep1ActiveState,
|
||||
testGuideStep1InProgressState,
|
||||
testGuideStep2InProgressState,
|
||||
|
@ -35,7 +34,7 @@ const applicationMock = applicationServiceMock.createStartContract();
|
|||
const notificationsMock = notificationServiceMock.createStartContract();
|
||||
|
||||
const mockGetResponse = (path: string, pluginState: PluginState) => {
|
||||
if (path === `${API_BASE_PATH}/configs/${testGuide}`) {
|
||||
if (path === `${API_BASE_PATH}/configs/${testGuideId}`) {
|
||||
return Promise.resolve({
|
||||
config: testGuideConfig,
|
||||
});
|
||||
|
|
|
@ -6,11 +6,10 @@
|
|||
* Side Public License, v 1.
|
||||
*/
|
||||
|
||||
import type { GuideState, GuideId, GuideStepIds } from '@kbn/guided-onboarding';
|
||||
import type { GuideState, GuideStepIds } from '@kbn/guided-onboarding';
|
||||
|
||||
import { PluginState } from '../../common';
|
||||
|
||||
export const testGuide: GuideId = 'testGuide';
|
||||
export const testGuideFirstStep: GuideStepIds = 'step1';
|
||||
export const testGuideManualCompletionStep = 'step2';
|
||||
export const testGuideLastStep: GuideStepIds = 'step3';
|
||||
|
|
|
@ -11,10 +11,9 @@ import { httpServiceMock } from '@kbn/core/public/mocks';
|
|||
import type { GuideState } from '@kbn/guided-onboarding';
|
||||
import { firstValueFrom, Subscription } from 'rxjs';
|
||||
|
||||
import { API_BASE_PATH, testGuideConfig } from '../../common';
|
||||
import { API_BASE_PATH, testGuideConfig, testGuideId } from '../../common';
|
||||
import { ApiService } from './api';
|
||||
import {
|
||||
testGuide,
|
||||
testGuideFirstStep,
|
||||
testGuideLastStep,
|
||||
testGuideManualCompletionStep,
|
||||
|
@ -135,7 +134,7 @@ describe('GuidedOnboarding ApiService', () => {
|
|||
});
|
||||
apiService.setup(httpClient, true);
|
||||
|
||||
await apiService.activateGuide(testGuide);
|
||||
await apiService.activateGuide(testGuideId);
|
||||
|
||||
expect(httpClient.put).toHaveBeenCalledTimes(1);
|
||||
expect(httpClient.put).toHaveBeenCalledWith(`${API_BASE_PATH}/state`, {
|
||||
|
@ -147,7 +146,7 @@ describe('GuidedOnboarding ApiService', () => {
|
|||
});
|
||||
|
||||
it('reactivates a guide that has already been started', async () => {
|
||||
await apiService.activateGuide(testGuide, testGuideStep1ActiveState);
|
||||
await apiService.activateGuide(testGuideId, testGuideStep1ActiveState);
|
||||
|
||||
expect(httpClient.put).toHaveBeenCalledTimes(1);
|
||||
expect(httpClient.put).toHaveBeenCalledWith(`${API_BASE_PATH}/state`, {
|
||||
|
@ -188,7 +187,7 @@ describe('GuidedOnboarding ApiService', () => {
|
|||
});
|
||||
|
||||
it('updates the selected guide and marks it as complete', async () => {
|
||||
await apiService.completeGuide(testGuide);
|
||||
await apiService.completeGuide(testGuideId);
|
||||
|
||||
expect(httpClient.put).toHaveBeenCalledTimes(1);
|
||||
expect(httpClient.put).toHaveBeenCalledWith(`${API_BASE_PATH}/state`, {
|
||||
|
@ -208,7 +207,7 @@ describe('GuidedOnboarding ApiService', () => {
|
|||
// mock the put api response
|
||||
pluginState: { status: 'complete', isActivePeriod: true },
|
||||
});
|
||||
await apiService.completeGuide(testGuide);
|
||||
await apiService.completeGuide(testGuideId);
|
||||
const updateState = await firstValueFrom(apiService.fetchPluginState$());
|
||||
expect(updateState?.status).toBe('complete');
|
||||
});
|
||||
|
@ -240,7 +239,7 @@ describe('GuidedOnboarding ApiService', () => {
|
|||
state: [incompleteGuideState],
|
||||
});
|
||||
apiService.setup(httpClient, true);
|
||||
const completedState = await apiService.completeGuide(testGuide);
|
||||
const completedState = await apiService.completeGuide(testGuideId);
|
||||
expect(completedState).not.toBeDefined();
|
||||
});
|
||||
});
|
||||
|
@ -252,7 +251,7 @@ describe('GuidedOnboarding ApiService', () => {
|
|||
});
|
||||
|
||||
subscription = apiService
|
||||
.isGuideStepActive$(testGuide, testGuideFirstStep)
|
||||
.isGuideStepActive$(testGuideId, testGuideFirstStep)
|
||||
.subscribe((isStepActive) => {
|
||||
if (isStepActive) {
|
||||
subscription.unsubscribe();
|
||||
|
@ -263,7 +262,7 @@ describe('GuidedOnboarding ApiService', () => {
|
|||
|
||||
it('returns false if the step is not been started', (done) => {
|
||||
subscription = apiService
|
||||
.isGuideStepActive$(testGuide, testGuideFirstStep)
|
||||
.isGuideStepActive$(testGuideId, testGuideFirstStep)
|
||||
.subscribe((isStepActive) => {
|
||||
if (!isStepActive) {
|
||||
subscription.unsubscribe();
|
||||
|
@ -275,7 +274,7 @@ describe('GuidedOnboarding ApiService', () => {
|
|||
|
||||
describe('startGuideStep', () => {
|
||||
it('updates the selected step and marks it as in_progress', async () => {
|
||||
await apiService.startGuideStep(testGuide, testGuideFirstStep);
|
||||
await apiService.startGuideStep(testGuideId, testGuideFirstStep);
|
||||
|
||||
expect(httpClient.put).toHaveBeenCalledWith(`${API_BASE_PATH}/state`, {
|
||||
body: JSON.stringify({ guide: testGuideStep1InProgressState }),
|
||||
|
@ -295,7 +294,7 @@ describe('GuidedOnboarding ApiService', () => {
|
|||
});
|
||||
apiService.setup(httpClient, true);
|
||||
|
||||
await apiService.completeGuideStep(testGuide, testGuideFirstStep);
|
||||
await apiService.completeGuideStep(testGuideId, testGuideFirstStep);
|
||||
|
||||
expect(httpClient.put).toHaveBeenCalledTimes(1);
|
||||
// Verify the completed step now has a "complete" status, and the subsequent step is "active"
|
||||
|
@ -313,7 +312,7 @@ describe('GuidedOnboarding ApiService', () => {
|
|||
});
|
||||
apiService.setup(httpClient, true);
|
||||
|
||||
await apiService.completeGuideStep(testGuide, testGuideManualCompletionStep);
|
||||
await apiService.completeGuideStep(testGuideId, testGuideManualCompletionStep);
|
||||
|
||||
expect(httpClient.put).toHaveBeenCalledTimes(1);
|
||||
// Verify the completed step now has a "ready_to_complete" status, and the subsequent step is "inactive"
|
||||
|
@ -349,7 +348,7 @@ describe('GuidedOnboarding ApiService', () => {
|
|||
});
|
||||
apiService.setup(httpClient, true);
|
||||
|
||||
await apiService.completeGuideStep(testGuide, testGuideLastStep);
|
||||
await apiService.completeGuideStep(testGuideId, testGuideLastStep);
|
||||
|
||||
expect(httpClient.put).toHaveBeenCalledTimes(1);
|
||||
// Verify the guide now has a "ready_to_complete" status and the last step is "complete"
|
||||
|
@ -376,10 +375,10 @@ describe('GuidedOnboarding ApiService', () => {
|
|||
});
|
||||
apiService.setup(httpClient, true);
|
||||
|
||||
await apiService.completeGuideStep(testGuide, testGuideFirstStep);
|
||||
await apiService.completeGuideStep(testGuideId, testGuideFirstStep);
|
||||
|
||||
expect(httpClient.put).toHaveBeenCalledTimes(1);
|
||||
// Verify the guide now has a "in_progress" status and the second step is "active"
|
||||
// Verify the guide now has an "in_progress" status and the second step is "active"
|
||||
expect(httpClient.put).toHaveBeenCalledWith(`${API_BASE_PATH}/state`, {
|
||||
body: JSON.stringify({
|
||||
guide: {
|
||||
|
@ -396,7 +395,7 @@ describe('GuidedOnboarding ApiService', () => {
|
|||
|
||||
it('does nothing if the step is not in progress', async () => {
|
||||
// by default the state set in beforeEach is test guide, step 1 active
|
||||
await apiService.completeGuideStep(testGuide, testGuideFirstStep);
|
||||
await apiService.completeGuideStep(testGuideId, testGuideFirstStep);
|
||||
expect(httpClient.put).toHaveBeenCalledTimes(0);
|
||||
});
|
||||
|
||||
|
@ -508,9 +507,9 @@ describe('GuidedOnboarding ApiService', () => {
|
|||
describe('getGuideConfig', () => {
|
||||
it('sends a request to the get config API', async () => {
|
||||
apiService.setup(httpClient, true);
|
||||
await apiService.getGuideConfig(testGuide);
|
||||
await apiService.getGuideConfig(testGuideId);
|
||||
expect(httpClient.get).toHaveBeenCalledTimes(1);
|
||||
expect(httpClient.get).toHaveBeenCalledWith(`${API_BASE_PATH}/configs/${testGuide}`);
|
||||
expect(httpClient.get).toHaveBeenCalledWith(`${API_BASE_PATH}/configs/${testGuideId}`);
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -535,7 +534,7 @@ describe('GuidedOnboarding ApiService', () => {
|
|||
});
|
||||
|
||||
it('getGuideConfig', async () => {
|
||||
await apiService.getGuideConfig(testGuide);
|
||||
await apiService.getGuideConfig(testGuideId);
|
||||
expect(httpClient.get).not.toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
|
|
@ -8,9 +8,8 @@
|
|||
|
||||
import { HttpSetup } from '@kbn/core-http-browser';
|
||||
import { httpServiceMock } from '@kbn/core-http-browser-mocks';
|
||||
import { API_BASE_PATH, testGuideConfig } from '../../common';
|
||||
import { API_BASE_PATH, testGuideConfig, testGuideId } from '../../common';
|
||||
import {
|
||||
testGuide,
|
||||
testGuideNotActiveState,
|
||||
testGuideStep1InProgressState,
|
||||
testGuideStep2InProgressState,
|
||||
|
@ -34,21 +33,21 @@ describe('GuidedOnboarding ConfigService', () => {
|
|||
});
|
||||
describe('getGuideConfig', () => {
|
||||
it('sends only one request to the get configs API', async () => {
|
||||
await configService.getGuideConfig(testGuide);
|
||||
await configService.getGuideConfig(testGuide);
|
||||
await configService.getGuideConfig(testGuideId);
|
||||
await configService.getGuideConfig(testGuideId);
|
||||
expect(httpClient.get).toHaveBeenCalledTimes(1);
|
||||
expect(httpClient.get).toHaveBeenCalledWith(`${API_BASE_PATH}/configs/${testGuide}`);
|
||||
expect(httpClient.get).toHaveBeenCalledWith(`${API_BASE_PATH}/configs/${testGuideId}`);
|
||||
});
|
||||
|
||||
it('returns undefined if the config is not found', async () => {
|
||||
httpClient.get.mockRejectedValueOnce(new Error('Not found'));
|
||||
configService.setup(httpClient);
|
||||
const config = await configService.getGuideConfig(testGuide);
|
||||
const config = await configService.getGuideConfig(testGuideId);
|
||||
expect(config).toBeUndefined();
|
||||
});
|
||||
|
||||
it('returns the config for the guide', async () => {
|
||||
const config = await configService.getGuideConfig(testGuide);
|
||||
const config = await configService.getGuideConfig(testGuideId);
|
||||
expect(config).toHaveProperty('title');
|
||||
});
|
||||
});
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
* Side Public License, v 1.
|
||||
*/
|
||||
|
||||
import { testGuideConfig } from '../../common';
|
||||
import { testGuideConfig, testGuideId } from '../../common';
|
||||
import type { GuidesConfig } from '../../common';
|
||||
import {
|
||||
findGuideConfigByGuideId,
|
||||
|
@ -22,7 +22,6 @@ import {
|
|||
import {
|
||||
mockPluginStateInProgress,
|
||||
mockPluginStateNotStarted,
|
||||
testGuide,
|
||||
testGuideFirstStep,
|
||||
testGuideLastStep,
|
||||
testGuideManualCompletionStep,
|
||||
|
@ -45,7 +44,7 @@ describe('GuidedOnboarding ApiService helpers', () => {
|
|||
it('returns the correct config guide', () => {
|
||||
const config = findGuideConfigByGuideId(
|
||||
{ testGuide: testGuideConfig } as GuidesConfig,
|
||||
testGuide
|
||||
testGuideId
|
||||
);
|
||||
expect(config).not.toBeUndefined();
|
||||
});
|
||||
|
@ -53,24 +52,24 @@ describe('GuidedOnboarding ApiService helpers', () => {
|
|||
|
||||
describe('getStepConfig', () => {
|
||||
it('returns undefined if the config is not found', async () => {
|
||||
const config = getStepConfig(undefined, testGuide, testGuideFirstStep);
|
||||
const config = getStepConfig(undefined, testGuideId, testGuideFirstStep);
|
||||
expect(config).toBeUndefined();
|
||||
});
|
||||
|
||||
it('returns the config for the step', async () => {
|
||||
const config = getStepConfig(testGuideConfig, testGuide, testGuideFirstStep);
|
||||
const config = getStepConfig(testGuideConfig, testGuideId, testGuideFirstStep);
|
||||
expect(config).toHaveProperty('title');
|
||||
});
|
||||
});
|
||||
|
||||
describe('isLastStep', () => {
|
||||
it('returns true if the passed params are for the last step', () => {
|
||||
const result = isLastStep(testGuideConfig, testGuide, testGuideLastStep);
|
||||
const result = isLastStep(testGuideConfig, testGuideId, testGuideLastStep);
|
||||
expect(result).toBe(true);
|
||||
});
|
||||
|
||||
it('returns false if the passed params are not for the last step', () => {
|
||||
const result = isLastStep(testGuideConfig, testGuide, testGuideFirstStep);
|
||||
const result = isLastStep(testGuideConfig, testGuideId, testGuideFirstStep);
|
||||
expect(result).toBe(false);
|
||||
});
|
||||
});
|
||||
|
@ -105,7 +104,7 @@ describe('GuidedOnboarding ApiService helpers', () => {
|
|||
|
||||
describe('isGuideActive', () => {
|
||||
it('returns false if plugin state is undefined', () => {
|
||||
const isActive = isGuideActive(undefined, testGuide);
|
||||
const isActive = isGuideActive(undefined, testGuideId);
|
||||
expect(isActive).toBe(false);
|
||||
});
|
||||
|
||||
|
@ -125,14 +124,14 @@ describe('GuidedOnboarding ApiService helpers', () => {
|
|||
});
|
||||
|
||||
it('returns true if guide is in progress', () => {
|
||||
const isActive = isGuideActive(mockPluginStateInProgress, testGuide);
|
||||
const isActive = isGuideActive(mockPluginStateInProgress, testGuideId);
|
||||
expect(isActive).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
describe('isStepInProgress', () => {
|
||||
it('returns false if guide state is undefined', () => {
|
||||
const isInProgress = isStepInProgress(undefined, testGuide, testGuideFirstStep);
|
||||
const isInProgress = isStepInProgress(undefined, testGuideId, testGuideFirstStep);
|
||||
expect(isInProgress).toBe(false);
|
||||
});
|
||||
|
||||
|
@ -148,7 +147,7 @@ describe('GuidedOnboarding ApiService helpers', () => {
|
|||
it('returns false if step is not in progress', () => {
|
||||
const isInProgress = isStepInProgress(
|
||||
testGuideStep1InProgressState,
|
||||
testGuide,
|
||||
testGuideId,
|
||||
testGuideLastStep
|
||||
);
|
||||
expect(isInProgress).toBe(false);
|
||||
|
@ -157,7 +156,7 @@ describe('GuidedOnboarding ApiService helpers', () => {
|
|||
it('returns true if step is in progress', () => {
|
||||
const isInProgress = isStepInProgress(
|
||||
testGuideStep1InProgressState,
|
||||
testGuide,
|
||||
testGuideId,
|
||||
testGuideFirstStep
|
||||
);
|
||||
expect(isInProgress).toBe(true);
|
||||
|
@ -166,7 +165,7 @@ describe('GuidedOnboarding ApiService helpers', () => {
|
|||
|
||||
describe('isStepReadyToComplete', () => {
|
||||
it('returns false if guide state is undefined', () => {
|
||||
const isReadyToComplete = isStepReadyToComplete(undefined, testGuide, testGuideFirstStep);
|
||||
const isReadyToComplete = isStepReadyToComplete(undefined, testGuideId, testGuideFirstStep);
|
||||
expect(isReadyToComplete).toBe(false);
|
||||
});
|
||||
|
||||
|
@ -182,7 +181,7 @@ describe('GuidedOnboarding ApiService helpers', () => {
|
|||
it('returns false if step is not ready not complete', () => {
|
||||
const isReadyToComplete = isStepReadyToComplete(
|
||||
testGuideStep2ReadyToCompleteState,
|
||||
testGuide,
|
||||
testGuideId,
|
||||
testGuideLastStep
|
||||
);
|
||||
expect(isReadyToComplete).toBe(false);
|
||||
|
@ -191,7 +190,7 @@ describe('GuidedOnboarding ApiService helpers', () => {
|
|||
it('returns true if step is ready to complete', () => {
|
||||
const isInProgress = isStepReadyToComplete(
|
||||
testGuideStep2ReadyToCompleteState,
|
||||
testGuide,
|
||||
testGuideId,
|
||||
testGuideManualCompletionStep
|
||||
);
|
||||
expect(isInProgress).toBe(true);
|
||||
|
|
|
@ -1,20 +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 and the Server Side Public License, v 1; you may not use this file except
|
||||
* in compliance with, at your election, the Elastic License 2.0 or the Server
|
||||
* Side Public License, v 1.
|
||||
*/
|
||||
|
||||
import type { GuidesConfig } from '../../../common';
|
||||
import { testGuideConfig } from '../../../common';
|
||||
import { securityConfig } from './security';
|
||||
import { observabilityConfig } from './observability';
|
||||
import { searchConfig } from './search';
|
||||
|
||||
export const guidesConfig: GuidesConfig = {
|
||||
security: securityConfig,
|
||||
observability: observabilityConfig,
|
||||
search: searchConfig,
|
||||
testGuide: testGuideConfig,
|
||||
};
|
|
@ -1,80 +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 and the Server Side Public License, v 1; you may not use this file except
|
||||
* in compliance with, at your election, the Elastic License 2.0 or the Server
|
||||
* Side Public License, v 1.
|
||||
*/
|
||||
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import type { GuideConfig } from '../../../common';
|
||||
|
||||
export const searchConfig: GuideConfig = {
|
||||
title: i18n.translate('guidedOnboarding.searchGuide.title', {
|
||||
defaultMessage: 'Search my data',
|
||||
}),
|
||||
description: i18n.translate('guidedOnboarding.searchGuide.description', {
|
||||
defaultMessage: `Build custom search experiences with your data using Elastic’s out-of-the-box web crawler, connectors, and robust APIs. Gain deep insights from the built-in search analytics to curate results and optimize relevance.`,
|
||||
}),
|
||||
guideName: 'Enterprise Search',
|
||||
steps: [
|
||||
{
|
||||
id: 'add_data',
|
||||
title: i18n.translate('guidedOnboarding.searchGuide.addDataStep.title', {
|
||||
defaultMessage: 'Add data',
|
||||
}),
|
||||
descriptionList: [
|
||||
i18n.translate('guidedOnboarding.searchGuide.addDataStep.description1', {
|
||||
defaultMessage: 'Select an ingestion method.',
|
||||
}),
|
||||
i18n.translate('guidedOnboarding.searchGuide.addDataStep.description2', {
|
||||
defaultMessage: 'Create a new Elasticsearch index.',
|
||||
}),
|
||||
i18n.translate('guidedOnboarding.searchGuide.addDataStep.description3', {
|
||||
defaultMessage: 'Configure your ingestion settings.',
|
||||
}),
|
||||
],
|
||||
location: {
|
||||
appID: 'enterpriseSearchContent',
|
||||
path: '/search_indices/new_index',
|
||||
},
|
||||
},
|
||||
{
|
||||
id: 'search_experience',
|
||||
title: i18n.translate('guidedOnboarding.searchGuide.searchExperienceStep.title', {
|
||||
defaultMessage: 'Build a search experience',
|
||||
}),
|
||||
descriptionList: [
|
||||
i18n.translate('guidedOnboarding.searchGuide.searchExperienceStep.descriptionList.item1', {
|
||||
defaultMessage: 'Learn more about Elastic’s Search UI framework.',
|
||||
}),
|
||||
i18n.translate('guidedOnboarding.searchGuide.searchExperienceStep.descriptionList.item2', {
|
||||
defaultMessage: 'Try the Search UI tutorial for Elasticsearch.',
|
||||
}),
|
||||
i18n.translate('guidedOnboarding.searchGuide.searchExperienceStep.descriptionList.item3', {
|
||||
defaultMessage:
|
||||
'Build a world-class search experience for your customers, employees, or users.',
|
||||
}),
|
||||
],
|
||||
location: {
|
||||
appID: 'searchExperiences',
|
||||
path: '',
|
||||
},
|
||||
manualCompletion: {
|
||||
title: i18n.translate(
|
||||
'guidedOnboarding.searchGuide.searchExperienceStep.manualCompletionPopoverTitle',
|
||||
{
|
||||
defaultMessage: 'Explore Search UI',
|
||||
}
|
||||
),
|
||||
description: i18n.translate(
|
||||
'guidedOnboarding.searchGuide.searchExperienceStep.manualCompletionPopoverDescription',
|
||||
{
|
||||
defaultMessage: `Take your time to explore how to use Search UI to build world-class search experiences. When you’re ready, click the Setup guide button to continue.`,
|
||||
}
|
||||
),
|
||||
readyToCompleteOnNavigation: true,
|
||||
},
|
||||
},
|
||||
],
|
||||
};
|
|
@ -14,3 +14,4 @@ export function plugin(initializerContext: PluginInitializerContext) {
|
|||
}
|
||||
|
||||
export type { GuidedOnboardingPluginSetup, GuidedOnboardingPluginStart } from './types';
|
||||
export { testGuideConfig } from '../common/test_guide_config';
|
||||
|
|
|
@ -8,17 +8,24 @@
|
|||
|
||||
import { PluginInitializerContext, CoreSetup, Plugin, Logger } from '@kbn/core/server';
|
||||
|
||||
import type { GuideId } from '@kbn/guided-onboarding';
|
||||
import { GuidedOnboardingPluginSetup, GuidedOnboardingPluginStart } from './types';
|
||||
import { defineRoutes } from './routes';
|
||||
import { guideStateSavedObjects, pluginStateSavedObjects } from './saved_objects';
|
||||
import type { GuideConfig, GuidesConfig } from '../common';
|
||||
import { testGuideConfig, testGuideId } from '../common';
|
||||
|
||||
export class GuidedOnboardingPlugin
|
||||
implements Plugin<GuidedOnboardingPluginSetup, GuidedOnboardingPluginStart>
|
||||
{
|
||||
private readonly logger: Logger;
|
||||
private readonly guidesConfig: GuidesConfig;
|
||||
private readonly isDevMode: boolean;
|
||||
|
||||
constructor(initializerContext: PluginInitializerContext) {
|
||||
this.logger = initializerContext.logger.get();
|
||||
this.guidesConfig = {} as GuidesConfig;
|
||||
this.isDevMode = initializerContext.env.mode.dev;
|
||||
}
|
||||
|
||||
public setup(core: CoreSetup) {
|
||||
|
@ -26,13 +33,26 @@ export class GuidedOnboardingPlugin
|
|||
const router = core.http.createRouter();
|
||||
|
||||
// Register server side APIs
|
||||
defineRoutes(router);
|
||||
defineRoutes(router, this.guidesConfig);
|
||||
|
||||
// register saved objects
|
||||
core.savedObjects.registerType(guideStateSavedObjects);
|
||||
core.savedObjects.registerType(pluginStateSavedObjects);
|
||||
|
||||
return {};
|
||||
// add a config for a test guide if running in dev mode
|
||||
if (this.isDevMode) {
|
||||
this.guidesConfig[testGuideId] = testGuideConfig;
|
||||
}
|
||||
return {
|
||||
registerGuideConfig: (guideId: GuideId, guideConfig: GuideConfig) => {
|
||||
if (this.guidesConfig[guideId]) {
|
||||
throw new Error(
|
||||
`Unable to register a config with the guideId ${guideId} because it already exists`
|
||||
);
|
||||
}
|
||||
this.guidesConfig[guideId] = guideConfig;
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
public start() {
|
||||
|
|
|
@ -10,9 +10,9 @@ import { IRouter } from '@kbn/core/server';
|
|||
import { schema } from '@kbn/config-schema';
|
||||
import type { GuideId } from '@kbn/guided-onboarding';
|
||||
import { API_BASE_PATH } from '../../common';
|
||||
import { guidesConfig } from '../helpers/guides_config';
|
||||
import type { GuidesConfig } from '../../common';
|
||||
|
||||
export const registerGetConfigRoute = (router: IRouter) => {
|
||||
export const registerGetConfigRoute = (router: IRouter, guidesConfig: GuidesConfig) => {
|
||||
// Fetch the config of the guide
|
||||
router.get(
|
||||
{
|
||||
|
|
|
@ -7,15 +7,16 @@
|
|||
*/
|
||||
|
||||
import type { IRouter } from '@kbn/core/server';
|
||||
import type { GuidesConfig } from '../../common/types';
|
||||
import { registerGetGuideStateRoute } from './guide_state_routes';
|
||||
import { registerGetPluginStateRoute, registerPutPluginStateRoute } from './plugin_state_routes';
|
||||
import { registerGetConfigRoute } from './config_routes';
|
||||
|
||||
export function defineRoutes(router: IRouter) {
|
||||
export function defineRoutes(router: IRouter, guidesConfig: GuidesConfig) {
|
||||
registerGetGuideStateRoute(router);
|
||||
|
||||
registerGetPluginStateRoute(router);
|
||||
registerPutPluginStateRoute(router);
|
||||
|
||||
registerGetConfigRoute(router);
|
||||
registerGetConfigRoute(router, guidesConfig);
|
||||
}
|
||||
|
|
|
@ -6,8 +6,12 @@
|
|||
* Side Public License, v 1.
|
||||
*/
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-empty-interface
|
||||
export interface GuidedOnboardingPluginSetup {}
|
||||
import type { GuideId } from '@kbn/guided-onboarding';
|
||||
import type { GuideConfig } from '../common';
|
||||
|
||||
export interface GuidedOnboardingPluginSetup {
|
||||
registerGuideConfig: (guideId: GuideId, guideConfig: GuideConfig) => void;
|
||||
}
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-empty-interface
|
||||
export interface GuidedOnboardingPluginStart {}
|
||||
|
|
|
@ -10,12 +10,12 @@ import expect from '@kbn/expect';
|
|||
import type { FtrProviderContext } from '../../ftr_provider_context';
|
||||
|
||||
const getConfigsPath = '/api/guided_onboarding/configs';
|
||||
export default function testGetGuidesState({ getService }: FtrProviderContext) {
|
||||
export default function testGetGuideConfig({ getService }: FtrProviderContext) {
|
||||
const supertest = getService('supertest');
|
||||
|
||||
describe('GET /api/guided_onboarding/configs', () => {
|
||||
// check that all guides are present
|
||||
['testGuide', 'security', 'search', 'observability'].map((guideId) => {
|
||||
// check that production guides are present
|
||||
['security', 'search', 'observability'].map((guideId) => {
|
||||
it(`returns config for ${guideId}`, async () => {
|
||||
const response = await supertest.get(`${getConfigsPath}/${guideId}`).expect(200);
|
||||
expect(response.body).not.to.be.empty();
|
||||
|
|
|
@ -10,13 +10,13 @@ import expect from '@kbn/expect';
|
|||
import {
|
||||
testGuideStep1ActiveState,
|
||||
testGuideNotActiveState,
|
||||
testGuide,
|
||||
} from '@kbn/guided-onboarding-plugin/public/services/api.mocks';
|
||||
import {
|
||||
pluginStateSavedObjectsType,
|
||||
pluginStateSavedObjectsId,
|
||||
guideStateSavedObjectsType,
|
||||
} from '@kbn/guided-onboarding-plugin/server/saved_objects/guided_setup';
|
||||
import { testGuideId } from '@kbn/guided-onboarding-plugin/common';
|
||||
import type { FtrProviderContext } from '../../ftr_provider_context';
|
||||
import { createGuides, createPluginState } from './helpers';
|
||||
|
||||
|
@ -97,7 +97,7 @@ export default function testPutState({ getService }: FtrProviderContext) {
|
|||
|
||||
const createdSO = await kibanaServer.savedObjects.get({
|
||||
type: guideStateSavedObjectsType,
|
||||
id: testGuide,
|
||||
id: testGuideId,
|
||||
});
|
||||
|
||||
expect(createdSO.attributes).to.eql(testGuideStep1ActiveState);
|
||||
|
@ -116,7 +116,7 @@ export default function testPutState({ getService }: FtrProviderContext) {
|
|||
|
||||
const createdSO = await kibanaServer.savedObjects.get({
|
||||
type: guideStateSavedObjectsType,
|
||||
id: testGuide,
|
||||
id: testGuideId,
|
||||
});
|
||||
|
||||
expect(createdSO.attributes).to.eql(testGuideNotActiveState);
|
||||
|
@ -144,7 +144,7 @@ export default function testPutState({ getService }: FtrProviderContext) {
|
|||
// Check that all guides except observability are inactive
|
||||
const testGuideSO = await kibanaServer.savedObjects.get({
|
||||
type: guideStateSavedObjectsType,
|
||||
id: testGuide,
|
||||
id: testGuideId,
|
||||
});
|
||||
expect(testGuideSO.attributes.isActive).to.eql(false);
|
||||
|
||||
|
|
|
@ -0,0 +1,91 @@
|
|||
/*
|
||||
* 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 { GuideConfig } from '@kbn/guided-onboarding-plugin/common';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
|
||||
export const searchGuideId = 'search';
|
||||
export const searchGuideConfig: GuideConfig = {
|
||||
title: i18n.translate('xpack.enterpriseSearch.guideConfig.title', {
|
||||
defaultMessage: 'Search my data',
|
||||
}),
|
||||
description: i18n.translate('xpack.enterpriseSearch.guideConfig.description', {
|
||||
defaultMessage:
|
||||
'Build custom search experiences with your data using Elastic’s out-of-the-box web crawler, connectors, and robust APIs. Gain deep insights from the built-in search analytics to curate results and optimize relevance.',
|
||||
}),
|
||||
guideName: 'Enterprise Search',
|
||||
steps: [
|
||||
{
|
||||
id: 'add_data',
|
||||
title: i18n.translate('xpack.enterpriseSearch.guideConfig.addDataStep.title', {
|
||||
defaultMessage: 'Add data',
|
||||
}),
|
||||
descriptionList: [
|
||||
i18n.translate('xpack.enterpriseSearch.guideConfig.addDataStep.description1', {
|
||||
defaultMessage: 'Select an ingestion method.',
|
||||
}),
|
||||
i18n.translate('xpack.enterpriseSearch.guideConfig.addDataStep.description2', {
|
||||
defaultMessage: 'Create a new Elasticsearch index.',
|
||||
}),
|
||||
i18n.translate('xpack.enterpriseSearch.guideConfig.addDataStep.description3', {
|
||||
defaultMessage: 'Configure your ingestion settings.',
|
||||
}),
|
||||
],
|
||||
location: {
|
||||
appID: 'enterpriseSearchContent',
|
||||
path: '/search_indices/new_index',
|
||||
},
|
||||
},
|
||||
{
|
||||
id: 'search_experience',
|
||||
title: i18n.translate('xpack.enterpriseSearch.guideConfig.searchExperienceStep.title', {
|
||||
defaultMessage: 'Build a search experience',
|
||||
}),
|
||||
descriptionList: [
|
||||
i18n.translate(
|
||||
'xpack.enterpriseSearch.guideConfig.searchExperienceStep.descriptionList.item1',
|
||||
{
|
||||
defaultMessage: 'Learn more about Elastic’s Search UI framework.',
|
||||
}
|
||||
),
|
||||
i18n.translate(
|
||||
'xpack.enterpriseSearch.guideConfig.searchExperienceStep.descriptionList.item2',
|
||||
{
|
||||
defaultMessage: 'Try the Search UI tutorial for Elasticsearch.',
|
||||
}
|
||||
),
|
||||
i18n.translate(
|
||||
'xpack.enterpriseSearch.guideConfig.searchExperienceStep.descriptionList.item3',
|
||||
{
|
||||
defaultMessage:
|
||||
'Build a world-class search experience for your customers, employees, or users.',
|
||||
}
|
||||
),
|
||||
],
|
||||
location: {
|
||||
appID: 'searchExperiences',
|
||||
path: '',
|
||||
},
|
||||
manualCompletion: {
|
||||
title: i18n.translate(
|
||||
'xpack.enterpriseSearch.guideConfig.searchExperienceStep.manualCompletionPopoverTitle',
|
||||
{
|
||||
defaultMessage: 'Explore Search UI',
|
||||
}
|
||||
),
|
||||
description: i18n.translate(
|
||||
'xpack.enterpriseSearch.guideConfig.searchExperienceStep.manualCompletionPopoverDescription',
|
||||
{
|
||||
defaultMessage:
|
||||
'Take your time to explore how to use Search UI to build world-class search experiences. When you’re ready, click the Setup guide button to continue.',
|
||||
}
|
||||
),
|
||||
readyToCompleteOnNavigation: true,
|
||||
},
|
||||
},
|
||||
],
|
||||
};
|
|
@ -18,6 +18,7 @@ import {
|
|||
import { CustomIntegrationsPluginSetup } from '@kbn/custom-integrations-plugin/server';
|
||||
import { DataPluginStart } from '@kbn/data-plugin/server/plugin';
|
||||
import { PluginSetupContract as FeaturesPluginSetup } from '@kbn/features-plugin/server';
|
||||
import type { GuidedOnboardingPluginSetup } from '@kbn/guided-onboarding-plugin/server';
|
||||
import { InfraPluginSetup } from '@kbn/infra-plugin/server';
|
||||
import type { MlPluginSetup } from '@kbn/ml-plugin/server';
|
||||
import { SecurityPluginSetup, SecurityPluginStart } from '@kbn/security-plugin/server';
|
||||
|
@ -37,6 +38,8 @@ import {
|
|||
ENTERPRISE_SEARCH_ANALYTICS_LOGS_SOURCE_ID,
|
||||
} from '../common/constants';
|
||||
|
||||
import { searchGuideId, searchGuideConfig } from '../common/guided_onboarding/search_guide_config';
|
||||
|
||||
import { registerTelemetryUsageCollector as registerASTelemetryUsageCollector } from './collectors/app_search/telemetry';
|
||||
import { registerTelemetryUsageCollector as registerESTelemetryUsageCollector } from './collectors/enterprise_search/telemetry';
|
||||
import { registerTelemetryUsageCollector as registerWSTelemetryUsageCollector } from './collectors/workplace_search/telemetry';
|
||||
|
@ -75,6 +78,7 @@ interface PluginsSetup {
|
|||
infra: InfraPluginSetup;
|
||||
customIntegrations?: CustomIntegrationsPluginSetup;
|
||||
ml?: MlPluginSetup;
|
||||
guidedOnboarding: GuidedOnboardingPluginSetup;
|
||||
}
|
||||
|
||||
interface PluginsStart {
|
||||
|
@ -103,7 +107,15 @@ export class EnterpriseSearchPlugin implements Plugin {
|
|||
|
||||
public setup(
|
||||
{ capabilities, http, savedObjects, getStartServices, uiSettings }: CoreSetup<PluginsStart>,
|
||||
{ usageCollection, security, features, infra, customIntegrations, ml }: PluginsSetup
|
||||
{
|
||||
usageCollection,
|
||||
security,
|
||||
features,
|
||||
infra,
|
||||
customIntegrations,
|
||||
ml,
|
||||
guidedOnboarding,
|
||||
}: PluginsSetup
|
||||
) {
|
||||
const config = this.config;
|
||||
const log = this.logger;
|
||||
|
@ -248,6 +260,11 @@ export class EnterpriseSearchPlugin implements Plugin {
|
|||
indexName: 'logs-elastic_analytics.events-*',
|
||||
},
|
||||
});
|
||||
|
||||
/**
|
||||
* Register a config for the search guide
|
||||
*/
|
||||
guidedOnboarding.registerGuideConfig(searchGuideId, searchGuideConfig);
|
||||
}
|
||||
|
||||
public start() {}
|
||||
|
|
|
@ -1,24 +1,24 @@
|
|||
/*
|
||||
* 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 and the Server Side Public License, v 1; you may not use this file except
|
||||
* in compliance with, at your election, the Elastic License 2.0 or the Server
|
||||
* Side Public License, v 1.
|
||||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
|
||||
import type { GuideConfig } from '@kbn/guided-onboarding-plugin/common';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import type { GuideConfig } from '../../../common';
|
||||
|
||||
export const observabilityConfig: GuideConfig = {
|
||||
title: i18n.translate('guidedOnboarding.observabilityGuide.title', {
|
||||
export const observabilityGuideId = 'observability';
|
||||
export const observabilityGuideConfig: GuideConfig = {
|
||||
title: i18n.translate('xpack.observability.guideConfig.title', {
|
||||
defaultMessage: 'Observe my Kubernetes infrastructure',
|
||||
}),
|
||||
description: i18n.translate('guidedOnboarding.observabilityGuide.description', {
|
||||
description: i18n.translate('xpack.observability.guideConfig.description', {
|
||||
defaultMessage: `We'll help you quickly get visibility into your Kubernetes environment with our Elastic integration. Gain deep insights from your logs, metrics, and traces to proactively detect issues and take action to resolve them.`,
|
||||
}),
|
||||
guideName: 'Kubernetes',
|
||||
docs: {
|
||||
text: i18n.translate('guidedOnboarding.observabilityGuide.documentationLink', {
|
||||
text: i18n.translate('xpack.observability.guideConfig.documentationLink', {
|
||||
defaultMessage: 'Learn more',
|
||||
}),
|
||||
url: 'https://docs.elastic.co/en/integrations/kubernetes',
|
||||
|
@ -26,16 +26,16 @@ export const observabilityConfig: GuideConfig = {
|
|||
steps: [
|
||||
{
|
||||
id: 'add_data',
|
||||
title: i18n.translate('guidedOnboarding.observabilityGuide.addDataStep.title', {
|
||||
title: i18n.translate('xpack.observability.guideConfig.addDataStep.title', {
|
||||
defaultMessage: 'Add and verify your data',
|
||||
}),
|
||||
integration: 'kubernetes',
|
||||
descriptionList: [
|
||||
i18n.translate('guidedOnboarding.observabilityGuide.addDataStep.descriptionList.item1', {
|
||||
i18n.translate('xpack.observability.guideConfig.addDataStep.descriptionList.item1', {
|
||||
// TODO add the link to the docs, when markdown support is implemented https://github.com/elastic/kibana/issues/146404
|
||||
defaultMessage: 'Deploy kube-state-metrics service to your Kubernetes.',
|
||||
}),
|
||||
i18n.translate('guidedOnboarding.observabilityGuide.addDataStep.descriptionList.item2', {
|
||||
i18n.translate('xpack.observability.guideConfig.addDataStep.descriptionList.item2', {
|
||||
defaultMessage: 'Add the Elastic Kubernetes integration.',
|
||||
}),
|
||||
],
|
||||
|
@ -46,28 +46,25 @@ export const observabilityConfig: GuideConfig = {
|
|||
},
|
||||
{
|
||||
id: 'view_dashboard',
|
||||
title: i18n.translate('guidedOnboarding.observabilityGuide.viewDashboardStep.title', {
|
||||
title: i18n.translate('xpack.observability.guideConfig.viewDashboardStep.title', {
|
||||
defaultMessage: 'Explore Kubernetes metrics',
|
||||
}),
|
||||
description: i18n.translate(
|
||||
'guidedOnboarding.observabilityGuide.viewDashboardStep.description',
|
||||
{
|
||||
defaultMessage: 'Stream, visualize, and analyze your Kubernetes infrastructure metrics.',
|
||||
}
|
||||
),
|
||||
description: i18n.translate('xpack.observability.guideConfig.viewDashboardStep.description', {
|
||||
defaultMessage: 'Stream, visualize, and analyze your Kubernetes infrastructure metrics.',
|
||||
}),
|
||||
location: {
|
||||
appID: 'dashboards',
|
||||
path: '#/view/kubernetes-f4dc26db-1b53-4ea2-a78b-1bfab8ea267c',
|
||||
},
|
||||
manualCompletion: {
|
||||
title: i18n.translate(
|
||||
'guidedOnboarding.observabilityGuide.viewDashboardStep.manualCompletionPopoverTitle',
|
||||
'xpack.observability.guideConfig.viewDashboardStep.manualCompletionPopoverTitle',
|
||||
{
|
||||
defaultMessage: 'Explore Kubernetes dashboards',
|
||||
}
|
||||
),
|
||||
description: i18n.translate(
|
||||
'guidedOnboarding.observabilityGuide.viewDashboardStep.manualCompletionPopoverDescription',
|
||||
'xpack.observability.guideConfig.viewDashboardStep.manualCompletionPopoverDescription',
|
||||
{
|
||||
defaultMessage: `Take your time to explore these pre-built dashboards included with the Kubernetes integration. When you’re ready, click the Setup guide button to continue.`,
|
||||
}
|
||||
|
@ -77,11 +74,11 @@ export const observabilityConfig: GuideConfig = {
|
|||
},
|
||||
{
|
||||
id: 'tour_observability',
|
||||
title: i18n.translate('guidedOnboarding.observabilityGuide.tourObservabilityStep.title', {
|
||||
title: i18n.translate('xpack.observability.guideConfig.tourObservabilityStep.title', {
|
||||
defaultMessage: 'Tour Elastic Observability',
|
||||
}),
|
||||
description: i18n.translate(
|
||||
'guidedOnboarding.observabilityGuide.tourObservabilityStep.description',
|
||||
'xpack.observability.guideConfig.tourObservabilityStep.description',
|
||||
{
|
||||
defaultMessage:
|
||||
'Get familiar with the rest of Elastic Observability and explore even more integrations.',
|
|
@ -21,6 +21,12 @@ import { SpacesPluginStart } from '@kbn/spaces-plugin/server';
|
|||
import { experimentalRuleFieldMap } from '@kbn/rule-registry-plugin/common/assets/field_maps/experimental_rule_field_map';
|
||||
import { mappingFromFieldMap } from '@kbn/rule-registry-plugin/common/mapping_from_field_map';
|
||||
import { ECS_COMPONENT_TEMPLATE_NAME } from '@kbn/rule-registry-plugin/common/assets';
|
||||
import type { GuidedOnboardingPluginSetup } from '@kbn/guided-onboarding-plugin/server';
|
||||
|
||||
import {
|
||||
observabilityGuideId,
|
||||
observabilityGuideConfig,
|
||||
} from '../common/guided_onboarding/observability_guide_config';
|
||||
import { ObservabilityConfig } from '.';
|
||||
import {
|
||||
bootstrapAnnotations,
|
||||
|
@ -42,6 +48,7 @@ interface PluginSetup {
|
|||
ruleRegistry: RuleRegistryPluginSetupContract;
|
||||
spaces: SpacesPluginStart;
|
||||
alerting: PluginSetupContract;
|
||||
guidedOnboarding: GuidedOnboardingPluginSetup;
|
||||
}
|
||||
|
||||
export class ObservabilityPlugin implements Plugin<ObservabilityPluginSetup> {
|
||||
|
@ -181,6 +188,11 @@ export class ObservabilityPlugin implements Plugin<ObservabilityPluginSetup> {
|
|||
ruleDataService,
|
||||
});
|
||||
|
||||
/**
|
||||
* Register a config for the observability guide
|
||||
*/
|
||||
plugins.guidedOnboarding.registerGuideConfig(observabilityGuideId, observabilityGuideConfig);
|
||||
|
||||
return {
|
||||
getAlertDetailsConfig() {
|
||||
return config.unsafe.alertDetails;
|
||||
|
|
|
@ -1,16 +1,16 @@
|
|||
/*
|
||||
* 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 and the Server Side Public License, v 1; you may not use this file except
|
||||
* in compliance with, at your election, the Elastic License 2.0 or the Server
|
||||
* Side Public License, v 1.
|
||||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
|
||||
import type { GuideConfig } from '@kbn/guided-onboarding-plugin/common';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import type { GuideConfig } from '../../../common';
|
||||
|
||||
export const securityConfig: GuideConfig = {
|
||||
title: i18n.translate('guidedOnboarding.securityGuide.title', {
|
||||
export const securityGuideId = 'security';
|
||||
export const securityGuideConfig: GuideConfig = {
|
||||
title: i18n.translate('xpack.securitySolution.guideConfig.title', {
|
||||
defaultMessage: 'Elastic Security guided setup',
|
||||
}),
|
||||
guideName: 'Security',
|
||||
|
@ -18,20 +18,20 @@ export const securityConfig: GuideConfig = {
|
|||
appID: 'securitySolutionUI',
|
||||
path: '/dashboards',
|
||||
},
|
||||
description: i18n.translate('guidedOnboarding.securityGuide.description', {
|
||||
description: i18n.translate('xpack.securitySolution.guideConfig.description', {
|
||||
defaultMessage: `We'll help you get set up quickly, using Elastic Defend.`,
|
||||
}),
|
||||
steps: [
|
||||
{
|
||||
id: 'add_data',
|
||||
title: i18n.translate('guidedOnboarding.securityGuide.addDataStep.title', {
|
||||
title: i18n.translate('xpack.securitySolution.guideConfig.addDataStep.title', {
|
||||
defaultMessage: 'Add data with Elastic Defend',
|
||||
}),
|
||||
descriptionList: [
|
||||
i18n.translate('guidedOnboarding.securityGuide.addDataStep.description1', {
|
||||
i18n.translate('xpack.securitySolution.guideConfig.addDataStep.description1', {
|
||||
defaultMessage: 'Use Elastic Defend to add your data.',
|
||||
}),
|
||||
i18n.translate('guidedOnboarding.securityGuide.addDataStep.description2', {
|
||||
i18n.translate('xpack.securitySolution.guideConfig.addDataStep.description2', {
|
||||
defaultMessage: 'See data coming in to your SIEM.',
|
||||
}),
|
||||
],
|
||||
|
@ -43,26 +43,29 @@ export const securityConfig: GuideConfig = {
|
|||
},
|
||||
{
|
||||
id: 'rules',
|
||||
title: i18n.translate('guidedOnboarding.securityGuide.rulesStep.title', {
|
||||
title: i18n.translate('xpack.securitySolution.guideConfig.rulesStep.title', {
|
||||
defaultMessage: 'Turn on rules',
|
||||
}),
|
||||
descriptionList: [
|
||||
i18n.translate('guidedOnboarding.securityGuide.rulesStep.description1', {
|
||||
i18n.translate('xpack.securitySolution.guideConfig.rulesStep.description1', {
|
||||
defaultMessage: 'Load the Elastic prebuilt rules.',
|
||||
}),
|
||||
i18n.translate('guidedOnboarding.securityGuide.rulesStep.description2', {
|
||||
i18n.translate('xpack.securitySolution.guideConfig.rulesStep.description2', {
|
||||
defaultMessage: 'Select and enable rules.',
|
||||
}),
|
||||
i18n.translate('guidedOnboarding.securityGuide.rulesStep.description3', {
|
||||
i18n.translate('xpack.securitySolution.guideConfig.rulesStep.description3', {
|
||||
defaultMessage: 'Enable rules to generate alerts.',
|
||||
}),
|
||||
],
|
||||
manualCompletion: {
|
||||
title: i18n.translate('guidedOnboarding.securityGuide.rulesStep.manualCompletion.title', {
|
||||
defaultMessage: 'Continue with the guide',
|
||||
}),
|
||||
title: i18n.translate(
|
||||
'xpack.securitySolution.guideConfig.rulesStep.manualCompletion.title',
|
||||
{
|
||||
defaultMessage: 'Continue with the guide',
|
||||
}
|
||||
),
|
||||
description: i18n.translate(
|
||||
'guidedOnboarding.securityGuide.rulesStep.manualCompletion.description',
|
||||
'xpack.securitySolution.guideConfig.rulesStep.manualCompletion.description',
|
||||
{
|
||||
defaultMessage: 'After you’ve enabled the rules you need, continue.',
|
||||
}
|
||||
|
@ -75,14 +78,14 @@ export const securityConfig: GuideConfig = {
|
|||
},
|
||||
{
|
||||
id: 'alertsCases',
|
||||
title: i18n.translate('guidedOnboarding.securityGuide.alertsStep.title', {
|
||||
title: i18n.translate('xpack.securitySolution.guideConfig.alertsStep.title', {
|
||||
defaultMessage: 'Manage alerts and cases',
|
||||
}),
|
||||
descriptionList: [
|
||||
i18n.translate('guidedOnboarding.securityGuide.alertsStep.description1', {
|
||||
i18n.translate('xpack.securitySolution.guideConfig.alertsStep.description1', {
|
||||
defaultMessage: 'View and triage alerts.',
|
||||
}),
|
||||
i18n.translate('guidedOnboarding.securityGuide.alertsStep.description2', {
|
||||
i18n.translate('xpack.securitySolution.guideConfig.alertsStep.description2', {
|
||||
defaultMessage: 'Create a case.',
|
||||
}),
|
||||
],
|
||||
|
@ -91,11 +94,14 @@ export const securityConfig: GuideConfig = {
|
|||
path: '/alerts',
|
||||
},
|
||||
manualCompletion: {
|
||||
title: i18n.translate('guidedOnboarding.securityGuide.alertsStep.manualCompletion.title', {
|
||||
defaultMessage: 'Continue the guide',
|
||||
}),
|
||||
title: i18n.translate(
|
||||
'xpack.securitySolution.guideConfig.alertsStep.manualCompletion.title',
|
||||
{
|
||||
defaultMessage: 'Continue the guide',
|
||||
}
|
||||
),
|
||||
description: i18n.translate(
|
||||
'guidedOnboarding.securityGuide.alertsStep.manualCompletion.description',
|
||||
'xpack.securitySolution.guideConfig.alertsStep.manualCompletion.description',
|
||||
{
|
||||
defaultMessage: `After you've explored the case, continue.`,
|
||||
}
|
|
@ -30,6 +30,10 @@ import { Dataset } from '@kbn/rule-registry-plugin/server';
|
|||
import type { ListPluginSetup } from '@kbn/lists-plugin/server';
|
||||
import type { ILicense } from '@kbn/licensing-plugin/server';
|
||||
|
||||
import {
|
||||
securityGuideId,
|
||||
securityGuideConfig,
|
||||
} from '../common/guided_onboarding/security_guide_config';
|
||||
import {
|
||||
createEqlAlertType,
|
||||
createIndicatorMatchAlertType,
|
||||
|
@ -398,6 +402,11 @@ export class Plugin implements ISecuritySolutionPlugin {
|
|||
|
||||
featureUsageService.setup(plugins.licensing);
|
||||
|
||||
/**
|
||||
* Register a config for the security guide
|
||||
*/
|
||||
plugins.guidedOnboarding.registerGuideConfig(securityGuideId, securityGuideConfig);
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
|
|
|
@ -37,6 +37,7 @@ import type { TelemetryPluginStart, TelemetryPluginSetup } from '@kbn/telemetry-
|
|||
import type { OsqueryPluginSetup } from '@kbn/osquery-plugin/server';
|
||||
import type { CloudSetup } from '@kbn/cloud-plugin/server';
|
||||
import type { CloudExperimentsPluginStart } from '@kbn/cloud-experiments-plugin/common';
|
||||
import type { GuidedOnboardingPluginSetup } from '@kbn/guided-onboarding-plugin/server';
|
||||
import type { PluginSetup as UnifiedSearchServerPluginSetup } from '@kbn/unified-search-plugin/server';
|
||||
|
||||
export interface SecuritySolutionPluginSetupDependencies {
|
||||
|
@ -56,6 +57,7 @@ export interface SecuritySolutionPluginSetupDependencies {
|
|||
usageCollection?: UsageCollectionPluginSetup;
|
||||
licensing: LicensingPluginSetup;
|
||||
osquery: OsqueryPluginSetup;
|
||||
guidedOnboarding: GuidedOnboardingPluginSetup;
|
||||
unifiedSearch: UnifiedSearchServerPluginSetup;
|
||||
}
|
||||
|
||||
|
|
|
@ -3108,49 +3108,11 @@
|
|||
"guidedOnboarding.dropdownPanel.stepHandlerError": "Impossible de mettre à jour le guide. Réessayez plus tard.",
|
||||
"guidedOnboarding.guidedSetupButtonLabel": "Guide de configuration",
|
||||
"guidedOnboarding.guidedSetupRedirectButtonLabel": "Guides de configuration",
|
||||
"guidedOnboarding.observabilityGuide.addDataStep.descriptionList.item2": "Ajoutez l'intégration Elastic Kubernetes.",
|
||||
"guidedOnboarding.observabilityGuide.addDataStep.title": "Ajouter et vérifier vos données",
|
||||
"guidedOnboarding.observabilityGuide.description": "Nous vous aiderons à obtenir rapidement de la visibilité dans votre environnement Kubernetes avec notre intégration d'Elastic. Obtenez des informations détaillées à partir de vos logs, indicateurs et traces pour détecter les problèmes de façon proactive et prendre des mesures pour les résoudre.",
|
||||
"guidedOnboarding.observabilityGuide.documentationLink": "En savoir plus",
|
||||
"guidedOnboarding.observabilityGuide.title": "Observer mon infrastructure Kubernetes",
|
||||
"guidedOnboarding.observabilityGuide.tourObservabilityStep.description": "Familiarisez-vous avec le reste d'Elastic Observability et explorez encore plus d'intégrations.",
|
||||
"guidedOnboarding.observabilityGuide.tourObservabilityStep.title": "Découvrir Elastic Observability",
|
||||
"guidedOnboarding.observabilityGuide.viewDashboardStep.description": "Diffusez, visualisez et analysez vos indicateurs d'infrastructure Kubernetes.",
|
||||
"guidedOnboarding.observabilityGuide.viewDashboardStep.manualCompletionPopoverDescription": "Prenez le temps d'explorer ces tableaux de bord prédéfinis inclus avec l'intégration Kubernetes. Lorsque vous serez prêt, cliquez sur le bouton Guide de configuration pour continuer.",
|
||||
"guidedOnboarding.observabilityGuide.viewDashboardStep.manualCompletionPopoverTitle": "Explorer les tableaux de bord Kubernetes",
|
||||
"guidedOnboarding.observabilityGuide.viewDashboardStep.title": "Explorer les indicateurs Kubernetes",
|
||||
"guidedOnboarding.quitGuideModal.cancelButtonLabel": "Annuler",
|
||||
"guidedOnboarding.quitGuideModal.deactivateGuideError": "Impossible de mettre à jour le guide. Réessayez plus tard.",
|
||||
"guidedOnboarding.quitGuideModal.modalDescription": "Vous pouvez redémarrer le guide de configuration à tout moment à partir du menu Aide.",
|
||||
"guidedOnboarding.quitGuideModal.modalTitle": "Quitter ce guide ?",
|
||||
"guidedOnboarding.quitGuideModal.quitButtonLabel": "Quitter le guide",
|
||||
"guidedOnboarding.searchGuide.addDataStep.description1": "Sélectionnez une méthode d'ingestion.",
|
||||
"guidedOnboarding.searchGuide.addDataStep.description2": "Créez un nouvel index Elasticsearch.",
|
||||
"guidedOnboarding.searchGuide.addDataStep.description3": "Configurez vos paramètres d'ingestion.",
|
||||
"guidedOnboarding.searchGuide.addDataStep.title": "Ajouter des données",
|
||||
"guidedOnboarding.searchGuide.description": "Créez des expériences de recherche personnalisées avec vos données grâce au robot d'indexation, aux connecteurs et aux API robustes prêts à l'emploi d'Elastic. Obtenez des informations détaillées à partir des analyses de recherche intégrées pour organiser les résultats et optimiser la pertinence.",
|
||||
"guidedOnboarding.searchGuide.searchExperienceStep.descriptionList.item1": "Découvrez plus de détails sur le framework d'interface utilisateur de recherche d'Elastic.",
|
||||
"guidedOnboarding.searchGuide.searchExperienceStep.descriptionList.item2": "Essayez le tutoriel dédié à l'interface utilisateur de recherche pour Elasticsearch.",
|
||||
"guidedOnboarding.searchGuide.searchExperienceStep.descriptionList.item3": "Créez une expérience de recherche de classe mondiale pour vos clients, vos employés ou vos utilisateurs.",
|
||||
"guidedOnboarding.searchGuide.searchExperienceStep.manualCompletionPopoverDescription": "Prenez le temps de découvrir comment utiliser l'interface utilisateur de recherche pour créer des expériences de recherche de classe mondiale. Lorsque vous serez prêt, cliquez sur le bouton Guide de configuration pour continuer.",
|
||||
"guidedOnboarding.searchGuide.searchExperienceStep.manualCompletionPopoverTitle": "Explorer l'interface utilisateur de recherche",
|
||||
"guidedOnboarding.searchGuide.searchExperienceStep.title": "Créer une expérience de recherche",
|
||||
"guidedOnboarding.searchGuide.title": "Rechercher dans mes données",
|
||||
"guidedOnboarding.securityGuide.addDataStep.description1": "Sélectionnez l'intégration Elastic Defend pour ajouter vos données.",
|
||||
"guidedOnboarding.securityGuide.addDataStep.description2": "Assurez-vous que vos données sont correctes.",
|
||||
"guidedOnboarding.securityGuide.addDataStep.title": "Ajouter des données avec Elastic Defend",
|
||||
"guidedOnboarding.securityGuide.alertsStep.description1": "Affichez et triez les alertes.",
|
||||
"guidedOnboarding.securityGuide.alertsStep.description2": "Créez un cas.",
|
||||
"guidedOnboarding.securityGuide.alertsStep.manualCompletion.description": "Après avoir exploré le cas que vous avez créé, cliquez ici pour continuer.",
|
||||
"guidedOnboarding.securityGuide.alertsStep.manualCompletion.title": "Continuer avec la visite",
|
||||
"guidedOnboarding.securityGuide.alertsStep.title": "Gérer les alertes et les cas",
|
||||
"guidedOnboarding.securityGuide.description": "Nous vous aiderons à vous mettre en route rapidement grâce aux intégrations prêtes à l'emploi d'Elastic.",
|
||||
"guidedOnboarding.securityGuide.rulesStep.description1": "Chargez les règles prédéfinies.",
|
||||
"guidedOnboarding.securityGuide.rulesStep.description2": "Sélectionnez les règles souhaitées.",
|
||||
"guidedOnboarding.securityGuide.rulesStep.manualCompletion.description": "Après avoir activé les règles souhaitées, cliquez ici pour continuer.",
|
||||
"guidedOnboarding.securityGuide.rulesStep.manualCompletion.title": "Continuer avec la visite",
|
||||
"guidedOnboarding.securityGuide.rulesStep.title": "Activer les règles",
|
||||
"guidedOnboarding.securityGuide.title": "Configuration guidée d'Elastic Security",
|
||||
"guidedOnboardingPackage.gettingStarted.guideCard.stepsLabel": "{progress} étapes",
|
||||
"guidedOnboardingPackage.gettingStarted.guideCard.continueGuide.buttonLabel": "Continuer",
|
||||
"guidedOnboardingPackage.gettingStarted.guideCard.observability.cardDescription": "Monitorez votre infrastructure Kubernetes en consolidant vos logs et indicateurs.",
|
||||
|
|
|
@ -3106,49 +3106,11 @@
|
|||
"guidedOnboarding.dropdownPanel.stepHandlerError": "ガイドを更新できません。しばらくたってから再試行してください。",
|
||||
"guidedOnboarding.guidedSetupButtonLabel": "セットアップガイド",
|
||||
"guidedOnboarding.guidedSetupRedirectButtonLabel": "セットアップガイド",
|
||||
"guidedOnboarding.observabilityGuide.addDataStep.descriptionList.item2": "Elastic Kubernetes統合を追加します。",
|
||||
"guidedOnboarding.observabilityGuide.addDataStep.title": "データを追加して検証",
|
||||
"guidedOnboarding.observabilityGuide.description": "Elastic統合では、Kubernetes環境をすばやく可視化できます。ログ、メトリック、トレースを深く分析し、能動的に問題を検出し、解決のためのアクションを実行できます。",
|
||||
"guidedOnboarding.observabilityGuide.documentationLink": "詳細",
|
||||
"guidedOnboarding.observabilityGuide.title": "Kubernetesインフラストラクチャーの監視",
|
||||
"guidedOnboarding.observabilityGuide.tourObservabilityStep.description": "その他のElasticオブザーバビリティを理解して、さらに多くの統合を探りましょう。",
|
||||
"guidedOnboarding.observabilityGuide.tourObservabilityStep.title": "Elasticオブザーバビリティのガイド",
|
||||
"guidedOnboarding.observabilityGuide.viewDashboardStep.description": "Kubernetesインフラストラクチャーメトリックをストリーム、可視化、分析します。",
|
||||
"guidedOnboarding.observabilityGuide.viewDashboardStep.manualCompletionPopoverDescription": "Kubernetes統合に含まれるこれらの組み込まれたダッシュボードをご検討ください。準備ができたら、[セットアップガイド]ボタンをクリックして続行します。",
|
||||
"guidedOnboarding.observabilityGuide.viewDashboardStep.manualCompletionPopoverTitle": "Kubernetesダッシュボードを見る",
|
||||
"guidedOnboarding.observabilityGuide.viewDashboardStep.title": "Kubernetesメトリックを見る",
|
||||
"guidedOnboarding.quitGuideModal.cancelButtonLabel": "キャンセル",
|
||||
"guidedOnboarding.quitGuideModal.deactivateGuideError": "ガイドを更新できません。しばらくたってから再試行してください。",
|
||||
"guidedOnboarding.quitGuideModal.modalDescription": "[ヘルプ]メニューを使用すると、いつでもセットアップガイドを再開できます。",
|
||||
"guidedOnboarding.quitGuideModal.modalTitle": "このガイドを終了しますか?",
|
||||
"guidedOnboarding.quitGuideModal.quitButtonLabel": "ガイドを終了",
|
||||
"guidedOnboarding.searchGuide.addDataStep.description1": "インジェスチョン方法を選択",
|
||||
"guidedOnboarding.searchGuide.addDataStep.description2": "新しいElasticsearchインデックスを作成します。",
|
||||
"guidedOnboarding.searchGuide.addDataStep.description3": "インジェスチョン設定を構成します。",
|
||||
"guidedOnboarding.searchGuide.addDataStep.title": "データの追加",
|
||||
"guidedOnboarding.searchGuide.description": "Elasticのすぐに使えるWebクローラー、コネクター、堅牢なAPIを使用すると、データ検索エクスペリエンスをカスタマイズできます。組み込まれた検索分析から深いインサイトを取り込み、結果を整理して、関連性を最適化します。",
|
||||
"guidedOnboarding.searchGuide.searchExperienceStep.descriptionList.item1": "ElasticのSearch UIフレームワークの詳細をご覧ください。",
|
||||
"guidedOnboarding.searchGuide.searchExperienceStep.descriptionList.item2": "ElasticsearchのSearch UIチュートリアルをお試しください。",
|
||||
"guidedOnboarding.searchGuide.searchExperienceStep.descriptionList.item3": "顧客、従業員、ユーザー向けに世界クラスの検索エクスペリエンスを構築できます。",
|
||||
"guidedOnboarding.searchGuide.searchExperienceStep.manualCompletionPopoverDescription": "Search UIを使用して、世界クラスの検索エクスペリエンスを構築する方法についてご覧ください。準備ができたら、[セットアップガイド]ボタンをクリックして続行します。",
|
||||
"guidedOnboarding.searchGuide.searchExperienceStep.manualCompletionPopoverTitle": "Search UIを見る",
|
||||
"guidedOnboarding.searchGuide.searchExperienceStep.title": "検索エクスペリエンスを構築",
|
||||
"guidedOnboarding.searchGuide.title": "データを検索",
|
||||
"guidedOnboarding.securityGuide.addDataStep.description1": "Elastic Defendを選択して、データを追加します。",
|
||||
"guidedOnboarding.securityGuide.addDataStep.description2": "データに問題がないことを確認します。",
|
||||
"guidedOnboarding.securityGuide.addDataStep.title": "Elastic Defendでデータを追加",
|
||||
"guidedOnboarding.securityGuide.alertsStep.description1": "アラートを表示してトリアージします。",
|
||||
"guidedOnboarding.securityGuide.alertsStep.description2": "ケースを作成します。",
|
||||
"guidedOnboarding.securityGuide.alertsStep.manualCompletion.description": "作成したケースを確認したら、ここをクリックして続行してください。",
|
||||
"guidedOnboarding.securityGuide.alertsStep.manualCompletion.title": "ツアーを続ける",
|
||||
"guidedOnboarding.securityGuide.alertsStep.title": "アラートとケースの管理",
|
||||
"guidedOnboarding.securityGuide.description": "Elasticのアウトオブボックス統合を使用すると、すばやく設定できます。",
|
||||
"guidedOnboarding.securityGuide.rulesStep.description1": "事前構築済みルールを読み込みます。",
|
||||
"guidedOnboarding.securityGuide.rulesStep.description2": "任意のルールを選択します。",
|
||||
"guidedOnboarding.securityGuide.rulesStep.manualCompletion.description": "任意のルールを有効化した後に、ここをクリックして続行してください。",
|
||||
"guidedOnboarding.securityGuide.rulesStep.manualCompletion.title": "ツアーを続ける",
|
||||
"guidedOnboarding.securityGuide.rulesStep.title": "ルールをオンにする",
|
||||
"guidedOnboarding.securityGuide.title": "Elastic Securityセットアップガイド",
|
||||
"guidedOnboardingPackage.gettingStarted.guideCard.stepsLabel": "{progress}ステップ",
|
||||
"guidedOnboardingPackage.gettingStarted.guideCard.continueGuide.buttonLabel": "続行",
|
||||
"guidedOnboardingPackage.gettingStarted.guideCard.observability.cardDescription": "ログとメトリックを統合して、Kubernetesインフラストラクチャーを監視できます。",
|
||||
|
|
|
@ -3110,49 +3110,11 @@
|
|||
"guidedOnboarding.dropdownPanel.stepHandlerError": "无法更新指南。请稍后重试。",
|
||||
"guidedOnboarding.guidedSetupButtonLabel": "设置指南",
|
||||
"guidedOnboarding.guidedSetupRedirectButtonLabel": "设置指南",
|
||||
"guidedOnboarding.observabilityGuide.addDataStep.descriptionList.item2": "添加 Elastic Kubernetes 集成。",
|
||||
"guidedOnboarding.observabilityGuide.addDataStep.title": "添加并验证您的数据",
|
||||
"guidedOnboarding.observabilityGuide.description": "我们将利用 Elastic 集成帮助您快速了解您的 Kubernetes 环境。从日志、指标和跟踪中获得深入洞察,以主动检测问题并采取操作解决问题。",
|
||||
"guidedOnboarding.observabilityGuide.documentationLink": "了解详情",
|
||||
"guidedOnboarding.observabilityGuide.title": "观察我的 Kubernetes 基础架构",
|
||||
"guidedOnboarding.observabilityGuide.tourObservabilityStep.description": "熟悉 Elastic Observability 的其余功能,并浏览更多集成。",
|
||||
"guidedOnboarding.observabilityGuide.tourObservabilityStep.title": "试用 Elastic Observability",
|
||||
"guidedOnboarding.observabilityGuide.viewDashboardStep.description": "流式传输、可视化并分析您的 Kubernetes 基础架构指标。",
|
||||
"guidedOnboarding.observabilityGuide.viewDashboardStep.manualCompletionPopoverDescription": "花时间浏览 Kubernetes 集成附带的这些预构建的仪表板。准备就绪后,单击“设置指南”按钮继续。",
|
||||
"guidedOnboarding.observabilityGuide.viewDashboardStep.manualCompletionPopoverTitle": "浏览 Kubernetes 仪表板",
|
||||
"guidedOnboarding.observabilityGuide.viewDashboardStep.title": "浏览 Kubernetes 指标",
|
||||
"guidedOnboarding.quitGuideModal.cancelButtonLabel": "取消",
|
||||
"guidedOnboarding.quitGuideModal.deactivateGuideError": "无法更新指南。请稍后重试。",
|
||||
"guidedOnboarding.quitGuideModal.modalDescription": "您可以随时从“帮助”菜单重新启动设置指南。",
|
||||
"guidedOnboarding.quitGuideModal.modalTitle": "退出本指南?",
|
||||
"guidedOnboarding.quitGuideModal.quitButtonLabel": "退出指南",
|
||||
"guidedOnboarding.searchGuide.addDataStep.description1": "选择采集方法。",
|
||||
"guidedOnboarding.searchGuide.addDataStep.description2": "创建新的 Elasticsearch 索引。",
|
||||
"guidedOnboarding.searchGuide.addDataStep.description3": "配置采集设置。",
|
||||
"guidedOnboarding.searchGuide.addDataStep.title": "添加数据",
|
||||
"guidedOnboarding.searchGuide.description": "使用 Elastic 开箱即用的网络爬虫、连接器和稳健的 API,利用您的数据构建定制搜索体验。从内置搜索分析中获得深入洞察,以策展结果并优化相关性。",
|
||||
"guidedOnboarding.searchGuide.searchExperienceStep.descriptionList.item1": "详细了解 Elastic 的搜索 UI 框架。",
|
||||
"guidedOnboarding.searchGuide.searchExperienceStep.descriptionList.item2": "试用 Elasticsearch 的搜索 UI 教程。",
|
||||
"guidedOnboarding.searchGuide.searchExperienceStep.descriptionList.item3": "为您的客户、员工或用户构建世界级的搜索体验。",
|
||||
"guidedOnboarding.searchGuide.searchExperienceStep.manualCompletionPopoverDescription": "花时间了解如何使用搜索 UI 构建世界级的搜索体验。准备就绪后,单击“设置指南”按钮继续。",
|
||||
"guidedOnboarding.searchGuide.searchExperienceStep.manualCompletionPopoverTitle": "了解搜索 UI",
|
||||
"guidedOnboarding.searchGuide.searchExperienceStep.title": "构建搜索体验",
|
||||
"guidedOnboarding.searchGuide.title": "搜索我的数据",
|
||||
"guidedOnboarding.securityGuide.addDataStep.description1": "选择 Elastic Defend 集成以添加您的数据。",
|
||||
"guidedOnboarding.securityGuide.addDataStep.description2": "确保数据看起来不错。",
|
||||
"guidedOnboarding.securityGuide.addDataStep.title": "使用 Elastic Defend 添加数据",
|
||||
"guidedOnboarding.securityGuide.alertsStep.description1": "查看告警并对其进行分类。",
|
||||
"guidedOnboarding.securityGuide.alertsStep.description2": "创建案例。",
|
||||
"guidedOnboarding.securityGuide.alertsStep.manualCompletion.description": "浏览您创建的案例后,请单击此处继续。",
|
||||
"guidedOnboarding.securityGuide.alertsStep.manualCompletion.title": "继续学习教程",
|
||||
"guidedOnboarding.securityGuide.alertsStep.title": "管理告警和案例",
|
||||
"guidedOnboarding.securityGuide.description": "我们将使用 Elastic 开箱即用的集成功能帮助您快速完成设置。",
|
||||
"guidedOnboarding.securityGuide.rulesStep.description1": "加载预构建的规则。",
|
||||
"guidedOnboarding.securityGuide.rulesStep.description2": "选择所需规则。",
|
||||
"guidedOnboarding.securityGuide.rulesStep.manualCompletion.description": "启用所需规则后,请单击此处继续。",
|
||||
"guidedOnboarding.securityGuide.rulesStep.manualCompletion.title": "继续学习教程",
|
||||
"guidedOnboarding.securityGuide.rulesStep.title": "打开规则",
|
||||
"guidedOnboarding.securityGuide.title": "Elastic Security 引导式设置",
|
||||
"guidedOnboardingPackage.gettingStarted.guideCard.stepsLabel": "{progress} 步骤",
|
||||
"guidedOnboardingPackage.gettingStarted.guideCard.continueGuide.buttonLabel": "继续",
|
||||
"guidedOnboardingPackage.gettingStarted.guideCard.observability.cardDescription": "通过整合日志和指标来监测您的 Kubernetes 基础架构。",
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue