Introduce component registry for advanced ui settings screen (#22315)

* introduce component registry for advanced ui settings screen
This commit is contained in:
Larry Gregory 2018-08-25 09:01:47 -04:00 committed by GitHub
parent e701a3f07b
commit 1b76134cdf
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
12 changed files with 344 additions and 26 deletions

View file

@ -17,15 +17,7 @@ exports[`AdvancedSettings should render normally 1`] = `
component="div"
grow={true}
>
<EuiText
grow={true}
>
<h1
data-test-subj="managementSettingsTitle"
>
Settings
</h1>
</EuiText>
<advanced_settings_page_title />
</EuiFlexItem>
<EuiFlexItem
component="div"
@ -331,15 +323,7 @@ exports[`AdvancedSettings should render specific setting if given setting key 1`
component="div"
grow={true}
>
<EuiText
grow={true}
>
<h1
data-test-subj="managementSettingsTitle"
>
Settings
</h1>
</EuiText>
<advanced_settings_page_title />
</EuiFlexItem>
<EuiFlexItem
component="div"

View file

@ -25,7 +25,6 @@ import {
EuiFlexGroup,
EuiFlexItem,
EuiSpacer,
EuiText,
Query,
} from '@elastic/eui';
@ -36,6 +35,8 @@ import { Form } from './components/form';
import { getAriaName, toEditableConfig, DEFAULT_CATEGORY } from './lib';
import './advanced_settings.less';
import { registerDefaultComponents, PAGE_TITLE_COMPONENT } from './components/default_component_registry';
import { getSettingsComponent } from './components/component_registry';
export class AdvancedSettings extends Component {
static propTypes = {
@ -52,6 +53,8 @@ export class AdvancedSettings extends Component {
query: parsedQuery,
filteredSettings: this.mapSettings(Query.execute(parsedQuery, this.settings)),
};
registerDefaultComponents();
}
init(config) {
@ -59,9 +62,9 @@ export class AdvancedSettings extends Component {
this.groupedSettings = this.mapSettings(this.settings);
this.categories = Object.keys(this.groupedSettings).sort((a, b) => {
if(a === DEFAULT_CATEGORY) return -1;
if(b === DEFAULT_CATEGORY) return 1;
if(a > b) return 1;
if (a === DEFAULT_CATEGORY) return -1;
if (b === DEFAULT_CATEGORY) return 1;
if (a > b) return 1;
return a === b ? 0 : -1;
});
@ -133,13 +136,13 @@ export class AdvancedSettings extends Component {
render() {
const { filteredSettings, query } = this.state;
const PageTitle = getSettingsComponent(PAGE_TITLE_COMPONENT);
return (
<div className="advancedSettings">
<EuiFlexGroup gutterSize="none">
<EuiFlexItem>
<EuiText>
<h1 data-test-subj="managementSettingsTitle">Settings</h1>
</EuiText>
<PageTitle />
</EuiFlexItem>
<EuiFlexItem>
<Search
@ -150,7 +153,7 @@ export class AdvancedSettings extends Component {
</EuiFlexItem>
</EuiFlexGroup>
<EuiSpacer size="m" />
<CallOuts/>
<CallOuts />
<EuiSpacer size="m" />
<Form
settings={filteredSettings}

View file

@ -0,0 +1,5 @@
// 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

@ -0,0 +1,73 @@
/*
* 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.
*/
const registry = {};
/**
* 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, component) {
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, component, 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) {
if (!(id in registry)) {
throw new Error(`Component not found with id ${id}`);
}
return registry[id];
}

View file

@ -0,0 +1,89 @@
/*
* 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 { tryRegisterSettingsComponent, registerSettingsComponent, getSettingsComponent } from './component_registry';
describe('tryRegisterSettingsComponent', () => {
it('should allow a component to be registered', () => {
const component = {};
expect(tryRegisterSettingsComponent('tryTest1', component)).toEqual(true);
});
it('should return false if the component is already registered, and not allow an override', () => {
const component = {};
expect(tryRegisterSettingsComponent('tryTest2', component)).toEqual(true);
const updatedComponent = { updated: 'yay' };
expect(tryRegisterSettingsComponent('tryTest2', updatedComponent)).toEqual(false);
expect(getSettingsComponent('tryTest2')).toBe(component);
});
});
describe('registerSettingsComponent', () => {
it('should allow a component to be registered', () => {
const component = {};
registerSettingsComponent('test', component);
});
it('should disallow registering a component with a duplicate id', () => {
const component = {};
registerSettingsComponent('test2', component);
expect(() => registerSettingsComponent('test2', 'some other component')).toThrowErrorMatchingSnapshot();
});
it('should allow a component to be overriden', () => {
const component = {};
registerSettingsComponent('test3', component);
const anotherComponent = { 'anotherComponent': 'ok' };
registerSettingsComponent('test3', anotherComponent, true);
expect(getSettingsComponent('test3')).toBe(anotherComponent);
});
it('should set a displayName for the component if one does not exist', () => {
const component = {};
registerSettingsComponent('display_name_component', component);
expect(component.displayName).toEqual('display_name_component');
});
it('should not set a displayName for the component if one already exists', () => {
const component = {
displayName: '<AwesomeComponent>'
};
registerSettingsComponent('another_display_name_component', component);
expect(component.displayName).toEqual('<AwesomeComponent>');
});
});
describe('getSettingsComponent', () => {
it('should allow a component to be retrieved', () => {
const component = {};
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

@ -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 { tryRegisterSettingsComponent } from './component_registry';
import { PageTitle } from './page_title';
export const PAGE_TITLE_COMPONENT = 'advanced_settings_page_title';
export function registerDefaultComponents() {
tryRegisterSettingsComponent(PAGE_TITLE_COMPONENT, PageTitle);
}

View file

@ -0,0 +1,43 @@
/*
* 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 { 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 = {};
registerSettingsComponent(PAGE_TITLE_COMPONENT, newComponent, true);
registerDefaultComponents();
expect(getSettingsComponent(PAGE_TITLE_COMPONENT)).toEqual(newComponent);
});
});

View file

@ -0,0 +1,13 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`PageTitle should render normally 1`] = `
<EuiText
grow={true}
>
<h1
data-test-subj="managementSettingsTitle"
>
Settings
</h1>
</EuiText>
`;

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 { PageTitle } from './page_title';

View file

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

View file

@ -0,0 +1,28 @@
/*
* 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 { shallow } from 'enzyme';
import { PageTitle } from './page_title';
describe('PageTitle', () => {
it('should render normally', () => {
expect(shallow(<PageTitle />)).toMatchSnapshot();
});
});

View file

@ -19,6 +19,8 @@
import { ManagementSection } from './section';
export { registerSettingsComponent } from '../../../core_plugins/kibana/public/management/sections/settings/components/component_registry';
export const management = new ManagementSection('management', {
display: 'Management'
});