[Stateful sidenav] Update feedback urls (#198143)

This commit is contained in:
Sébastien Loix 2024-10-31 08:55:49 +00:00 committed by GitHub
parent 2162c56b59
commit 89fe54815d
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
29 changed files with 113 additions and 77 deletions

View file

@ -36,6 +36,7 @@ import type {
ChromeSetProjectBreadcrumbsParams,
NavigationTreeDefinition,
AppDeepLinkId,
SolutionId,
} from '@kbn/core-chrome-browser';
import type { CustomBrandingStart } from '@kbn/core-custom-branding-browser';
import type {
@ -343,7 +344,10 @@ export class ChromeService {
LinkId extends AppDeepLinkId = AppDeepLinkId,
Id extends string = string,
ChildrenId extends string = Id
>(id: string, navigationTree$: Observable<NavigationTreeDefinition<LinkId, Id, ChildrenId>>) {
>(
id: SolutionId,
navigationTree$: Observable<NavigationTreeDefinition<LinkId, Id, ChildrenId>>
) {
validateChromeStyle();
projectNavigation.initNavigation(id, navigationTree$);
}

View file

@ -110,7 +110,7 @@ describe('initNavigation()', () => {
beforeAll(() => {
projectNavigation.initNavigation<any>(
'foo',
'es',
of({
body: [
{
@ -185,7 +185,7 @@ describe('initNavigation()', () => {
const { projectNavigation: projNavigation, getNavigationTree: getNavTree } =
setupInitNavigation();
projNavigation.initNavigation<any>(
'foo',
'es',
of({
body: [
{
@ -210,7 +210,7 @@ describe('initNavigation()', () => {
const { projectNavigation: projNavigation } = setupInitNavigation();
projNavigation.initNavigation<any>(
'foo',
'es',
of({
body: [
{
@ -399,7 +399,7 @@ describe('initNavigation()', () => {
// 2. initNavigation() is called
projectNavigation.initNavigation<any>(
'foo',
'es',
of({
body: [
{
@ -427,7 +427,7 @@ describe('initNavigation()', () => {
});
projectNavigation.initNavigation<any>(
'foo',
'es',
// @ts-expect-error - We pass a non valid cloudLink that is not TS valid
of({
body: [
@ -533,7 +533,7 @@ describe('breadcrumbs', () => {
const obs = subj.asObservable();
if (initiateNavigation) {
projectNavigation.initNavigation('foo', obs);
projectNavigation.initNavigation('es', obs);
}
return {
@ -740,7 +740,7 @@ describe('breadcrumbs', () => {
{ text: 'custom1', href: '/custom1' },
{ text: 'custom2', href: '/custom1/custom2' },
]);
projectNavigation.initNavigation('foo', of(mockNavigation)); // init navigation
projectNavigation.initNavigation('es', of(mockNavigation)); // init navigation
const breadcrumbs = await firstValueFrom(projectNavigation.getProjectBreadcrumbs$());
expect(breadcrumbs).toHaveLength(4);
@ -779,7 +779,7 @@ describe('getActiveNodes$()', () => {
expect(activeNodes).toEqual([]);
projectNavigation.initNavigation<any>(
'foo',
'es',
of({
body: [
{
@ -835,7 +835,7 @@ describe('getActiveNodes$()', () => {
expect(activeNodes).toEqual([]);
projectNavigation.initNavigation<any>(
'foo',
'es',
of({
body: [
{
@ -889,7 +889,7 @@ describe('getActiveNodes$()', () => {
describe('solution navigations', () => {
const solution1: SolutionNavigationDefinition<any> = {
id: 'solution1',
id: 'es',
title: 'Solution 1',
icon: 'logoSolution1',
homePage: 'discover',
@ -897,7 +897,7 @@ describe('solution navigations', () => {
};
const solution2: SolutionNavigationDefinition<any> = {
id: 'solution2',
id: 'oblt',
title: 'Solution 2',
icon: 'logoSolution2',
homePage: 'app2',
@ -906,7 +906,7 @@ describe('solution navigations', () => {
};
const solution3: SolutionNavigationDefinition<any> = {
id: 'solution3',
id: 'security',
title: 'Solution 3',
icon: 'logoSolution3',
homePage: 'discover',
@ -943,30 +943,30 @@ describe('solution navigations', () => {
}
{
projectNavigation.updateSolutionNavigations({ 1: solution1, 2: solution2 });
projectNavigation.updateSolutionNavigations({ es: solution1, oblt: solution2 });
const solutionNavs = await lastValueFrom(
projectNavigation.getSolutionsNavDefinitions$().pipe(take(1))
);
expect(solutionNavs).toEqual({ 1: solution1, 2: solution2 });
expect(solutionNavs).toEqual({ es: solution1, oblt: solution2 });
}
{
// Test partial update
projectNavigation.updateSolutionNavigations({ 3: solution3 }, false);
projectNavigation.updateSolutionNavigations({ security: solution3 }, false);
const solutionNavs = await lastValueFrom(
projectNavigation.getSolutionsNavDefinitions$().pipe(take(1))
);
expect(solutionNavs).toEqual({ 1: solution1, 2: solution2, 3: solution3 });
expect(solutionNavs).toEqual({ es: solution1, oblt: solution2, security: solution3 });
}
{
// Test full replacement
projectNavigation.updateSolutionNavigations({ 4: solution3 }, true);
projectNavigation.updateSolutionNavigations({ security: solution3 }, true);
const solutionNavs = await lastValueFrom(
projectNavigation.getSolutionsNavDefinitions$().pipe(take(1))
);
expect(solutionNavs).toEqual({ 4: solution3 });
expect(solutionNavs).toEqual({ security: solution3 });
}
});
@ -980,8 +980,8 @@ describe('solution navigations', () => {
expect(activeSolution).toBeNull();
}
projectNavigation.changeActiveSolutionNavigation('2'); // Set **before** the navs are registered
projectNavigation.updateSolutionNavigations({ 1: solution1, 2: solution2 });
projectNavigation.changeActiveSolutionNavigation('oblt'); // Set **before** the navs are registered
projectNavigation.updateSolutionNavigations({ es: solution1, oblt: solution2 });
{
const activeSolution = await lastValueFrom(
@ -994,7 +994,7 @@ describe('solution navigations', () => {
expect(activeSolution).toEqual(rest);
}
projectNavigation.changeActiveSolutionNavigation('1'); // Set **after** the navs are registered
projectNavigation.changeActiveSolutionNavigation('es'); // Set **after** the navs are registered
{
const activeSolution = await lastValueFrom(
@ -1027,7 +1027,7 @@ describe('solution navigations', () => {
{
const fooSolution: SolutionNavigationDefinition<any> = {
id: 'fooSolution',
id: 'es',
title: 'Foo solution',
icon: 'logoSolution',
homePage: 'discover',
@ -1053,8 +1053,8 @@ describe('solution navigations', () => {
}),
};
projectNavigation.changeActiveSolutionNavigation('foo');
projectNavigation.updateSolutionNavigations({ foo: fooSolution });
projectNavigation.changeActiveSolutionNavigation('es');
projectNavigation.updateSolutionNavigations({ es: fooSolution });
projectNavigation.setPanelSelectedNode('link2'); // Set the selected node using its id

View file

@ -17,6 +17,7 @@ import type {
NavigationTreeDefinition,
SolutionNavigationDefinitions,
CloudLinks,
SolutionId,
} from '@kbn/core-chrome-browser';
import type { InternalHttpStart } from '@kbn/core-http-browser-internal';
import {
@ -86,9 +87,9 @@ export class ProjectNavigationService {
private readonly solutionNavDefinitions$ = new BehaviorSubject<SolutionNavigationDefinitions>({});
// As the active definition **id** and the definitions are set independently, one before the other without
// any guarantee of order, we need to store the next active definition id in a separate BehaviorSubject
private readonly nextSolutionNavDefinitionId$ = new BehaviorSubject<string | null>(null);
private readonly nextSolutionNavDefinitionId$ = new BehaviorSubject<SolutionId | null>(null);
// The active solution navigation definition id that has been initiated and is currently active
private readonly activeSolutionNavDefinitionId$ = new BehaviorSubject<string | null>(null);
private readonly activeSolutionNavDefinitionId$ = new BehaviorSubject<SolutionId | null>(null);
private readonly location$ = new BehaviorSubject<Location>(createLocation('/'));
private deepLinksMap$: Observable<Record<string, ChromeNavLink>> = of({});
private cloudLinks$ = new BehaviorSubject<CloudLinks>({});
@ -138,7 +139,7 @@ export class ProjectNavigationService {
return this.projectName$.asObservable();
},
initNavigation: <LinkId extends AppDeepLinkId = AppDeepLinkId>(
id: string,
id: SolutionId,
navTreeDefinition$: Observable<NavigationTreeDefinition<LinkId>>
) => {
this.initNavigation(id, navTreeDefinition$);
@ -202,7 +203,7 @@ export class ProjectNavigationService {
* @param id Id for the navigation tree definition
* @param navTreeDefinition$ The navigation tree definition
*/
private initNavigation(id: string, navTreeDefinition$: Observable<NavigationTreeDefinition>) {
private initNavigation(id: SolutionId, navTreeDefinition$: Observable<NavigationTreeDefinition>) {
if (this.activeSolutionNavDefinitionId$.getValue() === id) return;
if (this.navigationChangeSubscription) {
@ -220,7 +221,7 @@ export class ProjectNavigationService {
.pipe(
takeUntil(this.stop$),
map(([def, deepLinksMap, cloudLinks]) => {
return parseNavigationTree(def, {
return parseNavigationTree(id, def, {
deepLinks: deepLinksMap,
cloudLinks,
});
@ -382,7 +383,7 @@ export class ProjectNavigationService {
this.projectHome$.next(homeHref);
}
private changeActiveSolutionNavigation(id: string | null) {
private changeActiveSolutionNavigation(id: SolutionId | null) {
if (this.nextSolutionNavDefinitionId$.getValue() === id) return;
this.nextSolutionNavDefinitionId$.next(id);
}
@ -400,7 +401,7 @@ export class ProjectNavigationService {
if (!definitions[id]) return null;
// We strip out the sideNavComponent from the definition as it should only be used internally
const { sideNavComponent, ...definition } = definitions[id];
const { sideNavComponent, ...definition } = definitions[id]!;
return definition;
})
);

View file

@ -22,6 +22,7 @@ import type {
CloudLinkId,
CloudLinks,
ItemDefinition,
SolutionId,
} from '@kbn/core-chrome-browser/src';
import type { Location } from 'history';
import type { MouseEventHandler } from 'react';
@ -364,6 +365,7 @@ const isRecentlyAccessedDefinition = (
};
export const parseNavigationTree = (
id: SolutionId,
navigationTreeDef: NavigationTreeDefinition,
{ deepLinks, cloudLinks }: { deepLinks: Record<string, ChromeNavLink>; cloudLinks: CloudLinks }
): {
@ -376,7 +378,7 @@ export const parseNavigationTree = (
const navigationTree: ChromeProjectNavigationNode[] = [];
// Contains UI layout information (body, footer) and render "special" blocks like recently accessed.
const navigationTreeUI: NavigationTreeDefinitionUI = { body: [] };
const navigationTreeUI: NavigationTreeDefinitionUI = { id, body: [] };
const initNodeAndChildren = (
node: GroupDefinition | ItemDefinition | NodeDefinition,

View file

@ -18,6 +18,7 @@ import type {
NavigationTreeDefinitionUI,
CloudURLs,
SolutionNavigationDefinitions,
SolutionId,
} from '@kbn/core-chrome-browser';
import type { Observable } from 'rxjs';
@ -66,7 +67,7 @@ export interface InternalChromeStart extends ChromeStart {
Id extends string = string,
ChildrenId extends string = Id
>(
id: string,
id: SolutionId,
navigationTree$: Observable<NavigationTreeDefinition<LinkId, Id, ChildrenId>>
): void;
@ -117,6 +118,6 @@ export interface InternalChromeStart extends ChromeStart {
* @param id The id of the active solution navigation. If `null` is provided, the solution navigation
* will be replaced with the legacy Kibana navigation.
*/
changeActiveSolutionNavigation(id: string | null): void;
changeActiveSolutionNavigation(id: SolutionId | null): void;
};
}

View file

@ -60,4 +60,5 @@ export type {
SolutionNavigationDefinitions,
EuiSideNavItemTypeEnhanced,
RenderAs,
SolutionId,
} from './src';

View file

@ -38,6 +38,7 @@ export type {
PanelSelectedNode,
AppDeepLinkId,
AppId,
SolutionId,
CloudLinkId,
CloudLink,
CloudLinks,

View file

@ -42,6 +42,8 @@ import type { AppId as SharedApp, DeepLinkId as SharedLink } from '@kbn/deeplink
import type { ChromeNavLink } from './nav_links';
import type { ChromeRecentlyAccessedHistoryItem } from './recently_accessed';
export type SolutionId = 'es' | 'oblt' | 'security';
/** @public */
export type AppId =
| DevToolsApp
@ -414,6 +416,7 @@ export interface NavigationTreeDefinition<
* with their corresponding "deepLink"...)
*/
export interface NavigationTreeDefinitionUI {
id: SolutionId;
body: Array<ChromeProjectNavigationNode | RecentlyAccessedDefinition>;
footer?: Array<ChromeProjectNavigationNode | RecentlyAccessedDefinition>;
}
@ -429,7 +432,7 @@ export interface NavigationTreeDefinitionUI {
export interface SolutionNavigationDefinition<LinkId extends AppDeepLinkId = AppDeepLinkId> {
/** Unique id for the solution navigation. */
id: string;
id: SolutionId;
/** Title for the solution navigation. */
title: string;
/** The navigation tree definition */
@ -442,9 +445,9 @@ export interface SolutionNavigationDefinition<LinkId extends AppDeepLinkId = App
homePage?: LinkId;
}
export interface SolutionNavigationDefinitions {
[id: string]: SolutionNavigationDefinition;
}
export type SolutionNavigationDefinitions = {
[id in SolutionId]?: SolutionNavigationDefinition;
};
/**
* Temporary helper interface while we have to maintain both the legacy side navigation

View file

@ -76,7 +76,7 @@ describe('Active node', () => {
];
const { findByTestId } = renderNavigation({
navTreeDef: of({ body: navigationBody }),
navTreeDef: of({ id: 'es', body: navigationBody }),
services: { activeNodes$: getActiveNodes$() },
});

View file

@ -21,6 +21,7 @@ describe('builds navigation tree', () => {
test('render reference UI and build the navigation tree', async () => {
const { findByTestId } = renderNavigation({
navTreeDef: of({
id: 'es',
body: [
{
id: 'group1',
@ -107,6 +108,7 @@ describe('builds navigation tree', () => {
{
const { findByTestId, unmount } = renderNavigation({
navTreeDef: of({
id: 'es',
body: [accordionNode],
}),
services: { navigateToUrl },
@ -121,6 +123,7 @@ describe('builds navigation tree', () => {
{
const { findByTestId } = renderNavigation({
navTreeDef: of({
id: 'es',
body: [
{
...accordionNode,
@ -165,6 +168,7 @@ describe('builds navigation tree', () => {
// Side nav is collapsed
const { queryAllByTestId, unmount } = renderNavigation({
navTreeDef: of({
id: 'es',
body: [nodes],
}),
services: { isSideNavCollapsed: true },
@ -180,6 +184,7 @@ describe('builds navigation tree', () => {
// Side nav is not collapsed
const { queryAllByTestId, unmount } = renderNavigation({
navTreeDef: of({
id: 'es',
body: [nodes],
}),
services: { isSideNavCollapsed: false }, // No conversion to accordion
@ -195,6 +200,7 @@ describe('builds navigation tree', () => {
// Panel opener with a link
const { queryAllByTestId, unmount } = renderNavigation({
navTreeDef: of({
id: 'es',
body: [
{
...nodes,
@ -238,6 +244,7 @@ describe('builds navigation tree', () => {
const { findByTestId } = renderNavigation({
navTreeDef: of({
id: 'es',
body: [node],
}),
services: { navigateToUrl, eventTracker: new EventTracker({ reportEvent }) },
@ -276,6 +283,7 @@ describe('builds navigation tree', () => {
const { findByTestId } = renderNavigation({
navTreeDef: of({
id: 'es',
body: [node],
}),
services: { navigateToUrl },
@ -290,6 +298,7 @@ describe('builds navigation tree', () => {
test('should not render the group if it does not have children', async () => {
const navTree: NavigationTreeDefinitionUI = {
id: 'es',
body: [
{
id: 'root',
@ -338,6 +347,7 @@ describe('builds navigation tree', () => {
]);
const navTree: NavigationTreeDefinitionUI = {
id: 'es',
body: [{ type: 'recentlyAccessed' }],
};
@ -364,6 +374,7 @@ describe('builds navigation tree', () => {
]);
const navTree: NavigationTreeDefinitionUI = {
id: 'es',
body: [{ type: 'recentlyAccessed' }],
};

View file

@ -21,6 +21,7 @@ import { renderNavigation } from './utils';
describe('Panel', () => {
test('should render group as panel opener', async () => {
const navigationTree: NavigationTreeDefinitionUI = {
id: 'es',
body: [
{
id: 'root',
@ -60,6 +61,7 @@ describe('Panel', () => {
test('should not render group if all children are hidden', async () => {
const navigationTree: NavigationTreeDefinitionUI = {
id: 'es',
body: [
{
id: 'root',
@ -146,6 +148,7 @@ describe('Panel', () => {
]);
const navTree: NavigationTreeDefinitionUI = {
id: 'es',
body: [
{
id: 'root',
@ -196,6 +199,7 @@ describe('Panel', () => {
describe('auto generated content', () => {
test('should rendre block groups with title', async () => {
const navTree: NavigationTreeDefinitionUI = {
id: 'es',
body: [
{
id: 'root',
@ -262,6 +266,7 @@ describe('Panel', () => {
test('should rendre block groups without title', async () => {
const navTree: NavigationTreeDefinitionUI = {
id: 'es',
body: [
{
id: 'root',
@ -327,6 +332,7 @@ describe('Panel', () => {
test('should rendre accordion groups', async () => {
const navTree: NavigationTreeDefinitionUI = {
id: 'es',
body: [
{
id: 'root',

View file

@ -10,11 +10,20 @@
import { EuiButton, EuiCallOut, useEuiTheme, EuiText, EuiSpacer } from '@elastic/eui';
import React, { FC, useState } from 'react';
import { i18n } from '@kbn/i18n';
import type { SolutionId } from '@kbn/core-chrome-browser';
const feedbackUrl = 'https://ela.st/nav-feedback';
const feedbackUrls: { [id in SolutionId]: string } = {
es: 'https://ela.st/search-nav-feedback',
oblt: 'https://ela.st/o11y-nav-feedback',
security: 'https://ela.st/security-nav-feedback',
};
const FEEDBACK_BTN_KEY = 'core.chrome.sideNav.feedbackBtn';
export const FeedbackBtn: FC = () => {
interface Props {
solutionId: SolutionId;
}
export const FeedbackBtn: FC<Props> = ({ solutionId }) => {
const { euiTheme } = useEuiTheme();
const [showCallOut, setShowCallOut] = useState(
sessionStorage.getItem(FEEDBACK_BTN_KEY) !== 'hidden'
@ -26,7 +35,7 @@ export const FeedbackBtn: FC = () => {
};
const onClick = () => {
window.open(feedbackUrl, '_blank');
window.open(feedbackUrls[solutionId], '_blank');
onDismiss();
};

View file

@ -91,6 +91,7 @@ const NavigationWrapper: FC<Props & Omit<Partial<EuiCollapsibleNavBetaProps>, 'c
};
const groupExamplesNavigationTree: NavigationTreeDefinitionUI = {
id: 'es',
body: [
// My custom project
{
@ -257,6 +258,7 @@ export const GroupsExamples = (args: NavigationServices) => {
};
const navigationTree: NavigationTreeDefinitionUI = {
id: 'es',
body: [
// My custom project
{
@ -568,6 +570,7 @@ const panelContentProvider: ContentProvider = (id: string) => {
};
const navigationTreeWithPanels: NavigationTreeDefinitionUI = {
id: 'es',
body: [
// My custom project
{

View file

@ -52,7 +52,8 @@ const NavigationComp: FC<Props> = ({ navigationTree$, dataTestSubj, panelContent
useNavigationService();
const activeNodes = useObservable(activeNodes$, []);
const navigationTree = useObservable(navigationTree$, { body: [] });
const navigationTree = useObservable(navigationTree$, { id: 'es', body: [] });
const { id: solutionId } = navigationTree;
const isFeedbackBtnVisible = useObservable(isFeedbackBtnVisible$, false);
const contextValue = useMemo<Context>(
@ -95,7 +96,7 @@ const NavigationComp: FC<Props> = ({ navigationTree$, dataTestSubj, panelContent
<EuiFlexItem>{renderNodes(navigationTree.body)}</EuiFlexItem>
{isFeedbackBtnVisible && (
<EuiFlexItem grow={false}>
<FeedbackBtn />
<FeedbackBtn solutionId={solutionId} />
</EuiFlexItem>
)}
</EuiFlexGroup>

View file

@ -106,7 +106,7 @@ describe('Navigation Plugin', () => {
await new Promise((resolve) => setTimeout(resolve));
const definition = {
id: 'es',
id: 'es' as const,
title: 'Elasticsearch',
navigationTree$: of({ body: [] }),
};

View file

@ -18,7 +18,7 @@ import {
} from '@kbn/core/public';
import type { UnifiedSearchPublicPluginStart } from '@kbn/unified-search-plugin/public';
import type { Space } from '@kbn/spaces-plugin/public';
import type { SolutionNavigationDefinition } from '@kbn/core-chrome-browser';
import type { SolutionId, SolutionNavigationDefinition } from '@kbn/core-chrome-browser';
import { InternalChromeStart } from '@kbn/core-chrome-browser-internal';
import type { PanelContentProvider } from '@kbn/shared-ux-chrome-navigation';
import type {
@ -195,7 +195,7 @@ export class NavigationPublicPlugin
}
}
if (isProjectNav) {
if (isProjectNav && solutionView !== 'classic') {
chrome.project.changeActiveSolutionNavigation(solutionView!);
}
}
@ -210,6 +210,6 @@ function getIsProjectNav(solutionView?: string) {
return Boolean(solutionView) && isKnownSolutionView(solutionView);
}
function isKnownSolutionView(solution?: string) {
function isKnownSolutionView(solution?: string): solution is SolutionId {
return Boolean(solution) && ['oblt', 'es', 'security'].includes(solution!);
}

View file

@ -1,8 +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 type { OnBoardingDefaultSolution } from './types';

View file

@ -5,7 +5,7 @@
* 2.0.
*/
import type { OnBoardingDefaultSolution } from './types';
import type { SolutionId } from '@kbn/core-chrome-browser';
/**
* Cloud does not type the value of the "use case" that is set during onboarding for a deployment. Any string can
@ -14,12 +14,12 @@ import type { OnBoardingDefaultSolution } from './types';
* @param value The solution value set by Cloud.
* @returns The default solution value for onboarding that matches Kibana naming.
*/
export function parseOnboardingSolution(value?: string): OnBoardingDefaultSolution | undefined {
export function parseOnboardingSolution(value?: string): SolutionId | undefined {
if (!value) return;
const solutions: Array<{
cloudValue: 'search' | 'elasticsearch' | 'observability' | 'security';
kibanaValue: OnBoardingDefaultSolution;
kibanaValue: SolutionId;
}> = [
{
cloudValue: 'search',

View file

@ -5,8 +5,6 @@
* 2.0.
*/
export type OnBoardingDefaultSolution = 'es' | 'oblt' | 'security';
export interface ElasticsearchConfigType {
elasticsearch_url?: string;
}

View file

@ -5,8 +5,8 @@
* 2.0.
*/
import type { SolutionId } from '@kbn/core-chrome-browser';
import type { FC, PropsWithChildren } from 'react';
import type { OnBoardingDefaultSolution } from '../common';
export interface CloudStart {
/**
@ -192,7 +192,7 @@ export interface CloudSetup {
/**
* The default solution selected during onboarding.
*/
defaultSolution?: OnBoardingDefaultSolution;
defaultSolution?: SolutionId;
};
/**
* `true` when running on Serverless Elastic Cloud

View file

@ -8,10 +8,10 @@
import type { Logger } from '@kbn/logging';
import type { CoreSetup, Plugin, PluginInitializerContext } from '@kbn/core/server';
import type { UsageCollectionSetup } from '@kbn/usage-collection-plugin/server';
import type { SolutionId } from '@kbn/core-chrome-browser';
import { registerCloudDeploymentMetadataAnalyticsContext } from '../common/register_cloud_deployment_id_analytics_context';
import type { CloudConfigType } from './config';
import { registerCloudUsageCollector } from './collectors';
import type { OnBoardingDefaultSolution } from '../common';
import { getIsCloudEnabled } from '../common/is_cloud_enabled';
import { parseDeploymentIdFromDeploymentUrl } from '../common/parse_deployment_id_from_deployment_url';
import { decodeCloudId, DecodedCloudId } from '../common/decode_cloud_id';
@ -108,7 +108,7 @@ export interface CloudSetup {
/**
* The default solution selected during onboarding.
*/
defaultSolution?: OnBoardingDefaultSolution;
defaultSolution?: SolutionId;
};
/**
* `true` when running on Serverless Elastic Cloud

View file

@ -12,6 +12,7 @@
],
"kbn_references": [
"@kbn/core",
"@kbn/core-chrome-browser",
"@kbn/usage-collection-plugin",
"@kbn/config-schema",
"@kbn/logging-mocks",

View file

@ -10,6 +10,7 @@ import type {
ChromeSetProjectBreadcrumbsParams,
SideNavComponent,
NavigationTreeDefinition,
SolutionId,
} from '@kbn/core-chrome-browser';
import type { CloudSetup, CloudStart } from '@kbn/cloud-plugin/public';
import type { Observable } from 'rxjs';
@ -26,7 +27,7 @@ export interface ServerlessPluginStart {
) => void;
setProjectHome(homeHref: string): void;
initNavigation(
id: string,
id: SolutionId,
navigationTree$: Observable<NavigationTreeDefinition>,
config?: {
dataTestSubj?: string;

View file

@ -149,7 +149,7 @@ export class ServerlessSearchPlugin
serverless.setProjectHome(services.searchIndices.startRoute);
const navigationTree$ = of(navigationTree());
serverless.initNavigation('search', navigationTree$, { dataTestSubj: 'svlSearchSideNav' });
serverless.initNavigation('es', navigationTree$, { dataTestSubj: 'svlSearchSideNav' });
const extendCardNavDefinitions = serverless.getNavigationCards(
security.authz.isRoleManagementEnabled()

View file

@ -5,11 +5,11 @@
* 2.0.
*/
import type { OnBoardingDefaultSolution } from '@kbn/cloud-plugin/common';
import type { SolutionId } from '@kbn/core-chrome-browser';
import type { SOLUTION_VIEW_CLASSIC } from '../../constants';
export type SolutionView = OnBoardingDefaultSolution | typeof SOLUTION_VIEW_CLASSIC;
export type SolutionView = SolutionId | typeof SOLUTION_VIEW_CLASSIC;
/**
* A Space.

View file

@ -9,7 +9,7 @@ import { EuiButtonEmpty, EuiLink, EuiText, EuiTourStep } from '@elastic/eui';
import React from 'react';
import type { FC, PropsWithChildren } from 'react';
import type { OnBoardingDefaultSolution } from '@kbn/cloud-plugin/common';
import type { SolutionId } from '@kbn/core-chrome-browser';
import { i18n } from '@kbn/i18n';
import { FormattedMessage } from '@kbn/i18n-react';
@ -26,7 +26,7 @@ const LearnMoreLink = () => (
</EuiLink>
);
const solutionMap: Record<OnBoardingDefaultSolution, string> = {
const solutionMap: Record<SolutionId, string> = {
es: i18n.translate('xpack.spaces.navControl.tour.esSolution', {
defaultMessage: 'Search',
}),

View file

@ -5,9 +5,9 @@
* 2.0.
*/
import type { OnBoardingDefaultSolution } from '@kbn/cloud-plugin/common';
import type { Logger, SavedObjectsRepository, SavedObjectsServiceStart } from '@kbn/core/server';
import { SavedObjectsErrorHelpers } from '@kbn/core/server';
import type { SolutionId } from '@kbn/core-chrome-browser';
import { i18n } from '@kbn/i18n';
import { DEFAULT_SPACE_ID } from '../../common/constants';
@ -15,7 +15,7 @@ import { DEFAULT_SPACE_ID } from '../../common/constants';
interface Deps {
getSavedObjects: () => Promise<Pick<SavedObjectsServiceStart, 'createInternalRepository'>>;
logger: Logger;
solution?: OnBoardingDefaultSolution;
solution?: SolutionId;
}
export async function createDefaultSpace({ getSavedObjects, logger, solution }: Deps) {

View file

@ -19,9 +19,9 @@ import {
timer,
} from 'rxjs';
import type { OnBoardingDefaultSolution } from '@kbn/cloud-plugin/common';
import type { CoreSetup, Logger, SavedObjectsServiceStart, ServiceStatus } from '@kbn/core/server';
import { ServiceStatusLevels } from '@kbn/core/server';
import type { SolutionId } from '@kbn/core-chrome-browser';
import type { ILicense } from '@kbn/licensing-plugin/server';
import { createDefaultSpace } from './create_default_space';
@ -33,7 +33,7 @@ interface Deps {
license$: Observable<ILicense>;
spacesLicense: SpacesLicense;
logger: Logger;
solution?: OnBoardingDefaultSolution;
solution?: SolutionId;
}
export const RETRY_SCALE_DURATION = 100;

View file

@ -52,7 +52,8 @@
"@kbn/core-logging-browser-mocks",
"@kbn/core-http-router-server-mocks",
"@kbn/core-application-browser-mocks",
"@kbn/ui-theme"
"@kbn/ui-theme",
"@kbn/core-chrome-browser"
],
"exclude": [
"target/**/*",