UNPKG

@react-awesome-query-builder-dev/ui

Version:
231 lines (207 loc) 9.02 kB
import React, { Component } from "react"; import { Utils } from "@react-awesome-query-builder-dev/core"; import PropTypes from "prop-types"; import context from "../../stores/context"; import {pureShouldComponentUpdate} from "../../utils/reactUtils"; import {connect} from "react-redux"; import classNames from "classnames"; const {getFieldConfig} = Utils.ConfigUtils; const createRuleContainer = (Rule) => class RuleContainer extends Component { static propTypes = { id: PropTypes.string.isRequired, groupId: PropTypes.string, config: PropTypes.object.isRequired, path: PropTypes.any.isRequired, //instanceOf(Immutable.List) operator: PropTypes.string, field: PropTypes.any, fieldSrc: PropTypes.string, fieldType: PropTypes.string, actions: PropTypes.object.isRequired, //{removeRule: Function, setField, setFieldSrc, setOperator, setOperatorOption, setValue, setValueSrc, ...} onDragStart: PropTypes.func, value: PropTypes.any, //depends on widget valueSrc: PropTypes.any, asyncListValues: PropTypes.array, valueError: PropTypes.any, fieldError: PropTypes.string, operatorOptions: PropTypes.object, reordableNodesCnt: PropTypes.number, parentField: PropTypes.string, //from RuleGroup isLocked: PropTypes.bool, isTrueLocked: PropTypes.bool, //connected: dragging: PropTypes.object, //{id, x, y, w, h} isDraggingTempo: PropTypes.bool, }; constructor(props) { super(props); this.pureShouldComponentUpdate = pureShouldComponentUpdate(this); this.dummyFn.isDummyFn = true; } dummyFn = () => {}; removeSelf = () => { this.props.actions.removeRule(this.props.path); }; setLock = (lock = null) => { this.props.actions.setLock(this.props.path, lock); }; setField = (field, asyncListValues, _meta) => { this.props.actions.setField(this.props.path, field, asyncListValues, _meta); }; setFieldSrc = (srcKey) => { this.props.actions.setFieldSrc(this.props.path, srcKey); }; setOperator = (operator) => { this.props.actions.setOperator(this.props.path, operator); }; setOperatorOption = (name, value) => { this.props.actions.setOperatorOption(this.props.path, name, value); }; setValue = (delta, value, type, asyncListValues, _meta) => { this.props.actions.setValue(this.props.path, delta, value, type, asyncListValues, _meta); }; setValueSrc = (delta, srcKey, _meta) => { this.props.actions.setValueSrc(this.props.path, delta, srcKey, _meta); }; // can be used for both LHS and LHS setFuncValue = (delta, parentFuncs, argKey, value, type, asyncListValues, _meta) => { this.props.actions.setFuncValue(this.props.path, delta, parentFuncs, argKey, value, type, asyncListValues, _meta); }; shouldComponentUpdate(nextProps, nextState) { let prevProps = this.props; let prevState = this.state; let should = this.pureShouldComponentUpdate(nextProps, nextState); if (should) { if (prevState == nextState && prevProps != nextProps) { const draggingId = (nextProps.dragging.id || prevProps.dragging.id); const isDraggingMe = draggingId == nextProps.id; let chs = []; for (let k in nextProps) { let changed = (nextProps[k] != prevProps[k]); if (k == "dragging" && !isDraggingMe) { changed = false; //dragging another item -> ignore } if (changed) { chs.push(k); } } if (!chs.length) should = false; } } return should; } render() { const isDraggingMe = this.props.dragging.id == this.props.id; const fieldConfig = getFieldConfig(this.props.config, this.props.field); const fieldType = this.props.fieldType || fieldConfig?.type || null; const {showErrorMessage} = this.props.config.settings; const _isGroup = fieldConfig && fieldConfig.type == "!struct"; const isInDraggingTempo = !isDraggingMe && this.props.isDraggingTempo; const {valueError, fieldError} = this.props; const oneError = [fieldError, ...(valueError?.toArray() || [])].filter(e => !!e).shift() || null; const hasError = oneError != null && showErrorMessage; return ( <div className={classNames("group-or-rule-container", "rule-container", hasError ? "rule-with-error" : null)} data-id={this.props.id} > {[ isDraggingMe ? <Rule key={"dragging"} id={this.props.id} groupId={this.props.groupId} lev={this.props.path.size - 1} isDraggingMe={true} isDraggingTempo={true} dragging={this.props.dragging} setField={this.dummyFn} setFieldSrc={this.dummyFn} setFuncValue={this.dummyFn} setOperator={this.dummyFn} setOperatorOption={this.dummyFn} setLock={this.dummyFn} removeSelf={this.dummyFn} setValue={this.dummyFn} setValueSrc={this.dummyFn} selectedField={this.props.field || null} selectedFieldSrc={this.props.fieldSrc || "field"} selectedFieldType={fieldType} parentField={this.props.parentField || null} parentFieldPathSize={this.props.parentFieldPathSize} parentFieldCanReorder={this.props.parentFieldCanReorder} selectedOperator={this.props.operator || null} value={this.props.value || null} valueSrc={this.props.valueSrc || null} valueType={this.props.valueType || null} valueError={this.props.valueError || null} fieldError={this.props.fieldError || null} operatorOptions={this.props.operatorOptions} config={this.props.config} reordableNodesCnt={this.props.reordableNodesCnt} totalRulesCnt={this.props.totalRulesCnt} asyncListValues={this.props.asyncListValues} isLocked={this.props.isLocked} isTrueLocked={this.props.isTrueLocked} parentReordableNodesCnt={this.props.parentReordableNodesCnt} /> : null , <Rule key={this.props.id} id={this.props.id} groupId={this.props.groupId} lev={this.props.path.size - 1} isDraggingMe={isDraggingMe} isDraggingTempo={isInDraggingTempo} onDragStart={this.props.onDragStart} setLock={isInDraggingTempo ? this.dummyFn : this.setLock} removeSelf={isInDraggingTempo ? this.dummyFn : this.removeSelf} setField={isInDraggingTempo ? this.dummyFn : this.setField} setFieldSrc={isInDraggingTempo ? this.dummyFn : this.setFieldSrc} setFuncValue={isInDraggingTempo ? this.dummyFn : this.setFuncValue} setOperator={isInDraggingTempo ? this.dummyFn : this.setOperator} setOperatorOption={isInDraggingTempo ? this.dummyFn : this.setOperatorOption} setValue={isInDraggingTempo ? this.dummyFn : this.setValue} setValueSrc={isInDraggingTempo ? this.dummyFn : this.setValueSrc} selectedField={this.props.field || null} selectedFieldSrc={this.props.fieldSrc || "field"} selectedFieldType={fieldType} parentField={this.props.parentField || null} parentFieldPathSize={this.props.parentFieldPathSize} parentFieldCanReorder={this.props.parentFieldCanReorder} selectedOperator={this.props.operator || null} value={this.props.value || null} valueSrc={this.props.valueSrc || null} valueType={this.props.valueType || null} valueError={this.props.valueError || null} fieldError={this.props.fieldError || null} operatorOptions={this.props.operatorOptions} config={this.props.config} reordableNodesCnt={this.props.reordableNodesCnt} totalRulesCnt={this.props.totalRulesCnt} asyncListValues={this.props.asyncListValues} isLocked={this.props.isLocked} isTrueLocked={this.props.isTrueLocked} parentReordableNodesCnt={this.props.parentReordableNodesCnt} /> ]} </div> ); } }; export default (Rule) => { const ConnectedRuleContainer = connect( (state) => { return { dragging: state.dragging, }; }, null, null, { context } )(createRuleContainer(Rule)); ConnectedRuleContainer.displayName = "ConnectedRuleContainer"; return ConnectedRuleContainer; };