Advanced settings component registry ⇒ kibana platform plugin (#55940) (#56808)

* advanced settings component registry to new platform
This commit is contained in:
Matthew Kime 2020-02-04 18:07:23 -06:00 committed by GitHub
parent f48c339f3f
commit 2b26a3950b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
41 changed files with 399 additions and 297 deletions

View file

@ -26,6 +26,7 @@
"src/legacy/core_plugins/management",
"src/plugins/management"
],
"advancedSettings": "src/plugins/advanced_settings",
"kibana_react": "src/legacy/core_plugins/kibana_react",
"kibana-react": "src/plugins/kibana_react",
"kibana_utils": "src/plugins/kibana_utils",

View file

@ -6,7 +6,7 @@ exports[`AdvancedSettings should render read-only when saving is disabled 1`] =
gutterSize="none"
>
<EuiFlexItem>
<advanced_settings_page_title />
<foo_component />
</EuiFlexItem>
<EuiFlexItem>
<Search
@ -57,7 +57,7 @@ exports[`AdvancedSettings should render read-only when saving is disabled 1`] =
/>
</EuiFlexItem>
</EuiFlexGroup>
<advanced_settings_page_subtitle />
<foo_component />
<EuiSpacer
size="m"
/>
@ -139,7 +139,7 @@ exports[`AdvancedSettings should render read-only when saving is disabled 1`] =
}
showNoResultsMessage={true}
/>
<advanced_settings_page_footer
<foo_component
enableSaving={false}
onQueryMatchChange={[Function]}
query={
@ -189,7 +189,7 @@ exports[`AdvancedSettings should render specific setting if given setting key 1`
gutterSize="none"
>
<EuiFlexItem>
<advanced_settings_page_title />
<foo_component />
</EuiFlexItem>
<EuiFlexItem>
<Search
@ -240,7 +240,7 @@ exports[`AdvancedSettings should render specific setting if given setting key 1`
/>
</EuiFlexItem>
</EuiFlexGroup>
<advanced_settings_page_subtitle />
<foo_component />
<EuiSpacer
size="m"
/>
@ -322,7 +322,7 @@ exports[`AdvancedSettings should render specific setting if given setting key 1`
}
showNoResultsMessage={true}
/>
<advanced_settings_page_footer
<foo_component
enableSaving={true}
onQueryMatchChange={[Function]}
query={

View file

@ -27,7 +27,9 @@ import {
UiSettingsType,
} from '../../../../../../../core/public';
import { FieldSetting } from './types';
import { AdvancedSettings } from './advanced_settings';
jest.mock('ui/new_platform');
jest.mock('ui/new_platform', () => ({
npStart: mockConfig(),
@ -215,6 +217,22 @@ function mockConfig() {
core: {
uiSettings: config,
},
plugins: {
advancedSettings: {
component: {
register: jest.fn(),
get: () => {
const foo: React.ComponentType = () => <div>Hello</div>;
foo.displayName = 'foo_component';
return foo;
},
componentType: {
PAGE_TITLE_COMPONENT: 'page_title_component',
PAGE_SUBTITLE_COMPONENT: 'page_subtitle_component',
},
},
},
},
};
}

View file

@ -31,14 +31,6 @@ import { getAriaName, toEditableConfig, DEFAULT_CATEGORY } from './lib';
import { FieldSetting, IQuery } from './types';
import {
registerDefaultComponents,
PAGE_TITLE_COMPONENT,
PAGE_SUBTITLE_COMPONENT,
PAGE_FOOTER_COMPONENT,
} from './components/default_component_registry';
import { getSettingsComponent } from './components/component_registry';
interface AdvancedSettingsProps {
queryText: string;
enableSaving: boolean;
@ -75,8 +67,6 @@ export class AdvancedSettings extends Component<AdvancedSettingsProps, AdvancedS
footerQueryMatched: false,
filteredSettings: this.mapSettings(Query.execute(parsedQuery, this.settings)),
};
registerDefaultComponents();
}
init(config: IUiSettingsClient) {
@ -166,10 +156,13 @@ export class AdvancedSettings extends Component<AdvancedSettingsProps, AdvancedS
render() {
const { filteredSettings, query, footerQueryMatched } = this.state;
const componentRegistry = npStart.plugins.advancedSettings.component;
const PageTitle = getSettingsComponent(PAGE_TITLE_COMPONENT);
const PageSubtitle = getSettingsComponent(PAGE_SUBTITLE_COMPONENT);
const PageFooter = getSettingsComponent(PAGE_FOOTER_COMPONENT);
const PageTitle = componentRegistry.get(componentRegistry.componentType.PAGE_TITLE_COMPONENT);
const PageSubtitle = componentRegistry.get(
componentRegistry.componentType.PAGE_SUBTITLE_COMPONENT
);
const PageFooter = componentRegistry.get(componentRegistry.componentType.PAGE_FOOTER_COMPONENT);
return (
<div>

View file

@ -1,5 +0,0 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`getSettingsComponent should throw an error when requesting a component that does not exist 1`] = `"Component not found with id does not exist"`;
exports[`registerSettingsComponent should disallow registering a component with a duplicate id 1`] = `"Component with id test2 is already registered."`;

View file

@ -1,82 +0,0 @@
/*
* 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 React, { FunctionComponent } from 'react';
import {
tryRegisterSettingsComponent,
registerSettingsComponent,
getSettingsComponent,
} from './component_registry';
describe('tryRegisterSettingsComponent', () => {
it('should allow a component to be registered', () => {
const component = () => <div />;
expect(tryRegisterSettingsComponent('tryTest1', component)).toEqual(true);
});
it('should return false if the component is already registered, and not allow an override', () => {
const component = () => <div />;
expect(tryRegisterSettingsComponent('tryTest2', component)).toEqual(true);
const updatedComponent = () => <div />;
expect(tryRegisterSettingsComponent('tryTest2', updatedComponent)).toEqual(false);
expect(getSettingsComponent('tryTest2')).toBe(component);
});
});
describe('registerSettingsComponent', () => {
it('should allow a component to be registered', () => {
const component = () => <div />;
registerSettingsComponent('test', component);
});
it('should disallow registering a component with a duplicate id', () => {
const component = () => <div />;
registerSettingsComponent('test2', component);
expect(() => registerSettingsComponent('test2', () => <span />)).toThrowErrorMatchingSnapshot();
});
it('should allow a component to be overriden', () => {
const component = () => <div />;
registerSettingsComponent('test3', component);
const anotherComponent = () => <span />;
registerSettingsComponent('test3', anotherComponent, true);
expect(getSettingsComponent('test3')).toBe(anotherComponent);
});
it('should set a displayName for the component', () => {
const component = () => <div />;
registerSettingsComponent('display_name_component', component);
expect((component as FunctionComponent).displayName).toEqual('display_name_component');
});
});
describe('getSettingsComponent', () => {
it('should allow a component to be retrieved', () => {
const component = () => <div />;
registerSettingsComponent('test4', component);
expect(getSettingsComponent('test4')).toBe(component);
});
it('should throw an error when requesting a component that does not exist', () => {
expect(() => getSettingsComponent('does not exist')).toThrowErrorMatchingSnapshot();
});
});

View file

@ -1,83 +0,0 @@
/*
* 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 { ComponentType } from 'react';
type Id = string;
const registry: Record<Id, ComponentType<Record<string, any> | undefined>> = {};
/**
* Attempts to register the provided component.
* If a component with that ID is already registered, then the registration fails.
*
* @param {*} id the id of the component to register
* @param {*} component the component
*/
export function tryRegisterSettingsComponent(
id: Id,
component: ComponentType<Record<string, any> | undefined>
) {
if (id in registry) {
return false;
}
registerSettingsComponent(id, component);
return true;
}
/**
* Attempts to register the provided component, with the ability to optionally allow
* the component to override an existing one.
*
* If the intent is to override, then `allowOverride` must be set to true, otherwise an exception is thrown.
*
* @param {*} id the id of the component to register
* @param {*} component the component
* @param {*} allowOverride (default: false) - optional flag to allow this component to override a previously registered component
*/
export function registerSettingsComponent(
id: Id,
component: ComponentType<Record<string, any> | undefined>,
allowOverride = false
) {
if (!allowOverride && id in registry) {
throw new Error(`Component with id ${id} is already registered.`);
}
// Setting a display name if one does not already exist.
// This enhances the snapshots, as well as the debugging experience.
if (!component.displayName) {
component.displayName = id;
}
registry[id] = component;
}
/**
* Retrieve a registered component by its ID.
* If the component does not exist, then an exception is thrown.
*
* @param {*} id the ID of the component to retrieve
*/
export function getSettingsComponent(id: Id): ComponentType<Record<string, any> | undefined> {
if (!(id in registry)) {
throw new Error(`Component not found with id ${id}`);
}
return registry[id];
}

View file

@ -1,44 +0,0 @@
/*
* 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 React from 'react';
import { registerDefaultComponents, PAGE_TITLE_COMPONENT } from './default_component_registry';
import { getSettingsComponent, registerSettingsComponent } from './component_registry';
import { PageTitle } from './page_title';
describe('default_component_registry', () => {
it('should register default components with the registry', () => {
registerDefaultComponents();
expect(getSettingsComponent(PAGE_TITLE_COMPONENT)).toEqual(PageTitle);
});
it('should be able to call "registerDefaultComponents" several times without throwing', () => {
registerDefaultComponents();
registerDefaultComponents();
registerDefaultComponents();
});
it('should not override components if they are already registered', () => {
const newComponent = () => <div />;
registerSettingsComponent(PAGE_TITLE_COMPONENT, newComponent, true);
registerDefaultComponents();
expect(getSettingsComponent(PAGE_TITLE_COMPONENT)).toEqual(newComponent);
});
});

View file

@ -19,7 +19,7 @@
import React from 'react';
import routes from 'ui/routes';
import { registerSettingsComponent, PAGE_FOOTER_COMPONENT } from 'ui/management';
import { npSetup } from 'ui/new_platform';
import { TelemetryOptInProvider } from '../../services';
import { TelemetryForm } from '../../components';
@ -27,6 +27,7 @@ routes.defaults(/\/management/, {
resolve: {
telemetryManagementSection: function(Private) {
const telemetryOptInProvider = Private(TelemetryOptInProvider);
const componentRegistry = npSetup.plugins.advancedSettings.component;
const Component = props => (
<TelemetryForm
@ -36,7 +37,11 @@ routes.defaults(/\/management/, {
/>
);
registerSettingsComponent(PAGE_FOOTER_COMPONENT, Component, true);
componentRegistry.register(
componentRegistry.componentType.PAGE_FOOTER_COMPONENT,
Component,
true
);
},
},
});

View file

@ -18,15 +18,7 @@
*/
declare module 'ui/management' {
export const PAGE_TITLE_COMPONENT: string;
export const PAGE_SUBTITLE_COMPONENT: string;
export const PAGE_FOOTER_COMPONENT: string;
export const SidebarNav: React.FC<any>;
export function registerSettingsComponent(
id: string,
component: string | React.FC<any>,
allowOverride: boolean
): void;
export const management: any; // TODO - properly provide types
export const MANAGEMENT_BREADCRUMB: {
text: string;

View file

@ -17,12 +17,6 @@
* under the License.
*/
export {
PAGE_TITLE_COMPONENT,
PAGE_SUBTITLE_COMPONENT,
PAGE_FOOTER_COMPONENT,
} from '../../../core_plugins/kibana/public/management/sections/settings/components/default_component_registry';
export { registerSettingsComponent } from '../../../core_plugins/kibana/public/management/sections/settings/components/component_registry';
export { MANAGEMENT_BREADCRUMB } from './breadcrumbs';
import { npStart } from 'ui/new_platform';
export const management = npStart.plugins.management.legacy;

View file

@ -29,6 +29,7 @@ import { managementPluginMock } from '../../../../../plugins/management/public/m
import { usageCollectionPluginMock } from '../../../../../plugins/usage_collection/public/mocks';
import { kibanaLegacyPluginMock } from '../../../../../plugins/kibana_legacy/public/mocks';
import { chartPluginMock } from '../../../../../plugins/charts/public/mocks';
import { advancedSettingsMock } from '../../../../../plugins/advanced_settings/public/mocks';
/* eslint-enable @kbn/eslint/no-restricted-paths */
export const pluginsMock = {
@ -41,6 +42,7 @@ export const pluginsMock = {
expressions: expressionsPluginMock.createSetupContract(),
uiActions: uiActionsPluginMock.createSetupContract(),
usageCollection: usageCollectionPluginMock.createSetupContract(),
advancedSettings: advancedSettingsMock.createSetupContract(),
kibana_legacy: kibanaLegacyPluginMock.createSetupContract(),
}),
createStart: () => ({
@ -52,6 +54,7 @@ export const pluginsMock = {
expressions: expressionsPluginMock.createStartContract(),
uiActions: uiActionsPluginMock.createStartContract(),
management: managementPluginMock.createStartContract(),
advancedSettings: advancedSettingsMock.createStartContract(),
kibana_legacy: kibanaLegacyPluginMock.createStartContract(),
}),
};

View file

@ -20,6 +20,7 @@
import sinon from 'sinon';
import { getFieldFormatsRegistry } from '../../../../test_utils/public/stub_field_formats';
import { METRIC_TYPE } from '@kbn/analytics';
import { ComponentRegistry } from '../../../../../src/plugins/advanced_settings/public/';
const mockObservable = () => {
return {
@ -58,6 +59,12 @@ const mockCore = {
export const npSetup = {
core: mockCore,
plugins: {
advancedSettings: {
component: {
register: sinon.fake(),
componentType: ComponentRegistry.componentType,
},
},
usageCollection: {
allowTrackUserAgent: sinon.fake(),
reportUiStats: sinon.fake(),

View file

@ -32,6 +32,10 @@ import { DevToolsSetup, DevToolsStart } from '../../../../plugins/dev_tools/publ
import { KibanaLegacySetup, KibanaLegacyStart } from '../../../../plugins/kibana_legacy/public';
import { HomePublicPluginSetup, HomePublicPluginStart } from '../../../../plugins/home/public';
import { SharePluginSetup, SharePluginStart } from '../../../../plugins/share/public';
import {
AdvancedSettingsSetup,
AdvancedSettingsStart,
} from '../../../../plugins/advanced_settings/public';
import { ManagementSetup, ManagementStart } from '../../../../plugins/management/public';
import { BfetchPublicSetup, BfetchPublicStart } from '../../../../plugins/bfetch/public';
import { UsageCollectionSetup } from '../../../../plugins/usage_collection/public';
@ -54,6 +58,7 @@ export interface PluginsSetup {
kibana_legacy: KibanaLegacySetup;
share: SharePluginSetup;
usageCollection: UsageCollectionSetup;
advancedSettings: AdvancedSettingsSetup;
management: ManagementSetup;
}
@ -71,6 +76,7 @@ export interface PluginsStart {
kibana_legacy: KibanaLegacyStart;
share: SharePluginStart;
management: ManagementStart;
advancedSettings: AdvancedSettingsStart;
}
export const npSetup = {

View file

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

View file

@ -0,0 +1,3 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`ComponentRegistry register should disallow registering a component with a duplicate id 1`] = `"Component with id advanced_settings_page_title is already registered."`;

View file

@ -0,0 +1,90 @@
/*
* 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 React from 'react';
import { ComponentRegistry } from './component_registry';
describe('ComponentRegistry', () => {
describe('register', () => {
it('should allow a component to be registered', () => {
const component = () => <div />;
new ComponentRegistry().setup.register(
ComponentRegistry.componentType.PAGE_TITLE_COMPONENT,
component
);
});
it('should disallow registering a component with a duplicate id', () => {
const registry = new ComponentRegistry();
const component = () => <div />;
registry.setup.register(ComponentRegistry.componentType.PAGE_TITLE_COMPONENT, component);
expect(() =>
registry.setup.register(ComponentRegistry.componentType.PAGE_TITLE_COMPONENT, () => (
<span />
))
).toThrowErrorMatchingSnapshot();
});
it('should allow a component to be overriden', () => {
const registry = new ComponentRegistry();
const component = () => <div />;
registry.setup.register(ComponentRegistry.componentType.PAGE_TITLE_COMPONENT, component);
const anotherComponent = () => <span />;
registry.setup.register(
ComponentRegistry.componentType.PAGE_TITLE_COMPONENT,
anotherComponent,
true
);
expect(registry.start.get(ComponentRegistry.componentType.PAGE_TITLE_COMPONENT)).toBe(
anotherComponent
);
});
});
describe('get', () => {
it('should allow a component to be retrieved', () => {
const registry = new ComponentRegistry();
const component = () => <div />;
registry.setup.register(ComponentRegistry.componentType.PAGE_TITLE_COMPONENT, component);
expect(registry.start.get(ComponentRegistry.componentType.PAGE_TITLE_COMPONENT)).toBe(
component
);
});
});
it('should set a displayName for the component if one does not exist', () => {
const component: React.ComponentType = () => <div />;
const registry = new ComponentRegistry();
registry.setup.register(ComponentRegistry.componentType.PAGE_TITLE_COMPONENT, component);
expect(component.displayName).toEqual(ComponentRegistry.componentType.PAGE_TITLE_COMPONENT);
});
it('should not set a displayName for the component if one already exists', () => {
const component: React.ComponentType = () => <div />;
component.displayName = '<AwesomeComponent>';
const registry = new ComponentRegistry();
registry.setup.register(ComponentRegistry.componentType.PAGE_TITLE_COMPONENT, component);
expect(component.displayName).toEqual('<AwesomeComponent>');
});
});

View file

@ -0,0 +1,91 @@
/*
* 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 { ComponentType } from 'react';
import { PageTitle } from './page_title';
import { PageSubtitle } from './page_subtitle';
import { PageFooter } from './page_footer';
type Id =
| 'advanced_settings_page_title'
| 'advanced_settings_page_subtitle'
| 'advanced_settings_page_footer';
const componentType: { [key: string]: Id } = {
PAGE_TITLE_COMPONENT: 'advanced_settings_page_title' as Id,
PAGE_SUBTITLE_COMPONENT: 'advanced_settings_page_subtitle' as Id,
PAGE_FOOTER_COMPONENT: 'advanced_settings_page_footer' as Id,
};
type RegistryComponent = ComponentType<Record<string, any> | undefined>;
export class ComponentRegistry {
static readonly componentType = componentType;
static readonly defaultRegistry: Record<Id, RegistryComponent> = {
advanced_settings_page_title: PageTitle,
advanced_settings_page_subtitle: PageSubtitle,
advanced_settings_page_footer: PageFooter,
};
registry: { [key in Id]?: RegistryComponent } = {};
/**
* Attempts to register the provided component, with the ability to optionally allow
* the component to override an existing one.
*
* If the intent is to override, then `allowOverride` must be set to true, otherwise an exception is thrown.
*
* @param {*} id the id of the component to register
* @param {*} component the component
* @param {*} allowOverride (default: false) - optional flag to allow this component to override a previously registered component
*/
private register(id: Id, component: RegistryComponent, allowOverride = false) {
if (!allowOverride && id in this.registry) {
throw new Error(`Component with id ${id} is already registered.`);
}
// Setting a display name if one does not already exist.
// This enhances the snapshots, as well as the debugging experience.
if (!component.displayName) {
component.displayName = id;
}
this.registry[id] = component;
}
/**
* Retrieve a registered component by its ID.
* If the component does not exist, then an exception is thrown.
*
* @param {*} id the ID of the component to retrieve
*/
private get(id: Id): RegistryComponent {
return this.registry[id] || ComponentRegistry.defaultRegistry[id];
}
setup = {
componentType: ComponentRegistry.componentType,
register: this.register.bind(this),
};
start = {
componentType: ComponentRegistry.componentType,
get: this.get.bind(this),
};
}

View file

@ -0,0 +1,20 @@
/*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
export { ComponentRegistry } from './component_registry';

View file

@ -7,7 +7,7 @@ exports[`PageTitle should render normally 1`] = `
>
<FormattedMessage
defaultMessage="Settings"
id="kbn.management.settings.pageTitle"
id="advancedSettings.pageTitle"
values={Object {}}
/>
</h1>

View file

@ -25,7 +25,7 @@ export const PageTitle = () => {
return (
<EuiText>
<h1 data-test-subj="managementSettingsTitle">
<FormattedMessage id="kbn.management.settings.pageTitle" defaultMessage="Settings" />
<FormattedMessage id="advancedSettings.pageTitle" defaultMessage="Settings" />
</h1>
</EuiText>
);

View file

@ -0,0 +1,27 @@
/*
* 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 'kibana/public';
import { AdvancedSettingsPlugin } from './plugin';
export { AdvancedSettingsSetup, AdvancedSettingsStart } from './types';
export { ComponentRegistry } from './component_registry';
export function plugin(initializerContext: PluginInitializerContext) {
return new AdvancedSettingsPlugin();
}

View file

@ -0,0 +1,33 @@
/*
* 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 { ComponentRegistry } from './component_registry';
const register = jest.fn();
const get = jest.fn();
const componentType = ComponentRegistry.componentType;
export const advancedSettingsMock = {
createSetupContract() {
return { register, componentType };
},
createStartContract() {
return { get, componentType };
},
};

View file

@ -17,17 +17,23 @@
* under the License.
*/
import { tryRegisterSettingsComponent } from './component_registry';
import { PageTitle } from './page_title';
import { PageSubtitle } from './page_subtitle';
import { PageFooter } from './page_footer';
import { CoreSetup, CoreStart, Plugin } from 'kibana/public';
import { ComponentRegistry } from './component_registry';
import { AdvancedSettingsSetup, AdvancedSettingsStart } from './types';
export const PAGE_TITLE_COMPONENT = 'advanced_settings_page_title';
export const PAGE_SUBTITLE_COMPONENT = 'advanced_settings_page_subtitle';
export const PAGE_FOOTER_COMPONENT = 'advanced_settings_page_footer';
const component = new ComponentRegistry();
export function registerDefaultComponents() {
tryRegisterSettingsComponent(PAGE_TITLE_COMPONENT, PageTitle);
tryRegisterSettingsComponent(PAGE_SUBTITLE_COMPONENT, PageSubtitle);
tryRegisterSettingsComponent(PAGE_FOOTER_COMPONENT, PageFooter);
export class AdvancedSettingsPlugin
implements Plugin<AdvancedSettingsSetup, AdvancedSettingsStart> {
public setup(core: CoreSetup) {
return {
component: component.setup,
};
}
public start(core: CoreStart) {
return {
component: component.start,
};
}
}

View file

@ -0,0 +1,27 @@
/*
* 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 { ComponentRegistry } from './component_registry';
export interface AdvancedSettingsSetup {
component: ComponentRegistry['setup'];
}
export interface AdvancedSettingsStart {
component: ComponentRegistry['start'];
}

View file

@ -5,33 +5,30 @@
*/
import { AdvancedSettingsService } from './advanced_settings_service';
jest.mock('ui/management', () => {
return {
PAGE_TITLE_COMPONENT: 'page_title_component',
PAGE_SUBTITLE_COMPONENT: 'page_subtitle_component',
};
});
import { advancedSettingsMock } from '../../../../../../src/plugins/advanced_settings/public/mocks';
const componentRegistryMock = advancedSettingsMock.createSetupContract();
describe('Advanced Settings Service', () => {
describe('#setup', () => {
it('registers space-aware components to augment the advanced settings screen', () => {
const deps = {
getActiveSpace: jest.fn().mockResolvedValue({ id: 'foo', name: 'foo-space' }),
registerSettingsComponent: jest.fn(),
componentRegistry: componentRegistryMock,
};
const advancedSettingsService = new AdvancedSettingsService();
advancedSettingsService.setup(deps);
expect(deps.registerSettingsComponent).toHaveBeenCalledTimes(2);
expect(deps.registerSettingsComponent).toHaveBeenCalledWith(
'page_title_component',
expect(deps.componentRegistry.register).toHaveBeenCalledTimes(2);
expect(deps.componentRegistry.register).toHaveBeenCalledWith(
componentRegistryMock.componentType.PAGE_TITLE_COMPONENT,
expect.any(Function),
true
);
expect(deps.registerSettingsComponent).toHaveBeenCalledWith(
'page_subtitle_component',
expect(deps.componentRegistry.register).toHaveBeenCalledWith(
componentRegistryMock.componentType.PAGE_SUBTITLE_COMPONENT,
expect.any(Function),
true
);

View file

@ -4,25 +4,29 @@
* you may not use this file except in compliance with the Elastic License.
*/
import React from 'react';
import { PAGE_TITLE_COMPONENT, PAGE_SUBTITLE_COMPONENT } from 'ui/management';
import { Space } from '../../common/model/space';
import { AdvancedSettingsTitle, AdvancedSettingsSubtitle } from './components';
import { AdvancedSettingsSetup } from '../../../../../../src/plugins/advanced_settings/public';
interface SetupDeps {
getActiveSpace: () => Promise<Space>;
registerSettingsComponent: (
id: string,
component: string | React.FC<any>,
allowOverride: boolean
) => void;
componentRegistry: AdvancedSettingsSetup['component'];
}
export class AdvancedSettingsService {
public setup({ getActiveSpace, registerSettingsComponent }: SetupDeps) {
public setup({ getActiveSpace, componentRegistry }: SetupDeps) {
const PageTitle = () => <AdvancedSettingsTitle getActiveSpace={getActiveSpace} />;
const SubTitle = () => <AdvancedSettingsSubtitle getActiveSpace={getActiveSpace} />;
registerSettingsComponent(PAGE_TITLE_COMPONENT, PageTitle, true);
registerSettingsComponent(PAGE_SUBTITLE_COMPONENT, SubTitle, true);
componentRegistry.register(
componentRegistry.componentType.PAGE_TITLE_COMPONENT,
PageTitle,
true
);
componentRegistry.register(
componentRegistry.componentType.PAGE_SUBTITLE_COMPONENT,
SubTitle,
true
);
}
}

View file

@ -4,7 +4,6 @@
* you may not use this file except in compliance with the Elastic License.
*/
import { registerSettingsComponent } from 'ui/management';
import { npSetup, npStart } from 'ui/new_platform';
import { setup as managementSetup } from '../../../../../src/legacy/core_plugins/management/public/legacy';
import { plugin } from '.';
@ -16,9 +15,7 @@ const spacesPlugin: SpacesPlugin = plugin();
const pluginsSetup: PluginsSetup = {
home: npSetup.plugins.home,
management: managementSetup,
__managementLegacyCompat: {
registerSettingsComponent,
},
advancedSettings: npSetup.plugins.advancedSettings,
};
const pluginsStart: PluginsStart = {

View file

@ -8,6 +8,7 @@ import { CoreSetup, CoreStart, Plugin } from 'src/core/public';
import { HomePublicPluginSetup } from 'src/plugins/home/public';
import { ManagementSetup } from 'src/legacy/core_plugins/management/public';
import { ManagementStart } from 'src/plugins/management/public';
import { AdvancedSettingsSetup } from 'src/plugins/advanced_settings/public';
import { SpacesManager } from './spaces_manager';
import { initSpacesNavControl } from './nav_control';
import { createSpacesFeatureCatalogueEntry } from './create_feature_catalogue_entry';
@ -22,13 +23,7 @@ export interface SpacesPluginStart {
export interface PluginsSetup {
home?: HomePublicPluginSetup;
management: ManagementSetup;
__managementLegacyCompat: {
registerSettingsComponent: (
id: string,
component: string | React.FC<any>,
allowOverride: boolean
) => void;
};
advancedSettings: AdvancedSettingsSetup;
}
export interface PluginsStart {
@ -53,7 +48,7 @@ export class SpacesPlugin implements Plugin<void, SpacesPluginStart, PluginsSetu
const advancedSettingsService = new AdvancedSettingsService();
advancedSettingsService.setup({
getActiveSpace: () => this.spacesManager.getActiveSpace(),
registerSettingsComponent: plugins.__managementLegacyCompat.registerSettingsComponent,
componentRegistry: plugins.advancedSettings.component,
});
if (plugins.home) {

View file

@ -1925,7 +1925,7 @@
"kbn.management.settings.form.clearSearchResultText": "(検索結果を消去)",
"kbn.management.settings.form.noSearchResultText": "設定が見つかりませんでした {clearSearch}",
"kbn.management.settings.form.searchResultText": "検索用語により {settingsCount} 件の設定が非表示になっています {clearSearch}",
"kbn.management.settings.pageTitle": "設定",
"advancedSettings.pageTitle": "設定",
"kbn.management.settings.searchBar.unableToParseQueryErrorMessage": "クエリをパースできません",
"kbn.management.settings.searchBarAriaLabel": "高度な設定を検索",
"kbn.management.settings.sectionLabel": "高度な設定",

View file

@ -1925,7 +1925,7 @@
"kbn.management.settings.form.clearSearchResultText": "(清除搜索)",
"kbn.management.settings.form.noSearchResultText": "未找到设置{clearSearch}",
"kbn.management.settings.form.searchResultText": "搜索词隐藏了 {settingsCount} 个设置{clearSearch}",
"kbn.management.settings.pageTitle": "设置",
"advancedSettings.pageTitle": "设置",
"kbn.management.settings.searchBar.unableToParseQueryErrorMessage": "无法解析查询",
"kbn.management.settings.searchBarAriaLabel": "搜索高级设置",
"kbn.management.settings.sectionLabel": "高级设置",