UNPKG

cspace-ui

Version:
228 lines (192 loc) 5.95 kB
import React, { Component } from 'react'; import PropTypes from 'prop-types'; import { defineMessages, FormattedMessage } from 'react-intl'; import Immutable from 'immutable'; import get from 'lodash/get'; import { ConnectedPanel } from '../../containers/layout/PanelContainer'; import { OP_AND, OP_OR, OP_GROUP } from '../../constants/searchOperators'; import GroupConditionInputContainer from '../../containers/search/input/GroupConditionInputContainer'; import BooleanConditionInput from './input/BooleanConditionInput'; import FieldConditionInput from './input/FieldConditionInput'; import { SEARCH_TERMS_GROUP_LIMIT_BY, SEARCH_TERMS_GROUP_SEARCH_TERMS, } from '../../constants/searchNames'; const propTypes = { condition: PropTypes.instanceOf(Immutable.Map), config: PropTypes.shape({ recordTypes: PropTypes.object, }), hasChildGroups: PropTypes.bool, inline: PropTypes.bool, withoutPanel: PropTypes.bool, preferredBooleanOp: PropTypes.string, preferredCondition: PropTypes.instanceOf(Immutable.Map), readOnly: PropTypes.bool, recordType: PropTypes.string, searchTermsGroup: PropTypes.string, onConditionCommit: PropTypes.func, isBroadSearch: PropTypes.bool, }; const defaultProps = { preferredBooleanOp: 'or', }; const childContextTypes = { recordType: PropTypes.string, }; const messages = defineMessages({ title: { id: 'advancedSearchBuilder.title', defaultMessage: 'Advanced Search', }, }); const ensureRootBooleanOp = (condition, preferredBooleanOp) => { const op = condition && condition.get('op'); if (op === OP_AND || op === OP_OR) { return condition; } return ( Immutable.Map() .set('op', preferredBooleanOp) .set('value', condition ? Immutable.List.of(condition) : Immutable.List()) ); }; export const getSearchConditionInputComponent = (condition) => { const operator = condition.get('op'); if (operator === OP_AND || operator === OP_OR) { return BooleanConditionInput; } if (operator === OP_GROUP) { return GroupConditionInputContainer; } return FieldConditionInput; }; export default class AdvancedSearchBuilder extends Component { constructor() { super(); this.handleConditionCommit = this.handleConditionCommit.bind(this); } getChildContext() { const { recordType, } = this.props; return { recordType, }; } componentDidMount() { this.normalizeCondition(); } componentDidUpdate() { this.normalizeCondition(); } handleConditionCommit(name, condition) { const { onConditionCommit, } = this.props; if (onConditionCommit) { onConditionCommit(condition); } } normalizeCondition() { const { condition, config, preferredBooleanOp, preferredCondition, recordType, onConditionCommit, searchTermsGroup, isBroadSearch, } = this.props; if (recordType && onConditionCommit) { let normalizedCondition; let initialCondition; if (condition) { normalizedCondition = ensureRootBooleanOp(condition, preferredBooleanOp); } else { const isNewSearchForm = searchTermsGroup === SEARCH_TERMS_GROUP_LIMIT_BY || searchTermsGroup === SEARCH_TERMS_GROUP_SEARCH_TERMS; // use preferred condition when not using new search form if (!isNewSearchForm) { initialCondition = preferredCondition; } // use config condition when there is no preferred condition // and not using new search form or for new search terms group when is broad search if ( !initialCondition && ( !isNewSearchForm || (searchTermsGroup === SEARCH_TERMS_GROUP_SEARCH_TERMS && isBroadSearch) ) ) { initialCondition = Immutable.fromJS( get(config, ['recordTypes', recordType, 'advancedSearch']), ); } normalizedCondition = ensureRootBooleanOp(initialCondition, preferredBooleanOp); if (normalizedCondition.get('op') !== preferredBooleanOp) { normalizedCondition = normalizedCondition.set('op', preferredBooleanOp); } } if (normalizedCondition !== condition) { onConditionCommit(normalizedCondition); } } } render() { const { condition, config, hasChildGroups, inline, readOnly, recordType, withoutPanel, searchTermsGroup, isBroadSearch, } = this.props; if (!condition) { return null; } const isNewSearchForm = searchTermsGroup === SEARCH_TERMS_GROUP_LIMIT_BY || searchTermsGroup === SEARCH_TERMS_GROUP_SEARCH_TERMS; const SearchConditionInputComponent = getSearchConditionInputComponent(condition); const searchConditionInput = ( <SearchConditionInputComponent condition={condition} config={config} hasChildGroups={hasChildGroups} inline={inline} name="advancedSearch" readOnly={readOnly} isNewSearchForm={isNewSearchForm} recordType={recordType} showInlineParens={false} showRemoveButton={false} showMiniButtonFooter={!(isBroadSearch && isNewSearchForm)} getSearchConditionInputComponent={getSearchConditionInputComponent} onCommit={this.handleConditionCommit} /> ); if (inline || withoutPanel) { return searchConditionInput; } const panelHeader = ( <h3><FormattedMessage {...messages.title} /></h3> ); return ( <ConnectedPanel collapsible header={panelHeader} name="advancedSearch" recordType={recordType} > {searchConditionInput} </ConnectedPanel> ); } } AdvancedSearchBuilder.propTypes = propTypes; AdvancedSearchBuilder.defaultProps = defaultProps; AdvancedSearchBuilder.childContextTypes = childContextTypes;