Skip to content

Commit

Permalink
Decorator UI Fixes (#2539)
Browse files Browse the repository at this point in the history
* Some minor fixes for decorator UI.

These include:

  - resetting the decorators form so old values are not kept on cancel
  - making add decorator component pure, to prevent flickering in select
  - checking if SearchPage is mounted before setting state in callback

* Adding some style fixes for cross-browser layout consistency.
  • Loading branch information
dennisoelkers authored and edmundoa committed Jul 27, 2016
1 parent 8e30924 commit eacb574
Show file tree
Hide file tree
Showing 6 changed files with 59 additions and 23 deletions.
11 changes: 11 additions & 0 deletions graylog2-web-interface/src/components/common/SortableListItem.css
@@ -0,0 +1,11 @@
:local(.fullWidth) {
width: 100%;
}

:local(.inlineFlex) {
display: inline-flex;
}

:local(.itemHandle) {
margin-right: 10px;
}
Expand Up @@ -3,6 +3,8 @@ import ReactDOM from 'react-dom';
import {ListGroupItem} from 'react-bootstrap';
import { DragSource, DropTarget } from 'react-dnd';

import SortableListItemStyle from '!style!css!components/common/SortableListItem.css';

const ItemTypes = {
ITEM: 'item',
};
Expand Down Expand Up @@ -90,7 +92,7 @@ const SortableListItem = React.createClass({
},
render() {
const { text, isDragging, isOver, connectDragSource, connectDropTarget } = this.props;
const classes = [];
const classes = [SortableListItemStyle.inlineFlex, SortableListItemStyle.fullWidth];
if (isDragging) {
classes.push('dragging');
}
Expand All @@ -100,8 +102,8 @@ const SortableListItem = React.createClass({

return connectDragSource(connectDropTarget(
<div className="sortable-list-item">
<ListGroupItem className={classes.join(' ')} style={{ display: 'inline-flex' }}>
<i className="fa fa-sort" style={{ marginRight: 10 }}/> {text}
<ListGroupItem className={classes.join(' ')}>
<i className={`fa fa-sort ${SortableListItemStyle.itemHandle}`}/> {text}
</ListGroupItem>
</div>
));
Expand Down
@@ -1,6 +1,7 @@
import React from 'react';
import Reflux from 'reflux';
import jQuery from 'jquery';
import PureRenderMixin from 'react-addons-pure-render-mixin';

import { ConfigurationForm } from 'components/configurationforms';
import { Select, Spinner } from 'components/common';
Expand All @@ -11,12 +12,14 @@ const DecoratorsStore = StoreProvider.getStore('Decorators');
import ActionsProvider from 'injection/ActionsProvider';
const DecoratorsActions = ActionsProvider.getActions('Decorators');

import DecoratorStyles from '!style!css!components/search/decoratorStyles.css';

const AddDecoratorButton = React.createClass({
propTypes: {
nextOrder: React.PropTypes.number,
stream: React.PropTypes.string,
},
mixins: [Reflux.connect(DecoratorsStore)],
mixins: [Reflux.connect(DecoratorsStore), PureRenderMixin],
getInitialState() {
return {
typeDefinition: {},
Expand All @@ -28,6 +31,7 @@ const AddDecoratorButton = React.createClass({
},
_handleCancel() {
this.refs.select.clearValue();
this.setState(this.getInitialState());
},
_handleSubmit(data) {
const request = {
Expand Down Expand Up @@ -62,9 +66,9 @@ const AddDecoratorButton = React.createClass({
typeName={this.state.typeName} includeTitleField={false}
submitAction={this._handleSubmit} cancelAction={this._handleCancel} /> : null);
return (
<div className="form-inline" style={{ margin: '4px' }}>
<div className="form-group">
<div className="form-group" style={{ width: 300 }}>
<div className={`form-inline ${DecoratorStyles.addDecoratorButtonContainer}`}>
<div className={`form-group ${DecoratorStyles.decoratorBox} ${DecoratorStyles.fullWidth}`}>
<div className={`form-group ${DecoratorStyles.addDecoratorSelect}`}>
<Select ref="select"
placeholder="Select decorator"
onValueChange={this._onTypeChange}
Expand All @@ -77,7 +81,7 @@ const AddDecoratorButton = React.createClass({
onClick={this._openModal}>Add</button>

</div>
{configurationForm}
{this.state.typeName && configurationForm}
</div>
);
},
Expand Down
28 changes: 14 additions & 14 deletions graylog2-web-interface/src/components/search/Decorator.jsx
Expand Up @@ -12,6 +12,8 @@ const DecoratorsStore = StoreProvider.getStore('Decorators');
import ActionsProvider from 'injection/ActionsProvider';
const DecoratorsActions = ActionsProvider.getActions('Decorators');

import DecoratorStyles from '!style!css!components/search/decoratorStyles.css';

const Decorator = React.createClass({
propTypes: {
decorator: React.PropTypes.object.isRequired,
Expand Down Expand Up @@ -45,21 +47,19 @@ const Decorator = React.createClass({
const decorator = this.props.decorator;
const decoratorType = this.state.types[decorator.type] || this._decoratorTypeNotPresent();
return (
<span>
<Col md={8}>
<span className={DecoratorStyles.fullWidth}>
<span className={DecoratorStyles.decoratorBox}>
<strong>{decoratorType.name}</strong>
</Col>
<Col md={4} className="text-right">
<Button bsStyle="primary" bsSize="xsmall" onClick={this._handleDeleteClick}>Delete</Button>
{' '}
<Button bsStyle="info" bsSize="xsmall" onClick={this._handleEditClick}>Edit</Button>
</Col>
<Col md={12}>
<ConfigurationWell key={`configuration-well-decorator-${decorator._id}`}
id={decorator._id}
configuration={decorator.config}
typeDefinition={this.props.typeDefinition}/>
</Col>
<span>
<Button bsStyle="primary" bsSize="xsmall" onClick={this._handleDeleteClick}>Delete</Button>
{' '}
<Button bsStyle="info" bsSize="xsmall" onClick={this._handleEditClick}>Edit</Button>
</span>
</span>
<ConfigurationWell key={`configuration-well-decorator-${decorator._id}`}
id={decorator._id}
configuration={decorator.config}
typeDefinition={this.props.typeDefinition}/>
<ConfigurationForm ref="editForm"
key="configuration-form-decorator"
configFields={this.props.typeDefinition.requested_configuration}
Expand Down
17 changes: 17 additions & 0 deletions graylog2-web-interface/src/components/search/decoratorStyles.css
@@ -0,0 +1,17 @@
:local(.fullWidth) {
width: 100%;
}

:local(.decoratorBox) {
display: flex;
justify-content: space-between;
}

:local(.addDecoratorButtonContainer) {
margin: 4px;
display: flex;
}

:local(.addDecoratorSelect) {
width: 80%;
}
4 changes: 3 additions & 1 deletion graylog2-web-interface/src/pages/SearchPage.jsx
Expand Up @@ -80,7 +80,9 @@ const SearchPage = React.createClass({
UniversalSearchStore.search(SearchStore.rangeType, query, SearchStore.rangeParams.toJS(), streamId, null, SearchStore.page, SearchStore.sortField, SearchStore.sortOrder)
.then(
response => {
this.setState({ searchResult: response, error: undefined });
if (this.isMounted()) {
this.setState({ searchResult: response, error: undefined });
}

const interval = this.props.location.query.interval ? this.props.location.query.interval : this._determineHistogramResolution(response);

Expand Down

0 comments on commit eacb574

Please sign in to comment.