mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 01:38:56 -04:00
parent
faa22e9aeb
commit
3508f12225
16 changed files with 248 additions and 14 deletions
|
@ -31,6 +31,7 @@ import { TelemetryPluginStart } from '../../../../../plugins/telemetry/public';
|
|||
import {
|
||||
Environment,
|
||||
HomePublicPluginSetup,
|
||||
TutorialStart,
|
||||
HomePublicPluginStart,
|
||||
} from '../../../../../plugins/home/public';
|
||||
import { KibanaLegacySetup } from '../../../../../plugins/kibana_legacy/public';
|
||||
|
@ -38,7 +39,6 @@ import { KibanaLegacySetup } from '../../../../../plugins/kibana_legacy/public';
|
|||
export interface HomeKibanaServices {
|
||||
indexPatternService: any;
|
||||
kibanaVersion: string;
|
||||
getInjected: (name: string, defaultValue?: any) => unknown;
|
||||
chrome: ChromeStart;
|
||||
uiSettings: IUiSettingsClient;
|
||||
config: KibanaLegacySetup['config'];
|
||||
|
@ -54,6 +54,7 @@ export interface HomeKibanaServices {
|
|||
addBasePath: (url: string) => string;
|
||||
environment: Environment;
|
||||
telemetry?: TelemetryPluginStart;
|
||||
tutorialVariables: TutorialStart['get'];
|
||||
}
|
||||
|
||||
let services: HomeKibanaServices | null = null;
|
||||
|
|
|
@ -29,7 +29,7 @@ import { FeatureCatalogueCategory } from '../../../../../../../plugins/home/publ
|
|||
jest.mock('../../kibana_services', () => ({
|
||||
getServices: () => ({
|
||||
getBasePath: () => 'path',
|
||||
getInjected: () => '',
|
||||
tutorialVariables: () => ({}),
|
||||
homeConfig: { disableWelcomeScreen: false },
|
||||
}),
|
||||
}));
|
||||
|
|
|
@ -33,7 +33,7 @@ mustacheWriter.escapedValue = function escapedValue(token, context) {
|
|||
};
|
||||
|
||||
export function replaceTemplateStrings(text, params = {}) {
|
||||
const { getInjected, kibanaVersion, docLinks } = getServices();
|
||||
const { tutorialVariables, kibanaVersion, docLinks } = getServices();
|
||||
|
||||
const variables = {
|
||||
// '{' and '}' can not be used in template since they are used as template tags.
|
||||
|
@ -41,9 +41,7 @@ export function replaceTemplateStrings(text, params = {}) {
|
|||
curlyOpen: '{',
|
||||
curlyClose: '}',
|
||||
config: {
|
||||
cloud: {
|
||||
id: getInjected('cloudId'),
|
||||
},
|
||||
...tutorialVariables(),
|
||||
docs: {
|
||||
base_url: docLinks.ELASTIC_WEBSITE_URL,
|
||||
beats: {
|
||||
|
|
|
@ -57,20 +57,22 @@ export class HomePlugin implements Plugin {
|
|||
|
||||
constructor(private initializerContext: PluginInitializerContext) {}
|
||||
|
||||
setup(core: CoreSetup, { home, kibanaLegacy, usageCollection }: HomePluginSetupDependencies) {
|
||||
setup(
|
||||
core: CoreSetup<HomePluginStartDependencies>,
|
||||
{ home, kibanaLegacy, usageCollection }: HomePluginSetupDependencies
|
||||
) {
|
||||
kibanaLegacy.registerLegacyApp({
|
||||
id: 'home',
|
||||
title: 'Home',
|
||||
mount: async (params: AppMountParameters) => {
|
||||
const trackUiMetric = usageCollection.reportUiStats.bind(usageCollection, 'Kibana_home');
|
||||
const [coreStart] = await core.getStartServices();
|
||||
const [coreStart, { home: homeStart }] = await core.getStartServices();
|
||||
setServices({
|
||||
trackUiMetric,
|
||||
kibanaVersion: this.initializerContext.env.packageInfo.version,
|
||||
http: coreStart.http,
|
||||
toastNotifications: core.notifications.toasts,
|
||||
banners: coreStart.overlays.banners,
|
||||
getInjected: core.injectedMetadata.getInjectedVar,
|
||||
docLinks: coreStart.docLinks,
|
||||
savedObjectsClient: this.savedObjectsClient!,
|
||||
chrome: coreStart.chrome,
|
||||
|
@ -82,6 +84,7 @@ export class HomePlugin implements Plugin {
|
|||
environment: this.environment!,
|
||||
config: kibanaLegacy.config,
|
||||
homeConfig: home.config,
|
||||
tutorialVariables: homeStart.tutorials.get,
|
||||
featureCatalogue: this.featureCatalogue!,
|
||||
});
|
||||
const { renderApp } = await import('./np_ready/application');
|
||||
|
|
|
@ -22,10 +22,19 @@ import { PluginInitializerContext } from 'kibana/public';
|
|||
export {
|
||||
FeatureCatalogueSetup,
|
||||
FeatureCatalogueStart,
|
||||
EnvironmentSetup,
|
||||
EnvironmentStart,
|
||||
TutorialSetup,
|
||||
TutorialStart,
|
||||
HomePublicPluginSetup,
|
||||
HomePublicPluginStart,
|
||||
} from './plugin';
|
||||
export { FeatureCatalogueEntry, FeatureCatalogueCategory, Environment } from './services';
|
||||
export {
|
||||
FeatureCatalogueEntry,
|
||||
FeatureCatalogueCategory,
|
||||
Environment,
|
||||
TutorialVariables,
|
||||
} from './services';
|
||||
export * from '../common/instruction_variant';
|
||||
import { HomePublicPlugin } from './plugin';
|
||||
|
||||
|
|
|
@ -20,16 +20,19 @@
|
|||
import { featureCatalogueRegistryMock } from '../services/feature_catalogue/feature_catalogue_registry.mock';
|
||||
import { environmentServiceMock } from '../services/environment/environment.mock';
|
||||
import { configSchema } from '../../config';
|
||||
import { tutorialServiceMock } from '../services/tutorials/tutorial_service.mock';
|
||||
|
||||
const createSetupContract = () => ({
|
||||
featureCatalogue: featureCatalogueRegistryMock.createSetup(),
|
||||
environment: environmentServiceMock.createSetup(),
|
||||
tutorials: tutorialServiceMock.createSetup(),
|
||||
config: configSchema.validate({}),
|
||||
});
|
||||
|
||||
const createStartContract = () => ({
|
||||
featureCatalogue: featureCatalogueRegistryMock.createStart(),
|
||||
environment: environmentServiceMock.createStart(),
|
||||
tutorials: tutorialServiceMock.createStart(),
|
||||
});
|
||||
|
||||
export const homePluginMock = {
|
||||
|
|
|
@ -19,10 +19,13 @@
|
|||
|
||||
import { featureCatalogueRegistryMock } from './services/feature_catalogue/feature_catalogue_registry.mock';
|
||||
import { environmentServiceMock } from './services/environment/environment.mock';
|
||||
import { tutorialServiceMock } from './services/tutorials/tutorial_service.mock';
|
||||
|
||||
export const registryMock = featureCatalogueRegistryMock.create();
|
||||
export const environmentMock = environmentServiceMock.create();
|
||||
export const tutorialMock = tutorialServiceMock.create();
|
||||
jest.doMock('./services', () => ({
|
||||
FeatureCatalogueRegistry: jest.fn(() => registryMock),
|
||||
EnvironmentService: jest.fn(() => environmentMock),
|
||||
TutorialService: jest.fn(() => tutorialMock),
|
||||
}));
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
* under the License.
|
||||
*/
|
||||
|
||||
import { registryMock, environmentMock } from './plugin.test.mocks';
|
||||
import { registryMock, environmentMock, tutorialMock } from './plugin.test.mocks';
|
||||
import { HomePublicPlugin } from './plugin';
|
||||
import { coreMock } from '../../../core/public/mocks';
|
||||
|
||||
|
@ -27,8 +27,10 @@ describe('HomePublicPlugin', () => {
|
|||
beforeEach(() => {
|
||||
registryMock.setup.mockClear();
|
||||
registryMock.start.mockClear();
|
||||
tutorialMock.setup.mockClear();
|
||||
environmentMock.setup.mockClear();
|
||||
environmentMock.start.mockClear();
|
||||
tutorialMock.start.mockClear();
|
||||
});
|
||||
|
||||
describe('setup', () => {
|
||||
|
@ -43,6 +45,12 @@ describe('HomePublicPlugin', () => {
|
|||
expect(setup).toHaveProperty('environment');
|
||||
expect(setup.environment).toHaveProperty('update');
|
||||
});
|
||||
|
||||
test('wires up and returns tutorial service', async () => {
|
||||
const setup = await new HomePublicPlugin(mockInitializerContext).setup();
|
||||
expect(setup).toHaveProperty('tutorials');
|
||||
expect(setup.tutorials).toHaveProperty('setVariable');
|
||||
});
|
||||
});
|
||||
|
||||
describe('start', () => {
|
||||
|
@ -66,5 +74,13 @@ describe('HomePublicPlugin', () => {
|
|||
expect(environmentMock.start).toHaveBeenCalled();
|
||||
expect(start.environment.get).toBeDefined();
|
||||
});
|
||||
|
||||
test('wires up and returns tutorial service', async () => {
|
||||
const service = new HomePublicPlugin(mockInitializerContext);
|
||||
await service.setup();
|
||||
const start = await service.start(coreMock.createStart());
|
||||
expect(tutorialMock.start).toHaveBeenCalled();
|
||||
expect(start.tutorials.get).toBeDefined();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -26,12 +26,16 @@ import {
|
|||
FeatureCatalogueRegistry,
|
||||
FeatureCatalogueRegistrySetup,
|
||||
FeatureCatalogueRegistryStart,
|
||||
TutorialService,
|
||||
TutorialServiceSetup,
|
||||
TutorialServiceStart,
|
||||
} from './services';
|
||||
import { ConfigSchema } from '../config';
|
||||
|
||||
export class HomePublicPlugin implements Plugin<HomePublicPluginSetup, HomePublicPluginStart> {
|
||||
private readonly featuresCatalogueRegistry = new FeatureCatalogueRegistry();
|
||||
private readonly environmentService = new EnvironmentService();
|
||||
private readonly tutorialService = new TutorialService();
|
||||
|
||||
constructor(private readonly initializerContext: PluginInitializerContext<ConfigSchema>) {}
|
||||
|
||||
|
@ -39,6 +43,7 @@ export class HomePublicPlugin implements Plugin<HomePublicPluginSetup, HomePubli
|
|||
return {
|
||||
featureCatalogue: { ...this.featuresCatalogueRegistry.setup() },
|
||||
environment: { ...this.environmentService.setup() },
|
||||
tutorials: { ...this.tutorialService.setup() },
|
||||
config: this.initializerContext.config.get(),
|
||||
};
|
||||
}
|
||||
|
@ -50,6 +55,7 @@ export class HomePublicPlugin implements Plugin<HomePublicPluginSetup, HomePubli
|
|||
capabilities: core.application.capabilities,
|
||||
}),
|
||||
},
|
||||
tutorials: { ...this.tutorialService.start() },
|
||||
environment: { ...this.environmentService.start() },
|
||||
};
|
||||
}
|
||||
|
@ -67,8 +73,15 @@ export type EnvironmentSetup = EnvironmentServiceSetup;
|
|||
/** @public */
|
||||
export type EnvironmentStart = EnvironmentServiceStart;
|
||||
|
||||
/** @public */
|
||||
export type TutorialSetup = TutorialServiceSetup;
|
||||
|
||||
/** @public */
|
||||
export type TutorialStart = TutorialServiceStart;
|
||||
|
||||
/** @public */
|
||||
export interface HomePublicPluginSetup {
|
||||
tutorials: TutorialServiceSetup;
|
||||
featureCatalogue: FeatureCatalogueSetup;
|
||||
/**
|
||||
* The environment service is only available for a transition period and will
|
||||
|
@ -81,6 +94,7 @@ export interface HomePublicPluginSetup {
|
|||
|
||||
/** @public */
|
||||
export interface HomePublicPluginStart {
|
||||
tutorials: TutorialServiceStart;
|
||||
featureCatalogue: FeatureCatalogueStart;
|
||||
environment: EnvironmentStart;
|
||||
}
|
||||
|
|
|
@ -20,15 +20,15 @@
|
|||
/** @public */
|
||||
export interface Environment {
|
||||
/**
|
||||
* Flag whether the home app should advertize cloud features
|
||||
* Flag whether the home app should advertise cloud features
|
||||
*/
|
||||
readonly cloud: boolean;
|
||||
/**
|
||||
* Flag whether the home app should advertize apm features
|
||||
* Flag whether the home app should advertise apm features
|
||||
*/
|
||||
readonly apmUi: boolean;
|
||||
/**
|
||||
* Flag whether the home app should advertize ml features
|
||||
* Flag whether the home app should advertise ml features
|
||||
*/
|
||||
readonly ml: boolean;
|
||||
}
|
||||
|
|
|
@ -19,3 +19,4 @@
|
|||
|
||||
export * from './feature_catalogue';
|
||||
export * from './environment';
|
||||
export * from './tutorials';
|
||||
|
|
25
src/plugins/home/public/services/tutorials/index.ts
Normal file
25
src/plugins/home/public/services/tutorials/index.ts
Normal file
|
@ -0,0 +1,25 @@
|
|||
/*
|
||||
* Licensed to Elasticsearch B.V. under one or more contributor
|
||||
* license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright
|
||||
* ownership. Elasticsearch B.V. licenses this file to you under
|
||||
* the Apache License, Version 2.0 (the "License"); you may
|
||||
* not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
export {
|
||||
TutorialService,
|
||||
TutorialVariables,
|
||||
TutorialServiceSetup,
|
||||
TutorialServiceStart,
|
||||
} from './tutorial_service';
|
|
@ -0,0 +1,50 @@
|
|||
/*
|
||||
* Licensed to Elasticsearch B.V. under one or more contributor
|
||||
* license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright
|
||||
* ownership. Elasticsearch B.V. licenses this file to you under
|
||||
* the Apache License, Version 2.0 (the "License"); you may
|
||||
* not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
import { TutorialService, TutorialServiceSetup, TutorialServiceStart } from './tutorial_service';
|
||||
|
||||
const createSetupMock = (): jest.Mocked<TutorialServiceSetup> => {
|
||||
const setup = {
|
||||
setVariable: jest.fn(),
|
||||
};
|
||||
return setup;
|
||||
};
|
||||
|
||||
const createStartMock = (): jest.Mocked<TutorialServiceStart> => {
|
||||
const start = {
|
||||
get: jest.fn(),
|
||||
};
|
||||
return start;
|
||||
};
|
||||
|
||||
const createMock = (): jest.Mocked<PublicMethodsOf<TutorialService>> => {
|
||||
const service = {
|
||||
setup: jest.fn(),
|
||||
start: jest.fn(),
|
||||
};
|
||||
service.setup.mockImplementation(createSetupMock);
|
||||
service.start.mockImplementation(createStartMock);
|
||||
return service;
|
||||
};
|
||||
|
||||
export const tutorialServiceMock = {
|
||||
createSetup: createSetupMock,
|
||||
createStart: createStartMock,
|
||||
create: createMock,
|
||||
};
|
|
@ -0,0 +1,55 @@
|
|||
/*
|
||||
* Licensed to Elasticsearch B.V. under one or more contributor
|
||||
* license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright
|
||||
* ownership. Elasticsearch B.V. licenses this file to you under
|
||||
* the Apache License, Version 2.0 (the "License"); you may
|
||||
* not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
import { TutorialService } from './tutorial_service';
|
||||
|
||||
describe('TutorialService', () => {
|
||||
describe('setup', () => {
|
||||
test('allows multiple set calls', () => {
|
||||
const setup = new TutorialService().setup();
|
||||
expect(() => {
|
||||
setup.setVariable('abc', 123);
|
||||
setup.setVariable('def', 456);
|
||||
}).not.toThrow();
|
||||
});
|
||||
|
||||
test('throws when same variable is set twice', () => {
|
||||
const setup = new TutorialService().setup();
|
||||
expect(() => {
|
||||
setup.setVariable('abc', 123);
|
||||
setup.setVariable('abc', 456);
|
||||
}).toThrow();
|
||||
});
|
||||
});
|
||||
|
||||
describe('start', () => {
|
||||
test('returns empty object', () => {
|
||||
const service = new TutorialService();
|
||||
expect(service.start().get()).toEqual({});
|
||||
});
|
||||
|
||||
test('returns last state of update calls', () => {
|
||||
const service = new TutorialService();
|
||||
const setup = service.setup();
|
||||
setup.setVariable('abc', 123);
|
||||
setup.setVariable('def', { subKey: 456 });
|
||||
expect(service.start().get()).toEqual({ abc: 123, def: { subKey: 456 } });
|
||||
});
|
||||
});
|
||||
});
|
|
@ -0,0 +1,53 @@
|
|||
/*
|
||||
* Licensed to Elasticsearch B.V. under one or more contributor
|
||||
* license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright
|
||||
* ownership. Elasticsearch B.V. licenses this file to you under
|
||||
* the Apache License, Version 2.0 (the "License"); you may
|
||||
* not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
/** @public */
|
||||
export type TutorialVariables = Partial<Record<string, unknown>>;
|
||||
|
||||
export class TutorialService {
|
||||
private tutorialVariables: TutorialVariables = {};
|
||||
|
||||
public setup() {
|
||||
return {
|
||||
/**
|
||||
* Set a variable usable in tutorial templates. Access with `{config.<key>}`.
|
||||
*/
|
||||
setVariable: (key: string, value: unknown) => {
|
||||
if (this.tutorialVariables[key]) {
|
||||
throw new Error('variable already set');
|
||||
}
|
||||
this.tutorialVariables[key] = value;
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
public start() {
|
||||
return {
|
||||
/**
|
||||
* Retrieve the variables for substitution in tutorials. This API is only intended for internal
|
||||
* use and is only exposed during a transition period of migrating the home app to the new platform.
|
||||
* @deprecated
|
||||
*/
|
||||
get: (): TutorialVariables => this.tutorialVariables,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
export type TutorialServiceSetup = ReturnType<TutorialService['setup']>;
|
||||
export type TutorialServiceStart = ReturnType<TutorialService['start']>;
|
|
@ -31,6 +31,9 @@ export class CloudPlugin implements Plugin<CloudSetup> {
|
|||
|
||||
if (home) {
|
||||
home.environment.update({ cloud: isCloudEnabled });
|
||||
if (isCloudEnabled) {
|
||||
home.tutorials.setVariable('cloud', { id });
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue