Management API - simpler interface, remove app context usage, consolidate rendeing
This commit is contained in:
parent
c19880915b
commit
17d8e864a7
|
@ -952,9 +952,9 @@ export class MyPlugin implements Plugin<MyPluginSetup> {
|
|||
async mount(params: AppMountParameters) {
|
||||
const { mountApp } = await import('./app/mount_app');
|
||||
return mountApp(await core.getStartServices(), params);
|
||||
},
|
||||
});
|
||||
plugins.management.sections.getSection('another').registerApp({
|
||||
},
|
||||
});
|
||||
plugins.management.sections.section.kibana.registerApp({
|
||||
id: 'app',
|
||||
title: 'My app',
|
||||
order: 1,
|
||||
|
|
|
@ -18,7 +18,6 @@
|
|||
*/
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import { CoreSetup, Plugin } from 'kibana/public';
|
||||
import { ManagementSectionId } from '../../management/public';
|
||||
import { ComponentRegistry } from './component_registry';
|
||||
import { AdvancedSettingsSetup, AdvancedSettingsStart, AdvancedSettingsPluginSetup } from './types';
|
||||
|
||||
|
@ -31,7 +30,7 @@ const title = i18n.translate('advancedSettings.advancedSettingsLabel', {
|
|||
export class AdvancedSettingsPlugin
|
||||
implements Plugin<AdvancedSettingsSetup, AdvancedSettingsStart, AdvancedSettingsPluginSetup> {
|
||||
public setup(core: CoreSetup, { management }: AdvancedSettingsPluginSetup) {
|
||||
const kibanaSection = management.sections.getSection(ManagementSectionId.Kibana);
|
||||
const kibanaSection = management.sections.section.kibana;
|
||||
|
||||
kibanaSection.registerApp({
|
||||
id: 'settings',
|
||||
|
|
|
@ -27,7 +27,7 @@ import {
|
|||
IndexPatternManagementServiceStart,
|
||||
} from './service';
|
||||
|
||||
import { ManagementSetup, ManagementSectionId } from '../../management/public';
|
||||
import { ManagementSetup } from '../../management/public';
|
||||
|
||||
export interface IndexPatternManagementSetupDependencies {
|
||||
management: ManagementSetup;
|
||||
|
@ -64,7 +64,7 @@ export class IndexPatternManagementPlugin
|
|||
core: CoreSetup<IndexPatternManagementStartDependencies, IndexPatternManagementStart>,
|
||||
{ management, kibanaLegacy }: IndexPatternManagementSetupDependencies
|
||||
) {
|
||||
const kibanaSection = management.sections.getSection(ManagementSectionId.Kibana);
|
||||
const kibanaSection = management.sections.section.kibana;
|
||||
|
||||
if (!kibanaSection) {
|
||||
throw new Error('`kibana` management section not found.');
|
||||
|
|
|
@ -4,5 +4,5 @@
|
|||
"server": true,
|
||||
"ui": true,
|
||||
"requiredPlugins": ["kibanaLegacy", "home"],
|
||||
"requiredBundles": ["kibanaReact"]
|
||||
"requiredBundles": ["kibanaReact", "kibanaUtils"]
|
||||
}
|
||||
|
|
|
@ -20,21 +20,15 @@
|
|||
import React from 'react';
|
||||
import ReactDOM from 'react-dom';
|
||||
|
||||
import { AppMountContext, AppMountParameters } from 'kibana/public';
|
||||
import { AppMountParameters } from 'kibana/public';
|
||||
import { ManagementApp, ManagementAppDependencies } from './components/management_app';
|
||||
|
||||
export const renderApp = async (
|
||||
context: AppMountContext,
|
||||
{ history, appBasePath, element }: AppMountParameters,
|
||||
dependencies: ManagementAppDependencies
|
||||
) => {
|
||||
ReactDOM.render(
|
||||
<ManagementApp
|
||||
context={context}
|
||||
dependencies={dependencies}
|
||||
appBasePath={appBasePath}
|
||||
history={history}
|
||||
/>,
|
||||
<ManagementApp dependencies={dependencies} appBasePath={appBasePath} history={history} />,
|
||||
element
|
||||
);
|
||||
|
||||
|
|
|
@ -18,4 +18,3 @@
|
|||
*/
|
||||
|
||||
export { ManagementApp } from './management_app';
|
||||
export { managementSections } from './management_sections';
|
||||
|
|
|
@ -17,36 +17,32 @@
|
|||
* under the License.
|
||||
*/
|
||||
import React, { useState, useEffect, useCallback } from 'react';
|
||||
import {
|
||||
AppMountContext,
|
||||
AppMountParameters,
|
||||
ChromeBreadcrumb,
|
||||
ScopedHistory,
|
||||
} from 'kibana/public';
|
||||
import { AppMountParameters, ChromeBreadcrumb, ScopedHistory } from 'kibana/public';
|
||||
import { I18nProvider } from '@kbn/i18n/react';
|
||||
import { EuiPage } from '@elastic/eui';
|
||||
import { ManagementStart } from '../../types';
|
||||
import { ManagementSection, MANAGEMENT_BREADCRUMB } from '../../utils';
|
||||
|
||||
import { ManagementRouter } from './management_router';
|
||||
import { ManagementSidebarNav } from '../management_sidebar_nav';
|
||||
import { reactRouterNavigate } from '../../../../kibana_react/public';
|
||||
import { SectionsServiceStart } from '../../types';
|
||||
|
||||
import './management_app.scss';
|
||||
|
||||
interface ManagementAppProps {
|
||||
appBasePath: string;
|
||||
context: AppMountContext;
|
||||
history: AppMountParameters['history'];
|
||||
dependencies: ManagementAppDependencies;
|
||||
}
|
||||
|
||||
export interface ManagementAppDependencies {
|
||||
management: ManagementStart;
|
||||
sections: SectionsServiceStart;
|
||||
kibanaVersion: string;
|
||||
setBreadcrumbs: (newBreadcrumbs: ChromeBreadcrumb[]) => void;
|
||||
}
|
||||
|
||||
export const ManagementApp = ({ context, dependencies, history }: ManagementAppProps) => {
|
||||
export const ManagementApp = ({ dependencies, history }: ManagementAppProps) => {
|
||||
const { setBreadcrumbs } = dependencies;
|
||||
const [selectedId, setSelectedId] = useState<string>('');
|
||||
const [sections, setSections] = useState<ManagementSection[]>();
|
||||
|
||||
|
@ -55,24 +51,24 @@ export const ManagementApp = ({ context, dependencies, history }: ManagementAppP
|
|||
window.scrollTo(0, 0);
|
||||
}, []);
|
||||
|
||||
const setBreadcrumbs = useCallback(
|
||||
const setBreadcrumbsScoped = useCallback(
|
||||
(crumbs: ChromeBreadcrumb[] = [], appHistory?: ScopedHistory) => {
|
||||
const wrapBreadcrumb = (item: ChromeBreadcrumb, scopedHistory: ScopedHistory) => ({
|
||||
...item,
|
||||
...(item.href ? reactRouterNavigate(scopedHistory, item.href) : {}),
|
||||
});
|
||||
|
||||
context.core.chrome.setBreadcrumbs([
|
||||
setBreadcrumbs([
|
||||
wrapBreadcrumb(MANAGEMENT_BREADCRUMB, history),
|
||||
...crumbs.map((item) => wrapBreadcrumb(item, appHistory || history)),
|
||||
]);
|
||||
},
|
||||
[context.core.chrome, history]
|
||||
[setBreadcrumbs, history]
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
setSections(dependencies.management.sections.getSectionsEnabled());
|
||||
}, [dependencies.management.sections]);
|
||||
setSections(dependencies.sections.getSectionsEnabled());
|
||||
}, [dependencies.sections]);
|
||||
|
||||
if (!sections) {
|
||||
return null;
|
||||
|
@ -84,7 +80,7 @@ export const ManagementApp = ({ context, dependencies, history }: ManagementAppP
|
|||
<ManagementSidebarNav selectedId={selectedId} sections={sections} history={history} />
|
||||
<ManagementRouter
|
||||
history={history}
|
||||
setBreadcrumbs={setBreadcrumbs}
|
||||
setBreadcrumbs={setBreadcrumbsScoped}
|
||||
onAppMounted={onAppMounted}
|
||||
sections={sections}
|
||||
dependencies={dependencies}
|
||||
|
|
|
@ -17,61 +17,104 @@
|
|||
* under the License.
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
import { EuiFlexGroup, EuiFlexItem, EuiToolTip, EuiIcon } from '@elastic/eui';
|
||||
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import { ManagementSectionId } from '../types';
|
||||
|
||||
interface ManagementSectionTitleProps {
|
||||
text: string;
|
||||
tip: string;
|
||||
}
|
||||
const ingestTitle = i18n.translate('management.sections.ingestTitle', {
|
||||
defaultMessage: 'Ingest',
|
||||
});
|
||||
|
||||
const ManagementSectionTitle = ({ text, tip }: ManagementSectionTitleProps) => (
|
||||
<EuiToolTip content={tip} position="right">
|
||||
<EuiFlexGroup alignItems="center" gutterSize="s" responsive={false}>
|
||||
<EuiFlexItem grow={false}>{text}</EuiFlexItem>
|
||||
const ingestTip = i18n.translate('management.sections.ingestTip', {
|
||||
defaultMessage: 'Manage how to transform data and load it into the cluster',
|
||||
});
|
||||
|
||||
<EuiFlexItem grow={false}>
|
||||
<EuiIcon type="questionInCircle" />
|
||||
</EuiFlexItem>
|
||||
</EuiFlexGroup>
|
||||
</EuiToolTip>
|
||||
);
|
||||
const dataTitle = i18n.translate('management.sections.dataTitle', {
|
||||
defaultMessage: 'Data',
|
||||
});
|
||||
|
||||
const dataTip = i18n.translate('management.sections.dataTip', {
|
||||
defaultMessage: 'Manage your cluster data and backups',
|
||||
});
|
||||
|
||||
const insightsAndAlertingTitle = i18n.translate('management.sections.insightsAndAlertingTitle', {
|
||||
defaultMessage: 'Alerts and Insights',
|
||||
});
|
||||
|
||||
const insightsAndAlertingTip = i18n.translate('management.sections.insightsAndAlertingTip', {
|
||||
defaultMessage: 'Manage how to detect changes in your data',
|
||||
});
|
||||
|
||||
const sectionTitle = i18n.translate('management.sections.section.title', {
|
||||
defaultMessage: 'Security',
|
||||
});
|
||||
|
||||
const sectionTip = i18n.translate('management.sections.section.tip', {
|
||||
defaultMessage: 'Control access to features and data',
|
||||
});
|
||||
|
||||
const kibanaTitle = i18n.translate('management.sections.kibanaTitle', {
|
||||
defaultMessage: 'Kibana',
|
||||
});
|
||||
|
||||
const kibanaTip = i18n.translate('management.sections.kibanaTip', {
|
||||
defaultMessage: 'Customize Kibana and manage saved objects',
|
||||
});
|
||||
|
||||
const stackTitle = i18n.translate('management.sections.stackTitle', {
|
||||
defaultMessage: 'Stack',
|
||||
});
|
||||
|
||||
const stackTip = i18n.translate('management.sections.stackTip', {
|
||||
defaultMessage: 'Manage your license and upgrade the Stack',
|
||||
});
|
||||
|
||||
export const IngestSection = {
|
||||
id: ManagementSectionId.Ingest,
|
||||
title: ingestTitle,
|
||||
tip: ingestTip,
|
||||
order: 0,
|
||||
};
|
||||
|
||||
export const DataSection = {
|
||||
id: ManagementSectionId.Data,
|
||||
title: dataTitle,
|
||||
tip: dataTip,
|
||||
order: 1,
|
||||
};
|
||||
|
||||
export const InsightsAndAlertingSection = {
|
||||
id: ManagementSectionId.InsightsAndAlerting,
|
||||
title: insightsAndAlertingTitle,
|
||||
tip: insightsAndAlertingTip,
|
||||
order: 2,
|
||||
};
|
||||
|
||||
export const SecuritySection = {
|
||||
id: 'security',
|
||||
title: sectionTitle,
|
||||
tip: sectionTip,
|
||||
order: 3,
|
||||
};
|
||||
|
||||
export const KibanaSection = {
|
||||
id: ManagementSectionId.Kibana,
|
||||
title: kibanaTitle,
|
||||
tip: kibanaTip,
|
||||
order: 4,
|
||||
};
|
||||
|
||||
export const StackSection = {
|
||||
id: ManagementSectionId.Stack,
|
||||
title: stackTitle,
|
||||
tip: stackTip,
|
||||
order: 4,
|
||||
};
|
||||
|
||||
export const managementSections = [
|
||||
{
|
||||
id: ManagementSectionId.Ingest,
|
||||
title: (
|
||||
<ManagementSectionTitle
|
||||
text="Ingest"
|
||||
tip="Manage how to transform data and load it into the cluster."
|
||||
/>
|
||||
),
|
||||
},
|
||||
{
|
||||
id: ManagementSectionId.Data,
|
||||
title: <ManagementSectionTitle text="Data" tip="Manage your cluster data and backups" />,
|
||||
},
|
||||
{
|
||||
id: ManagementSectionId.InsightsAndAlerting,
|
||||
title: (
|
||||
<ManagementSectionTitle
|
||||
text="Alerts and Insights"
|
||||
tip="Manage how to detect changes in your data"
|
||||
/>
|
||||
),
|
||||
},
|
||||
{
|
||||
id: ManagementSectionId.Security,
|
||||
title: <ManagementSectionTitle text="Security" tip="Control access to features and data" />,
|
||||
},
|
||||
{
|
||||
id: ManagementSectionId.Kibana,
|
||||
title: <ManagementSectionTitle text="Kibana" tip="Customize Kibana and manage saved objects" />,
|
||||
},
|
||||
{
|
||||
id: ManagementSectionId.Stack,
|
||||
title: <ManagementSectionTitle text="Stack" tip="Manage your license and upgrade the Stack" />,
|
||||
},
|
||||
IngestSection,
|
||||
DataSection,
|
||||
InsightsAndAlertingSection,
|
||||
SecuritySection,
|
||||
KibanaSection,
|
||||
StackSection,
|
||||
];
|
||||
|
|
|
@ -21,7 +21,15 @@ import React, { useState } from 'react';
|
|||
import { i18n } from '@kbn/i18n';
|
||||
import { sortBy } from 'lodash';
|
||||
|
||||
import { EuiIcon, EuiSideNav, EuiScreenReaderOnly, EuiSideNavItemType } from '@elastic/eui';
|
||||
import {
|
||||
EuiIcon,
|
||||
EuiSideNav,
|
||||
EuiScreenReaderOnly,
|
||||
EuiSideNavItemType,
|
||||
EuiFlexGroup,
|
||||
EuiFlexItem,
|
||||
EuiToolTip,
|
||||
} from '@elastic/eui';
|
||||
import { AppMountParameters } from 'kibana/public';
|
||||
import { ManagementApp, ManagementSection } from '../../utils';
|
||||
|
||||
|
@ -79,6 +87,23 @@ export const ManagementSidebarNav = ({
|
|||
}),
|
||||
}));
|
||||
|
||||
interface TooltipWrapperProps {
|
||||
text: string;
|
||||
tip?: string;
|
||||
}
|
||||
|
||||
const TooltipWrapper = ({ text, tip }: TooltipWrapperProps) => (
|
||||
<EuiToolTip content={tip} position="right">
|
||||
<EuiFlexGroup alignItems="center" gutterSize="s" responsive={false}>
|
||||
<EuiFlexItem grow={false}>{text}</EuiFlexItem>
|
||||
|
||||
<EuiFlexItem grow={false}>
|
||||
<EuiIcon type="questionInCircle" />
|
||||
</EuiFlexItem>
|
||||
</EuiFlexGroup>
|
||||
</EuiToolTip>
|
||||
);
|
||||
|
||||
const createNavItem = <T extends ManagementItem>(
|
||||
item: T,
|
||||
customParams: Partial<EuiSideNavItemType<any>> = {}
|
||||
|
@ -87,7 +112,7 @@ export const ManagementSidebarNav = ({
|
|||
|
||||
return {
|
||||
id: item.id,
|
||||
name: item.title,
|
||||
name: item.tip ? <TooltipWrapper text={item.title} tip={item.tip} /> : item.title,
|
||||
isSelected: item.id === selectedId,
|
||||
icon: iconType ? <EuiIcon type={iconType} size="m" /> : undefined,
|
||||
'data-test-subj': item.id,
|
||||
|
|
|
@ -27,8 +27,8 @@ export function plugin(initializerContext: PluginInitializerContext) {
|
|||
export { RegisterManagementAppArgs, ManagementSection, ManagementApp } from './utils';
|
||||
|
||||
export {
|
||||
ManagementSectionId,
|
||||
ManagementAppMountParams,
|
||||
ManagementSetup,
|
||||
ManagementStart,
|
||||
DefinedSections,
|
||||
} from './types';
|
||||
|
|
|
@ -17,8 +17,10 @@
|
|||
* under the License.
|
||||
*/
|
||||
|
||||
import { ManagementSectionId } from './index';
|
||||
import { ManagementSectionsService } from './management_sections_service';
|
||||
import {
|
||||
ManagementSectionsService,
|
||||
getSectionsServiceStartPrivate,
|
||||
} from './management_sections_service';
|
||||
|
||||
describe('ManagementService', () => {
|
||||
let managementService: ManagementSectionsService;
|
||||
|
@ -35,15 +37,10 @@ describe('ManagementService', () => {
|
|||
|
||||
test('Provides default sections', () => {
|
||||
managementService.setup();
|
||||
const start = managementService.start({ capabilities });
|
||||
managementService.start({ capabilities });
|
||||
const start = getSectionsServiceStartPrivate();
|
||||
|
||||
expect(start.getAllSections().length).toEqual(6);
|
||||
expect(start.getSection(ManagementSectionId.Ingest)).toBeDefined();
|
||||
expect(start.getSection(ManagementSectionId.Data)).toBeDefined();
|
||||
expect(start.getSection(ManagementSectionId.InsightsAndAlerting)).toBeDefined();
|
||||
expect(start.getSection(ManagementSectionId.Security)).toBeDefined();
|
||||
expect(start.getSection(ManagementSectionId.Kibana)).toBeDefined();
|
||||
expect(start.getSection(ManagementSectionId.Stack)).toBeDefined();
|
||||
expect(start.getSectionsEnabled().length).toEqual(6);
|
||||
});
|
||||
|
||||
test('Register section, enable and disable', () => {
|
||||
|
@ -51,10 +48,11 @@ describe('ManagementService', () => {
|
|||
const setup = managementService.setup();
|
||||
const testSection = setup.register({ id: 'test-section', title: 'Test Section' });
|
||||
|
||||
expect(setup.getSection('test-section')).not.toBeUndefined();
|
||||
expect(testSection).not.toBeUndefined();
|
||||
|
||||
// Start phase:
|
||||
const start = managementService.start({ capabilities });
|
||||
managementService.start({ capabilities });
|
||||
const start = getSectionsServiceStartPrivate();
|
||||
|
||||
expect(start.getSectionsEnabled().length).toEqual(7);
|
||||
|
||||
|
@ -71,7 +69,7 @@ describe('ManagementService', () => {
|
|||
testSection.registerApp({ id: 'test-app-2', title: 'Test App 2', mount: jest.fn() });
|
||||
testSection.registerApp({ id: 'test-app-3', title: 'Test App 3', mount: jest.fn() });
|
||||
|
||||
expect(setup.getSection('test-section')).not.toBeUndefined();
|
||||
expect(testSection).not.toBeUndefined();
|
||||
|
||||
// Start phase:
|
||||
managementService.start({
|
||||
|
|
|
@ -17,22 +17,47 @@
|
|||
* under the License.
|
||||
*/
|
||||
|
||||
import { ReactElement } from 'react';
|
||||
import { ManagementSection, RegisterManagementSectionArgs } from './utils';
|
||||
import { managementSections } from './components/management_sections';
|
||||
import {
|
||||
IngestSection,
|
||||
DataSection,
|
||||
InsightsAndAlertingSection,
|
||||
SecuritySection,
|
||||
KibanaSection,
|
||||
StackSection,
|
||||
} from './components/management_sections';
|
||||
|
||||
import {
|
||||
ManagementSectionId,
|
||||
SectionsServiceSetup,
|
||||
SectionsServiceStart,
|
||||
SectionsServiceStartDeps,
|
||||
DefinedSections,
|
||||
ManagementSectionsStartPrivate,
|
||||
} from './types';
|
||||
import { createGetterSetter } from '../../kibana_utils/public';
|
||||
|
||||
const [getSectionsServiceStartPrivate, setSectionsServiceStartPrivate] = createGetterSetter<
|
||||
ManagementSectionsStartPrivate
|
||||
>('SectionsServiceStartPrivate');
|
||||
|
||||
export { getSectionsServiceStartPrivate };
|
||||
|
||||
export class ManagementSectionsService {
|
||||
private sections: Map<ManagementSectionId | string, ManagementSection> = new Map();
|
||||
definedSections: DefinedSections;
|
||||
|
||||
private getSection = (sectionId: ManagementSectionId | string) =>
|
||||
this.sections.get(sectionId) as ManagementSection;
|
||||
constructor() {
|
||||
// Note on adding sections - sections can be defined in a plugin and exported as a contract
|
||||
// It is not necessary to define all sections here, although we've chose to do it for discovery reasons.
|
||||
this.definedSections = {
|
||||
ingest: this.registerSection(IngestSection),
|
||||
data: this.registerSection(DataSection),
|
||||
insightsAndAlerting: this.registerSection(InsightsAndAlertingSection),
|
||||
security: this.registerSection(SecuritySection),
|
||||
kibana: this.registerSection(KibanaSection),
|
||||
stack: this.registerSection(StackSection),
|
||||
};
|
||||
}
|
||||
private sections: Map<ManagementSectionId | string, ManagementSection> = new Map();
|
||||
|
||||
private getAllSections = () => [...this.sections.values()];
|
||||
|
||||
|
@ -48,19 +73,15 @@ export class ManagementSectionsService {
|
|||
};
|
||||
|
||||
setup(): SectionsServiceSetup {
|
||||
managementSections.forEach(
|
||||
({ id, title }: { id: ManagementSectionId; title: ReactElement }, idx: number) => {
|
||||
this.registerSection({ id, title, order: idx });
|
||||
}
|
||||
);
|
||||
|
||||
return {
|
||||
register: this.registerSection,
|
||||
getSection: this.getSection,
|
||||
section: {
|
||||
...this.definedSections,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
start({ capabilities }: SectionsServiceStartDeps): SectionsServiceStart {
|
||||
start({ capabilities }: SectionsServiceStartDeps) {
|
||||
this.getAllSections().forEach((section) => {
|
||||
if (capabilities.management.hasOwnProperty(section.id)) {
|
||||
const sectionCapabilities = capabilities.management[section.id];
|
||||
|
@ -72,10 +93,10 @@ export class ManagementSectionsService {
|
|||
}
|
||||
});
|
||||
|
||||
return {
|
||||
getSection: this.getSection,
|
||||
getAllSections: this.getAllSections,
|
||||
setSectionsServiceStartPrivate({
|
||||
getSectionsEnabled: () => this.getAllSections().filter((section) => section.enabled),
|
||||
};
|
||||
});
|
||||
|
||||
return {};
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,10 +17,10 @@
|
|||
* under the License.
|
||||
*/
|
||||
|
||||
import { ManagementSetup, ManagementStart } from '../types';
|
||||
import { ManagementSetup, ManagementStart, DefinedSections } from '../types';
|
||||
import { ManagementSection } from '../index';
|
||||
|
||||
const createManagementSectionMock = () =>
|
||||
export const createManagementSectionMock = () =>
|
||||
(({
|
||||
disable: jest.fn(),
|
||||
enable: jest.fn(),
|
||||
|
@ -29,19 +29,22 @@ const createManagementSectionMock = () =>
|
|||
getEnabledItems: jest.fn().mockReturnValue([]),
|
||||
} as unknown) as ManagementSection);
|
||||
|
||||
const createSetupContract = (): DeeplyMockedKeys<ManagementSetup> => ({
|
||||
const createSetupContract = (): ManagementSetup => ({
|
||||
sections: {
|
||||
register: jest.fn(),
|
||||
getSection: jest.fn().mockReturnValue(createManagementSectionMock()),
|
||||
register: jest.fn(() => createManagementSectionMock()),
|
||||
section: ({
|
||||
ingest: createManagementSectionMock(),
|
||||
data: createManagementSectionMock(),
|
||||
insightsAndAlerting: createManagementSectionMock(),
|
||||
security: createManagementSectionMock(),
|
||||
kibana: createManagementSectionMock(),
|
||||
stack: createManagementSectionMock(),
|
||||
} as unknown) as DefinedSections,
|
||||
},
|
||||
});
|
||||
|
||||
const createStartContract = (): DeeplyMockedKeys<ManagementStart> => ({
|
||||
sections: {
|
||||
getSection: jest.fn(),
|
||||
getAllSections: jest.fn(),
|
||||
getSectionsEnabled: jest.fn(),
|
||||
},
|
||||
const createStartContract = (): ManagementStart => ({
|
||||
sections: {},
|
||||
});
|
||||
|
||||
export const managementPluginMock = {
|
||||
|
|
|
@ -26,9 +26,13 @@ import {
|
|||
Plugin,
|
||||
DEFAULT_APP_CATEGORIES,
|
||||
PluginInitializerContext,
|
||||
AppMountParameters,
|
||||
} from '../../../core/public';
|
||||
|
||||
import { ManagementSectionsService } from './management_sections_service';
|
||||
import {
|
||||
ManagementSectionsService,
|
||||
getSectionsServiceStartPrivate,
|
||||
} from './management_sections_service';
|
||||
|
||||
interface ManagementSetupDependencies {
|
||||
home: HomePublicPluginSetup;
|
||||
|
@ -64,13 +68,14 @@ export class ManagementPlugin implements Plugin<ManagementSetup, ManagementStart
|
|||
order: 9003,
|
||||
euiIconType: 'managementApp',
|
||||
category: DEFAULT_APP_CATEGORIES.management,
|
||||
async mount(context, params) {
|
||||
async mount(params: AppMountParameters) {
|
||||
const { renderApp } = await import('./application');
|
||||
const selfStart = (await core.getStartServices())[2] as ManagementStart;
|
||||
const [coreStart] = await core.getStartServices();
|
||||
|
||||
return renderApp(context, params, {
|
||||
return renderApp(params, {
|
||||
sections: getSectionsServiceStartPrivate(),
|
||||
kibanaVersion,
|
||||
management: selfStart,
|
||||
setBreadcrumbs: coreStart.chrome.setBreadcrumbs,
|
||||
});
|
||||
},
|
||||
});
|
||||
|
@ -81,8 +86,7 @@ export class ManagementPlugin implements Plugin<ManagementSetup, ManagementStart
|
|||
}
|
||||
|
||||
public start(core: CoreStart) {
|
||||
return {
|
||||
sections: this.managementSections.start({ capabilities: core.application.capabilities }),
|
||||
};
|
||||
this.managementSections.start({ capabilities: core.application.capabilities });
|
||||
return {};
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,7 +17,6 @@
|
|||
* under the License.
|
||||
*/
|
||||
|
||||
import { ReactElement } from 'react';
|
||||
import { ScopedHistory, Capabilities } from 'kibana/public';
|
||||
import { ManagementSection, RegisterManagementSectionArgs } from './utils';
|
||||
import { ChromeBreadcrumb } from '../../../core/public/';
|
||||
|
@ -26,8 +25,20 @@ export interface ManagementSetup {
|
|||
sections: SectionsServiceSetup;
|
||||
}
|
||||
|
||||
export interface ManagementStart {
|
||||
sections: SectionsServiceStart;
|
||||
export interface DefinedSections {
|
||||
ingest: ManagementSection;
|
||||
data: ManagementSection;
|
||||
insightsAndAlerting: ManagementSection;
|
||||
security: ManagementSection;
|
||||
kibana: ManagementSection;
|
||||
stack: ManagementSection;
|
||||
}
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-empty-interface
|
||||
export interface ManagementStart {}
|
||||
|
||||
export interface ManagementSectionsStartPrivate {
|
||||
getSectionsEnabled: () => ManagementSection[];
|
||||
}
|
||||
|
||||
export interface SectionsServiceStartDeps {
|
||||
|
@ -36,12 +47,10 @@ export interface SectionsServiceStartDeps {
|
|||
|
||||
export interface SectionsServiceSetup {
|
||||
register: (args: Omit<RegisterManagementSectionArgs, 'capabilities'>) => ManagementSection;
|
||||
getSection: (sectionId: ManagementSectionId | string) => ManagementSection;
|
||||
section: DefinedSections;
|
||||
}
|
||||
|
||||
export interface SectionsServiceStart {
|
||||
getSection: (sectionId: ManagementSectionId | string) => ManagementSection;
|
||||
getAllSections: () => ManagementSection[];
|
||||
getSectionsEnabled: () => ManagementSection[];
|
||||
}
|
||||
|
||||
|
@ -66,7 +75,8 @@ export interface ManagementAppMountParams {
|
|||
|
||||
export interface CreateManagementItemArgs {
|
||||
id: string;
|
||||
title: string | ReactElement;
|
||||
title: string;
|
||||
tip?: string;
|
||||
order?: number;
|
||||
euiIconType?: string; // takes precedence over `icon` property.
|
||||
icon?: string; // URL to image file; fallback if no `euiIconType`
|
||||
|
|
|
@ -16,21 +16,22 @@
|
|||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
import { ReactElement } from 'react';
|
||||
import { CreateManagementItemArgs } from '../types';
|
||||
|
||||
export class ManagementItem {
|
||||
public readonly id: string = '';
|
||||
public readonly title: string | ReactElement = '';
|
||||
public readonly title: string;
|
||||
public readonly tip?: string;
|
||||
public readonly order: number;
|
||||
public readonly euiIconType?: string;
|
||||
public readonly icon?: string;
|
||||
|
||||
public enabled: boolean = true;
|
||||
|
||||
constructor({ id, title, order = 100, euiIconType, icon }: CreateManagementItemArgs) {
|
||||
constructor({ id, title, tip, order = 100, euiIconType, icon }: CreateManagementItemArgs) {
|
||||
this.id = id;
|
||||
this.title = title;
|
||||
this.tip = tip;
|
||||
this.order = order;
|
||||
this.euiIconType = euiIconType;
|
||||
this.icon = icon;
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import { CoreSetup, CoreStart, Plugin } from 'src/core/public';
|
||||
import { ManagementSetup, ManagementSectionId } from '../../management/public';
|
||||
import { ManagementSetup } from '../../management/public';
|
||||
import { DataPublicPluginStart } from '../../data/public';
|
||||
import { DashboardStart } from '../../dashboard/public';
|
||||
import { DiscoverStart } from '../../discover/public';
|
||||
|
@ -87,7 +87,7 @@ export class SavedObjectsManagementPlugin
|
|||
category: FeatureCatalogueCategory.ADMIN,
|
||||
});
|
||||
|
||||
const kibanaSection = management.sections.getSection(ManagementSectionId.Kibana);
|
||||
const kibanaSection = management.sections.section.kibana;
|
||||
kibanaSection.registerApp({
|
||||
id: 'objects',
|
||||
title: i18n.translate('savedObjectsManagement.managementSectionLabel', {
|
||||
|
|
|
@ -21,12 +21,12 @@ import * as React from 'react';
|
|||
import ReactDOM from 'react-dom';
|
||||
import { Router, Switch, Route, Link } from 'react-router-dom';
|
||||
import { CoreSetup, Plugin } from 'kibana/public';
|
||||
import { ManagementSetup, ManagementSectionId } from '../../../../../src/plugins/management/public';
|
||||
import { ManagementSetup } from '../../../../../src/plugins/management/public';
|
||||
|
||||
export class ManagementTestPlugin
|
||||
implements Plugin<ManagementTestPluginSetup, ManagementTestPluginStart> {
|
||||
public setup(core: CoreSetup, { management }: { management: ManagementSetup }) {
|
||||
const testSection = management.sections.getSection(ManagementSectionId.Data);
|
||||
const testSection = management.sections.section.data;
|
||||
|
||||
testSection.registerApp({
|
||||
id: 'test-management',
|
||||
|
|
|
@ -22,7 +22,6 @@ import {
|
|||
import {
|
||||
ManagementSetup,
|
||||
RegisterManagementAppArgs,
|
||||
ManagementSectionId,
|
||||
} from '../../../../../../../src/plugins/management/public';
|
||||
import { LicensingPluginSetup } from '../../../../../licensing/public';
|
||||
import { BeatsManagementConfigType } from '../../../../common';
|
||||
|
@ -105,7 +104,7 @@ export class KibanaFrameworkAdapter implements FrameworkAdapter {
|
|||
}
|
||||
|
||||
public registerManagementUI(mount: RegisterManagementAppArgs['mount']) {
|
||||
const section = this.management.sections.getSection(ManagementSectionId.Ingest);
|
||||
const section = this.management.sections.section.ingest;
|
||||
section.registerApp({
|
||||
id: 'beats_management',
|
||||
title: i18n.translate('xpack.beatsManagement.centralManagementLinkLabel', {
|
||||
|
|
|
@ -9,7 +9,6 @@ import { get } from 'lodash';
|
|||
import { first } from 'rxjs/operators';
|
||||
import { CoreSetup, Plugin, PluginInitializerContext } from 'src/core/public';
|
||||
|
||||
import { ManagementSectionId } from '../../../../src/plugins/management/public';
|
||||
import { PLUGIN, MANAGEMENT_ID } from '../common/constants';
|
||||
import { init as initUiMetric } from './app/services/track_ui_metric';
|
||||
import { init as initNotification } from './app/services/notifications';
|
||||
|
@ -23,7 +22,7 @@ export class CrossClusterReplicationPlugin implements Plugin {
|
|||
|
||||
public setup(coreSetup: CoreSetup, plugins: PluginDependencies) {
|
||||
const { licensing, remoteClusters, usageCollection, management, indexManagement } = plugins;
|
||||
const esSection = management.sections.getSection(ManagementSectionId.Data);
|
||||
const esSection = management.sections.section.data;
|
||||
|
||||
const {
|
||||
http,
|
||||
|
|
|
@ -6,7 +6,6 @@
|
|||
|
||||
import { CoreSetup, PluginInitializerContext } from 'src/core/public';
|
||||
|
||||
import { ManagementSectionId } from '../../../../src/plugins/management/public';
|
||||
import { PLUGIN } from '../common/constants';
|
||||
import { init as initHttp } from './application/services/http';
|
||||
import { init as initDocumentation } from './application/services/documentation';
|
||||
|
@ -38,7 +37,7 @@ export class IndexLifecycleManagementPlugin {
|
|||
initUiMetric(usageCollection);
|
||||
initNotification(toasts, fatalErrors);
|
||||
|
||||
management.sections.getSection(ManagementSectionId.Data).registerApp({
|
||||
management.sections.section.data.registerApp({
|
||||
id: PLUGIN.ID,
|
||||
title: PLUGIN.TITLE,
|
||||
order: 2,
|
||||
|
|
|
@ -7,7 +7,7 @@ import { i18n } from '@kbn/i18n';
|
|||
|
||||
import { CoreSetup } from '../../../../src/core/public';
|
||||
import { UsageCollectionSetup } from '../../../../src/plugins/usage_collection/public';
|
||||
import { ManagementSetup, ManagementSectionId } from '../../../../src/plugins/management/public';
|
||||
import { ManagementSetup } from '../../../../src/plugins/management/public';
|
||||
|
||||
import { IngestManagerSetup } from '../../ingest_manager/public';
|
||||
import { UIM_APP_NAME, PLUGIN } from '../common/constants';
|
||||
|
@ -51,7 +51,7 @@ export class IndexMgmtUIPlugin {
|
|||
notificationService.setup(notifications);
|
||||
this.uiMetricService.setup(usageCollection);
|
||||
|
||||
management.sections.getSection(ManagementSectionId.Data).registerApp({
|
||||
management.sections.section.data.registerApp({
|
||||
id: PLUGIN.id,
|
||||
title: i18n.translate('xpack.idxMgmt.appTitle', { defaultMessage: 'Index Management' }),
|
||||
order: 0,
|
||||
|
|
|
@ -7,7 +7,6 @@
|
|||
import { i18n } from '@kbn/i18n';
|
||||
import { CoreSetup, Plugin } from 'src/core/public';
|
||||
|
||||
import { ManagementSectionId } from '../../../../src/plugins/management/public';
|
||||
import { PLUGIN_ID } from '../common/constants';
|
||||
import { uiMetricService, apiService } from './application/services';
|
||||
import { Dependencies } from './types';
|
||||
|
@ -21,7 +20,7 @@ export class IngestPipelinesPlugin implements Plugin {
|
|||
uiMetricService.setup(usageCollection);
|
||||
apiService.setup(http, uiMetricService);
|
||||
|
||||
management.sections.getSection(ManagementSectionId.Ingest).registerApp({
|
||||
management.sections.section.ingest.registerApp({
|
||||
id: PLUGIN_ID,
|
||||
order: 1,
|
||||
title: i18n.translate('xpack.ingestPipelines.appTitle', {
|
||||
|
|
|
@ -7,7 +7,7 @@ import { first } from 'rxjs/operators';
|
|||
import { CoreSetup, Plugin, PluginInitializerContext } from 'src/core/public';
|
||||
|
||||
import { TelemetryPluginStart } from '../../../../src/plugins/telemetry/public';
|
||||
import { ManagementSetup, ManagementSectionId } from '../../../../src/plugins/management/public';
|
||||
import { ManagementSetup } from '../../../../src/plugins/management/public';
|
||||
import { LicensingPluginSetup } from '../../../plugins/licensing/public';
|
||||
import { PLUGIN } from '../common/constants';
|
||||
import { ClientConfigType } from './types';
|
||||
|
@ -50,7 +50,7 @@ export class LicenseManagementUIPlugin
|
|||
const { getStartServices } = coreSetup;
|
||||
const { management, licensing } = plugins;
|
||||
|
||||
management.sections.getSection(ManagementSectionId.Stack).registerApp({
|
||||
management.sections.section.stack.registerApp({
|
||||
id: PLUGIN.id,
|
||||
title: PLUGIN.title,
|
||||
order: 0,
|
||||
|
|
|
@ -14,7 +14,7 @@ import {
|
|||
HomePublicPluginSetup,
|
||||
FeatureCatalogueCategory,
|
||||
} from '../../../../src/plugins/home/public';
|
||||
import { ManagementSetup, ManagementSectionId } from '../../../../src/plugins/management/public';
|
||||
import { ManagementSetup } from '../../../../src/plugins/management/public';
|
||||
import { LicensingPluginSetup } from '../../licensing/public';
|
||||
|
||||
// @ts-ignore
|
||||
|
@ -35,22 +35,20 @@ export class LogstashPlugin implements Plugin<void, void, SetupDeps> {
|
|||
map((license) => new LogstashLicenseService(license))
|
||||
);
|
||||
|
||||
const managementApp = plugins.management.sections
|
||||
.getSection(ManagementSectionId.Ingest)
|
||||
.registerApp({
|
||||
id: 'pipelines',
|
||||
title: i18n.translate('xpack.logstash.managementSection.pipelinesTitle', {
|
||||
defaultMessage: 'Logstash Pipelines',
|
||||
}),
|
||||
order: 1,
|
||||
mount: async (params) => {
|
||||
const [coreStart] = await core.getStartServices();
|
||||
const { renderApp } = await import('./application');
|
||||
const isMonitoringEnabled = 'monitoring' in plugins;
|
||||
const managementApp = plugins.management.sections.section.ingest.registerApp({
|
||||
id: 'pipelines',
|
||||
title: i18n.translate('xpack.logstash.managementSection.pipelinesTitle', {
|
||||
defaultMessage: 'Logstash Pipelines',
|
||||
}),
|
||||
order: 1,
|
||||
mount: async (params) => {
|
||||
const [coreStart] = await core.getStartServices();
|
||||
const { renderApp } = await import('./application');
|
||||
const isMonitoringEnabled = 'monitoring' in plugins;
|
||||
|
||||
return renderApp(coreStart, params, isMonitoringEnabled, logstashLicense$);
|
||||
},
|
||||
});
|
||||
return renderApp(coreStart, params, isMonitoringEnabled, logstashLicense$);
|
||||
},
|
||||
});
|
||||
|
||||
this.licenseSubscription = logstashLicense$.subscribe((license: any) => {
|
||||
if (license.enableLinks) {
|
||||
|
|
|
@ -30,7 +30,6 @@
|
|||
"esUiShared",
|
||||
"kibanaUtils",
|
||||
"kibanaReact",
|
||||
"management",
|
||||
"dashboard",
|
||||
"savedObjects"
|
||||
]
|
||||
|
|
|
@ -16,10 +16,7 @@ import { take } from 'rxjs/operators';
|
|||
import { CoreSetup } from 'kibana/public';
|
||||
import { MlStartDependencies, MlSetupDependencies } from '../../plugin';
|
||||
|
||||
import {
|
||||
ManagementAppMountParams,
|
||||
ManagementSectionId,
|
||||
} from '../../../../../../src/plugins/management/public';
|
||||
import { ManagementAppMountParams } from '../../../../../../src/plugins/management/public';
|
||||
import { PLUGIN_ID } from '../../../common/constants/app';
|
||||
import { MINIMUM_FULL_LICENSE } from '../../../common/license';
|
||||
|
||||
|
@ -34,7 +31,7 @@ export function initManagementSection(
|
|||
management !== undefined &&
|
||||
license.check(PLUGIN_ID, MINIMUM_FULL_LICENSE).state === 'valid'
|
||||
) {
|
||||
management.sections.getSection(ManagementSectionId.InsightsAndAlerting).registerApp({
|
||||
management.sections.section.insightsAndAlerting.registerApp({
|
||||
id: 'jobsListLink',
|
||||
title: i18n.translate('xpack.ml.management.jobsListTitle', {
|
||||
defaultMessage: 'Machine Learning Jobs',
|
||||
|
|
|
@ -7,7 +7,6 @@
|
|||
import { i18n } from '@kbn/i18n';
|
||||
import { CoreSetup, Plugin, CoreStart, PluginInitializerContext } from 'kibana/public';
|
||||
|
||||
import { ManagementSectionId } from '../../../../src/plugins/management/public';
|
||||
import { init as initBreadcrumbs } from './application/services/breadcrumb';
|
||||
import { init as initDocumentation } from './application/services/documentation';
|
||||
import { init as initHttp } from './application/services/http';
|
||||
|
@ -33,7 +32,7 @@ export class RemoteClustersUIPlugin
|
|||
} = this.initializerContext.config.get<ClientConfigType>();
|
||||
|
||||
if (isRemoteClustersUiEnabled) {
|
||||
const esSection = management.sections.getSection(ManagementSectionId.Data);
|
||||
const esSection = management.sections.section.data;
|
||||
|
||||
esSection.registerApp({
|
||||
id: 'remote_clusters',
|
||||
|
|
|
@ -23,7 +23,7 @@ import {
|
|||
FeatureCatalogueCategory,
|
||||
HomePublicPluginSetup,
|
||||
} from '../../../../src/plugins/home/public';
|
||||
import { ManagementSectionId, ManagementSetup } from '../../../../src/plugins/management/public';
|
||||
import { ManagementSetup } from '../../../../src/plugins/management/public';
|
||||
import { SharePluginSetup } from '../../../../src/plugins/share/public';
|
||||
import { LicensingPluginSetup } from '../../licensing/public';
|
||||
import { JobId, JobStatusBuckets, ReportingConfigType } from '../common/types';
|
||||
|
@ -115,8 +115,7 @@ export class ReportingPublicPlugin implements Plugin<void, void> {
|
|||
showOnHomePage: false,
|
||||
category: FeatureCatalogueCategory.ADMIN,
|
||||
});
|
||||
|
||||
management.sections.getSection(ManagementSectionId.InsightsAndAlerting).registerApp({
|
||||
management.sections.section.insightsAndAlerting.registerApp({
|
||||
id: 'reporting',
|
||||
title: this.title,
|
||||
order: 1,
|
||||
|
|
|
@ -16,7 +16,7 @@ import {
|
|||
FeatureCatalogueCategory,
|
||||
HomePublicPluginSetup,
|
||||
} from '../../../../src/plugins/home/public';
|
||||
import { ManagementSetup, ManagementSectionId } from '../../../../src/plugins/management/public';
|
||||
import { ManagementSetup } from '../../../../src/plugins/management/public';
|
||||
import { IndexManagementPluginSetup } from '../../index_management/public';
|
||||
import { IndexPatternManagementSetup } from '../../../../src/plugins/index_pattern_management/public';
|
||||
// @ts-ignore
|
||||
|
@ -75,7 +75,7 @@ export class RollupPlugin implements Plugin {
|
|||
});
|
||||
}
|
||||
|
||||
management.sections.getSection(ManagementSectionId.Data).registerApp({
|
||||
management.sections.section.data.registerApp({
|
||||
id: 'rollup_jobs',
|
||||
title: i18n.translate('xpack.rollupJobs.appTitle', { defaultMessage: 'Rollup Jobs' }),
|
||||
order: 4,
|
||||
|
|
|
@ -9,10 +9,8 @@
|
|||
"ui": true,
|
||||
"requiredBundles": [
|
||||
"home",
|
||||
"management",
|
||||
"kibanaReact",
|
||||
"spaces",
|
||||
"esUiShared",
|
||||
"management"
|
||||
"esUiShared"
|
||||
]
|
||||
}
|
||||
|
|
|
@ -8,8 +8,9 @@ import { BehaviorSubject } from 'rxjs';
|
|||
import {
|
||||
ManagementApp,
|
||||
ManagementSetup,
|
||||
ManagementStart,
|
||||
DefinedSections,
|
||||
} from '../../../../../src/plugins/management/public';
|
||||
import { createManagementSectionMock } from '../../../../../src/plugins/management/public/mocks';
|
||||
import { SecurityLicenseFeatures } from '../../common/licensing/license_features';
|
||||
import { ManagementService } from './management_service';
|
||||
import { usersManagementApp } from './users';
|
||||
|
@ -21,7 +22,7 @@ import { rolesManagementApp } from './roles';
|
|||
import { apiKeysManagementApp } from './api_keys';
|
||||
import { roleMappingsManagementApp } from './role_mappings';
|
||||
|
||||
const mockSection = { registerApp: jest.fn() };
|
||||
const mockSection = createManagementSectionMock();
|
||||
|
||||
describe('ManagementService', () => {
|
||||
describe('setup()', () => {
|
||||
|
@ -32,8 +33,10 @@ describe('ManagementService', () => {
|
|||
|
||||
const managementSetup: ManagementSetup = {
|
||||
sections: {
|
||||
register: jest.fn(),
|
||||
getSection: jest.fn().mockReturnValue(mockSection),
|
||||
register: jest.fn(() => mockSection),
|
||||
section: {
|
||||
security: mockSection,
|
||||
} as DefinedSections,
|
||||
},
|
||||
};
|
||||
|
||||
|
@ -88,8 +91,10 @@ describe('ManagementService', () => {
|
|||
|
||||
const managementSetup: ManagementSetup = {
|
||||
sections: {
|
||||
register: jest.fn(),
|
||||
getSection: jest.fn().mockReturnValue(mockSection),
|
||||
register: jest.fn(() => mockSection),
|
||||
section: {
|
||||
security: mockSection,
|
||||
} as DefinedSections,
|
||||
},
|
||||
};
|
||||
|
||||
|
@ -116,6 +121,7 @@ describe('ManagementService', () => {
|
|||
}),
|
||||
} as unknown) as jest.Mocked<ManagementApp>;
|
||||
};
|
||||
mockSection.getApp = jest.fn().mockImplementation((id) => mockApps.get(id));
|
||||
const mockApps = new Map<string, jest.Mocked<ManagementApp>>([
|
||||
[usersManagementApp.id, getMockedApp()],
|
||||
[rolesManagementApp.id, getMockedApp()],
|
||||
|
@ -123,19 +129,7 @@ describe('ManagementService', () => {
|
|||
[roleMappingsManagementApp.id, getMockedApp()],
|
||||
] as Array<[string, jest.Mocked<ManagementApp>]>);
|
||||
|
||||
const managementStart: ManagementStart = {
|
||||
sections: {
|
||||
getSection: jest
|
||||
.fn()
|
||||
.mockReturnValue({ getApp: jest.fn().mockImplementation((id) => mockApps.get(id)) }),
|
||||
getAllSections: jest.fn(),
|
||||
getSectionsEnabled: jest.fn(),
|
||||
},
|
||||
};
|
||||
|
||||
service.start({
|
||||
management: managementStart,
|
||||
});
|
||||
service.start();
|
||||
|
||||
return {
|
||||
mockApps,
|
||||
|
|
|
@ -9,8 +9,7 @@ import { StartServicesAccessor, FatalErrorsSetup } from 'src/core/public';
|
|||
import {
|
||||
ManagementApp,
|
||||
ManagementSetup,
|
||||
ManagementStart,
|
||||
ManagementSectionId,
|
||||
ManagementSection,
|
||||
} from '../../../../../src/plugins/management/public';
|
||||
import { SecurityLicense } from '../../common/licensing';
|
||||
import { AuthenticationServiceSetup } from '../authentication';
|
||||
|
@ -28,30 +27,26 @@ interface SetupParams {
|
|||
getStartServices: StartServicesAccessor<PluginStartDependencies>;
|
||||
}
|
||||
|
||||
interface StartParams {
|
||||
management: ManagementStart;
|
||||
}
|
||||
|
||||
export class ManagementService {
|
||||
private license!: SecurityLicense;
|
||||
private licenseFeaturesSubscription?: Subscription;
|
||||
private securitySection?: ManagementSection;
|
||||
|
||||
setup({ getStartServices, management, authc, license, fatalErrors }: SetupParams) {
|
||||
this.license = license;
|
||||
this.securitySection = management.sections.section.security;
|
||||
|
||||
const securitySection = management.sections.getSection(ManagementSectionId.Security);
|
||||
|
||||
securitySection.registerApp(usersManagementApp.create({ authc, getStartServices }));
|
||||
securitySection.registerApp(
|
||||
this.securitySection.registerApp(usersManagementApp.create({ authc, getStartServices }));
|
||||
this.securitySection.registerApp(
|
||||
rolesManagementApp.create({ fatalErrors, license, getStartServices })
|
||||
);
|
||||
securitySection.registerApp(apiKeysManagementApp.create({ getStartServices }));
|
||||
securitySection.registerApp(roleMappingsManagementApp.create({ getStartServices }));
|
||||
this.securitySection.registerApp(apiKeysManagementApp.create({ getStartServices }));
|
||||
this.securitySection.registerApp(roleMappingsManagementApp.create({ getStartServices }));
|
||||
}
|
||||
|
||||
start({ management }: StartParams) {
|
||||
start() {
|
||||
this.licenseFeaturesSubscription = this.license.features$.subscribe(async (features) => {
|
||||
const securitySection = management.sections.getSection(ManagementSectionId.Security);
|
||||
const securitySection = this.securitySection!;
|
||||
|
||||
const securityManagementAppsStatuses: Array<[ManagementApp, boolean]> = [
|
||||
[securitySection.getApp(usersManagementApp.id)!, features.showLinks],
|
||||
|
|
|
@ -33,7 +33,9 @@ describe('Security Plugin', () => {
|
|||
coreMock.createSetup({ basePath: '/some-base-path' }) as CoreSetup<
|
||||
PluginStartDependencies
|
||||
>,
|
||||
{ licensing: licensingMock.createSetup() }
|
||||
{
|
||||
licensing: licensingMock.createSetup(),
|
||||
}
|
||||
)
|
||||
).toEqual({
|
||||
__legacyCompat: { logoutUrl: '/some-base-path/logout', tenant: '/some-base-path' },
|
||||
|
@ -117,7 +119,6 @@ describe('Security Plugin', () => {
|
|||
});
|
||||
|
||||
expect(startManagementServiceMock).toHaveBeenCalledTimes(1);
|
||||
expect(startManagementServiceMock).toHaveBeenCalledWith({ management: managementStartMock });
|
||||
});
|
||||
});
|
||||
|
||||
|
|
|
@ -139,9 +139,8 @@ export class SecurityPlugin
|
|||
public start(core: CoreStart, { management }: PluginStartDependencies) {
|
||||
this.sessionTimeout.start();
|
||||
this.navControlService.start({ core });
|
||||
|
||||
if (management) {
|
||||
this.managementService.start({ management });
|
||||
this.managementService.start();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -7,7 +7,7 @@ import { i18n } from '@kbn/i18n';
|
|||
import { CoreSetup, PluginInitializerContext } from 'src/core/public';
|
||||
|
||||
import { UsageCollectionSetup } from '../../../../src/plugins/usage_collection/public';
|
||||
import { ManagementSetup, ManagementSectionId } from '../../../../src/plugins/management/public';
|
||||
import { ManagementSetup } from '../../../../src/plugins/management/public';
|
||||
import { PLUGIN } from '../common/constants';
|
||||
|
||||
import { ClientConfigType } from './types';
|
||||
|
@ -40,7 +40,7 @@ export class SnapshotRestoreUIPlugin {
|
|||
textService.setup(i18n);
|
||||
httpService.setup(http);
|
||||
|
||||
management.sections.getSection(ManagementSectionId.Data).registerApp({
|
||||
management.sections.section.data.registerApp({
|
||||
id: PLUGIN.id,
|
||||
title: i18n.translate('xpack.snapshotRestore.appTitle', {
|
||||
defaultMessage: 'Snapshot and Restore',
|
||||
|
|
|
@ -18,7 +18,6 @@
|
|||
"requiredBundles": [
|
||||
"kibanaReact",
|
||||
"savedObjectsManagement",
|
||||
"management",
|
||||
"home"
|
||||
]
|
||||
}
|
||||
|
|
|
@ -18,22 +18,19 @@ describe('ManagementService', () => {
|
|||
const mockKibanaSection = ({
|
||||
registerApp: jest.fn(),
|
||||
} as unknown) as ManagementSection;
|
||||
const managementMockSetup = managementPluginMock.createSetupContract();
|
||||
managementMockSetup.sections.section.kibana = mockKibanaSection;
|
||||
const deps = {
|
||||
management: managementPluginMock.createSetupContract(),
|
||||
management: managementMockSetup,
|
||||
getStartServices: coreMock.createSetup().getStartServices as CoreSetup<
|
||||
PluginsStart
|
||||
>['getStartServices'],
|
||||
spacesManager: spacesManagerMock.create(),
|
||||
};
|
||||
|
||||
deps.management.sections.getSection.mockReturnValue(mockKibanaSection);
|
||||
|
||||
const service = new ManagementService();
|
||||
service.setup(deps);
|
||||
|
||||
expect(deps.management.sections.getSection).toHaveBeenCalledTimes(1);
|
||||
expect(deps.management.sections.getSection).toHaveBeenCalledWith('kibana');
|
||||
|
||||
expect(mockKibanaSection.registerApp).toHaveBeenCalledTimes(1);
|
||||
expect(mockKibanaSection.registerApp).toHaveBeenCalledWith({
|
||||
id: 'spaces',
|
||||
|
@ -63,20 +60,17 @@ describe('ManagementService', () => {
|
|||
const mockKibanaSection = ({
|
||||
registerApp: jest.fn().mockReturnValue(mockSpacesManagementPage),
|
||||
} as unknown) as ManagementSection;
|
||||
const managementMockSetup = managementPluginMock.createSetupContract();
|
||||
managementMockSetup.sections.section.kibana = mockKibanaSection;
|
||||
|
||||
const deps = {
|
||||
management: managementPluginMock.createSetupContract(),
|
||||
management: managementMockSetup,
|
||||
getStartServices: coreMock.createSetup().getStartServices as CoreSetup<
|
||||
PluginsStart
|
||||
>['getStartServices'],
|
||||
spacesManager: spacesManagerMock.create(),
|
||||
};
|
||||
|
||||
deps.management.sections.getSection.mockImplementation((id) => {
|
||||
if (id === 'kibana') return mockKibanaSection;
|
||||
throw new Error(`unexpected getSection call: ${id}`);
|
||||
});
|
||||
|
||||
const service = new ManagementService();
|
||||
service.setup(deps);
|
||||
|
||||
|
|
|
@ -5,11 +5,7 @@
|
|||
*/
|
||||
|
||||
import { StartServicesAccessor } from 'src/core/public';
|
||||
import {
|
||||
ManagementSetup,
|
||||
ManagementApp,
|
||||
ManagementSectionId,
|
||||
} from '../../../../../src/plugins/management/public';
|
||||
import { ManagementSetup, ManagementApp } from '../../../../../src/plugins/management/public';
|
||||
import { SecurityLicense } from '../../../security/public';
|
||||
import { SpacesManager } from '../spaces_manager';
|
||||
import { PluginsStart } from '../plugin';
|
||||
|
@ -26,11 +22,9 @@ export class ManagementService {
|
|||
private registeredSpacesManagementApp?: ManagementApp;
|
||||
|
||||
public setup({ getStartServices, management, spacesManager, securityLicense }: SetupDeps) {
|
||||
this.registeredSpacesManagementApp = management.sections
|
||||
.getSection(ManagementSectionId.Kibana)
|
||||
.registerApp(
|
||||
spacesManagementApp.create({ getStartServices, spacesManager, securityLicense })
|
||||
);
|
||||
this.registeredSpacesManagementApp = management.sections.section.kibana.registerApp(
|
||||
spacesManagementApp.create({ getStartServices, spacesManager, securityLicense })
|
||||
);
|
||||
}
|
||||
|
||||
public stop() {
|
||||
|
|
|
@ -7,8 +7,10 @@
|
|||
import { coreMock } from 'src/core/public/mocks';
|
||||
import { SpacesPlugin } from './plugin';
|
||||
import { homePluginMock } from '../../../../src/plugins/home/public/mocks';
|
||||
import { ManagementSection, ManagementSectionId } from '../../../../src/plugins/management/public';
|
||||
import { managementPluginMock } from '../../../../src/plugins/management/public/mocks';
|
||||
import {
|
||||
managementPluginMock,
|
||||
createManagementSectionMock,
|
||||
} from '../../../../src/plugins/management/public/mocks';
|
||||
import { advancedSettingsMock } from '../../../../src/plugins/advanced_settings/public/mocks';
|
||||
import { featuresPluginMock } from '../../features/public/mocks';
|
||||
|
||||
|
@ -32,19 +34,13 @@ describe('Spaces plugin', () => {
|
|||
|
||||
it('should register the management and feature catalogue sections when the management and home plugins are both available', () => {
|
||||
const coreSetup = coreMock.createSetup();
|
||||
|
||||
const kibanaSection = new ManagementSection({
|
||||
id: ManagementSectionId.Kibana,
|
||||
title: 'Mock Kibana Section',
|
||||
order: 1,
|
||||
});
|
||||
|
||||
const registerAppSpy = jest.spyOn(kibanaSection, 'registerApp');
|
||||
|
||||
const home = homePluginMock.createSetupContract();
|
||||
|
||||
const management = managementPluginMock.createSetupContract();
|
||||
management.sections.getSection.mockReturnValue(kibanaSection);
|
||||
const mockSection = createManagementSectionMock();
|
||||
mockSection.registerApp = jest.fn();
|
||||
|
||||
management.sections.section.kibana = mockSection;
|
||||
|
||||
const plugin = new SpacesPlugin();
|
||||
plugin.setup(coreSetup, {
|
||||
|
@ -52,7 +48,9 @@ describe('Spaces plugin', () => {
|
|||
home,
|
||||
});
|
||||
|
||||
expect(registerAppSpy).toHaveBeenCalledWith(expect.objectContaining({ id: 'spaces' }));
|
||||
expect(mockSection.registerApp).toHaveBeenCalledWith(
|
||||
expect.objectContaining({ id: 'spaces' })
|
||||
);
|
||||
|
||||
expect(home.featureCatalogue.register).toHaveBeenCalledWith(
|
||||
expect.objectContaining({
|
||||
|
|
|
@ -8,7 +8,7 @@ import { i18n as kbnI18n } from '@kbn/i18n';
|
|||
import { CoreSetup } from 'src/core/public';
|
||||
import { DataPublicPluginStart } from 'src/plugins/data/public';
|
||||
import { HomePublicPluginSetup } from 'src/plugins/home/public';
|
||||
import { ManagementSetup, ManagementSectionId } from '../../../../src/plugins/management/public';
|
||||
import { ManagementSetup } from '../../../../src/plugins/management/public';
|
||||
import { registerFeature } from './register_feature';
|
||||
|
||||
export interface PluginsDependencies {
|
||||
|
@ -22,7 +22,7 @@ export class TransformUiPlugin {
|
|||
const { management, home } = pluginsSetup;
|
||||
|
||||
// Register management section
|
||||
const esSection = management.sections.getSection(ManagementSectionId.Data);
|
||||
const esSection = management.sections.section.data;
|
||||
esSection.registerApp({
|
||||
id: 'transform',
|
||||
title: kbnI18n.translate('xpack.transform.appTitle', {
|
||||
|
|
|
@ -4,7 +4,12 @@
|
|||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
|
||||
import { CoreStart, PluginInitializerContext, Plugin as CorePlugin } from 'src/core/public';
|
||||
import {
|
||||
CoreStart,
|
||||
CoreSetup,
|
||||
PluginInitializerContext,
|
||||
Plugin as CorePlugin,
|
||||
} from 'src/core/public';
|
||||
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import { registerBuiltInActionTypes } from './application/components/builtin_action_types';
|
||||
|
@ -12,7 +17,11 @@ import { registerBuiltInAlertTypes } from './application/components/builtin_aler
|
|||
import { hasShowActionsCapability, hasShowAlertsCapability } from './application/lib/capabilities';
|
||||
import { ActionTypeModel, AlertTypeModel } from './types';
|
||||
import { TypeRegistry } from './application/type_registry';
|
||||
import { ManagementStart, ManagementSectionId } from '../../../../src/plugins/management/public';
|
||||
import {
|
||||
ManagementSetup,
|
||||
ManagementAppMountParams,
|
||||
ManagementApp,
|
||||
} from '../../../../src/plugins/management/public';
|
||||
import { boot } from './application/boot';
|
||||
import { ChartsPluginStart } from '../../../../src/plugins/charts/public';
|
||||
import { PluginStartContract as AlertingStart } from '../../alerts/public';
|
||||
|
@ -28,10 +37,13 @@ export interface TriggersAndActionsUIPublicPluginStart {
|
|||
alertTypeRegistry: TypeRegistry<AlertTypeModel>;
|
||||
}
|
||||
|
||||
interface PluginsSetup {
|
||||
management: ManagementSetup;
|
||||
}
|
||||
|
||||
interface PluginsStart {
|
||||
data: DataPublicPluginStart;
|
||||
charts: ChartsPluginStart;
|
||||
management: ManagementStart;
|
||||
alerts?: AlertingStart;
|
||||
navigateToApp: CoreStart['application']['navigateToApp'];
|
||||
}
|
||||
|
@ -41,6 +53,7 @@ export class Plugin
|
|||
CorePlugin<TriggersAndActionsUIPublicPluginSetup, TriggersAndActionsUIPublicPluginStart> {
|
||||
private actionTypeRegistry: TypeRegistry<ActionTypeModel>;
|
||||
private alertTypeRegistry: TypeRegistry<AlertTypeModel>;
|
||||
private managementApp?: ManagementApp;
|
||||
|
||||
constructor(initializerContext: PluginInitializerContext) {
|
||||
const actionTypeRegistry = new TypeRegistry<ActionTypeModel>();
|
||||
|
@ -50,7 +63,45 @@ export class Plugin
|
|||
this.alertTypeRegistry = alertTypeRegistry;
|
||||
}
|
||||
|
||||
public setup(): TriggersAndActionsUIPublicPluginSetup {
|
||||
public setup(core: CoreSetup, plugins: PluginsSetup): TriggersAndActionsUIPublicPluginSetup {
|
||||
const actionTypeRegistry = this.actionTypeRegistry;
|
||||
const alertTypeRegistry = this.alertTypeRegistry;
|
||||
|
||||
this.managementApp = plugins.management.sections.section.insightsAndAlerting.registerApp({
|
||||
id: 'triggersActions',
|
||||
title: i18n.translate('xpack.triggersActionsUI.managementSection.displayName', {
|
||||
defaultMessage: 'Alerts and Actions',
|
||||
}),
|
||||
order: 0,
|
||||
async mount(params: ManagementAppMountParams) {
|
||||
const [coreStart, pluginsStart] = (await core.getStartServices()) as [
|
||||
CoreStart,
|
||||
PluginsStart,
|
||||
unknown
|
||||
];
|
||||
boot({
|
||||
dataPlugin: pluginsStart.data,
|
||||
charts: pluginsStart.charts,
|
||||
alerts: pluginsStart.alerts,
|
||||
element: params.element,
|
||||
toastNotifications: coreStart.notifications.toasts,
|
||||
http: coreStart.http,
|
||||
uiSettings: coreStart.uiSettings,
|
||||
docLinks: coreStart.docLinks,
|
||||
chrome: coreStart.chrome,
|
||||
savedObjects: coreStart.savedObjects.client,
|
||||
I18nContext: coreStart.i18n.Context,
|
||||
capabilities: coreStart.application.capabilities,
|
||||
navigateToApp: coreStart.application.navigateToApp,
|
||||
setBreadcrumbs: params.setBreadcrumbs,
|
||||
history: params.history,
|
||||
actionTypeRegistry,
|
||||
alertTypeRegistry,
|
||||
});
|
||||
return () => {};
|
||||
},
|
||||
});
|
||||
|
||||
registerBuiltInActionTypes({
|
||||
actionTypeRegistry: this.actionTypeRegistry,
|
||||
});
|
||||
|
@ -65,43 +116,18 @@ export class Plugin
|
|||
};
|
||||
}
|
||||
|
||||
public start(core: CoreStart, plugins: PluginsStart): TriggersAndActionsUIPublicPluginStart {
|
||||
public start(core: CoreStart): TriggersAndActionsUIPublicPluginStart {
|
||||
const { capabilities } = core.application;
|
||||
|
||||
const canShowActions = hasShowActionsCapability(capabilities);
|
||||
const canShowAlerts = hasShowAlertsCapability(capabilities);
|
||||
const managementApp = this.managementApp as ManagementApp;
|
||||
|
||||
// Don't register routes when user doesn't have access to the application
|
||||
if (canShowActions || canShowAlerts) {
|
||||
plugins.management.sections.getSection(ManagementSectionId.InsightsAndAlerting).registerApp({
|
||||
id: 'triggersActions',
|
||||
title: i18n.translate('xpack.triggersActionsUI.managementSection.displayName', {
|
||||
defaultMessage: 'Alerts and Actions',
|
||||
}),
|
||||
order: 0,
|
||||
mount: (params) => {
|
||||
boot({
|
||||
dataPlugin: plugins.data,
|
||||
charts: plugins.charts,
|
||||
alerts: plugins.alerts,
|
||||
element: params.element,
|
||||
toastNotifications: core.notifications.toasts,
|
||||
http: core.http,
|
||||
uiSettings: core.uiSettings,
|
||||
docLinks: core.docLinks,
|
||||
chrome: core.chrome,
|
||||
savedObjects: core.savedObjects.client,
|
||||
I18nContext: core.i18n.Context,
|
||||
capabilities: core.application.capabilities,
|
||||
navigateToApp: core.application.navigateToApp,
|
||||
setBreadcrumbs: params.setBreadcrumbs,
|
||||
history: params.history,
|
||||
actionTypeRegistry: this.actionTypeRegistry,
|
||||
alertTypeRegistry: this.alertTypeRegistry,
|
||||
});
|
||||
return () => {};
|
||||
},
|
||||
});
|
||||
managementApp.enable();
|
||||
} else {
|
||||
managementApp.disable();
|
||||
}
|
||||
return {
|
||||
actionTypeRegistry: this.actionTypeRegistry,
|
||||
|
|
|
@ -5,6 +5,5 @@
|
|||
"ui": true,
|
||||
"configPath": ["xpack", "upgrade_assistant"],
|
||||
"requiredPlugins": ["management", "licensing", "apmOss"],
|
||||
"optionalPlugins": ["cloud", "usageCollection"],
|
||||
"requiredBundles": ["management"]
|
||||
"optionalPlugins": ["cloud", "usageCollection"]
|
||||
}
|
||||
|
|
|
@ -7,7 +7,7 @@ import { i18n } from '@kbn/i18n';
|
|||
import { Plugin, CoreSetup, PluginInitializerContext } from 'src/core/public';
|
||||
|
||||
import { CloudSetup } from '../../cloud/public';
|
||||
import { ManagementSetup, ManagementSectionId } from '../../../../src/plugins/management/public';
|
||||
import { ManagementSetup } from '../../../../src/plugins/management/public';
|
||||
|
||||
import { NEXT_MAJOR_VERSION } from '../common/version';
|
||||
import { Config } from '../common/config';
|
||||
|
@ -24,7 +24,7 @@ export class UpgradeAssistantUIPlugin implements Plugin {
|
|||
if (!enabled) {
|
||||
return;
|
||||
}
|
||||
const appRegistrar = management.sections.getSection(ManagementSectionId.Stack);
|
||||
const appRegistrar = management.sections.section.stack;
|
||||
const isCloudEnabled = Boolean(cloud?.isCloudEnabled);
|
||||
|
||||
appRegistrar.registerApp({
|
||||
|
|
|
@ -7,7 +7,6 @@ import { i18n } from '@kbn/i18n';
|
|||
import { CoreSetup, Plugin, CoreStart } from 'kibana/public';
|
||||
import { first, map, skip } from 'rxjs/operators';
|
||||
|
||||
import { ManagementSectionId } from '../../../../src/plugins/management/public';
|
||||
import { FeatureCatalogueCategory } from '../../../../src/plugins/home/public';
|
||||
|
||||
import { LicenseStatus } from '../common/types/license_status';
|
||||
|
@ -29,7 +28,7 @@ export class WatcherUIPlugin implements Plugin<void, void, Dependencies, any> {
|
|||
{ notifications, http, uiSettings, getStartServices }: CoreSetup,
|
||||
{ licensing, management, data, home, charts }: Dependencies
|
||||
) {
|
||||
const esSection = management.sections.getSection(ManagementSectionId.InsightsAndAlerting);
|
||||
const esSection = management.sections.section.insightsAndAlerting;
|
||||
|
||||
const watcherESApp = esSection.registerApp({
|
||||
id: 'watcher',
|
||||
|
|
Loading…
Reference in a new issue