@coocoon/react-awesome-query-builder
Version:
User-friendly query builder for React. Demo: https://ukrbublik.github.io/react-awesome-query-builder
571 lines (461 loc) • 23.3 kB
JavaScript
"use strict";
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.getWidgetsForFieldOp = exports.getWidgetForFieldOp = exports.getValueSourcesForFieldOp = exports.getValueLabel = exports.getOperatorsForField = exports.getNewValueForFieldOp = exports.getFuncPathLabels = exports.getFirstOperator = exports.getFirstField = exports.getFieldPathLabels = exports.getFieldPath = exports.getFieldPartsConfigs = exports.formatFieldName = exports.filterValueSourcesForField = void 0;
var _typeof2 = _interopRequireDefault(require("@babel/runtime/helpers/typeof"));
var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime/helpers/toConsumableArray"));
var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));
var _configUtils = require("./configUtils");
var _stuff = require("../utils/stuff");
var _immutable = _interopRequireDefault(require("immutable"));
var _validation = require("../utils/validation");
var _last = _interopRequireDefault(require("lodash/last"));
var selectTypes = ["select", "multiselect", "treeselect", "treemultiselect"];
/**
* @param {object} config
* @param {object} oldConfig
* @param {Immutable.Map} current
* @param {string} newField
* @param {string} newOperator
* @param {string} changedProp
* @return {object} - {canReuseValue, newValue, newValueSrc, newValueType, newValueError}
*/
var getNewValueForFieldOp = function getNewValueForFieldOp(config) {
var oldConfig = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null;
var current = arguments.length > 2 ? arguments[2] : undefined;
var newField = arguments.length > 3 ? arguments[3] : undefined;
var newOperator = arguments.length > 4 ? arguments[4] : undefined;
var changedProp = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : null;
var canFix = arguments.length > 6 && arguments[6] !== undefined ? arguments[6] : true;
var isFunc = arguments.length > 7 ? arguments[7] : undefined;
if (!oldConfig) oldConfig = config;
var currentField = current.get("field");
var currentOperator = current.get("operator");
var currentValue = current.get("value");
var currentValueSrc = current.get("valueSrc", new _immutable["default"].List());
var currentValueType = current.get("valueType", new _immutable["default"].List());
var currentAsyncListValues = current.get("asyncListValues"); //const isValidatingTree = (changedProp === null);
var _config$settings = config.settings,
convertableWidgets = _config$settings.convertableWidgets,
clearValueOnChangeField = _config$settings.clearValueOnChangeField,
clearValueOnChangeOp = _config$settings.clearValueOnChangeOp,
showErrorMessage = _config$settings.showErrorMessage; //const currentOperatorConfig = getOperatorConfig(oldConfig, currentOperator, currentField);
var newOperatorConfig = (0, _configUtils.getOperatorConfig)(config, newOperator, newField); //const currentOperatorCardinality = currentOperator ? defaultValue(currentOperatorConfig.cardinality, 1) : null;
var operatorCardinality = newOperator ? (0, _stuff.defaultValue)(newOperatorConfig.cardinality, 1) : null;
var currentFieldConfig = (0, _configUtils.getFieldConfig)(oldConfig, currentField, isFunc);
var newFieldConfig = (0, _configUtils.getFieldConfig)(config, newField, isFunc);
var canReuseValue = currentField && currentOperator && newOperator && currentValue != undefined && (!changedProp || changedProp == "field" && !clearValueOnChangeField || changedProp == "operator" && !clearValueOnChangeOp) && currentFieldConfig && newFieldConfig && currentFieldConfig.type == newFieldConfig.type;
if (canReuseValue && selectTypes.includes(currentFieldConfig.type) && changedProp == "field") {
// different fields of select types has different listValues
canReuseValue = false;
} // compare old & new widgets
for (var i = 0; i < operatorCardinality; i++) {
var vs = currentValueSrc.get(i) || null;
var currentWidget = getWidgetForFieldOp(oldConfig, currentField, currentOperator, vs, isFunc);
var newWidget = getWidgetForFieldOp(config, newField, newOperator, vs, isFunc); // need to also check value widgets if we changed operator and current value source was 'field'
// cause for select type op '=' requires single value and op 'in' requires array value
var currentValueWidget = vs == "value" ? currentWidget : getWidgetForFieldOp(oldConfig, currentField, currentOperator, "value", isFunc);
var newValueWidget = vs == "value" ? newWidget : getWidgetForFieldOp(config, newField, newOperator, "value", isFunc);
var canReuseWidget = newValueWidget == currentValueWidget || (convertableWidgets[currentValueWidget] || []).includes(newValueWidget);
if (!canReuseWidget) canReuseValue = false;
}
if (currentOperator != newOperator && [currentOperator, newOperator].includes("proximity")) canReuseValue = false;
var firstWidgetConfig = (0, _configUtils.getFieldWidgetConfig)(config, newField, newOperator, null, currentValueSrc.first(), isFunc);
var valueSources = getValueSourcesForFieldOp(config, newField, newOperator, null, null, isFunc);
var valueFixes = {};
var valueErrors = Array.from({
length: operatorCardinality
}, function () {
return null;
});
if (canReuseValue) {
var _loop = function _loop(_i) {
var v = currentValue.get(_i);
var vType = currentValueType.get(_i) || null;
var vSrc = currentValueSrc.get(_i) || null;
var isValidSrc = valueSources.find(function (v) {
return v == vSrc;
}) != null;
if (!isValidSrc && _i > 0 && vSrc == null) isValidSrc = true; // make exception for range widgets (when changing op from '==' to 'between')
var isEndValue = !canFix;
var asyncListValues = currentAsyncListValues;
var _validateValue = (0, _validation.validateValue)(config, newField, newField, newOperator, v, vType, vSrc, asyncListValues, canFix, isEndValue, true, isFunc),
_validateValue2 = (0, _slicedToArray2["default"])(_validateValue, 2),
validateError = _validateValue2[0],
fixedValue = _validateValue2[1];
var isValid = !validateError;
if (!isValid && showErrorMessage && changedProp != "field") {
// allow bad value
// but not on field change - in that case just drop bad value that can't be reused
// ? maybe we should also drop bad value on op change?
valueErrors[_i] = validateError;
} else if (!isValidSrc || !isValid) {
canReuseValue = false;
return "break";
} else if (canFix && fixedValue !== v) {
valueFixes[_i] = fixedValue;
}
};
for (var _i = 0; _i < operatorCardinality; _i++) {
var _ret = _loop(_i);
if (_ret === "break") break;
}
} // reuse value OR get defaultValue for cardinality 1 (it means default range values is not supported yet, todo)
var newValue = null,
newValueSrc = null,
newValueType = null,
newValueError = null;
newValue = new _immutable["default"].List(Array.from({
length: operatorCardinality
}, function (_ignore, i) {
var v = undefined;
if (canReuseValue) {
if (i < currentValue.size) {
v = currentValue.get(i);
if (valueFixes[i] !== undefined) {
v = valueFixes[i];
}
}
} else if (operatorCardinality == 1) {
var _newFieldConfig$field;
v = (0, _stuff.getFirstDefined)([newFieldConfig === null || newFieldConfig === void 0 ? void 0 : newFieldConfig.defaultValue, newFieldConfig === null || newFieldConfig === void 0 ? void 0 : (_newFieldConfig$field = newFieldConfig.fieldSettings) === null || _newFieldConfig$field === void 0 ? void 0 : _newFieldConfig$field.defaultValue, firstWidgetConfig === null || firstWidgetConfig === void 0 ? void 0 : firstWidgetConfig.defaultValue]);
}
return v;
}));
newValueSrc = new _immutable["default"].List(Array.from({
length: operatorCardinality
}, function (_ignore, i) {
var vs = null;
if (canReuseValue) {
if (i < currentValueSrc.size) vs = currentValueSrc.get(i);
} else if (valueSources.length == 1) {
vs = valueSources[0];
} else if (valueSources.length > 1) {
vs = valueSources[0];
}
return vs;
}));
if (showErrorMessage) {
if (newOperatorConfig && newOperatorConfig.validateValues && newValueSrc.toJS().filter(function (vs) {
return vs == "value" || vs == null;
}).length == operatorCardinality) {
// last element in `valueError` list is for range validation error
var jsValues = firstWidgetConfig && firstWidgetConfig.toJS ? newValue.toJS().map(function (v) {
return firstWidgetConfig.toJS(v, firstWidgetConfig);
}) : newValue.toJS();
var rangeValidateError = newOperatorConfig.validateValues(jsValues);
if (showErrorMessage) {
valueErrors.push(rangeValidateError);
}
}
newValueError = new _immutable["default"].List(valueErrors);
}
newValueType = new _immutable["default"].List(Array.from({
length: operatorCardinality
}, function (_ignore, i) {
var vt = null;
if (canReuseValue) {
if (i < currentValueType.size) vt = currentValueType.get(i);
} else if (operatorCardinality == 1 && firstWidgetConfig && firstWidgetConfig.type !== undefined) {
vt = firstWidgetConfig.type;
} else if (operatorCardinality == 1 && newFieldConfig && newFieldConfig.type !== undefined) {
vt = newFieldConfig.type == "!group" ? "number" : newFieldConfig.type;
}
return vt;
}));
return {
canReuseValue: canReuseValue,
newValue: newValue,
newValueSrc: newValueSrc,
newValueType: newValueType,
newValueError: newValueError,
operatorCardinality: operatorCardinality
};
};
exports.getNewValueForFieldOp = getNewValueForFieldOp;
var getFirstField = function getFirstField(config) {
var parentRuleGroupPath = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null;
var fieldSeparator = config.settings.fieldSeparator;
var parentPathArr = typeof parentRuleGroupPath == "string" ? parentRuleGroupPath.split(fieldSeparator) : parentRuleGroupPath;
var parentField = parentRuleGroupPath ? (0, _configUtils.getFieldRawConfig)(config, parentRuleGroupPath) : config;
var firstField = parentField,
key = null,
keysPath = [];
do {
var subfields = firstField === config ? config.fields : firstField.subfields;
if (!subfields || !Object.keys(subfields).length) {
firstField = key = null;
break;
}
key = Object.keys(subfields)[0];
keysPath.push(key);
firstField = subfields[key];
} while (firstField.type == "!struct" || firstField.type == "!group");
return (parentPathArr || []).concat(keysPath).join(fieldSeparator);
};
exports.getFirstField = getFirstField;
var getOperatorsForField = function getOperatorsForField(config, field) {
var fieldConfig = (0, _configUtils.getFieldConfig)(config, field);
var fieldOps = fieldConfig ? fieldConfig.operators : [];
return fieldOps;
};
exports.getOperatorsForField = getOperatorsForField;
var getFirstOperator = function getFirstOperator(config, field) {
var fieldOps = getOperatorsForField(config, field);
return fieldOps ? fieldOps[0] : null;
};
exports.getFirstOperator = getFirstOperator;
var getFieldPath = function getFieldPath(field, config) {
var onlyKeys = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
if (!field) return null;
var fieldSeparator = config.settings.fieldSeparator;
var parts = Array.isArray(field) ? field : field.split(fieldSeparator);
if (onlyKeys) return parts;else return parts.map(function (_curr, ind, arr) {
return arr.slice(0, ind + 1);
}).map(function (parts) {
return parts.join(fieldSeparator);
});
};
exports.getFieldPath = getFieldPath;
var getFuncPathLabels = function getFuncPathLabels(field, config) {
var parentField = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : null;
return getFieldPathLabels(field, config, parentField, "funcs", "subfields");
};
exports.getFuncPathLabels = getFuncPathLabels;
var getFieldPathLabels = function getFieldPathLabels(field, config) {
var parentField = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : null;
var fieldsKey = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : "fields";
var subfieldsKey = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : "subfields";
if (!field) return null;
var fieldSeparator = config.settings.fieldSeparator;
var parts = Array.isArray(field) ? field : field.split(fieldSeparator);
var parentParts = parentField ? Array.isArray(parentField) ? parentField : parentField.split(fieldSeparator) : [];
return parts.slice(parentParts.length).map(function (_curr, ind, arr) {
return arr.slice(0, ind + 1);
}).map(function (parts) {
return [].concat((0, _toConsumableArray2["default"])(parentParts), (0, _toConsumableArray2["default"])(parts)).join(fieldSeparator);
}).map(function (part) {
var cnf = (0, _configUtils.getFieldRawConfig)(config, part, fieldsKey, subfieldsKey);
return cnf && cnf.label || cnf && (0, _last["default"])(part.split(fieldSeparator));
}).filter(function (label) {
return label != null;
});
};
exports.getFieldPathLabels = getFieldPathLabels;
var getFieldPartsConfigs = function getFieldPartsConfigs(field, config) {
var parentField = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : null;
if (!field) return null;
var parentFieldDef = parentField && (0, _configUtils.getFieldRawConfig)(config, parentField) || null;
var fieldSeparator = config.settings.fieldSeparator;
var parts = Array.isArray(field) ? field : field.split(fieldSeparator);
var parentParts = parentField ? Array.isArray(parentField) ? parentField : parentField.split(fieldSeparator) : [];
return parts.slice(parentParts.length).map(function (_curr, ind, arr) {
return arr.slice(0, ind + 1);
}).map(function (parts) {
return {
part: [].concat((0, _toConsumableArray2["default"])(parentParts), (0, _toConsumableArray2["default"])(parts)).join(fieldSeparator),
key: parts[parts.length - 1]
};
}).map(function (_ref) {
var part = _ref.part,
key = _ref.key;
var cnf = (0, _configUtils.getFieldRawConfig)(config, part);
return {
key: key,
cnf: cnf
};
}).map(function (_ref2, ind, arr) {
var key = _ref2.key,
cnf = _ref2.cnf;
var parentCnf = ind > 0 ? arr[ind - 1].cnf : parentFieldDef;
return [key, cnf, parentCnf];
});
};
exports.getFieldPartsConfigs = getFieldPartsConfigs;
var getValueLabel = function getValueLabel(config, field, operator, delta) {
var valueSrc = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : null;
var isSpecialRange = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : false;
var isFuncArg = field && (0, _typeof2["default"])(field) == "object" && !!field.func && !!field.arg;
var showLabels = config.settings.showLabels;
var fieldConfig = (0, _configUtils.getFieldConfig)(config, field);
var fieldWidgetConfig = (0, _configUtils.getFieldWidgetConfig)(config, field, operator, null, valueSrc) || {};
var mergedOpConfig = (0, _configUtils.getOperatorConfig)(config, operator, field) || {};
var cardinality = isSpecialRange ? 1 : mergedOpConfig.cardinality;
var ret = null;
if (cardinality > 1) {
var valueLabels = fieldWidgetConfig.valueLabels || mergedOpConfig.valueLabels;
if (valueLabels) ret = valueLabels[delta];
if (ret && (0, _typeof2["default"])(ret) != "object") {
ret = {
label: ret,
placeholder: ret
};
}
if (!ret) {
ret = {
label: config.settings.valueLabel + " " + (delta + 1),
placeholder: config.settings.valuePlaceholder + " " + (delta + 1)
};
}
} else {
var label = fieldWidgetConfig.valueLabel;
var placeholder = fieldWidgetConfig.valuePlaceholder;
if (isFuncArg) {
if (!label) label = fieldConfig.label || field.arg;
if (!placeholder && !showLabels) placeholder = fieldConfig.label || field.arg;
}
ret = {
label: label || config.settings.valueLabel,
placeholder: placeholder || config.settings.valuePlaceholder
};
}
return ret;
};
exports.getValueLabel = getValueLabel;
function _getWidgetsAndSrcsForFieldOp(config, field) {
var operator = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : null;
var valueSrc = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : null;
var isFunc = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : false;
var widgets = [];
var valueSrcs = [];
if (!field) return {
widgets: widgets,
valueSrcs: valueSrcs
};
var isFuncArg = (0, _typeof2["default"])(field) == "object" && (!!field.func && !!field.arg || field._isFuncArg);
var fieldConfig = (0, _configUtils.getFieldConfig)(config, field, isFunc);
var opConfig = operator ? config.operators[operator] : null;
if (fieldConfig && fieldConfig.widgets) {
var _loop2 = function _loop2(widget) {
var widgetConfig = fieldConfig.widgets[widget]; // if (!config.widgets[widget]) {
// continue;
// }
var widgetValueSrc = config.widgets[widget].valueSrc || "value";
var canAdd = true;
if (widget == "field") {
canAdd = canAdd && filterValueSourcesForField(config, ["field"], fieldConfig).length > 0;
}
if (widget == "func") {
canAdd = canAdd && filterValueSourcesForField(config, ["func"], fieldConfig).length > 0;
} // If can't check operators, don't add
// Func args don't have operators
if (valueSrc == "value" && !widgetConfig.operators && !isFuncArg && field != "!case_value") canAdd = false;
if (widgetConfig.operators && operator) canAdd = canAdd && widgetConfig.operators.indexOf(operator) != -1;
if (valueSrc && valueSrc != widgetValueSrc && valueSrc != "const") canAdd = false;
if (opConfig && opConfig.cardinality == 0 && widgetValueSrc != "value") canAdd = false;
if (canAdd) {
widgets.push(widget);
var canAddValueSrc = fieldConfig.valueSources && fieldConfig.valueSources.indexOf(widgetValueSrc) != -1;
if (opConfig && opConfig.valueSources && opConfig.valueSources.indexOf(widgetValueSrc) == -1) canAddValueSrc = false;
if (canAddValueSrc && !valueSrcs.find(function (v) {
return v == widgetValueSrc;
})) valueSrcs.push(widgetValueSrc);
}
};
for (var widget in fieldConfig.widgets) {
_loop2(widget);
}
}
var widgetWeight = function widgetWeight(w) {
var wg = 0;
if (fieldConfig.preferWidgets) {
if (fieldConfig.preferWidgets.includes(w)) wg += 10 - fieldConfig.preferWidgets.indexOf(w);
} else if (w == fieldConfig.mainWidget) {
wg += 100;
}
if (w == "field") {
wg -= 1;
}
if (w == "func") {
wg -= 2;
}
return wg;
};
widgets.sort(function (w1, w2) {
return widgetWeight(w2) - widgetWeight(w1);
});
return {
widgets: widgets,
valueSrcs: valueSrcs
};
}
var getWidgetsForFieldOp = function getWidgetsForFieldOp(config, field, operator) {
var valueSrc = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : null;
var isFunc = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : false;
var _getWidgetsAndSrcsFor = _getWidgetsAndSrcsForFieldOp(config, field, operator, valueSrc, isFunc),
widgets = _getWidgetsAndSrcsFor.widgets;
return widgets;
};
exports.getWidgetsForFieldOp = getWidgetsForFieldOp;
var filterValueSourcesForField = function filterValueSourcesForField(config, valueSrcs, fieldDefinition) {
if (!fieldDefinition) return valueSrcs;
return valueSrcs.filter(function (vs) {
var canAdd = true;
if (vs == "field") {
if (config._fieldsCntByType) {
// tip: LHS field can be used as arg in RHS function
var minCnt = fieldDefinition._isFuncArg ? 0 : 1;
canAdd = canAdd && config._fieldsCntByType[fieldDefinition.type] > minCnt;
}
}
if (vs == "func") {
if (config._funcsCntByType) canAdd = canAdd && !!config._funcsCntByType[fieldDefinition.type];
if (fieldDefinition.funcs) canAdd = canAdd && fieldDefinition.funcs.length > 0;
}
return canAdd;
});
};
exports.filterValueSourcesForField = filterValueSourcesForField;
var getValueSourcesForFieldOp = function getValueSourcesForFieldOp(config, field, operator) {
var fieldDefinition = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : null;
var leftFieldForFunc = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : null;
var isFunc = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : false;
var _getWidgetsAndSrcsFor2 = _getWidgetsAndSrcsForFieldOp(config, field, operator, null, isFunc),
valueSrcs = _getWidgetsAndSrcsFor2.valueSrcs;
var filteredValueSrcs = filterValueSourcesForField(config, valueSrcs, fieldDefinition);
return filteredValueSrcs;
};
exports.getValueSourcesForFieldOp = getValueSourcesForFieldOp;
var getWidgetForFieldOp = function getWidgetForFieldOp(config, field, operator) {
var valueSrc = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : null;
var isFunc = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : false;
var _getWidgetsAndSrcsFor3 = _getWidgetsAndSrcsForFieldOp(config, field, operator, valueSrc, isFunc),
widgets = _getWidgetsAndSrcsFor3.widgets;
var widget = null;
if (widgets.length) widget = widgets[0];
return widget;
};
exports.getWidgetForFieldOp = getWidgetForFieldOp;
var formatFieldName = function formatFieldName(field, config, meta) {
var parentField = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : null;
if (!field) return;
var fieldDef = (0, _configUtils.getFieldConfig)(config, field) || {};
var fieldSeparator = config.settings.fieldSeparator;
var fieldParts = Array.isArray(field) ? field : field.split(fieldSeparator);
var fieldName = Array.isArray(field) ? field.join(fieldSeparator) : field;
if (fieldDef.tableName) {
// legacy
var fieldPartsCopy = (0, _toConsumableArray2["default"])(fieldParts);
fieldPartsCopy[0] = fieldDef.tableName;
fieldName = fieldPartsCopy.join(fieldSeparator);
}
if (fieldDef.fieldName) {
fieldName = fieldDef.fieldName;
}
if (parentField) {
var parentFieldDef = (0, _configUtils.getFieldConfig)(config, parentField) || {};
var parentFieldName = parentField;
if (parentFieldDef.fieldName) {
parentFieldName = parentFieldDef.fieldName;
}
if (fieldName.indexOf(parentFieldName + fieldSeparator) == 0) {
fieldName = fieldName.slice((parentFieldName + fieldSeparator).length);
} else {
meta.errors.push("Can't cut group ".concat(parentFieldName, " from field ").concat(fieldName));
}
}
return fieldName;
};
exports.formatFieldName = formatFieldName;