mirror of
https://github.com/elastic/kibana.git
synced 2025-04-23 09:19:04 -04:00
* advanced settings component registry to new platform
This commit is contained in:
parent
f48c339f3f
commit
2b26a3950b
41 changed files with 399 additions and 297 deletions
|
@ -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",
|
||||
|
|
|
@ -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={
|
||||
|
|
|
@ -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',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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."`;
|
|
@ -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();
|
||||
});
|
||||
});
|
|
@ -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];
|
||||
}
|
|
@ -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);
|
||||
});
|
||||
});
|
|
@ -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
|
||||
);
|
||||
},
|
||||
},
|
||||
});
|
||||
|
|
8
src/legacy/ui/public/management/index.d.ts
vendored
8
src/legacy/ui/public/management/index.d.ts
vendored
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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(),
|
||||
}),
|
||||
};
|
||||
|
|
|
@ -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(),
|
||||
|
|
|
@ -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 = {
|
||||
|
|
7
src/plugins/advanced_settings/kibana.json
Normal file
7
src/plugins/advanced_settings/kibana.json
Normal file
|
@ -0,0 +1,7 @@
|
|||
{
|
||||
"id": "advancedSettings",
|
||||
"version": "kibana",
|
||||
"server": false,
|
||||
"ui": true,
|
||||
"requiredPlugins": []
|
||||
}
|
|
@ -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."`;
|
|
@ -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>');
|
||||
});
|
||||
});
|
|
@ -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),
|
||||
};
|
||||
}
|
|
@ -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';
|
|
@ -7,7 +7,7 @@ exports[`PageTitle should render normally 1`] = `
|
|||
>
|
||||
<FormattedMessage
|
||||
defaultMessage="Settings"
|
||||
id="kbn.management.settings.pageTitle"
|
||||
id="advancedSettings.pageTitle"
|
||||
values={Object {}}
|
||||
/>
|
||||
</h1>
|
|
@ -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>
|
||||
);
|
27
src/plugins/advanced_settings/public/index.ts
Normal file
27
src/plugins/advanced_settings/public/index.ts
Normal 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();
|
||||
}
|
33
src/plugins/advanced_settings/public/mocks.ts
Normal file
33
src/plugins/advanced_settings/public/mocks.ts
Normal 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 };
|
||||
},
|
||||
};
|
|
@ -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,
|
||||
};
|
||||
}
|
||||
}
|
27
src/plugins/advanced_settings/public/types.ts
Normal file
27
src/plugins/advanced_settings/public/types.ts
Normal 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'];
|
||||
}
|
|
@ -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
|
||||
);
|
||||
|
|
|
@ -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
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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 = {
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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": "高度な設定",
|
||||
|
|
|
@ -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": "高级设置",
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue