Move top nav to NP (#52877) (#53114)

* Move top nav to NP

* TopNavMenu karma mock

* Fixed lens test mocking
Removed old plugin code

* readme

* Code review fixes

* lint

* ts
This commit is contained in:
Liza Katz 2019-12-16 15:18:09 +00:00 committed by GitHub
parent 601c241cc5
commit fc0d6afbb5
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
38 changed files with 182 additions and 101 deletions

View file

@ -4,7 +4,10 @@
"console": "src/legacy/core_plugins/console",
"core": "src/core",
"dashboardEmbeddableContainer": "src/plugins/dashboard_embeddable_container",
"data": ["src/legacy/core_plugins/data", "src/plugins/data"],
"data": [
"src/legacy/core_plugins/data",
"src/plugins/data"
],
"embeddableApi": "src/plugins/embeddable",
"share": "src/plugins/share",
"esUi": "src/plugins/es_ui_shared",
@ -21,7 +24,7 @@
"kibana_react": "src/legacy/core_plugins/kibana_react",
"kibana-react": "src/plugins/kibana_react",
"kibana_utils": "src/plugins/kibana_utils",
"navigation": "src/legacy/core_plugins/navigation",
"navigation": "src/plugins/navigation",
"newsfeed": "src/plugins/newsfeed",
"regionMap": "src/legacy/core_plugins/region_map",
"server": "src/legacy/server",
@ -36,8 +39,13 @@
"visTypeTagCloud": "src/legacy/core_plugins/vis_type_tagcloud",
"visTypeTimeseries": "src/legacy/core_plugins/vis_type_timeseries",
"visTypeVega": "src/legacy/core_plugins/vis_type_vega",
"visualizations": ["src/plugins/visualizations", "src/legacy/core_plugins/visualizations"]
"visualizations": [
"src/plugins/visualizations",
"src/legacy/core_plugins/visualizations"
]
},
"exclude": ["src/legacy/ui/ui_render/ui_render_mixin.js"],
"exclude": [
"src/legacy/ui/ui_render/ui_render_mixin.js"
],
"translations": []
}
}

View file

@ -48,7 +48,7 @@ import {
// @ts-ignore
import { initDashboardApp } from './legacy_app';
import { IEmbeddableStart } from '../../../../../plugins/embeddable/public';
import { NavigationStart } from '../../../navigation/public';
import { NavigationPublicPluginStart as NavigationStart } from '../../../../../plugins/navigation/public';
import { DataPublicPluginStart as NpDataStart } from '../../../../../plugins/data/public';
import { SharePluginStart } from '../../../../../plugins/share/public';

View file

@ -27,7 +27,6 @@ import {
import { DashboardPlugin, LegacyAngularInjectedDependencies } from './plugin';
import { start as data } from '../../../data/public/legacy';
import { start as embeddables } from '../../../embeddable_api/public/np_ready/public/legacy';
import { start as navigation } from '../../../navigation/public/legacy';
import './saved_dashboard/saved_dashboards';
import './dashboard_config';
@ -62,6 +61,6 @@ async function getAngularDependencies(): Promise<LegacyAngularInjectedDependenci
data,
npData: npStart.plugins.data,
embeddables,
navigation,
navigation: npStart.plugins.navigation,
});
})();

View file

@ -31,7 +31,7 @@ import { DataStart } from '../../../data/public';
import { DataPublicPluginStart as NpDataStart } from '../../../../../plugins/data/public';
import { IEmbeddableStart } from '../../../../../plugins/embeddable/public';
import { Storage } from '../../../../../plugins/kibana_utils/public';
import { NavigationStart } from '../../../navigation/public';
import { NavigationPublicPluginStart as NavigationStart } from '../../../../../plugins/navigation/public';
import { DashboardConstants } from './dashboard_constants';
import { SharePluginStart } from '../../../../../plugins/share/public';
import {

View file

@ -68,7 +68,7 @@ import { createTopNavDirective, createTopNavHelper } from 'ui/kbn_top_nav/kbn_to
import { configureAppAngularModule } from 'ui/legacy_compat';
import { IndexPatterns } from '../../../../../plugins/data/public';
import { Storage } from '../../../../../plugins/kibana_utils/public';
import { NavigationStart } from '../../../navigation/public';
import { NavigationPublicPluginStart as NavigationStart } from '../../../../../plugins/navigation/public';
import { createDocTableDirective } from './angular/doc_table/doc_table';
import { createTableHeaderDirective } from './angular/doc_table/components/table_header';
import {

View file

@ -20,7 +20,6 @@ import { PluginInitializer, PluginInitializerContext } from 'kibana/public';
import { npSetup, npStart } from 'ui/new_platform';
import { SavedObjectRegistryProvider } from 'ui/saved_objects';
import { DiscoverPlugin, DiscoverSetup, DiscoverStart } from './plugin';
import { start as navigation } from '../../../navigation/public/legacy';
// Core will be looking for this when loading our plugin in the new platform
export const plugin: PluginInitializer<DiscoverSetup, DiscoverStart> = (
@ -33,7 +32,7 @@ export const plugin: PluginInitializer<DiscoverSetup, DiscoverStart> = (
export const pluginInstance = plugin({} as PluginInitializerContext);
(async () => {
pluginInstance.setup(npSetup.core, npSetup.plugins);
pluginInstance.start(npStart.core, { ...npStart.plugins, navigation });
pluginInstance.start(npStart.core, npStart.plugins);
})();
SavedObjectRegistryProvider.register((savedSearches: any) => {

View file

@ -25,7 +25,7 @@ import './kibana_services';
import { IEmbeddableStart, IEmbeddableSetup } from '../../../../../plugins/embeddable/public';
import { getInnerAngularModule, getInnerAngularModuleEmbeddable } from './get_inner_angular';
import { setAngularModule, setServices } from './kibana_services';
import { NavigationStart } from '../../../navigation/public';
import { NavigationPublicPluginStart as NavigationStart } from '../../../../../plugins/navigation/public';
import { EuiUtilsStart } from '../../../../../plugins/eui_utils/public';
import { buildServices } from './helpers/build_services';
import { SharePluginStart } from '../../../../../plugins/share/public';

View file

@ -39,7 +39,7 @@ import {
PromiseServiceCreator,
StateManagementConfigProvider,
} from './legacy_imports';
import { NavigationStart } from '../../../navigation/public';
import { NavigationPublicPluginStart as NavigationStart } from '../../../../../plugins/navigation/public';
// @ts-ignore
import { initVisualizeApp } from './legacy_app';

View file

@ -30,7 +30,6 @@ import {
} from './legacy_imports';
import { VisualizePlugin, LegacyAngularInjectedDependencies } from './plugin';
import { start as embeddables } from '../../../embeddable_api/public/np_ready/public/legacy';
import { start as navigation } from '../../../navigation/public/legacy';
import { start as visualizations } from '../../../visualizations/public/np_ready/public/legacy';
/**
@ -64,7 +63,6 @@ async function getAngularDependencies(): Promise<LegacyAngularInjectedDependenci
instance.start(npStart.core, {
...npStart.plugins,
embeddables,
navigation,
visualizations,
});
})();

View file

@ -25,7 +25,7 @@ import {
IUiSettingsClient,
} from 'kibana/public';
import { NavigationStart } from '../../../navigation/public';
import { NavigationPublicPluginStart as NavigationStart } from '../../../../../plugins/navigation/public';
import { Storage } from '../../../../../plugins/kibana_utils/public';
import { IEmbeddableStart } from '../../../../../plugins/embeddable/public';
import { SharePluginStart } from '../../../../../plugins/share/public';

View file

@ -30,7 +30,7 @@ import {
import { Storage } from '../../../../../plugins/kibana_utils/public';
import { DataPublicPluginStart } from '../../../../../plugins/data/public';
import { IEmbeddableStart } from '../../../../../plugins/embeddable/public';
import { NavigationStart } from '../../../navigation/public';
import { NavigationPublicPluginStart as NavigationStart } from '../../../../../plugins/navigation/public';
import { SharePluginStart } from '../../../../../plugins/share/public';
import { KibanaLegacySetup } from '../../../../../plugins/kibana_legacy/public';
import { VisualizationsStart } from '../../../visualizations/public';

View file

@ -1,3 +1,3 @@
@import 'src/legacy/ui/public/styles/styling_constants';
@import './top_nav_menu/index';
@import '../../../../plugins/navigation/public/top_nav_menu/index';

View file

@ -21,12 +21,3 @@
// Once the new platform is ready, they can get removed
// and handled by the platform itself in the setup method
// of the ExpressionExectorService
/** @public types */
export { TopNavMenu, TopNavMenuData } from './top_nav_menu';
export { NavigationSetup, NavigationStart } from './plugin';
import { NavigationPlugin as Plugin } from './plugin';
export function plugin() {
return new Plugin();
}

View file

@ -20,7 +20,7 @@
import 'ngreact';
import { wrapInI18nContext } from 'ui/i18n';
import { uiModules } from 'ui/modules';
import { start as navigation } from '../../../core_plugins/navigation/public/legacy';
import { npStart } from 'ui/new_platform';
const module = uiModules.get('kibana');
@ -116,4 +116,4 @@ export const createTopNavHelper = ({ TopNavMenu }) => reactDirective => {
]);
};
module.directive('kbnTopNavHelper', createTopNavHelper(navigation.ui));
module.directive('kbnTopNavHelper', createTopNavHelper(npStart.plugins.navigation.ui));

View file

@ -21,6 +21,7 @@
import { coreMock } from '../../../../../core/public/mocks';
import { dataPluginMock } from '../../../../../plugins/data/public/mocks';
import { embeddablePluginMock } from '../../../../../plugins/embeddable/public/mocks';
import { navigationPluginMock } from '../../../../../plugins/navigation/public/mocks';
import { expressionsPluginMock } from '../../../../../plugins/expressions/public/mocks';
import { inspectorPluginMock } from '../../../../../plugins/inspector/public/mocks';
import { uiActionsPluginMock } from '../../../../../plugins/ui_actions/public/mocks';
@ -30,6 +31,7 @@ import { usageCollectionPluginMock } from '../../../../../plugins/usage_collecti
export const pluginsMock = {
createSetup: () => ({
data: dataPluginMock.createSetupContract(),
navigation: navigationPluginMock.createSetupContract(),
embeddable: embeddablePluginMock.createSetupContract(),
inspector: inspectorPluginMock.createSetupContract(),
expressions: expressionsPluginMock.createSetupContract(),
@ -38,6 +40,7 @@ export const pluginsMock = {
}),
createStart: () => ({
data: dataPluginMock.createStartContract(),
navigation: navigationPluginMock.createStartContract(),
embeddable: embeddablePluginMock.createStartContract(),
inspector: inspectorPluginMock.createStartContract(),
expressions: expressionsPluginMock.createStartContract(),

View file

@ -244,6 +244,11 @@ export const npStart = {
register: sinon.fake(),
},
},
navigation: {
ui: {
TopNavMenu: mockComponent,
},
},
},
};

View file

@ -34,6 +34,10 @@ import { HomePublicPluginSetup, HomePublicPluginStart } from '../../../../plugin
import { SharePluginSetup, SharePluginStart } from '../../../../plugins/share/public';
import { BfetchPublicSetup, BfetchPublicStart } from '../../../../plugins/bfetch/public';
import { UsageCollectionSetup } from '../../../../plugins/usage_collection/public';
import {
NavigationPublicPluginSetup,
NavigationPublicPluginStart,
} from '../../../../plugins/navigation/public';
export interface PluginsSetup {
bfetch: BfetchPublicSetup;
@ -43,6 +47,7 @@ export interface PluginsSetup {
home: HomePublicPluginSetup;
inspector: InspectorSetup;
uiActions: IUiActionsSetup;
navigation: NavigationPublicPluginSetup;
dev_tools: DevToolsSetup;
kibana_legacy: KibanaLegacySetup;
share: SharePluginSetup;
@ -58,6 +63,7 @@ export interface PluginsStart {
home: HomePublicPluginStart;
inspector: InspectorStart;
uiActions: IUiActionsStart;
navigation: NavigationPublicPluginStart;
dev_tools: DevToolsStart;
kibana_legacy: KibanaLegacyStart;
share: SharePluginStart;

View file

@ -0,0 +1,5 @@
# navigation
The navigation plugins exports the `TopNavMenu` component.
It also provides a stateful version of it on the `start` contract.

View file

@ -0,0 +1,7 @@
{
"id": "navigation",
"version": "kibana",
"server": false,
"ui": true,
"requiredPlugins": ["data"]
}

View file

@ -0,0 +1,31 @@
/*
* 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 { PluginInitializerContext } from '../../../core/public';
export function plugin(initializerContext: PluginInitializerContext) {
return new NavigationPublicPlugin(initializerContext);
}
export { TopNavMenuData, TopNavMenu } from './top_nav_menu';
export { NavigationPublicPluginSetup, NavigationPublicPluginStart } from './types';
// Export plugin after all other imports
import { NavigationPublicPlugin } from './plugin';
export { NavigationPublicPlugin as Plugin };

View file

@ -0,0 +1,44 @@
/*
* 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 { Plugin } from '.';
export type Setup = jest.Mocked<ReturnType<Plugin['setup']>>;
export type Start = jest.Mocked<ReturnType<Plugin['start']>>;
const createSetupContract = (): jest.Mocked<Setup> => {
const setupContract = {
registerMenuItem: jest.fn(),
};
return setupContract;
};
const createStartContract = (): jest.Mocked<Start> => {
const startContract = {
ui: {
TopNavMenu: jest.fn(),
},
};
return startContract;
};
export const navigationPluginMock = {
createSetupContract,
createStartContract,
};

View file

@ -17,40 +17,21 @@
* under the License.
*/
import { CoreSetup, CoreStart, Plugin } from 'kibana/public';
import { DataPublicPluginStart } from 'src/plugins/data/public';
import { TopNavMenuExtensionsRegistry, TopNavMenuExtensionsRegistrySetup } from './top_nav_menu';
import { createTopNav } from './top_nav_menu/create_top_nav_menu';
import { TopNavMenuProps } from './top_nav_menu/top_nav_menu';
import { PluginInitializerContext, CoreSetup, CoreStart, Plugin } from 'src/core/public';
import {
NavigationPublicPluginSetup,
NavigationPublicPluginStart,
NavigationPluginStartDependencies,
} from './types';
import { TopNavMenuExtensionsRegistry, createTopNav } from './top_nav_menu';
/**
* Interface for this plugin's returned `setup` contract.
*
* @public
*/
export interface NavigationSetup {
registerMenuItem: TopNavMenuExtensionsRegistrySetup['register'];
}
/**
* Interface for this plugin's returned `start` contract.
*
* @public
*/
export interface NavigationStart {
ui: {
TopNavMenu: React.ComponentType<TopNavMenuProps>;
};
}
export interface NavigationPluginStartDependencies {
data: DataPublicPluginStart;
}
export class NavigationPlugin implements Plugin<NavigationSetup, NavigationStart> {
export class NavigationPublicPlugin
implements Plugin<NavigationPublicPluginSetup, NavigationPublicPluginStart> {
private readonly topNavMenuExtensionsRegistry: TopNavMenuExtensionsRegistry = new TopNavMenuExtensionsRegistry();
public setup(core: CoreSetup): NavigationSetup {
constructor(initializerContext: PluginInitializerContext) {}
public setup(core: CoreSetup): NavigationPublicPluginSetup {
return {
registerMenuItem: this.topNavMenuExtensionsRegistry.register.bind(
this.topNavMenuExtensionsRegistry
@ -58,7 +39,10 @@ export class NavigationPlugin implements Plugin<NavigationSetup, NavigationStart
};
}
public start(core: CoreStart, { data }: NavigationPluginStartDependencies): NavigationStart {
public start(
core: CoreStart,
{ data }: NavigationPluginStartDependencies
): NavigationPublicPluginStart {
const extensions = this.topNavMenuExtensionsRegistry.getAll();
return {
@ -68,7 +52,5 @@ export class NavigationPlugin implements Plugin<NavigationSetup, NavigationStart
};
}
public stop() {
this.topNavMenuExtensionsRegistry.clear();
}
public stop() {}
}

View file

@ -17,6 +17,10 @@
* under the License.
*/
export { TopNavMenu } from './top_nav_menu';
export { createTopNav } from './create_top_nav_menu';
export { TopNavMenu, TopNavMenuProps } from './top_nav_menu';
export { TopNavMenuData } from './top_nav_menu_data';
export * from './top_nav_menu_extensions_registry';
export {
TopNavMenuExtensionsRegistrySetup,
TopNavMenuExtensionsRegistry,
} from './top_nav_menu_extensions_registry';

View file

@ -24,7 +24,7 @@ import { I18nProvider } from '@kbn/i18n/react';
import { TopNavMenuData } from './top_nav_menu_data';
import { TopNavMenuItem } from './top_nav_menu_item';
import { SearchBarProps, DataPublicPluginStart } from '../../../../../plugins/data/public';
import { SearchBarProps, DataPublicPluginStart } from '../../../data/public';
export type TopNavMenuProps = Partial<SearchBarProps> & {
appName: string;

View file

@ -17,13 +17,19 @@
* under the License.
*/
import { npSetup, npStart } from 'ui/new_platform';
import { plugin } from '.';
import { TopNavMenuProps, TopNavMenuExtensionsRegistrySetup } from './top_nav_menu';
import { DataPublicPluginStart } from '../../data/public';
const navPlugin = plugin();
export interface NavigationPublicPluginSetup {
registerMenuItem: TopNavMenuExtensionsRegistrySetup['register'];
}
export const setup = navPlugin.setup(npSetup.core);
export interface NavigationPublicPluginStart {
ui: {
TopNavMenu: React.ComponentType<TopNavMenuProps>;
};
}
export const start = navPlugin.start(npStart.core, {
data: npStart.plugins.data,
});
export interface NavigationPluginStartDependencies {
data: DataPublicPluginStart;
}

View file

@ -18,10 +18,7 @@
*/
import React from 'react';
import {
setup as navSetup,
start as navStart,
} from '../../../../../src/legacy/core_plugins/navigation/public/legacy';
import { npSetup, npStart } from 'ui/new_platform';
const customExtension = {
id: 'registered-prop',
@ -31,10 +28,10 @@ const customExtension = {
testId: 'demoRegisteredNewButton',
};
navSetup.registerMenuItem(customExtension);
npSetup.plugins.navigation.registerMenuItem(customExtension);
export const AppWithTopNav = () => {
const { TopNavMenu } = navStart.ui;
const { TopNavMenu } = npStart.plugins.navigation.ui;
const config = [
{
id: 'new',

View file

@ -16,7 +16,6 @@ import { SavedObjectRegistryProvider } from 'ui/saved_objects/saved_object_regis
import { npSetup, npStart } from 'ui/new_platform';
import { Storage } from '../../../../../src/plugins/kibana_utils/public';
import { start as navigation } from '../../../../../src/legacy/core_plugins/navigation/public/legacy';
import { LicensingPluginSetup } from '../../../../plugins/licensing/public';
import { GraphPlugin } from './plugin';
@ -54,7 +53,7 @@ type XpackNpSetupDeps = typeof npSetup.plugins & {
});
instance.start(npStart.core, {
npData: npStart.plugins.data,
navigation,
navigation: npStart.plugins.navigation,
__LEGACY: {
angularDependencies: await getAngularInjectedDependencies(),
},

View file

@ -8,8 +8,8 @@
import { CoreSetup, CoreStart, Plugin, SavedObjectsClientContract } from 'src/core/public';
import { Plugin as DataPlugin } from 'src/plugins/data/public';
import { LegacyAngularInjectedDependencies } from './render_app';
import { NavigationStart } from '../../../../../src/legacy/core_plugins/navigation/public';
import { LicensingPluginSetup } from '../../../../plugins/licensing/public';
import { NavigationPublicPluginStart as NavigationStart } from '../../../../../src/plugins/navigation/public';
export interface GraphPluginStartDependencies {
npData: ReturnType<DataPlugin['start']>;

View file

@ -37,9 +37,9 @@ import {
Plugin as DataPlugin,
IndexPatternsContract,
} from '../../../../../src/plugins/data/public';
import { NavigationStart } from '../../../../../src/legacy/core_plugins/navigation/public';
import { LicensingPluginSetup } from '../../../../plugins/licensing/public';
import { checkLicense } from '../../../../plugins/graph/common/check_license';
import { NavigationPublicPluginStart as NavigationStart } from '../../../../../src/plugins/navigation/public';
/**
* These are dependencies of the Graph app besides the base dependencies

View file

@ -16,26 +16,23 @@ import { esFilters, IFieldType, IIndexPattern } from '../../../../../../src/plug
import { dataPluginMock } from '../../../../../../src/plugins/data/public/mocks';
const dataStartMock = dataPluginMock.createStartContract();
import { TopNavMenuData } from '../../../../../../src/legacy/core_plugins/navigation/public';
import { TopNavMenuData } from '../../../../../../src/plugins/navigation/public';
import { DataStart } from '../../../../../../src/legacy/core_plugins/data/public';
import { coreMock } from 'src/core/public/mocks';
jest.mock('../../../../../../src/legacy/core_plugins/navigation/public/legacy', () => ({
start: {
ui: {
TopNavMenu: jest.fn(() => null),
},
},
}));
import { start as navigation } from '../../../../../../src/legacy/core_plugins/navigation/public/legacy';
const { TopNavMenu } = navigation.ui;
jest.mock('ui/new_platform');
jest.mock('../persistence');
jest.mock('src/core/public');
import { npStart } from 'ui/new_platform';
jest
.spyOn(npStart.plugins.navigation.ui.TopNavMenu.prototype, 'constructor')
.mockImplementation(() => {
return <div className="topNavMenu" />;
});
const { TopNavMenu } = npStart.plugins.navigation.ui;
const waitForPromises = () => new Promise(resolve => setTimeout(resolve));
function createMockFrame(): jest.Mocked<EditorFrameInstance> {

View file

@ -11,9 +11,8 @@ import { i18n } from '@kbn/i18n';
import { Query, DataPublicPluginStart } from 'src/plugins/data/public';
import { SavedObjectSaveModal } from 'ui/saved_objects/components/saved_object_save_modal';
import { AppMountContext, NotificationsStart } from 'src/core/public';
import { SavedQuery } from 'src/legacy/core_plugins/data/public';
import { IStorageWrapper } from 'src/plugins/kibana_utils/public';
import { start as navigation } from '../../../../../../src/legacy/core_plugins/navigation/public/legacy';
import { npStart } from 'ui/new_platform';
import { KibanaContextProvider } from '../../../../../../src/plugins/kibana_react/public';
import { Document, SavedObjectStore } from '../persistence';
import { EditorFrameInstance } from '../types';
@ -23,6 +22,7 @@ import {
esFilters,
IndexPattern as IndexPatternInstance,
IndexPatternsContract,
SavedQuery,
} from '../../../../../../src/plugins/data/public';
interface State {
@ -160,7 +160,7 @@ export function App({
[]
);
const { TopNavMenu } = navigation.ui;
const { TopNavMenu } = npStart.plugins.navigation.ui;
return (
<I18nProvider>