Hosts side panel (#472)

* Host side panel

* Query form handles labels

* QueryComposer handles labels

* ManageHostsPage add label transitions

* Stop preventing default on click outside of ellipsis menu

* get labels from API

* use real label data in hosts side panel

* create label on label form submit

* adds platform dropdown

* Validate query text

* Label header

* validate presence of query text
This commit is contained in:
Mike Stone
2016-11-17 12:12:41 -05:00
committed by GitHub
parent eff7f60dc2
commit bb62993ea5
40 changed files with 1006 additions and 165 deletions
@@ -2,6 +2,7 @@ import React, { Component, PropTypes } from 'react';
import { isEqual } from 'lodash';
import Button from 'components/buttons/Button';
import Dropdown from 'components/forms/fields/Dropdown';
import helpers from 'components/forms/queries/QueryForm/helpers';
import InputField from 'components/forms/fields/InputField';
import queryInterface from 'interfaces/query';
@@ -11,11 +12,13 @@ const baseClass = 'query-form';
class QueryForm extends Component {
static propTypes = {
onCancel: PropTypes.func,
onRunQuery: PropTypes.func,
onSaveAsNew: PropTypes.func,
onSaveChanges: PropTypes.func,
onSave: PropTypes.func,
onUpdate: PropTypes.func,
query: queryInterface,
queryText: PropTypes.string.isRequired,
queryType: PropTypes.string,
};
static defaultProps = {
@@ -25,27 +28,34 @@ class QueryForm extends Component {
constructor (props) {
super(props);
const { query: { description, name }, queryText } = this.props;
const {
query: { description, name },
queryText,
queryType,
} = this.props;
const errors = { description: null, name: null };
const formData = { description, name, query: queryText };
this.state = {
errors: {
description: null,
name: null,
},
formData: {
description,
name,
query: queryText,
},
};
if (queryType === 'label') {
const { allPlatforms: platform } = helpers;
this.state = {
errors: { ...errors, platform: null },
formData: { ...formData, platform },
};
} else {
this.state = { errors, formData };
}
}
componentDidMount = () => {
const { query, queryText } = this.props;
const { description, name } = query;
const { formData } = this.state;
this.setState({
formData: {
...formData,
description,
name,
query: queryText,
@@ -58,10 +68,13 @@ class QueryForm extends Component {
const { query: staleQuery, queryText: staleQueryText } = this.props;
if (!isEqual(query, staleQuery) || !isEqual(queryText, staleQueryText)) {
const { formData } = this.state;
this.setState({
formData: {
description: query.description,
name: query.name,
...formData,
description: query.description || formData.description,
name: query.name || formData.name,
query: queryText,
},
});
@@ -70,11 +83,23 @@ class QueryForm extends Component {
return false;
}
onCancel = (evt) => {
evt.preventDefault();
const { onCancel: handleCancel } = this.props;
return handleCancel();
}
onFieldChange = (name) => {
return (value) => {
const { formData } = this.state;
const { errors, formData } = this.state;
this.setState({
errors: {
...errors,
[name]: null,
},
formData: {
...formData,
[name]: value,
@@ -85,29 +110,29 @@ class QueryForm extends Component {
};
}
onSaveAsNew = (evt) => {
onSave = (evt) => {
evt.preventDefault();
const { formData } = this.state;
const { valid } = this;
const { onSaveAsNew: handleSaveAsNew } = this.props;
const { onSave: handleSave } = this.props;
if (valid()) {
handleSaveAsNew(formData);
handleSave(formData);
}
return false;
}
onSaveChanges = (evt) => {
onUpdate = (evt) => {
evt.preventDefault();
const { formData } = this.state;
const { valid } = this;
const { onSaveChanges: handleSaveChanges } = this.props;
const { onUpdate: handleUpdate } = this.props;
if (valid()) {
handleSaveChanges(formData);
handleUpdate(formData);
}
return false;
@@ -115,6 +140,7 @@ class QueryForm extends Component {
valid = () => {
const { errors, formData: { name } } = this.state;
const { queryType } = this.props;
const namePresent = validatePresence(name);
@@ -122,7 +148,7 @@ class QueryForm extends Component {
this.setState({
errors: {
...errors,
name: 'Query name must be present',
name: `${queryType === 'label' ? 'Label title' : 'Query title'} must be present`,
},
});
@@ -134,24 +160,94 @@ class QueryForm extends Component {
return true;
}
renderButtons = () => {
const { canSaveAsNew, canSaveChanges } = helpers;
const { formData } = this.state;
const { onRunQuery, query, queryType } = this.props;
const { onCancel, onSave, onUpdate } = this;
if (queryType === 'label') {
return (
<div className={`${baseClass}__button-wrap`}>
<Button
className={`${baseClass}__save-changes-btn`}
onClick={onCancel}
text="Cancel"
variant="inverse"
/>
<Button
className={`${baseClass}__save-as-new-btn`}
disabled={!canSaveAsNew(formData, query)}
onClick={onSave}
text="Save Label"
variant="brand"
/>
</div>
);
}
return (
<div className={`${baseClass}__button-wrap`}>
<Button
className={`${baseClass}__save-changes-btn`}
disabled={!canSaveChanges(formData, query)}
onClick={onUpdate}
text="Save Changes"
variant="inverse"
/>
<Button
className={`${baseClass}__save-as-new-btn`}
disabled={!canSaveAsNew(formData, query)}
onClick={onSave}
text="Save As New..."
variant="success"
/>
<Button
className={`${baseClass}__run-query-btn`}
onClick={onRunQuery}
text="Run Query"
variant="brand"
/>
</div>
);
}
renderPlatformDropdown = () => {
const { queryType } = this.props;
if (queryType !== 'label') {
return false;
}
const { formData: { platform } } = this.state;
const { onFieldChange } = this;
const { platformOptions } = helpers;
return (
<Dropdown
options={platformOptions}
onSelect={onFieldChange('platform')}
value={platform.value}
/>
);
}
render () {
const {
errors,
formData,
formData: {
description,
name,
},
} = this.state;
const { onFieldChange, onSaveAsNew, onSaveChanges } = this;
const { onRunQuery, query } = this.props;
const { canSaveAsNew, canSaveChanges } = helpers;
const { onFieldChange, renderPlatformDropdown, renderButtons } = this;
const { queryType } = this.props;
return (
<form className={baseClass}>
<InputField
error={errors.name}
label="Query Title"
label={queryType === 'label' ? 'Label title' : 'Query Title'}
name="name"
onChange={onFieldChange('name')}
value={name}
@@ -159,35 +255,15 @@ class QueryForm extends Component {
/>
<InputField
error={errors.description}
label="Query Description"
label="Description"
name="description"
onChange={onFieldChange('description')}
value={description}
type="textarea"
inputClassName={`${baseClass}__query-description`}
/>
<div className={`${baseClass}__button-wrap`}>
<Button
className={`${baseClass}__save-changes-btn`}
disabled={!canSaveChanges(formData, query)}
onClick={onSaveChanges}
text="Save Changes"
variant="inverse"
/>
<Button
className={`${baseClass}__save-as-new-btn`}
disabled={!canSaveAsNew(formData, query)}
onClick={onSaveAsNew}
text="Save As New..."
variant="success"
/>
<Button
className={`${baseClass}__run-query-btn`}
onClick={onRunQuery}
text="Run Query"
variant="brand"
/>
</div>
{renderPlatformDropdown()}
{renderButtons()}
</form>
);
}