Management app locator (#101795)

* feat: 🎸 create management app locator

* refactor: 💡 simplify management locator

* feat: 🎸 export management app locator from plugin contract

* feat: 🎸 improve share plugin exports

* test: 💍 fix test mock

* test: 💍 adjust test mocks

* Update src/plugins/management/public/plugin.ts

Co-authored-by: Tim Roes <mail@timroes.de>

* Update src/plugins/management/public/types.ts

Co-authored-by: Tim Roes <mail@timroes.de>

* Update src/plugins/management/public/types.ts

Co-authored-by: Tim Roes <mail@timroes.de>

* Update src/plugins/management/server/plugin.ts

Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>
Co-authored-by: Tim Roes <mail@timroes.de>
This commit is contained in:
Vadim Dalecky 2021-06-14 14:23:14 +02:00 committed by GitHub
parent b60a438dd3
commit fa855b35b6
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
11 changed files with 150 additions and 7 deletions

View file

@ -0,0 +1,53 @@
/*
* 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 { MANAGEMENT_APP_ID } from './contants';
import { ManagementAppLocator, MANAGEMENT_APP_LOCATOR } from './locator';
test('locator has the right ID', () => {
const locator = new ManagementAppLocator();
expect(locator.id).toBe(MANAGEMENT_APP_LOCATOR);
});
test('returns management app ID', async () => {
const locator = new ManagementAppLocator();
const location = await locator.getLocation({
sectionId: 'a',
appId: 'b',
});
expect(location).toMatchObject({
app: MANAGEMENT_APP_ID,
});
});
test('returns Kibana location for section ID and app ID pair', async () => {
const locator = new ManagementAppLocator();
const location = await locator.getLocation({
sectionId: 'ingest',
appId: 'index',
});
expect(location).toMatchObject({
route: '/ingest/index',
state: {},
});
});
test('when app ID is not provided, returns path to just the section ID', async () => {
const locator = new ManagementAppLocator();
const location = await locator.getLocation({
sectionId: 'data',
});
expect(location).toMatchObject({
route: '/data',
state: {},
});
});

View file

@ -0,0 +1,32 @@
/*
* 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 { SerializableState } from 'src/plugins/kibana_utils/common';
import { LocatorDefinition } from 'src/plugins/share/common';
import { MANAGEMENT_APP_ID } from './contants';
export const MANAGEMENT_APP_LOCATOR = 'MANAGEMENT_APP_LOCATOR';
export interface ManagementAppLocatorParams extends SerializableState {
sectionId: string;
appId?: string;
}
export class ManagementAppLocator implements LocatorDefinition<ManagementAppLocatorParams> {
public readonly id = MANAGEMENT_APP_LOCATOR;
public readonly getLocation = async (params: ManagementAppLocatorParams) => {
const route = `/${params.sectionId}${params.appId ? '/' + params.appId : ''}`;
return {
app: MANAGEMENT_APP_ID,
route,
state: {},
};
};
}

View file

@ -3,6 +3,6 @@
"version": "kibana",
"server": true,
"ui": true,
"optionalPlugins": ["home"],
"optionalPlugins": ["home", "share"],
"requiredBundles": ["kibanaReact", "kibanaUtils", "home"]
}

View file

@ -30,6 +30,14 @@ const createSetupContract = (): ManagementSetup => ({
stack: createManagementSectionMock(),
} as unknown) as DefinedSections,
},
locator: {
getLocation: jest.fn(async () => ({
app: 'MANAGEMENT',
route: '',
state: {},
})),
navigate: jest.fn(),
},
});
const createStartContract = (): ManagementStart => ({

View file

@ -8,6 +8,7 @@
import { i18n } from '@kbn/i18n';
import { BehaviorSubject } from 'rxjs';
import type { SharePluginSetup, SharePluginStart } from 'src/plugins/share/public';
import { ManagementSetup, ManagementStart } from './types';
import { FeatureCatalogueCategory, HomePublicPluginSetup } from '../../home/public';
import {
@ -24,6 +25,7 @@ import {
} from '../../../core/public';
import { MANAGEMENT_APP_ID } from '../common/contants';
import { ManagementAppLocator } from '../common/locator';
import {
ManagementSectionsService,
getSectionsServiceStartPrivate,
@ -32,9 +34,21 @@ import { ManagementSection } from './utils';
interface ManagementSetupDependencies {
home?: HomePublicPluginSetup;
share: SharePluginSetup;
}
export class ManagementPlugin implements Plugin<ManagementSetup, ManagementStart> {
interface ManagementStartDependencies {
share: SharePluginStart;
}
export class ManagementPlugin
implements
Plugin<
ManagementSetup,
ManagementStart,
ManagementSetupDependencies,
ManagementStartDependencies
> {
private readonly managementSections = new ManagementSectionsService();
private readonly appUpdater = new BehaviorSubject<AppUpdater>(() => {
@ -58,8 +72,9 @@ export class ManagementPlugin implements Plugin<ManagementSetup, ManagementStart
constructor(private initializerContext: PluginInitializerContext) {}
public setup(core: CoreSetup, { home }: ManagementSetupDependencies) {
public setup(core: CoreSetup, { home, share }: ManagementSetupDependencies) {
const kibanaVersion = this.initializerContext.env.packageInfo.version;
const locator = share.url.locators.create(new ManagementAppLocator());
if (home) {
home.featureCatalogue.register({
@ -101,10 +116,11 @@ export class ManagementPlugin implements Plugin<ManagementSetup, ManagementStart
return {
sections: this.managementSections.setup(),
locator,
};
}
public start(core: CoreStart) {
public start(core: CoreStart, plugins: ManagementStartDependencies) {
this.managementSections.start({ capabilities: core.application.capabilities });
this.hasAnyEnabledApps = getSectionsServiceStartPrivate()
.getSectionsEnabled()

View file

@ -7,11 +7,14 @@
*/
import { ScopedHistory, Capabilities } from 'kibana/public';
import type { LocatorPublic } from 'src/plugins/share/common';
import { ManagementSection, RegisterManagementSectionArgs } from './utils';
import { ChromeBreadcrumb } from '../../../core/public/';
import type { ManagementAppLocatorParams } from '../common/locator';
export interface ManagementSetup {
sections: SectionsServiceSetup;
locator: LocatorPublic<ManagementAppLocatorParams>;
}
export interface DefinedSections {

View file

@ -7,21 +7,37 @@
*/
import { PluginInitializerContext, CoreSetup, CoreStart, Plugin, Logger } from 'kibana/server';
import { LocatorPublic } from 'src/plugins/share/common';
import type { SharePluginSetup } from 'src/plugins/share/server';
import { ManagementAppLocator, ManagementAppLocatorParams } from '../common/locator';
import { capabilitiesProvider } from './capabilities_provider';
export class ManagementServerPlugin implements Plugin<object, object> {
interface ManagementSetupDependencies {
share: SharePluginSetup;
}
export interface ManagementSetup {
locator: LocatorPublic<ManagementAppLocatorParams>;
}
export class ManagementServerPlugin
implements Plugin<ManagementSetup, object, ManagementSetupDependencies> {
private readonly logger: Logger;
constructor(initializerContext: PluginInitializerContext) {
this.logger = initializerContext.logger.get();
}
public setup(core: CoreSetup) {
public setup(core: CoreSetup, { share }: ManagementSetupDependencies) {
this.logger.debug('management: Setup');
const locator = share.url.locators.create(new ManagementAppLocator());
core.capabilities.registerProvider(capabilitiesProvider);
return {};
return {
locator,
};
}
public start(core: CoreStart) {

View file

@ -0,0 +1,9 @@
/*
* 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.
*/
export { LocatorDefinition, LocatorPublic } from './url_service';

View file

@ -7,10 +7,12 @@
*/
export { CSV_QUOTE_VALUES_SETTING, CSV_SEPARATOR_SETTING } from '../common/constants';
export { LocatorDefinition } from '../common/url_service';
export { UrlGeneratorStateMapping } from './url_generators/url_generator_definition';
export { SharePluginSetup, SharePluginStart } from './plugin';
export {
ShareContext,
ShareMenuProvider,

View file

@ -9,6 +9,8 @@
import { PluginInitializerContext } from '../../../core/server';
import { SharePlugin } from './plugin';
export { SharePluginSetup, SharePluginStart } from './plugin';
export { CSV_QUOTE_VALUES_SETTING, CSV_SEPARATOR_SETTING } from '../common/constants';
export function plugin(initializerContext: PluginInitializerContext) {

View file

@ -40,6 +40,7 @@ describe('ManagementService', () => {
security: mockSection,
} as DefinedSections,
},
locator: {} as any,
};
const service = new ManagementService();
@ -101,6 +102,7 @@ describe('ManagementService', () => {
security: mockSection,
} as DefinedSections,
},
locator: {} as any,
};
service.setup({