Skip to content

Commit

Permalink
feat(toolbar,toolbarTypes): issues/76 add toolbar with SLA filter
Browse files Browse the repository at this point in the history
* toolbar, apply PF toolbar pattern for single select/dropdown
* toolbarTypes, sla select/dropdown options
  • Loading branch information
cdcabrera committed Mar 11, 2020
1 parent 539cfaa commit efc9416
Show file tree
Hide file tree
Showing 8 changed files with 345 additions and 0 deletions.
8 changes: 8 additions & 0 deletions public/locales/en-US.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,14 @@
"physicalSocketsLabel": "Physical {{product}}",
"thresholdLabel": "Subscription threshold"
},
"curiosity-toolbar": {
"slaCategory": "SLA",
"slaNone": "No SLA",
"slaPlaceholder": "Filter by SLA",
"slaPremium": "Premium",
"slaSelfSupport": "Self-Support",
"slaStandard": "Standard"
},
"curiosity-tour": {
"emptyStateIconAlt": "{{appName}} logo",
"emptyStateTitle": "{{appName}} is an early access beta",
Expand Down
25 changes: 25 additions & 0 deletions src/components/i18n/__tests__/__snapshots__/i18n.test.js.snap
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,31 @@ msgstr \\"\\"
msgid \\"curiosity-graph.thresholdLabel\\"
msgstr \\"\\"
#: src/components/toolbar/toolbar.js:68
#: src/components/toolbar/toolbar.js:71
msgid \\"curiosity-toolbar.slaCategory\\"
msgstr \\"\\"
#: src/components/toolbar/toolbarTypes.js:22
msgid \\"curiosity-toolbar.slaNone\\"
msgstr \\"\\"
#: src/components/toolbar/toolbar.js:74
msgid \\"curiosity-toolbar.slaPlaceholder\\"
msgstr \\"\\"
#: src/components/toolbar/toolbarTypes.js:10
msgid \\"curiosity-toolbar.slaPremium\\"
msgstr \\"\\"
#: src/components/toolbar/toolbarTypes.js:18
msgid \\"curiosity-toolbar.slaSelfSupport\\"
msgstr \\"\\"
#: src/components/toolbar/toolbarTypes.js:14
msgid \\"curiosity-toolbar.slaStandard\\"
msgstr \\"\\"
#: src/components/tourView/tourView.js:64
msgid \\"curiosity-tour.emptyStateButton\\"
msgstr \\"\\"
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`Toolbar Component should handle updating state and dispatching an sla filter: clear filters 1`] = `
Object {
"filterSla": null,
}
`;

exports[`Toolbar Component should handle updating state and dispatching an sla filter: sla selected 1`] = `
Object {
"filterSla": Object {
"title": "t(curiosity-toolbar.slaPremium)",
"value": "premium",
},
}
`;

exports[`Toolbar Component should render a non-connected component: non-connected 1`] = `
<DataToolbar
className="pf-m-toggle-group-container ins-c-primary-toolbar"
clearAllFilters={[Function]}
collapseListedFiltersBreakpoint="xl"
id="curiosity-toolbar"
>
<DataToolbarContent
breakpointMods={Array []}
isExpanded={false}
showClearFiltersButton={false}
>
<ForwardRef
variant="filter-group"
>
<DataToolbarFilter
categoryName="t(curiosity-toolbar.slaCategory)"
chips={Array []}
deleteChip={[Function]}
showToolbarItem={true}
>
<Select
aria-label="t(curiosity-toolbar.slaCategory)"
ariaLabel="Select option"
className=""
id="generatedid-"
isDisabled={false}
name={null}
onSelect={[Function]}
options={
Array [
Object {
"title": "t(curiosity-toolbar.slaPremium)",
"value": "premium",
},
Object {
"title": "t(curiosity-toolbar.slaStandard)",
"value": "standard",
},
Object {
"title": "t(curiosity-toolbar.slaSelfSupport)",
"value": "self-support",
},
Object {
"title": "t(curiosity-toolbar.slaNone)",
"value": "",
},
]
}
placeholder="t(curiosity-toolbar.slaPlaceholder)"
selectedOptions={Array []}
variant="single"
/>
</DataToolbarFilter>
</ForwardRef>
</DataToolbarContent>
</DataToolbar>
`;
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`ToolbarTypes should have specific types: toolbarTypes 1`] = `
Object {
"getOptions": [Function],
}
`;

exports[`ToolbarTypes should return an output for options selection: getOptionsType 1`] = `
Object {
"options": Array [
Object {
"title": "t(curiosity-toolbar.slaPremium)",
"value": "premium",
},
Object {
"title": "t(curiosity-toolbar.slaStandard)",
"value": "standard",
},
Object {
"title": "t(curiosity-toolbar.slaSelfSupport)",
"value": "self-support",
},
Object {
"title": "t(curiosity-toolbar.slaNone)",
"value": "",
},
],
"selected": null,
}
`;

exports[`ToolbarTypes should return an output for options selection: getOptionsType:null 1`] = `
Object {
"options": Array [],
}
`;

exports[`ToolbarTypes should return an output for options selection: getOptionsType:sla 1`] = `
Object {
"options": Array [
Object {
"title": "t(curiosity-toolbar.slaPremium)",
"value": "premium",
},
Object {
"title": "t(curiosity-toolbar.slaStandard)",
"value": "standard",
},
Object {
"title": "t(curiosity-toolbar.slaSelfSupport)",
"value": "self-support",
},
Object {
"title": "t(curiosity-toolbar.slaNone)",
"value": "",
},
],
"selected": null,
}
`;
30 changes: 30 additions & 0 deletions src/components/toolbar/__tests__/toolbar.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import React from 'react';
import { mount, shallow } from 'enzyme';
import { Toolbar } from '../toolbar';
import { toolbarTypes } from '../toolbarTypes';

describe('Toolbar Component', () => {
it('should render a non-connected component', () => {
const props = {};
const component = shallow(<Toolbar {...props} />);

expect(component).toMatchSnapshot('non-connected');
});

it('should handle updating state and dispatching an sla filter', () => {
const props = {};

const dispatchFilter = jest.spyOn(Toolbar.prototype, 'dispatchFilter');
const component = mount(<Toolbar {...props} />);
const componentInstance = component.instance();

const slaOption = toolbarTypes.getOptions('sla').options[0];
componentInstance.onSlaSelect({ selected: { ...slaOption }, value: slaOption.value });
expect(componentInstance.state).toMatchSnapshot('sla selected');

componentInstance.onClear();
expect(componentInstance.state).toMatchSnapshot('clear filters');

expect(dispatchFilter).toHaveBeenCalledTimes(2);
});
});
13 changes: 13 additions & 0 deletions src/components/toolbar/__tests__/toolbarTypes.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { toolbarTypes, getOptionsType } from '../toolbarTypes';

describe('ToolbarTypes', () => {
it('should have specific types', () => {
expect(toolbarTypes).toMatchSnapshot('toolbarTypes');
});

it('should return an output for options selection', () => {
expect(getOptionsType('sla')).toMatchSnapshot('getOptionsType:sla');
expect(getOptionsType()).toMatchSnapshot('getOptionsType');
expect(getOptionsType(null)).toMatchSnapshot('getOptionsType:null');
});
});
97 changes: 97 additions & 0 deletions src/components/toolbar/toolbar.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
import React from 'react';
import PropTypes from 'prop-types';
import { withTranslation } from 'react-i18next';
import { DataToolbar, DataToolbarContent, DataToolbarFilter, DataToolbarGroup } from '@patternfly/react-core';
import { Select } from '../select/select';
import { reduxTypes, store } from '../../redux';
import { toolbarTypes } from './toolbarTypes';
import { helpers } from '../../common';

class Toolbar extends React.Component {
state = { filterSla: toolbarTypes.getOptions().selected };

onClear = () => {
this.setState(
{
filterSla: null
},
() => {
this.dispatchFilter(reduxTypes.rhsm.SET_GRAPH_SLA_RHSM, { sla: null });
}
);
};

onSlaSelect = event => {
const { selected, value } = event;

this.setState(
{
filterSla: { ...selected }
},
() => {
this.dispatchFilter(reduxTypes.rhsm.SET_GRAPH_SLA_RHSM, { sla: value });
}
);
};

dispatchFilter(type, data = {}) {
const { viewId } = this.props;

if (type) {
store.dispatch({
type,
viewId,
...data
});
}
}

render() {
const { filterSla } = this.state;
const { t } = this.props;
const slaOptions = toolbarTypes.getOptions();
const slaOptionsSelected =
(filterSla && filterSla.title && [filterSla.title]) || (slaOptions.selected && [slaOptions.selected]) || [];

return (
<DataToolbar
id="curiosity-toolbar"
className="pf-m-toggle-group-container ins-c-primary-toolbar"
collapseListedFiltersBreakpoint="xl"
clearAllFilters={this.onClear}
>
<DataToolbarContent>
<DataToolbarGroup variant="filter-group">
<DataToolbarFilter
chips={slaOptionsSelected}
deleteChip={this.onClear}
categoryName={t('curiosity-toolbar.slaCategory')}
>
<Select
aria-label={t('curiosity-toolbar.slaCategory')}
onSelect={this.onSlaSelect}
selectedOptions={slaOptionsSelected}
placeholder={t('curiosity-toolbar.slaPlaceholder')}
options={slaOptions.options}
/>
</DataToolbarFilter>
</DataToolbarGroup>
</DataToolbarContent>
</DataToolbar>
);
}
}

Toolbar.propTypes = {
t: PropTypes.func,
viewId: PropTypes.string
};

Toolbar.defaultProps = {
t: helpers.noopTranslate,
viewId: 'toolbar'
};

const TranslatedToolbar = withTranslation()(Toolbar);

export { TranslatedToolbar as default, TranslatedToolbar, Toolbar };
36 changes: 36 additions & 0 deletions src/components/toolbar/toolbarTypes.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import { translate } from '../i18n/i18n';
import { RHSM_API_QUERY_SLA_TYPES as SLA_TYPES } from '../../types/rhsmApiTypes';

const getOptionsType = (optionsType = 'sla') => {
if (optionsType === 'sla') {
return {
selected: null,
options: [
{
title: translate('curiosity-toolbar.slaPremium'),
value: SLA_TYPES.PREMIUM
},
{
title: translate('curiosity-toolbar.slaStandard'),
value: SLA_TYPES.STANDARD
},
{
title: translate('curiosity-toolbar.slaSelfSupport'),
value: SLA_TYPES.SELF
},
{
title: translate('curiosity-toolbar.slaNone'),
value: SLA_TYPES.NONE
}
]
};
}

return { options: [] };
};

const toolbarTypes = {
getOptions: getOptionsType
};

export { toolbarTypes as default, toolbarTypes, getOptionsType };

0 comments on commit efc9416

Please sign in to comment.