cspace-ui
Version:
CollectionSpace user interface for browsers
303 lines (295 loc) • 11.5 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
var _react = _interopRequireWildcard(require("react"));
var _propTypes = _interopRequireDefault(require("prop-types"));
var _reactIntl = require("react-intl");
var _immutable = _interopRequireDefault(require("immutable"));
var _get = _interopRequireDefault(require("lodash/get"));
var _FieldInput = _interopRequireDefault(require("./FieldInput"));
var _OperatorInput = _interopRequireDefault(require("./OperatorInput"));
var _RangeSearchField = _interopRequireDefault(require("../RangeSearchField"));
var _SearchField = _interopRequireDefault(require("../SearchField"));
var _RemoveConditionButton = _interopRequireDefault(require("../RemoveConditionButton"));
var _searchOperators = require("../../../constants/searchOperators");
var _configHelpers = require("../../../helpers/configHelpers");
var _configContextInputs = require("../../../helpers/configContextInputs");
var _searchHelpers = require("../../../helpers/searchHelpers");
var _FieldConditionInput = _interopRequireDefault(require("../../../../styles/cspace-ui/FieldConditionInput.css"));
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); }
function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
const propTypes = {
condition: _propTypes.default.instanceOf(_immutable.default.Map),
config: _propTypes.default.shape({
recordTypes: _propTypes.default.object
}),
inline: _propTypes.default.bool,
name: _propTypes.default.string,
readOnly: _propTypes.default.bool,
recordType: _propTypes.default.string,
rootPath: _propTypes.default.string,
onCommit: _propTypes.default.func,
onRemove: _propTypes.default.func
};
const messages = (0, _reactIntl.defineMessages)({
notFound: {
"id": "fieldConditionInput.notFound",
"defaultMessage": "field not found"
}
});
const isFieldControlled = fieldDescriptor => {
const viewType = (0, _get.default)(fieldDescriptor, [_configHelpers.configKey, 'view', 'type']);
return viewType === _configContextInputs.AutocompleteInput || viewType === _configContextInputs.OptionPickerInput || viewType === _configContextInputs.TermPickerInput;
};
class FieldConditionInput extends _react.Component {
constructor() {
super();
this.handleFieldCommit = this.handleFieldCommit.bind(this);
this.handleOperatorCommit = this.handleOperatorCommit.bind(this);
this.handleRef = this.handleRef.bind(this);
this.handleRemoveButtonClick = this.handleRemoveButtonClick.bind(this);
this.handleValueCommit = this.handleValueCommit.bind(this);
}
componentDidMount() {
const {
condition
} = this.props;
const path = condition.get('path');
if (path === null) {
// The condition was just added, and the field needs to be selected. Focus it.
if (this.domNode) {
const input = this.domNode.querySelector('input[data-name="field"]');
if (input) {
input.focus();
}
}
}
}
componentDidUpdate(prevProps) {
const {
condition
} = this.props;
const {
condition: prevCondition
} = prevProps;
if (condition !== prevCondition) {
const path = condition.get('path');
if (path) {
const ops = this.getOperators(path);
if (!ops.includes(condition.get('op'))) {
// The new field's operators don't include the current operator. Set the operator to the
// first of the new field's supported operators.
// FIXME: This doesn't work if componentDidUpdate in AdvancedSearchBuilder executes
// normalizeCondition, and the condition is normalized. In that case, it will restore the
// previous operator. This all needs to be reworked.
this.setOperator(ops[0]);
}
}
if (path !== null && prevCondition.get('path') === null) {
// The field was just selected. Focus the operator.
if (this.domNode) {
const input = this.domNode.querySelector('input[data-name="searchOp"]');
if (input) {
input.focus();
}
}
}
}
}
handleFieldCommit(path, fieldPath) {
const {
condition,
name,
onCommit
} = this.props;
if (onCommit) {
// Delete the current value, since it may not be valid for the new field.
onCommit(name, condition.set('path', fieldPath).delete('value'));
}
}
handleOperatorCommit(path, operator) {
this.setOperator(operator);
}
handleRef(ref) {
this.domNode = ref;
}
handleRemoveButtonClick() {
const {
name,
onRemove
} = this.props;
if (onRemove) {
onRemove(name);
}
}
handleValueCommit(path, value) {
const {
condition,
name,
onCommit
} = this.props;
if (onCommit) {
onCommit(name, condition.set('value', value));
}
}
getOperators(path) {
const {
config,
recordType
} = this.props;
const fieldDescriptor = (0, _get.default)(config, ['recordTypes', recordType, 'fields', 'document', ...path.split('/')]);
const dataType = (0, _configHelpers.getFieldDataType)(fieldDescriptor);
const isControlled = isFieldControlled(fieldDescriptor);
return (0, _searchHelpers.getOperatorsForDataType)(dataType, isControlled);
}
setOperator(operator) {
const {
condition,
name,
onCommit
} = this.props;
if (onCommit) {
let nextCondition = condition.set('op', operator);
if (!(0, _searchHelpers.operatorExpectsValue)(operator)) {
// If the new operator doesn't expect a value, remove any values that exist.
nextCondition = nextCondition.delete('value');
} else if (!(0, _searchHelpers.operatorSupportsMultipleValues)(operator)) {
// If the new operator doesn't support multiple values, prune all values except the first.
const value = condition.get('value');
if (_immutable.default.List.isList(value)) {
nextCondition = nextCondition.set('value', value.first());
}
}
onCommit(name, nextCondition);
}
}
renderFieldInput() {
const {
condition,
config,
inline,
recordType,
rootPath
} = this.props;
const pathSpec = condition.get('path');
if (!pathSpec) {
if (inline) {
return null;
}
return /*#__PURE__*/_react.default.createElement(_FieldInput.default, {
config: config,
inline: inline,
name: "field",
placeholder: "Field",
recordType: recordType,
rootPath: rootPath,
onCommit: this.handleFieldCommit
});
}
const path = ['document', ...pathSpec.split('/')];
const fieldDescriptor = (0, _get.default)(config, ['recordTypes', recordType, 'fields', ...path]);
return /*#__PURE__*/_react.default.createElement(_FieldInput.default, {
config: config,
inline: inline,
readOnly: true,
recordType: recordType,
rootPath: rootPath,
value: pathSpec,
valueDescriptor: fieldDescriptor,
onCommit: this.handleFieldCommit
});
}
renderOperatorInput() {
const {
condition,
config,
inline,
readOnly,
recordType
} = this.props;
const pathSpec = condition.get('path');
if (!pathSpec) {
return inline ? null : /*#__PURE__*/_react.default.createElement("div", null, /*#__PURE__*/_react.default.createElement("span", null, "..."));
}
const operator = condition.get('op');
const path = ['document', ...pathSpec.split('/')];
const fieldDescriptor = (0, _get.default)(config, ['recordTypes', recordType, 'fields', ...path]);
if (!fieldDescriptor) {
return inline ? null : /*#__PURE__*/_react.default.createElement("div", null, /*#__PURE__*/_react.default.createElement(_reactIntl.FormattedMessage, messages.notFound));
}
const dataType = (0, _configHelpers.getFieldDataType)(fieldDescriptor);
const isControlled = isFieldControlled(fieldDescriptor);
const operators = (0, _searchHelpers.getOperatorsForDataType)(dataType, isControlled);
return /*#__PURE__*/_react.default.createElement(_OperatorInput.default, {
compact: inline,
inline: inline,
name: "searchOp",
operators: operators,
readOnly: readOnly,
value: operator,
onCommit: this.handleOperatorCommit
});
}
renderValueInput() {
const {
condition,
config,
inline,
readOnly,
recordType
} = this.props;
const pathSpec = condition.get('path');
let valueSearchField = null;
if (pathSpec) {
const operator = condition.get('op');
const value = condition.get('value');
const path = ['document', ...pathSpec.split('/')];
const name = path[path.length - 1];
const parentPath = path.slice(0, path.length - 1);
const fieldDescriptor = (0, _get.default)(config, ['recordTypes', recordType, 'fields', ...path]);
if (!fieldDescriptor) {
return /*#__PURE__*/_react.default.createElement("div", null);
}
const dataType = (0, _configHelpers.getFieldDataType)(fieldDescriptor);
if ((0, _searchHelpers.operatorExpectsValue)(operator)) {
const ValueSearchFieldComponent = operator === _searchOperators.OP_RANGE || operator === _searchOperators.OP_NOT_RANGE ? _RangeSearchField.default : _SearchField.default;
valueSearchField = /*#__PURE__*/_react.default.createElement(ValueSearchFieldComponent, {
inline: inline,
parentPath: parentPath,
name: name,
readOnly: readOnly,
repeating: (0, _searchHelpers.operatorSupportsMultipleValues)(operator) && (0, _searchHelpers.dataTypeSupportsMultipleValues)(dataType),
value: value,
onCommit: this.handleValueCommit
});
}
}
return /*#__PURE__*/_react.default.createElement("div", null, valueSearchField);
}
renderRemoveButton() {
const {
readOnly
} = this.props;
if (readOnly) {
return null;
}
return /*#__PURE__*/_react.default.createElement(_RemoveConditionButton.default, {
onClick: this.handleRemoveButtonClick
});
}
render() {
const {
inline
} = this.props;
const className = inline ? _FieldConditionInput.default.inline : _FieldConditionInput.default.normal;
return /*#__PURE__*/_react.default.createElement("div", {
className: className,
ref: this.handleRef
}, this.renderFieldInput(), inline ? ' ' : null, this.renderOperatorInput(), inline ? ' ' : null, this.renderValueInput(), this.renderRemoveButton());
}
}
exports.default = FieldConditionInput;
FieldConditionInput.propTypes = propTypes;