@react-awesome-query-builder/core
Version:
User-friendly query builder for React. Core
427 lines (411 loc) • 19.5 kB
JavaScript
"use strict";
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.whatRulePropertiesAreCompleted = exports.setFuncDefaultArgs = exports.setFuncDefaultArg = exports.setArgValue = exports.isEmptyRuleProperties = exports.isEmptyRuleGroupExtPropertiesAndChildren = exports.isEmptyItem = exports.isEmptyGroupChildren = exports.getValueLabel = exports.getOneChildOrDescendant = exports.getFuncPathLabels = exports.getFieldPathLabels = exports.getDefaultArgValue = exports.formatFieldName = exports.completeValue = exports.completeFuncValue = exports.calculateValueType = void 0;
var _typeof2 = _interopRequireDefault(require("@babel/runtime/helpers/typeof"));
var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime/helpers/toConsumableArray"));
var _immutable = _interopRequireDefault(require("immutable"));
var _configUtils = require("./configUtils");
var _stuff = require("./stuff");
var _last = _interopRequireDefault(require("lodash/last"));
var calculateValueType = exports.calculateValueType = function calculateValueType(value, valueSrc, config) {
var calculatedValueType = null;
if (value) {
if (valueSrc === "field") {
var fieldConfig = (0, _configUtils.getFieldConfig)(config, value);
if (fieldConfig) {
calculatedValueType = fieldConfig.type;
}
} else if (valueSrc === "func") {
var funcKey = value.get("func");
if (funcKey) {
var funcConfig = (0, _configUtils.getFuncConfig)(config, funcKey);
if (funcConfig) {
calculatedValueType = funcConfig.returnType || funcConfig.type;
}
}
}
}
return calculatedValueType;
};
var getFuncPathLabels = exports.getFuncPathLabels = function getFuncPathLabels(field, config) {
var parentField = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : null;
return getFieldPathLabels(field, config, parentField, "funcs", "subfields");
};
var getFieldPathLabels = exports.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 = (0, _configUtils.getFieldParts)(field, config);
var parentParts = (0, _configUtils.getFieldParts)(parentField, config);
var res = 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 || (0, _last["default"])(part.split(fieldSeparator));
}).filter(function (label) {
return label != null;
});
return res;
};
var getValueLabel = exports.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;
// const isFuncArg = field && typeof field == "object" && !!field.func && !!field.arg;
// const {showLabels} = config.settings;
// const fieldConfig = 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;
// tip: this logic moved to extendFieldConfig(), see comment "label for func arg"
// 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;
};
// can use alias (fieldName)
// even if `parentField` is provided, `field` is still a full path
var formatFieldName = exports.formatFieldName = function formatFieldName(field, config, meta) {
var parentField = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : null;
var options = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : {};
if (!field) return;
var fieldDef = (0, _configUtils.getFieldConfig)(config, field) || {};
var fieldSeparator = config.settings.fieldSeparator;
var fieldParts = (0, _configUtils.getFieldParts)(field, config);
var fieldName = Array.isArray(field) ? field.join(fieldSeparator) : field;
if (options !== null && options !== void 0 && options.useTableName && 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 (fieldName.indexOf(parentFieldName + fieldSeparator) == 0) {
fieldName = fieldName.slice((parentFieldName + fieldSeparator).length);
// fieldName = "#this." + fieldName; // ? for spel
} else {
if (fieldDef.fieldName) {
// ignore
} else {
meta.errors.push("Can't cut group ".concat(parentFieldName, " from field ").concat(fieldName));
}
}
}
return fieldName;
};
/**
* Used together with keepInputOnChangeFieldSrc
*/
var isEmptyItem = exports.isEmptyItem = function isEmptyItem(item, config) {
var type = item.get("type");
var mode = item.getIn(["properties", "mode"]);
if (type == "rule_group" && mode == "array") {
return isEmptyRuleGroupExt(item, config);
} else if (type == "group" || type == "rule_group") {
return isEmptyGroup(item, config);
} else {
return isEmptyRule(item, config);
}
};
var isEmptyRuleGroupExt = function isEmptyRuleGroupExt(item, config) {
var children = item.get("children1");
var properties = item.get("properties");
return isEmptyRuleGroupExtPropertiesAndChildren(properties.toObject(), children, config);
};
/**
* Used to remove group ext without confirmation
*
* If group operator is count, children can be empty.
* If group operator is some/none/all, there should be at least one non-empty (even incomplete) child.
*/
var isEmptyRuleGroupExtPropertiesAndChildren = exports.isEmptyRuleGroupExtPropertiesAndChildren = function isEmptyRuleGroupExtPropertiesAndChildren(properties, children, config) {
var _config$operators$ope, _config$operators$ope2;
var operator = properties.operator;
var cardinality = (_config$operators$ope = (_config$operators$ope2 = config.operators[operator]) === null || _config$operators$ope2 === void 0 ? void 0 : _config$operators$ope2.cardinality) !== null && _config$operators$ope !== void 0 ? _config$operators$ope : 1;
var childrenAreRequired = cardinality == 0; // tip: for group operators some/none/all
var filledParts = {
group: !isEmptyRuleProperties(properties, config),
children: !isEmptyGroupChildren(children, config)
};
var hasEnough = filledParts.group && (childrenAreRequired ? filledParts.children : true);
return !hasEnough;
};
var isEmptyGroup = function isEmptyGroup(group, config) {
var children = group.get("children1");
return isEmptyGroupChildren(children, config);
};
/**
* Used to remove group without confirmation
* @returns {boolean} false if there is at least one (even incomplete) child
*/
var isEmptyGroupChildren = exports.isEmptyGroupChildren = function isEmptyGroupChildren(children, config) {
var hasEnough = (children === null || children === void 0 ? void 0 : children.size) > 0 && children.filter(function (ch) {
return !isEmptyItem(ch, config);
}).size > 0;
return !hasEnough;
};
var isEmptyRule = function isEmptyRule(rule, config) {
var properties = rule.get("properties");
return isEmptyRuleProperties((properties === null || properties === void 0 ? void 0 : properties.toObject()) || {}, config);
};
/**
* Used to remove rule without confirmation
* @param properties is an Object, but properties (like value) are Immutable
* @returns {boolean} true if there is no enough data in rule
*/
var isEmptyRuleProperties = exports.isEmptyRuleProperties = function isEmptyRuleProperties(properties, config) {
var liteCheck = true;
var scoreThreshold = 3;
var compl = whatRulePropertiesAreCompleted(properties, config, liteCheck);
var hasEnough = compl.score >= scoreThreshold;
return !hasEnough;
};
/**
* Used to validate rule
* @param properties is an Object, but its properties (like `value`) are Immutable
* @param liteCheck true can be used to check that rule has enough data to ask confirmation before delete
* @return {{parts: {field: boolean, operator: boolean, value: boolean}, score: number}}
*/
var whatRulePropertiesAreCompleted = exports.whatRulePropertiesAreCompleted = function whatRulePropertiesAreCompleted(_ref, config) {
var _config$operators$ope3, _config$operators$ope4, _value$filter;
var field = _ref.field,
fieldSrc = _ref.fieldSrc,
fieldType = _ref.fieldType,
operator = _ref.operator,
value = _ref.value,
valueSrc = _ref.valueSrc,
valueType = _ref.valueType;
var liteCheck = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
var cardinality = (_config$operators$ope3 = (_config$operators$ope4 = config.operators[operator]) === null || _config$operators$ope4 === void 0 ? void 0 : _config$operators$ope4.cardinality) !== null && _config$operators$ope3 !== void 0 ? _config$operators$ope3 : 1;
var valueSrcs = valueSrc !== null && valueSrc !== void 0 && valueSrc.get ? valueSrc.toJS() : valueSrc;
// tip: for liteCheck==true `score` should equal 3 if both LHS and RHS are at least partially filled
var res = {
parts: {},
score: 0
};
res.parts.field = liteCheck ? field != null : _isCompletedValue(field, fieldSrc, config);
res.parts.operator = !!operator;
res.parts.value = (value === null || value === void 0 || (_value$filter = value.filter(function (val, delta) {
return _isCompletedValue(val, valueSrcs === null || valueSrcs === void 0 ? void 0 : valueSrcs[delta], config, liteCheck);
})) === null || _value$filter === void 0 ? void 0 : _value$filter.size) >= (liteCheck ? Math.min(cardinality, 1) : cardinality);
res.score = Object.keys(res.parts).filter(function (k) {
return !!res.parts[k];
}).length;
if (liteCheck && res.score < 3) {
// Boost score to confirm deletion:
// - if RHS is empty, but LHS is a completed function
// - if LHS is empty (only fieldType is set), but there is a completed function in RHS
var deepCheck = true;
if (!res.parts.value && fieldSrc === "func" && _isCompletedValue(field, fieldSrc, config, false, deepCheck)) {
res.score++;
}
if (!res.parts.field) {
value === null || value === void 0 || value.map(function (val, delta) {
if ((valueSrcs === null || valueSrcs === void 0 ? void 0 : valueSrcs[delta]) === "func" && _isCompletedValue(val, valueSrcs === null || valueSrcs === void 0 ? void 0 : valueSrcs[delta], config, false, deepCheck)) {
res.score++;
}
});
}
}
return res;
};
var _isCompletedValue = function isCompletedValue(value, valueSrc, config) {
var liteCheck = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false;
var deepCheck = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : true;
if (!liteCheck && valueSrc == "func" && value) {
var _value$get;
var funcKey = (_value$get = value.get) === null || _value$get === void 0 ? void 0 : _value$get.call(value, "func");
var funcConfig = (0, _configUtils.getFuncConfig)(config, funcKey);
if (funcConfig) {
var args = value.get("args");
for (var argKey in funcConfig.args) {
var argConfig = funcConfig.args[argKey];
var argVal = args ? args.get(argKey) : undefined;
// const argDef = getFieldConfig(config, argConfig);
var argValue = argVal ? argVal.get("value") : undefined;
var argValueSrc = argVal ? argVal.get("valueSrc") : undefined;
if (argValue == undefined && (argConfig === null || argConfig === void 0 ? void 0 : argConfig.defaultValue) === undefined && !(argConfig !== null && argConfig !== void 0 && argConfig.isOptional)) {
// arg is not completed
return false;
}
if (argValue != undefined) {
if (!_isCompletedValue(argValue, argValueSrc, config, deepCheck ? liteCheck : true)) {
// arg is complex and is not completed
return false;
}
}
}
// all args are completed
return true;
}
}
return value != undefined;
};
/**
* @param {*} value
* @param {'value'|'field'|'func'} valueSrc
* @param {object} config
* @return {* | undefined} undefined if func value is not complete (missing required arg vals); can return completed value != value
*/
var completeValue = exports.completeValue = function completeValue(value, valueSrc, config) {
if (valueSrc == "func") return completeFuncValue(value, config);else return value;
};
/**
* @param {Immutable.Map} value
* @param {object} config
* @return {Immutable.Map | undefined} - undefined if func value is not complete (missing required arg vals); can return completed value != value
*/
var completeFuncValue = exports.completeFuncValue = function completeFuncValue(value, config) {
if (!value) return undefined;
var funcKey = value.get("func");
var funcConfig = funcKey && (0, _configUtils.getFuncConfig)(config, funcKey);
if (!funcConfig) return undefined;
var complValue = value;
var tmpHasOptional = false;
for (var argKey in funcConfig.args) {
var argConfig = funcConfig.args[argKey];
var valueSources = argConfig.valueSources,
isOptional = argConfig.isOptional,
defaultValue = argConfig.defaultValue;
var filteredValueSources = (0, _configUtils.filterValueSourcesForField)(config, valueSources, argConfig);
var args = complValue.get("args");
var argDefaultValueSrc = filteredValueSources.length == 1 ? filteredValueSources[0] : undefined;
var argVal = args ? args.get(argKey) : undefined;
var argValue = argVal ? argVal.get("value") : undefined;
var argValueSrc = (argVal ? argVal.get("valueSrc") : undefined) || argDefaultValueSrc;
if (argValue !== undefined) {
var completeArgValue = completeValue(argValue, argValueSrc, config);
if (completeArgValue === undefined) {
return undefined;
} else if (completeArgValue !== argValue) {
complValue = complValue.setIn(["args", argKey, "value"], completeArgValue);
}
if (tmpHasOptional) {
// has gap
return undefined;
}
} else if (defaultValue !== undefined && !(0, _stuff.isObject)(defaultValue)) {
complValue = complValue.setIn(["args", argKey, "value"], getDefaultArgValue(argConfig));
complValue = complValue.setIn(["args", argKey, "valueSrc"], "value");
} else if (isOptional) {
// optional
tmpHasOptional = true;
} else {
// missing value
return undefined;
}
}
return complValue;
};
// item - Immutable
var _getOneChildOrDescendant = exports.getOneChildOrDescendant = function getOneChildOrDescendant(item) {
var children = item.get("children1");
if ((children === null || children === void 0 ? void 0 : children.size) == 1) {
var child = children.first();
var childType = child.get("type");
if (childType === "group") {
return _getOneChildOrDescendant(child);
}
return child;
}
return null;
};
///// Func utils
var getDefaultArgValue = exports.getDefaultArgValue = function getDefaultArgValue(_ref2) {
var value = _ref2.defaultValue;
if ((0, _stuff.isObject)(value) && !_immutable["default"].Map.isMap(value) && value.func) {
return _immutable["default"].fromJS(value, function (k, v) {
return _immutable["default"].Iterable.isIndexed(v) ? v.toList() : v.toOrderedMap();
});
}
return value;
};
/**
* Used @ FuncWidget
* @param {Immutable.Map} value
* @param {string} argKey
* @param {*} argVal
* @param {object} argConfig
*/
var setArgValue = exports.setArgValue = function setArgValue(value, argKey, argVal, argConfig, config) {
if (value && value.get("func")) {
value = value.setIn(["args", argKey, "value"], argVal);
// set default arg value source
var valueSrc = value.getIn(["args", argKey, "valueSrc"]);
var valueSources = argConfig.valueSources;
var filteredValueSources = (0, _configUtils.filterValueSourcesForField)(config, valueSources, argConfig);
var argDefaultValueSrc = filteredValueSources.length == 1 ? filteredValueSources[0] : undefined;
if (!argDefaultValueSrc && filteredValueSources.includes("value")) {
argDefaultValueSrc = "value";
}
if (!valueSrc && argDefaultValueSrc) {
value = value.setIn(["args", argKey, "valueSrc"], argDefaultValueSrc);
}
}
return value;
};
var setFuncDefaultArgs = exports.setFuncDefaultArgs = function setFuncDefaultArgs(config, funcValue, funcConfig) {
if (funcConfig) {
for (var argKey in funcConfig.args) {
funcValue = setFuncDefaultArg(config, funcValue, funcConfig, argKey);
}
}
return funcValue;
};
var setFuncDefaultArg = exports.setFuncDefaultArg = function setFuncDefaultArg(config, funcValue, funcConfig, argKey) {
var argConfig = funcConfig.args[argKey];
var valueSources = argConfig.valueSources,
defaultValue = argConfig.defaultValue;
var filteredValueSources = (0, _configUtils.filterValueSourcesForField)(config, valueSources, argConfig);
var firstValueSrc = filteredValueSources.length ? filteredValueSources[0] : undefined;
var defaultValueSrc = defaultValue ? (0, _stuff.isObject)(defaultValue) && !!defaultValue.func ? "func" : "value" : undefined;
var argDefaultValueSrc = defaultValueSrc || firstValueSrc;
var hasValue = funcValue.getIn(["args", argKey]);
if (!hasValue) {
if (defaultValue !== undefined) {
funcValue = funcValue.setIn(["args", argKey, "value"], getDefaultArgValue(argConfig));
}
if (argDefaultValueSrc) {
funcValue = funcValue.setIn(["args", argKey, "valueSrc"], argDefaultValueSrc);
}
}
return funcValue;
};