mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 09:48:58 -04:00
parent
60092c2bd3
commit
d523039764
16 changed files with 288 additions and 13 deletions
|
@ -29,7 +29,11 @@ import {
|
|||
UiSettingsState,
|
||||
} from 'kibana/public';
|
||||
import { UiStatsMetricType } from '@kbn/analytics';
|
||||
import { Environment, FeatureCatalogueEntry } from '../../../../../plugins/home/public';
|
||||
import {
|
||||
Environment,
|
||||
FeatureCatalogueEntry,
|
||||
TutorialStart,
|
||||
} from '../../../../../plugins/home/public';
|
||||
|
||||
export interface HomeKibanaServices {
|
||||
indexPatternService: any;
|
||||
|
@ -47,7 +51,6 @@ export interface HomeKibanaServices {
|
|||
devMode: boolean;
|
||||
uiSettings: { defaults: UiSettingsState; user?: UiSettingsState | undefined };
|
||||
};
|
||||
getInjected: (name: string, defaultValue?: any) => unknown;
|
||||
chrome: ChromeStart;
|
||||
telemetryOptInProvider: any;
|
||||
uiSettings: IUiSettingsClient;
|
||||
|
@ -62,6 +65,8 @@ export interface HomeKibanaServices {
|
|||
docLinks: DocLinksStart;
|
||||
addBasePath: (url: string) => string;
|
||||
environment: Environment;
|
||||
tutorialVariables: TutorialStart['get'];
|
||||
getInjected: (name: string, defaultValue?: any) => unknown;
|
||||
}
|
||||
|
||||
let services: HomeKibanaServices | null = null;
|
||||
|
|
|
@ -29,6 +29,7 @@ import { FeatureCatalogueCategory } from '../../../../../../../plugins/home/publ
|
|||
jest.mock('../../kibana_services', () => ({
|
||||
getServices: () => ({
|
||||
getBasePath: () => 'path',
|
||||
tutorialVariables: () => ({}),
|
||||
getInjected: () => '',
|
||||
}),
|
||||
}));
|
||||
|
|
|
@ -33,7 +33,7 @@ mustacheWriter.escapedValue = function escapedValue(token, context) {
|
|||
};
|
||||
|
||||
export function replaceTemplateStrings(text, params = {}) {
|
||||
const { getInjected, metadata, docLinks } = getServices();
|
||||
const { tutorialVariables, metadata, 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: {
|
||||
|
|
|
@ -68,7 +68,7 @@ export class HomePlugin implements Plugin {
|
|||
private environment: Environment | null = null;
|
||||
|
||||
setup(
|
||||
core: CoreSetup,
|
||||
core: CoreSetup<HomePluginStartDependencies>,
|
||||
{
|
||||
kibana_legacy,
|
||||
__LEGACY: { getAngularDependencies, ...legacyServices },
|
||||
|
@ -79,12 +79,12 @@ export class HomePlugin implements Plugin {
|
|||
title: 'Home',
|
||||
mount: async ({ core: contextCore }, params) => {
|
||||
const angularDependencies = await getAngularDependencies();
|
||||
const [, { home: homeStart }] = await core.getStartServices();
|
||||
setServices({
|
||||
...legacyServices,
|
||||
http: contextCore.http,
|
||||
toastNotifications: core.notifications.toasts,
|
||||
banners: contextCore.overlays.banners,
|
||||
getInjected: core.injectedMetadata.getInjectedVar,
|
||||
docLinks: contextCore.docLinks,
|
||||
savedObjectsClient: this.savedObjectsClient!,
|
||||
chrome: contextCore.chrome,
|
||||
|
@ -93,6 +93,8 @@ export class HomePlugin implements Plugin {
|
|||
getBasePath: core.http.basePath.get,
|
||||
indexPatternService: this.dataStart!.indexPatterns,
|
||||
environment: this.environment!,
|
||||
tutorialVariables: homeStart.tutorials.get,
|
||||
getInjected: core.injectedMetadata.getInjectedVar,
|
||||
...angularDependencies,
|
||||
});
|
||||
const { renderApp } = await import('./np_ready/application');
|
||||
|
|
|
@ -20,10 +20,19 @@
|
|||
export {
|
||||
FeatureCatalogueSetup,
|
||||
FeatureCatalogueStart,
|
||||
EnvironmentSetup,
|
||||
EnvironmentStart,
|
||||
TutorialSetup,
|
||||
TutorialStart,
|
||||
HomePublicPluginSetup,
|
||||
HomePublicPluginStart,
|
||||
} from './plugin';
|
||||
export { FeatureCatalogueEntry, FeatureCatalogueCategory, Environment } from './services';
|
||||
export {
|
||||
FeatureCatalogueEntry,
|
||||
FeatureCatalogueCategory,
|
||||
Environment,
|
||||
TutorialVariables,
|
||||
} from './services';
|
||||
import { HomePublicPlugin } from './plugin';
|
||||
|
||||
export const plugin = () => new HomePublicPlugin();
|
||||
|
|
39
src/plugins/home/public/mocks/index.ts
Normal file
39
src/plugins/home/public/mocks/index.ts
Normal file
|
@ -0,0 +1,39 @@
|
|||
/*
|
||||
* 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 { featureCatalogueRegistryMock } from '../services/feature_catalogue/feature_catalogue_registry.mock';
|
||||
import { environmentServiceMock } from '../services/environment/environment.mock';
|
||||
import { tutorialServiceMock } from '../services/tutorials/tutorial_service.mock';
|
||||
|
||||
const createSetupContract = () => ({
|
||||
featureCatalogue: featureCatalogueRegistryMock.createSetup(),
|
||||
environment: environmentServiceMock.createSetup(),
|
||||
tutorials: tutorialServiceMock.createSetup(),
|
||||
});
|
||||
|
||||
const createStartContract = () => ({
|
||||
featureCatalogue: featureCatalogueRegistryMock.createStart(),
|
||||
environment: environmentServiceMock.createStart(),
|
||||
tutorials: tutorialServiceMock.createStart(),
|
||||
});
|
||||
|
||||
export const homePluginMock = {
|
||||
createSetupContract,
|
||||
createStartContract,
|
||||
};
|
|
@ -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,15 +17,17 @@
|
|||
* under the License.
|
||||
*/
|
||||
|
||||
import { registryMock, environmentMock } from './plugin.test.mocks';
|
||||
import { registryMock, environmentMock, tutorialMock } from './plugin.test.mocks';
|
||||
import { HomePublicPlugin } from './plugin';
|
||||
|
||||
describe('HomePublicPlugin', () => {
|
||||
beforeEach(() => {
|
||||
registryMock.setup.mockClear();
|
||||
registryMock.start.mockClear();
|
||||
tutorialMock.setup.mockClear();
|
||||
environmentMock.setup.mockClear();
|
||||
environmentMock.start.mockClear();
|
||||
tutorialMock.start.mockClear();
|
||||
});
|
||||
|
||||
describe('setup', () => {
|
||||
|
@ -40,6 +42,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().setup();
|
||||
expect(setup).toHaveProperty('tutorials');
|
||||
expect(setup.tutorials).toHaveProperty('setVariable');
|
||||
});
|
||||
});
|
||||
|
||||
describe('start', () => {
|
||||
|
@ -63,5 +71,14 @@ describe('HomePublicPlugin', () => {
|
|||
expect(environmentMock.start).toHaveBeenCalled();
|
||||
expect(start.environment.get).toBeDefined();
|
||||
});
|
||||
|
||||
test('wires up and returns tutorial service', async () => {
|
||||
const service = new HomePublicPlugin();
|
||||
await service.setup();
|
||||
const core = { application: { capabilities: { catalogue: {} } } } as any;
|
||||
const start = await service.start(core);
|
||||
expect(tutorialMock.start).toHaveBeenCalled();
|
||||
expect(start.tutorials.get).toBeDefined();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -25,16 +25,21 @@ import {
|
|||
FeatureCatalogueRegistry,
|
||||
FeatureCatalogueRegistrySetup,
|
||||
FeatureCatalogueRegistryStart,
|
||||
TutorialService,
|
||||
TutorialServiceSetup,
|
||||
TutorialServiceStart,
|
||||
} from './services';
|
||||
|
||||
export class HomePublicPlugin implements Plugin<HomePublicPluginSetup, HomePublicPluginStart> {
|
||||
private readonly featuresCatalogueRegistry = new FeatureCatalogueRegistry();
|
||||
private readonly environmentService = new EnvironmentService();
|
||||
private readonly tutorialService = new TutorialService();
|
||||
|
||||
public async setup() {
|
||||
return {
|
||||
featureCatalogue: { ...this.featuresCatalogueRegistry.setup() },
|
||||
environment: { ...this.environmentService.setup() },
|
||||
tutorials: { ...this.tutorialService.setup() },
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -45,6 +50,7 @@ export class HomePublicPlugin implements Plugin<HomePublicPluginSetup, HomePubli
|
|||
capabilities: core.application.capabilities,
|
||||
}),
|
||||
},
|
||||
tutorials: { ...this.tutorialService.start() },
|
||||
environment: { ...this.environmentService.start() },
|
||||
};
|
||||
}
|
||||
|
@ -62,8 +68,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
|
||||
|
@ -75,6 +88,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