UNPKG

@qikdev/sdk

Version:

Promise based Javascript SDK

543 lines (466 loc) 14 kB
/** * @name filter * @classdesc Provides functions helpful for interacting with the filtering system * @class */ /////////////////////// var service = {}; /////////////////////// function isEmpty(value) { if (value === 0) { return false; } var empty = typeof value === 'undefined' || value === null || String(value).trim() === ''; if (empty) { return true; } //If it's a string of undefined or null then treat it as empty also if (value === 'undefined' || value === 'null') { return true; } return false; } function compactFunction(val) { return !isEmpty(val) } /////////////////////// service.cleanKey = function(key) { key = String(key).split('|')[0]; if (key[0] == '.') { key = key.slice(1); } return key; } /////////////////////// /** * @description Check if an object is a valid filter * @alias filter.isValidFilter * @param {Object} filter The filter block to check * @example * // Missing a 'key' * const invalidFilter = sdk.filter.isValidFilter({comparator:'in', values:['Red', 'Green', 'Blue']}) * // returns false * * const validFilter = sdk.filter.isValidFilter({key:'favoriteColor', comparator:'in', values:['Red', 'Green', 'Blue']}) * // returns true */ service.isValidFilter = function(filter) { if (!filter) { return false; } /////////////////////////// //If the filter has nested filters consider it valid //if it has valid child filters if (filter.operator) { if (!filter.filters || !filter.filters.length) { return false; } return filter.filters.some(service.isValidFilter); } // /////////////////////////// // //Get the comparator for the filter // var comparator = hash[filter.comparator]; // if (!comparator) { // //No comparator was specified for the filter // return false; // } /////////////////////////// var key = service.cleanKey(filter.key); if (!key) { //No key has been specified for the filter return false; } // if(filter.comparator.inputType === 'none') { // console.log('COMPARATOR IS EMPTY') // return true; // } switch (filter.comparator) { case 'empty': case 'notempty': case 'datetoday': case 'datenottoday': case 'datebeforetoday': case 'dateaftertoday': case 'dateweektoday': case 'datemonthtoday': case 'datebeforenow': case 'dateafternow': case 'datethisweek': case 'datethismonth': return true; break; } var multiValues = (filter.values || []).filter(compactFunction); return !isEmpty(filter.value) || !isEmpty(filter.value2) || multiValues.length; // /////////////////////////// // switch (filter.inputType) { // case 'none': // //If we are checking empty/notempty // //the filter is always valid without any extra parameters // return true; // break; // case 'range': // //If we are filtering a number range // //we need the start and end of the range // if (!filter.value || isNaN(filter.value)) { // return false; // } // if (!filter.value2 || isNaN(filter.value2)) { // return false; // } // break; // case 'daterange': // if (!filter.value || !parseDate(filter.value)) { // return false; // } // if (!filter.value2 || !parseDate(filter.value2)) { // return false; // } // break; // case 'array': // if (!filter.values || !filter.values.length) { // return false; // } // break; // default: // // if (filter.dataType == 'boolean') { // // //Check if they provided a valid boolean value to the filter // // return validBooleans[String(filter.value).toLowerCase()]; // // } else { // // //The filter has not been provided with a value // if (isEmpty(filter.value)) { // return false; // } // // } // break; // } /////////////////////////// //If we got this far then the information //provided to the filter is enough to run it return true; } //////////////////////////////////////////////// /** * * @description Returns an array of all active filters * @alias filter.activeFilters * @param {Object} filterConfiguration A filter configuration object * @example * * const filterConfiguration = { * "operator": "and", * "filters": [ * { * "operator": "and", * "filters": [ * { * "key": "formData.person.firstName", * "comparator": "startswith", * "value": "c" * }, * { * "key": "invalid no comparator", * "value": "e" * } * { * "key": "formData.person.lastName", * "comparator": "endswith", * "value": "e" * } * ] * } * ] * } * * const activeFilters = sdk.filter.activeFilters(filterConfiguration); * * const returns = [ * { * "key": "formData.person.firstName", * "comparator": "startswith", * "value": "c" * }, * { * "key": "formData.person.lastName", * "comparator": "endswith", * "value": "e" * }] * */ service.activeFilters = function(filterConfiguration) { var memo = []; retrieveActiveFilter(filterConfiguration, memo); return memo; //////////////////////////// function retrieveActiveFilter(filterBlock, memo) { if (!filterBlock) { return; } var isValid = service.isValidFilter(filterBlock); if (isValid) { memo.push(filterBlock); } if (filterBlock.filters && filterBlock.filters.length) { filterBlock.filters.forEach(function(b) { retrieveActiveFilter(b, memo); }) } } } //////////////////////////////////////////////// /** * * @description Returns an array of all keys that are being actively filtered on * @alias filter.activeFilterKeys * @param {Object} filterConfiguration A filter configuration object * @example * * const filterConfiguration = { * "operator": "and", * "filters": [ * { * "operator": "and", * "filters": [ * { * "key": "formData.person.firstName", * "comparator": "startswith", * "value": "c" * }, * { * "key": "invalid no comparator", * "value": "e" * } * { * "key": "formData.person.lastName", * "comparator": "endswith", * "value": "e" * } * ] * } * ] * } * * const activeFilters = sdk.filter.activeFilterKeys(filterConfiguration); * // Returns ['formData.person.firstName', 'formData.person.lastName'] * */ service.activeFilterKeys = function(filterConfiguration, options) { options = options || {} var activeFilters = service.activeFilters(filterConfiguration); var value = activeFilters .filter(function(entry) { //Ignore all the wrapping entries return !entry.operator; }) .reduce(function(set, filter) { var rootKey = service.cleanKey(filter.key); if (options.trimArrayDelimeters !== false) { rootKey = rootKey.split('[]').join(''); } set[rootKey] = true; return set; }, {}); var keys = Object.keys(value); return keys; }; /** * * @description Returns an array of all comparators that are being actively filtered * @alias filter.activeFilterComparators * @param {Object} filterConfiguration A filter configuration object * @example * * const filterConfiguration = { * "operator": "and", * "filters": [ * { * "operator": "and", * "filters": [ * { * "key": "formData.person.firstName", * "comparator": "startswith", * "value": "c" * }, * { * "key": "invalid no comparator", * "value": "e" * } * { * "key": "formData.person.lastName", * "comparator": "endswith", * "value": "e" * } * ] * } * ] * } * * const activeFilters = sdk.filter.activeFilterKeys(filterConfiguration); * // Returns ['startswith', 'endswith'] * */ service.activeFilterComparators = function(filterConfiguration) { var comparators = service.activeFilters(filterConfiguration) .filter(function(entry) { //Ignore all the wrapping entries return !entry.operator; }) .reduce(function(set, filter) { set[filter.comparator] = true; return set; }, {}) return Object.keys(comparators); } /** * * @description Returns an array of all comparators that are being actively filtered * @alias filter.activeFilterOperators * @param {Object} filterConfiguration A filter configuration object * @example * * const filterConfiguration = { * "operator": "and", * "filters": [ * { * "operator": "nor", * "filters": [ * { * "key": "formData.person.firstName", * "comparator": "startswith", * "value": "c" * }, * { * "key": "invalid no comparator", * "value": "e" * } * { * "key": "formData.person.lastName", * "comparator": "endswith", * "value": "e" * } * ] * } * ] * } * * const activeFilterOperators = sdk.filter.activeFilterOperators(filterConfiguration); * // Returns ['and', 'nor'] * */ service.activeFilterOperators = function(filterConfiguration) { var operators = service.activeFilters(filterConfiguration) .filter(function(entry) { return entry.operator; }) .reduce(function(set, filter) { set[filter.operator] = true; return set; }, {}) return Object.keys(operators); } /** * * @description Returns an array of all values that are being actively used by a filter * @alias filter.activeFilterValues * @param {Object} filterConfiguration A filter configuration object * @example * * const filterConfiguration = { * "operator": "and", * "filters": [ * { * "operator": "nor", * "filters": [ * { * "key": "formData.person.firstName", * "comparator": "startswith", * "value": "c" * }, * { * "key": "invalid no comparator", * "value": "e" * } * { * "key": "formData.person.lastName", * "comparator": "endswith", * "value": "a" * } * ] * } * ] * } * * const activeFilterValues = sdk.filter.activeFilterValues(filterConfiguration); * // Returns ['c', 'a'] * */ service.activeFilterValues = function(filterConfiguration, options) { options = options || {}; var activeFilters = service.activeFilters(filterConfiguration); function mapValue(v) { if (!v) { return; } return v._id || v.id || v.title || v.name || v; } var values = activeFilters .filter(function(entry) { //Ignore all the wrapping entries return !entry.operator; }) .reduce(function(set, filter) { set = [...set, ...(filter.values || []).map(mapValue), mapValue(filter.value), mapValue(filter.value2)]; return set; }, []) .filter(compactFunction); return values; } /** * * @description Returns an string representation of a filter configuration. * Often used to check if a user has changed the filter in any way, the string only takes into consideration active valid filters * @alias filter.filterChangeString * @param {Object} filterConfiguration A filter configuration object * @example * * const filterConfiguration = { * "operator": "and", * "filters": [ * { * "operator": "nor", * "filters": [ * { * "key": "formData.person.firstName", * "comparator": "startswith", * "value": "c" * }, * { * "key": "invalid no comparator", * "value": "e" * } * { * "key": "formData.person.lastName", * "comparator": "endswith", * "value": "a" * } * ] * } * ] * } * * // Watch this string for changes * const changeString = sdk.filter.filterChangeString(filterConfiguration); */ service.filterChangeString = function(config) { var activeFilters = service.activeFilters(config); return JSON.stringify(activeFilters); // const string = [ // service.activeFilterKeys(config).join(', '), // service.activeFilterValues(config).join(', '), // service.activeFilterComparators(config).join(', '), // service.activeFilterOperators(config).join(', '), // ] // return string.filter(compactFunction).join(', '); }; /////////////////////// export default service;