diff --git a/assets/images/down-arrow.png b/assets/images/down-arrow.png
new file mode 100644
index 0000000000..443ecdcdd1
Binary files /dev/null and b/assets/images/down-arrow.png differ
diff --git a/frontend/components/forms/fields/Dropdown/Dropdown.jsx b/frontend/components/forms/fields/Dropdown/Dropdown.jsx
index 37e26a2338..485c74ca5c 100644
--- a/frontend/components/forms/fields/Dropdown/Dropdown.jsx
+++ b/frontend/components/forms/fields/Dropdown/Dropdown.jsx
@@ -6,7 +6,6 @@ import componentStyles from './styles';
class Dropdown extends Component {
static propTypes = {
containerStyles: PropTypes.object,
- fieldName: PropTypes.string,
options: PropTypes.arrayOf(PropTypes.shape({
text: PropTypes.string,
value: PropTypes.string,
@@ -19,12 +18,11 @@ class Dropdown extends Component {
};
onOptionClick = (evt) => {
- const { target: { value } } = evt;
- const { fieldName, onSelect } = this.props;
+ evt.preventDefault();
- onSelect({
- [fieldName]: value,
- });
+ const { onSelect } = this.props;
+
+ onSelect(evt);
return false;
}
@@ -46,11 +44,13 @@ class Dropdown extends Component {
const { selectWrapperStyles } = componentStyles;
return (
-
- {options.map(option => {
- return renderOption(option);
- })}
-
+
+
+ {options.map(option => {
+ return renderOption(option);
+ })}
+
+
);
}
}
diff --git a/frontend/components/forms/queries/SaveQueryForm/SaveQueryForm.jsx b/frontend/components/forms/queries/SaveQueryForm/SaveQueryForm.jsx
index d08c445613..86774543ec 100644
--- a/frontend/components/forms/queries/SaveQueryForm/SaveQueryForm.jsx
+++ b/frontend/components/forms/queries/SaveQueryForm/SaveQueryForm.jsx
@@ -2,6 +2,7 @@ import React, { Component, PropTypes } from 'react';
import radium from 'radium';
import componentStyles from './styles';
import Button from '../../../buttons/Button';
+import Dropdown from '../../fields/Dropdown';
import InputField from '../../fields/InputField';
import validatePresence from '../../validators/validate_presence';
@@ -54,7 +55,6 @@ class SaveQueryForm extends Component {
onFieldChange = (fieldName) => {
return ({ target }) => {
const { errors, formData } = this.state;
-
this.setState({
errors: {
...errors,
@@ -160,11 +160,7 @@ class SaveQueryForm extends Component {
renderMoreOptionsFormFields = () => {
const {
errors,
- formData: {
- duration,
- platforms,
- hosts,
- },
+ formData: { hosts },
showMoreOptions,
} = this.state;
const {
@@ -200,16 +196,12 @@ class SaveQueryForm extends Component {
Query Duration
-
- Short
- Long
-
+ options={[{ text: 'Short', value: 'short' }, { text: 'Long', value: 'long' }]}
+ onSelect={onFieldChange('duration')}
+ containerStyles={dropdownInputStyles}
+ />
Individual hosts are not always online. A longer duration will return more complete results. You can view results of any in-progress query at any time.
@@ -218,16 +210,12 @@ class SaveQueryForm extends Component {
Query Platform
-
- ALL PLATFORMS
- NO PLATFORMS
-
+ options={[{ text: 'ALL PLATFORMS', value: 'all' }, { text: 'NO PLATFORMS', value: 'none' }]}
+ onSelect={onFieldChange('platforms')}
+ containerStyles={dropdownInputStyles}
+ />
Specifying a platform allows you to restrict the query from running on a certain platform (even on hosts specifically targeted that do not match).
diff --git a/frontend/pages/Admin/UserManagementPage/UserBlock/UserBlock.jsx b/frontend/pages/Admin/UserManagementPage/UserBlock/UserBlock.jsx
index 0f6e7d180e..a67ba9fd22 100644
--- a/frontend/pages/Admin/UserManagementPage/UserBlock/UserBlock.jsx
+++ b/frontend/pages/Admin/UserManagementPage/UserBlock/UserBlock.jsx
@@ -7,6 +7,7 @@ import EditUserForm from '../../../../components/forms/Admin/EditUserForm';
class UserBlock extends Component {
static propTypes = {
+ onEditUser: PropTypes.func,
onSelect: PropTypes.func,
user: PropTypes.object,
};
@@ -49,23 +50,20 @@ class UserBlock extends Component {
}
onEditUserFormSubmit = (updatedUser) => {
- const { user, onSelect } = this.props;
- const formData = {
- user_actions: 'edit_user',
- updated_user: updatedUser,
- };
+ const { user, onEditUser } = this.props;
this.setState({
isEdit: false,
});
- return onSelect(user, formData);
+ return onEditUser(user, updatedUser);
}
- onUserActionSelect = (formData) => {
+ onUserActionSelect = ({ target }) => {
const { onSelect, user } = this.props;
+ const { value: action } = target;
- if (formData.user_actions === 'modify_details') {
+ if (action === 'modify_details') {
this.setState({
isEdit: true,
});
@@ -73,7 +71,7 @@ class UserBlock extends Component {
return false;
}
- return onSelect(user, formData);
+ return onSelect(user, action);
}
render () {
@@ -125,7 +123,6 @@ class UserBlock extends Component {
{position}
{email}
{
+ onUserActionSelect = (user, action) => {
const { dispatch } = this.props;
const { update } = userActions;
- if (formData.user_actions) {
- switch (formData.user_actions) {
+ if (action) {
+ switch (action) {
case 'demote_user':
return dispatch(update(user, { admin: false }))
.then(() => {
@@ -63,11 +63,6 @@ class UserManagementPage extends Component {
.then(() => {
return dispatch(renderFlash('success', 'User forced to reset password', update(user, { force_password_reset: false })));
});
- case 'edit_user':
- return dispatch(update(user, formData.updated_user))
- .then(() => {
- return dispatch(renderFlash('success', 'User updated', update(user, user)));
- });
default:
return false;
}
@@ -76,6 +71,18 @@ class UserManagementPage extends Component {
return false;
}
+ onEditUser = (user, updatedUser) => {
+ const { dispatch } = this.props;
+ const { update } = userActions;
+
+ return dispatch(update(user, updatedUser))
+ .then(() => {
+ return dispatch(
+ renderFlash('success', 'User updated', update(user, user))
+ );
+ });
+ }
+
onInviteUserSubmit = (formData) => {
console.log('user invited', formData);
return this.toggleInviteUserModal();
@@ -98,11 +105,12 @@ class UserManagementPage extends Component {
}
renderUserBlock = (user) => {
- const { onUserActionSelect } = this;
+ const { onEditUser, onUserActionSelect } = this;
return (
diff --git a/frontend/styles/stylesheets/forms.scss b/frontend/styles/stylesheets/forms.scss
index 2990ed2c76..f850cbd14a 100644
--- a/frontend/styles/stylesheets/forms.scss
+++ b/frontend/styles/stylesheets/forms.scss
@@ -2,7 +2,6 @@
color: #A8B1CD;
opacity: 1;
}
-
.Select.target-select {
.Select-control {
padding-bottom: 5px;
@@ -26,3 +25,40 @@
color: #A8B1CD;
}
}
+.kolide-dropdown {
+ -webkit-appearance: none;
+ -moz-appearance: none;
+ appearance: none;
+ border: 1px solid #AE6DDf;
+ border-radius: 2px;
+ color: #858495;
+ font-size: 14px;
+ height: 30px;
+ text-indent: 4px;
+ text-transform: uppercase;
+ width: 100%;
+ background-color: #FFFFFF;
+}
+.kolide-dropdown-wrapper {
+ height: 30px;
+ position: relative;
+ :focus {
+ outline: none;
+ }
+ &:after {
+ content: '';
+ display: block;
+ width: 30px;
+ height: 29px;
+ background: url('/assets/images/down-arrow.png') no-repeat;
+ background-color: #AE6DDF;
+ background-position: center;
+ background-size: 15px;
+ border-top-right-radius: 2px;
+ border-bottom-right-radius: 2px;
+ pointer-events: none;
+ position: absolute;
+ top: 1px;
+ right: 0;
+ }
+}