Skip to content

Commit

Permalink
Introduce component registry for advanced ui settings screen (elastic…
Browse files Browse the repository at this point in the history
…#22315) (elastic#22391)

* introduce component registry for advanced ui settings screen
  • Loading branch information
legrego authored Aug 25, 2018
1 parent df453a6 commit e83dc15
Show file tree
Hide file tree
Showing 12 changed files with 344 additions and 26 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@ import {
EuiFlexGroup,
EuiFlexItem,
EuiSpacer,
EuiText,
Query,
} from '@elastic/eui';

Expand All @@ -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 = {
Expand All @@ -52,16 +53,18 @@ export class AdvancedSettings extends Component {
query: parsedQuery,
filteredSettings: this.mapSettings(Query.execute(parsedQuery, this.settings)),
};

registerDefaultComponents();
}

init(config) {
this.settings = this.mapConfig(config);
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;
});

Expand Down Expand Up @@ -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
Expand All @@ -150,7 +153,7 @@ export class AdvancedSettings extends Component {
</EuiFlexItem>
</EuiFlexGroup>
<EuiSpacer size="m" />
<CallOuts/>
<CallOuts />
<EuiSpacer size="m" />
<Form
settings={filteredSettings}
Expand Down
Original file line number Diff line number Diff line change
@@ -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."`;
Original file line number Diff line number Diff line change
@@ -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];
}
Original file line number Diff line number Diff line change
@@ -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();
});
});
Original file line number Diff line number Diff line change
@@ -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);
}
Original file line number Diff line number Diff line change
@@ -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);
});
});
Original file line number Diff line number Diff line change
@@ -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>
`;
Original file line number Diff line number Diff line change
@@ -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';
Loading

0 comments on commit e83dc15

Please sign in to comment.