cspace-ui
Version:
CollectionSpace user interface for browsers
165 lines (141 loc) • 3.88 kB
JSX
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import { defineMessages, injectIntl, intlShape, FormattedMessage } from 'react-intl';
import Immutable from 'immutable';
import { baseComponents as inputComponents } from 'cspace-input';
import SearchConditionInput from './SearchConditionInput';
import {
OP_AND,
OP_OR,
} from '../../../constants/searchOperators';
import styles from '../../../../styles/cspace-ui/BooleanConditionInput.css';
const {
DropdownMenuInput,
} = inputComponents;
const messages = {
[OP_AND]: defineMessages({
label: {
id: 'booleanConditionInput.and.label',
defaultMessage: 'and',
},
opSelectorLabel: {
id: 'booleanConditionInput.and.opSelectorLabel',
defaultMessage: 'All',
},
}),
[OP_OR]: defineMessages({
label: {
id: 'booleanConditionInput.or.label',
defaultMessage: 'or',
},
opSelectorLabel: {
id: 'booleanConditionInput.or.opSelectorLabel',
defaultMessage: 'Any',
},
}),
opSelector: defineMessages({
label: {
id: 'booleanConditionInput.opSelector.label',
defaultMessage: `{opSelectorInput} of the following conditions { operator, select,
and {must}
or {may}
} be satisfied:`,
},
}),
};
const propTypes = {
condition: PropTypes.instanceOf(Immutable.Map),
fields: PropTypes.object,
inline: PropTypes.bool,
intl: intlShape,
readOnly: PropTypes.bool,
onCommit: PropTypes.func,
};
class BooleanConditionInput extends Component {
constructor() {
super();
this.handleOpSelectorCommit = this.handleOpSelectorCommit.bind(this);
}
handleOpSelectorCommit(path, value) {
const {
condition,
onCommit,
} = this.props;
if (onCommit) {
onCommit(condition.set('op', value));
}
}
handleChildConditionCommit(index, childCondition) {
const {
condition,
onCommit,
} = this.props;
if (onCommit) {
onCommit(condition.setIn(['value', index], childCondition));
}
}
render() {
const {
condition,
fields,
inline,
intl,
readOnly,
} = this.props;
const handleChildConditionCommit = index => (childCondition) => {
this.handleChildConditionCommit(index, childCondition);
};
const operator = condition.get('op');
const childConditions = condition.get('value');
const inputs = childConditions.map((childCondition, index) => {
const operatorLabel = (index > 0)
? <FormattedMessage {...messages[operator].label} />
: <span />;
return (
<li key={index}>
{operatorLabel}
<SearchConditionInput
condition={childCondition}
fields={fields}
index={index}
inline={inline}
readOnly={readOnly}
onCommit={handleChildConditionCommit(index)}
/>
</li>
);
});
let opSelector;
if (!readOnly) {
const opSelectorInput = (
<DropdownMenuInput
name="booleanSearchOp"
options={[
{ value: OP_OR, label: intl.formatMessage(messages[OP_OR].opSelectorLabel) },
{ value: OP_AND, label: intl.formatMessage(messages[OP_AND].opSelectorLabel) },
]}
value={operator}
onCommit={this.handleOpSelectorCommit}
/>
);
opSelector = (
<FormattedMessage
{...messages.opSelector.label}
tagName="div"
values={{ opSelectorInput, operator }}
/>
);
}
const className = inline ? styles.inline : styles.normal;
return (
<div className={className}>
{opSelector}
<ul>
{inputs}
</ul>
</div>
);
}
}
BooleanConditionInput.propTypes = propTypes;
export default injectIntl(BooleanConditionInput);