dtable-utils
Version:
dtable common utils
472 lines (460 loc) • 16.8 kB
JavaScript
import _typeof from '@babel/runtime/helpers/typeof';
import _classCallCheck from '@babel/runtime/helpers/classCallCheck';
import _createClass from '@babel/runtime/helpers/createClass';
import { CellType } from '../constants/cell-type.js';
import { COLLABORATOR_COLUMN_TYPES, DEPARTMENT_SELECT_RANGE_MAP } from '../constants/column.js';
import { FORMULA_COLUMN_TYPES_MAP, FORMULA_RESULT_TYPE } from '../constants/formula.js';
import { FILTER_ERR_MSG } from '../constants/filter/index.js';
import { getColumnOptions } from '../column/option.js';
import { isDateColumn } from '../column/date.js';
import { FILTER_PREDICATE_TYPE } from '../constants/filter/filter-predicate.js';
import { FILTER_TERM_MODIFIER_TYPE } from '../constants/filter/filter-modifier.js';
import { FILTER_COLUMN_OPTIONS } from '../constants/filter/filter-column-options.js';
import { filterTermModifierIsWithin, filterTermModifierNotWithin } from '../constants/filter/filter-is-within.js';
var TERM_TYPE_MAP = {
NUMBER: 'number',
STRING: 'string',
BOOLEAN: 'boolean',
ARRAY: 'array'
};
var TEXT_COLUMN_TYPES = [CellType.TEXT, CellType.STRING];
var CHECK_EMPTY_PREDICATES = [FILTER_PREDICATE_TYPE.EMPTY, FILTER_PREDICATE_TYPE.NOT_EMPTY];
var PREDICATES_REQUIRE_ARRAY_TERM = [FILTER_PREDICATE_TYPE.IS_ANY_OF, FILTER_PREDICATE_TYPE.IS_NONE_OF];
var DATE_MODIFIERS_REQUIRE_TERM = [FILTER_TERM_MODIFIER_TYPE.NUMBER_OF_DAYS_AGO, FILTER_TERM_MODIFIER_TYPE.NUMBER_OF_DAYS_FROM_NOW, FILTER_TERM_MODIFIER_TYPE.THE_NEXT_NUMBERS_OF_DAYS, FILTER_TERM_MODIFIER_TYPE.THE_PAST_NUMBERS_OF_DAYS, FILTER_TERM_MODIFIER_TYPE.EXACT_DATE];
var MODIFIERS_REQUIRE_NUMERIC_TERM = [FILTER_TERM_MODIFIER_TYPE.NUMBER_OF_DAYS_AGO, FILTER_TERM_MODIFIER_TYPE.NUMBER_OF_DAYS_FROM_NOW, FILTER_TERM_MODIFIER_TYPE.THE_NEXT_NUMBERS_OF_DAYS, FILTER_TERM_MODIFIER_TYPE.THE_PAST_NUMBERS_OF_DAYS];
var ValidateFilter = /*#__PURE__*/function () {
function ValidateFilter() {
_classCallCheck(this, ValidateFilter);
}
return _createClass(ValidateFilter, null, [{
key: "validate",
value:
/**
* Check filter is valid. The error_message from returns will be null if the filter is valid.
* 1.incomplete filter which should be ignored
* - column_key: required
* - filter_predicate: required
* - filter_term_modifier: determined by the column to filter with
* - filter_term: determined by filter_predicate / the column to filter with
* 2.illegal filter
* - column missing: cannot find the column to filter
* - column not support: the column to filter is not support
* - mismatch: filter_predicate, filter_term_modifier mismatch
* - wrong data type: filter_term with wrong data type
* @param {object} filter e.g. { column_key, filter_term, ... }
* @param {array} columns e.g. [{ key, name, ... }, ...]
* @param {bool} isValidTerm No longer to validate filter term if false. default as false
* @returns { error_message }, object
*/
function validate(filter, columns) {
var isValidTerm = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : true;
var column_key = filter.column_key,
filter_predicate = filter.filter_predicate,
filter_term_modifier = filter.filter_term_modifier,
filter_term = filter.filter_term;
var _this$validateColumn = this.validateColumn(column_key, columns),
column_error_message = _this$validateColumn.error_message;
if (column_error_message) {
return {
error_message: column_error_message
};
}
var filterColumn = columns.find(function (column) {
return column.key === column_key;
});
var _this$validatePredica = this.validatePredicate(filter_predicate, filterColumn),
predicate_error_message = _this$validatePredica.error_message;
if (predicate_error_message) {
return {
error_message: predicate_error_message
};
}
if (this.isFilterOnlyWithPredicate(filter_predicate, filterColumn)) {
return {
error_message: null
};
}
var _this$validateModifie = this.validateModifier(filter_term_modifier, filter_predicate, filterColumn),
modifier_error_message = _this$validateModifie.error_message;
if (modifier_error_message) {
return {
error_message: modifier_error_message
};
}
if (this.isFilterOnlyWithModifier(filter_term_modifier, filterColumn)) {
return {
error_message: null
};
}
if (isValidTerm) {
var _this$validateTerm = this.validateTerm(filter_term, filter_predicate, filter_term_modifier, filterColumn),
term_error_message = _this$validateTerm.error_message;
if (term_error_message) {
return {
error_message: term_error_message
};
}
}
return {
error_message: null
};
}
}, {
key: "validateColumn",
value: function validateColumn(column_key, columns) {
if (!column_key) {
return {
error_message: FILTER_ERR_MSG.INCOMPLETE_FILTER
};
}
var filterColumn = columns.find(function (column) {
return column.key === column_key;
});
if (!filterColumn) {
return {
error_message: FILTER_ERR_MSG.COLUMN_MISSING
};
}
if (!this.isValidColumnType(filterColumn)) {
return {
error_message: FILTER_ERR_MSG.COLUMN_NOT_SUPPORTED
};
}
return {
error_message: null
};
}
/**
* the column to filter must be available
*/
}, {
key: "validatePredicate",
value: function validatePredicate(predicate, filterColumn) {
if (!predicate) {
return {
error_message: FILTER_ERR_MSG.INCOMPLETE_FILTER
};
}
var columnType = filterColumn.type,
data = filterColumn.data;
var filterConfigs = FILTER_COLUMN_OPTIONS[columnType];
var predicateList = filterConfigs.filterPredicateList;
if (FORMULA_COLUMN_TYPES_MAP[columnType] || columnType === CellType.LINK) {
var result_type = data.result_type;
if (result_type === FORMULA_RESULT_TYPE.ARRAY) {
return this.validatePredicateWithArrayType(predicate, filterColumn);
}
return this.validatePredicate(predicate, {
type: result_type
});
}
if (!predicateList.includes(predicate)) {
return {
error_message: FILTER_ERR_MSG.UNMATCHED_PREDICATE
};
}
return {
error_message: null
};
}
}, {
key: "validatePredicateWithArrayType",
value: function validatePredicateWithArrayType(predicate, filterColumn) {
var data = filterColumn.data;
var array_type = data.array_type;
// Only support: is
if (array_type === CellType.CHECKBOX || array_type === CellType.BOOL) {
return this.validatePredicate(predicate, {
type: CellType.CHECKBOX
});
}
// Filter predicate should support: is_empty/is_not_empty(excludes checkbox and bool)
if (CHECK_EMPTY_PREDICATES.includes(predicate)) {
return true;
}
if (array_type === CellType.SINGLE_SELECT || array_type === CellType.DEPARTMENT_SINGLE_SELECT) {
return this.validatePredicate(predicate, {
type: CellType.MULTIPLE_SELECT
});
}
if (COLLABORATOR_COLUMN_TYPES.includes(array_type)) {
return this.validatePredicate(predicate, {
type: CellType.COLLABORATOR
});
}
return this.validatePredicate(predicate, {
type: array_type
});
}
/**
* filter predicate must be available.
* filterColumn the column to filter must be available
*/
}, {
key: "isFilterOnlyWithPredicate",
value: function isFilterOnlyWithPredicate(predicate, filterColumn) {
if (CHECK_EMPTY_PREDICATES.includes(predicate)) {
return true;
}
var columnType = filterColumn.type,
data = filterColumn.data;
if (FORMULA_COLUMN_TYPES_MAP[columnType] || columnType === CellType.LINK) {
var result_type = data.result_type,
array_type = data.array_type;
if (result_type === FORMULA_RESULT_TYPE.ARRAY) {
return this.isFilterOnlyWithPredicate(predicate, {
type: array_type
});
}
return this.isFilterOnlyWithPredicate(predicate, {
type: result_type
});
}
var IS_CURRENT_USER_ID = FILTER_PREDICATE_TYPE.IS_CURRENT_USER_ID,
INCLUDE_ME = FILTER_PREDICATE_TYPE.INCLUDE_ME;
if (predicate === IS_CURRENT_USER_ID && TEXT_COLUMN_TYPES.includes(columnType)) {
return true;
}
if (predicate === INCLUDE_ME && COLLABORATOR_COLUMN_TYPES.includes(columnType)) {
return true;
}
return false;
}
/**
* filter predicate must be available.
* the column to filter must be available
*/
}, {
key: "validateModifier",
value: function validateModifier(modifier, predicate, filterColumn) {
if (!isDateColumn(filterColumn)) {
return {
error_message: null
};
}
if (!modifier) {
return {
error_message: FILTER_ERR_MSG.INCOMPLETE_FILTER
};
}
if (predicate === FILTER_PREDICATE_TYPE.IS_WITHIN) {
if (filterTermModifierIsWithin.includes(modifier)) {
return {
error_message: null
};
}
} else if (filterTermModifierNotWithin.includes(modifier)) {
return {
error_message: null
};
}
return {
error_message: FILTER_ERR_MSG.UNMATCHED_MODIFIER
};
}
/**
* filter predicate must be available.
* filter modifier must be available.
* the column to filter must be available
*/
}, {
key: "isFilterOnlyWithModifier",
value: function isFilterOnlyWithModifier(modifier, filterColumn) {
if (isDateColumn(filterColumn)) {
return !DATE_MODIFIERS_REQUIRE_TERM.includes(modifier);
}
return false;
}
}, {
key: "validateTerm",
value: function validateTerm(term, predicate, modifier, filterColumn) {
if (this.isTermMissing(term)) {
return {
error_message: FILTER_ERR_MSG.INCOMPLETE_FILTER
};
}
if (!this.isValidTerm(term, predicate, modifier, filterColumn)) {
return {
error_message: FILTER_ERR_MSG.INVALID_TERM
};
}
return {
error_message: null
};
}
}, {
key: "isTermMissing",
value: function isTermMissing(term) {
return !term && term !== 0 && term !== false || Array.isArray(term) && term.length === 0;
}
}, {
key: "isValidTerm",
value: function isValidTerm(term, predicate, modifier, filterColumn) {
switch (filterColumn.type) {
case CellType.TEXT:
case CellType.GEOLOCATION:
case CellType.AUTO_NUMBER:
case CellType.EMAIL:
case CellType.URL:
case CellType.STRING:
{
return this.isValidTermType(term, TERM_TYPE_MAP.STRING);
}
case CellType.SINGLE_SELECT:
{
var options = getColumnOptions(filterColumn);
if (PREDICATES_REQUIRE_ARRAY_TERM.includes(predicate)) {
if (!this.isValidTermType(term, TERM_TYPE_MAP.ARRAY)) {
return false;
}
// contains deleted option(s)
return this.isValidSelectedOptions(term, options);
}
if (!this.isValidTermType(term, TERM_TYPE_MAP.STRING)) {
return false;
}
// invalid filter_term if selected option is deleted
return !!options.find(function (option) {
return term === option.id;
});
}
case CellType.NUMBER:
case CellType.DURATION:
case CellType.RATE:
{
return this.isValidTermType(term, TERM_TYPE_MAP.NUMBER);
}
case CellType.CHECKBOX:
case CellType.BOOL:
{
return this.isValidTermType(term, TERM_TYPE_MAP.BOOLEAN);
}
case CellType.COLLABORATOR:
case CellType.CREATOR:
case CellType.LAST_MODIFIER:
{
return this.isValidTermType(term, TERM_TYPE_MAP.ARRAY);
}
case CellType.DEPARTMENT_SINGLE_SELECT:
{
if (PREDICATES_REQUIRE_ARRAY_TERM.includes(predicate)) {
return this.isValidTermType(term, TERM_TYPE_MAP.ARRAY);
}
if ([DEPARTMENT_SELECT_RANGE_MAP.CURRENT_USER_DEPARTMENT, DEPARTMENT_SELECT_RANGE_MAP.CURRENT_USER_DEPARTMENT_AND_SUB].includes(term)) {
return true;
}
return this.isValidTermType(term, TERM_TYPE_MAP.NUMBER);
}
case CellType.MULTIPLE_SELECT:
{
if (!this.isValidTermType(term, TERM_TYPE_MAP.ARRAY)) {
return false;
}
// contains deleted option(s)
var _options = getColumnOptions(filterColumn);
return this.isValidSelectedOptions(term, _options);
}
case CellType.DATE:
case CellType.CTIME:
case CellType.MTIME:
{
if (MODIFIERS_REQUIRE_NUMERIC_TERM.includes(modifier)) {
return this.isValidTermType(term, TERM_TYPE_MAP.NUMBER);
}
return this.isValidTermType(term, TERM_TYPE_MAP.STRING);
}
case CellType.FORMULA:
case CellType.LINK_FORMULA:
{
var data = filterColumn.data;
var result_type = data.result_type;
if (result_type === FORMULA_RESULT_TYPE.ARRAY) {
return this.isValidTermWithArrayType(term, predicate, modifier, filterColumn);
}
return this.isValidTerm(term, predicate, modifier, {
type: result_type
});
}
case CellType.LINK:
{
return this.isValidTermWithArrayType(term, predicate, modifier, filterColumn);
}
default:
{
return false;
}
}
}
}, {
key: "isValidTermType",
value: function isValidTermType(term, type) {
if (type === TERM_TYPE_MAP.ARRAY) {
return Array.isArray(term) && term.length > 0;
}
if (type === CellType.NUMBER) {
// is a number or a number string
// eslint-disable-next-line
return _typeof(term) === type || !isNaN(Number(term));
}
// eslint-disable-next-line
return _typeof(term) === type;
}
}, {
key: "isValidTermWithArrayType",
value: function isValidTermWithArrayType(term, predicate, modifier, filterColumn) {
var data = filterColumn.data;
var array_type = data.array_type,
array_data = data.array_data;
if (array_type === CellType.SINGLE_SELECT) {
return this.isValidTerm(term, predicate, modifier, {
type: CellType.MULTIPLE_SELECT,
data: array_data
});
}
if (array_type === CellType.DEPARTMENT_SINGLE_SELECT) {
return this.isValidTermType(term, TERM_TYPE_MAP.ARRAY);
}
if (COLLABORATOR_COLUMN_TYPES.includes(array_type)) {
return this.isValidTerm(term, predicate, modifier, {
type: CellType.COLLABORATOR
});
}
return this.isValidTerm(term, predicate, modifier, {
type: array_type,
data: array_data
});
}
}, {
key: "isValidColumnType",
value: function isValidColumnType(filterColumn) {
var columnType = filterColumn.type,
data = filterColumn.data;
if (FORMULA_COLUMN_TYPES_MAP[columnType] || columnType === CellType.LINK) {
if (!data) {
return false;
}
var result_type = data.result_type,
array_type = data.array_type;
if (result_type === FORMULA_RESULT_TYPE.ARRAY) {
return this.isValidColumnType({
type: array_type
});
}
return this.isValidColumnType({
type: result_type
});
}
// eslint-disable-next-line
return FILTER_COLUMN_OPTIONS.hasOwnProperty(columnType);
}
}, {
key: "isValidSelectedOptions",
value: function isValidSelectedOptions(selectedOptionIds, options) {
var validSelectedOptions = options.filter(function (option) {
return selectedOptionIds.includes(option.id);
});
return selectedOptionIds.length === validSelectedOptions.length;
}
}]);
}();
export { DATE_MODIFIERS_REQUIRE_TERM, ValidateFilter };