Converting use of native select elements to react-select library (#440)

This commit is contained in:
Kyle Knight
2016-11-09 08:26:15 -06:00
committed by GitHub
parent ecf9eddbca
commit b4572b7327
6 changed files with 66 additions and 62 deletions
@@ -1,53 +1,38 @@
import React, { Component, PropTypes } from 'react';
import Select from 'react-select';
import { noop } from 'lodash';
import dropdownOptionInterface from '../../../../interfaces/dropdownOption';
const baseClass = 'kolide-dropdown';
class Dropdown extends Component {
static propTypes = {
options: PropTypes.arrayOf(dropdownOptionInterface),
options: PropTypes.arrayOf(dropdownOptionInterface).isRequired,
onSelect: PropTypes.func,
className: PropTypes.string,
placeholder: PropTypes.string,
value: PropTypes.string,
clearable: PropTypes.bool,
};
static defaultProps = {
onSelect: noop,
clearable: false,
placeholder: 'Select One...',
};
onOptionClick = (evt) => {
evt.preventDefault();
const { onSelect } = this.props;
onSelect(evt);
return false;
}
renderOption = (option) => {
const { disabled = false, value, text } = option;
return (
<option key={value} className={`${baseClass}__option`} value={value} disabled={disabled}>
{text}
</option>
);
}
render () {
const { options, className } = this.props;
const { onOptionClick, renderOption } = this;
const { options, className, placeholder, value, clearable, onSelect } = this.props;
return (
<div className={[`${baseClass}__wrapper ${className}`]}>
<select className={baseClass} onChange={onOptionClick}>
{options.map((option) => {
return renderOption(option);
})}
</select>
</div>
<Select
className={className}
name="targets"
options={options}
onChange={onSelect}
placeholder={placeholder}
value={value}
clearable={clearable}
/>
);
}
}
@@ -0,0 +1,23 @@
import React from 'react';
import expect from 'expect';
import { mount } from 'enzyme';
import Dropdown from './Dropdown';
describe('Dropdown - component', () => {
const options = [
{ text: 'Users', value: 'users' },
{ text: 'Groups', value: 'groups' },
];
const props = {
options,
};
it('renders the dropdown', () => {
const component = mount(<Dropdown {...props} />);
const dropdownSelect = component.find('Select');
expect(dropdownSelect).toExist();
});
});
@@ -9,8 +9,9 @@ import {
shouldShowAllColumns,
} from './helpers';
import osqueryTableInterface from '../../../interfaces/osquery_table';
import { osqueryTables } from '../../../utilities/osquery_tables';
import { osqueryTableNames } from '../../../utilities/osquery_tables';
import SecondarySidePanelContainer from '../SecondarySidePanelContainer';
import Dropdown from '../../../components/forms/fields/Dropdown';
const baseClass = 'query-side-panel';
@@ -40,11 +41,10 @@ class QuerySidePanel extends Component {
return false;
}
onSelectTable = ({ target }) => {
onSelectTable = ({ value }) => {
const { onOsqueryTableSelect } = this.props;
const { value: tableName } = target;
onOsqueryTableSelect(tableName);
onOsqueryTableSelect(value);
return false;
}
@@ -120,14 +120,17 @@ class QuerySidePanel extends Component {
const { onSelectTable } = this;
const { selectedOsqueryTable } = this.props;
const tableNames = osqueryTableNames.map((name) => {
return { label: name, value: name };
});
return (
<div className="kolide-dropdown__wrapper">
<select className="kolide-dropdown" onChange={onSelectTable} value={selectedOsqueryTable.name}>
{osqueryTables.map((table) => {
return <option key={table.name} value={table.name} className="kolide-dropdown__option">{table.name}</option>;
})}
</select>
</div>
<Dropdown
options={tableNames}
value={selectedOsqueryTable.name}
onSelect={onSelectTable}
placeholder="Choose Table..."
/>
);
}
@@ -2,11 +2,8 @@ import React from 'react';
import expect, { createSpy, restoreSpies } from 'expect';
import { mount } from 'enzyme';
import helpers from '../../../test/helpers';
import QuerySidePanel from './QuerySidePanel';
const { fillInFormInput } = helpers;
describe('QuerySidePanel - component', () => {
afterEach(restoreSpies);
@@ -45,15 +42,14 @@ describe('QuerySidePanel - component', () => {
it('renders the selected table in the dropdown', () => {
const component = mount(<QuerySidePanel {...props} />);
const tableSelect = component.find('.kolide-dropdown');
const tableSelect = component.find('Dropdown');
expect(tableSelect.prop('value')).toEqual('users');
});
it('calls the onOsqueryTableSelect prop when a new table is selected in the dropdown', () => {
const component = mount(<QuerySidePanel {...props} />);
const tableSelect = component.find('.kolide-dropdown');
fillInFormInput(tableSelect, 'groups');
component.node.onSelectTable({ value: 'groups' });
expect(onOsqueryTableSelect).toHaveBeenCalledWith('groups');
});
+1 -1
View File
@@ -2,6 +2,6 @@ import { PropTypes } from 'react';
export default PropTypes.shape({
disabled: PropTypes.bool,
text: PropTypes.string,
label: PropTypes.string,
value: PropTypes.string,
});
@@ -19,24 +19,22 @@ class UserBlock extends Component {
static userActionOptions = (currentUser, user, invite) => {
const disableActions = currentUser.id === user.id;
const inviteActions = [
{ text: 'Actions...', value: '' },
{ text: 'Revoke Invitation', value: 'revert_invitation' },
{ label: 'Revoke Invitation', value: 'revert_invitation' },
];
const userEnableAction = user.enabled
? { disabled: disableActions, text: 'Disable Account', value: 'disable_account' }
: { text: 'Enable Account', value: 'enable_account' };
? { disabled: disableActions, label: 'Disable Account', value: 'disable_account' }
: { label: 'Enable Account', value: 'enable_account' };
const userPromotionAction = user.admin
? { disabled: disableActions, text: 'Demote User', value: 'demote_user' }
: { text: 'Promote User', value: 'promote_user' };
? { disabled: disableActions, label: 'Demote User', value: 'demote_user' }
: { label: 'Promote User', value: 'promote_user' };
if (invite) return inviteActions;
return [
{ text: 'Actions...', value: '' },
userEnableAction,
userPromotionAction,
{ text: 'Require Password Reset', value: 'reset_password' },
{ text: 'Modify Details', value: 'modify_details' },
{ label: 'Require Password Reset', value: 'reset_password' },
{ label: 'Modify Details', value: 'modify_details' },
];
};
@@ -70,9 +68,8 @@ class UserBlock extends Component {
return onEditUser(user, updatedUser);
}
onUserActionSelect = ({ target }) => {
onUserActionSelect = ({ value: action }) => {
const { onSelect, user } = this.props;
const { value: action } = target;
if (action === 'modify_details') {
this.setState({
@@ -93,7 +90,7 @@ class UserBlock extends Component {
return (
<Dropdown
options={userActionOptions}
initialOption={{ text: 'Actions...' }}
placeholder="Actions..."
onSelect={onUserActionSelect}
className={invite ? 'revoke-invite' : ''}
/>