Skip to content

Commit

Permalink
Management app locator (#101795)
Browse files Browse the repository at this point in the history
* 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>
  • Loading branch information
3 people authored Jun 14, 2021
1 parent b60a438 commit fa855b3
Show file tree
Hide file tree
Showing 11 changed files with 150 additions and 7 deletions.
53 changes: 53 additions & 0 deletions src/plugins/management/common/locator.test.ts
Original file line number Diff line number Diff line change
@@ -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: {},
});
});
32 changes: 32 additions & 0 deletions src/plugins/management/common/locator.ts
Original file line number Diff line number Diff line change
@@ -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: {},
};
};
}
2 changes: 1 addition & 1 deletion src/plugins/management/kibana.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,6 @@
"version": "kibana",
"server": true,
"ui": true,
"optionalPlugins": ["home"],
"optionalPlugins": ["home", "share"],
"requiredBundles": ["kibanaReact", "kibanaUtils", "home"]
}
8 changes: 8 additions & 0 deletions src/plugins/management/public/mocks/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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 => ({
Expand Down
22 changes: 19 additions & 3 deletions src/plugins/management/public/plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand All @@ -24,6 +25,7 @@ import {
} from '../../../core/public';

import { MANAGEMENT_APP_ID } from '../common/contants';
import { ManagementAppLocator } from '../common/locator';
import {
ManagementSectionsService,
getSectionsServiceStartPrivate,
Expand All @@ -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>(() => {
Expand All @@ -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({
Expand Down Expand Up @@ -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()
Expand Down
3 changes: 3 additions & 0 deletions src/plugins/management/public/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
22 changes: 19 additions & 3 deletions src/plugins/management/server/plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down
9 changes: 9 additions & 0 deletions src/plugins/share/common/index.ts
Original file line number Diff line number Diff line change
@@ -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';
2 changes: 2 additions & 0 deletions src/plugins/share/public/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
2 changes: 2 additions & 0 deletions src/plugins/share/server/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ describe('ManagementService', () => {
security: mockSection,
} as DefinedSections,
},
locator: {} as any,
};

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

service.setup({
Expand Down

0 comments on commit fa855b3

Please sign in to comment.