(function() { window.initDQ = function() { $(document) .off('change input paste', '.dq-edit-container input, .dq-edit-container textarea, .dq-edit-container select') .on('change input paste', '.dq-edit-container input, .dq-edit-container textarea, .dq-edit-container select', function() { let key = $(this).closest('.dq-line').attr('dq-key'), dataElem = $(this).closest('.dq-edit-container').find('>.dq-data-map').first(), current = JSON.parse(dataElem.text()); current[key] = $(this).val(); let serialized = JSON.stringify(current); dataElem.text(serialized); $(this).closest('form').find('input[name="data"]').val(serialized); let fullData = { lines: JSON.parse($(this).closest('.dq-edit-container').find('>.dq-definition').first().text()), dataMap: current }; $(this).closest('form').find('input[name="data"]').val(JSON.stringify(fullData)); runDQConditions($(this).closest('.dq-edit-container')); }); $(document) .off('input.auto-grow', '.dq-edit-container textarea') .on('input.auto-grow', '.dq-edit-container textarea', function() { this.style.minHeight = "calc(1.5em + .5rem + 2px)"; this.style.height = "calc(1.5em + .5rem + 2px)"; this.style.height = (this.scrollHeight)+"px"; }); }; function resolveAtomicCondition(_condition, _dataMap) { if(!_condition.hasOwnProperty('key') || !_condition.hasOwnProperty('value')) { _condition.resolution = false; return; } let key = _condition.key, op = _condition.hasOwnProperty('op') ? _condition.op : 'eq'; let lhs = _dataMap[key], rhs = _condition.value; switch(op) { case 'eq': _condition.resolution = (lhs == rhs); // NOTE: using == instead of === on purpose break; case 'lt': _condition.resolution = (+lhs < +rhs); break; case 'lte': _condition.resolution = (+lhs <= +rhs); break; case 'gt': _condition.resolution = (+lhs > +rhs); break; case 'gte': _condition.resolution = (+lhs >= +rhs); break; default: _condition.resolution = false; } } function resolveAllAtomicConditions(_conditions, _dataMap) { if(Array.isArray(_conditions)) { for (let i = 0; i < _conditions.length; i++) { resolveAllAtomicConditions(_conditions[i], _dataMap); } } else if(typeof _conditions === 'object') { resolveAtomicCondition(_conditions, _dataMap); } } function reduceConditionsIntoResolutions(_conditions) { for (let i = 0; i < _conditions.length; i++) { // if simple object, resolve if(!Array.isArray(_conditions[i]) && typeof _conditions[i] === 'object') { _conditions.splice(i, 1, _conditions[i].resolution); } else if(Array.isArray(_conditions[i])) { reduceConditionsIntoResolutions(_conditions[i]); } } } function combineResolutionListsIntoSingleResolutions(_conditions) { console.log('ALIX 1', _conditions); for (let i = 0; i < _conditions.length; i++) { if(Array.isArray(_conditions[i])) { _conditions[i] = combineResolutionListsIntoSingleResolutions(_conditions[i]); } } console.log('ALIX 2', _conditions); // at this point, the array will have only booleans and "AND", "OR" combinators let resolution = _conditions[0]; for (let i = 1; i < _conditions.length; i+=2) { if(_conditions[i] === 'AND') { resolution = resolution && _conditions[i + 1]; } else if(_conditions[i] === 'OR') { resolution = resolution || _conditions[i + 1]; } } return resolution; } window.runDQConditions = function(_parent) { _parent.find('.dq-line.has-pre-condition').each(function() { let conditions = JSON.parse($(this).find('>.dq-pre-condition').first().text()), dataMap = JSON.parse($(this).closest('.dq-edit-container').find('>.dq-data-map').first().text()); resolveAllAtomicConditions(conditions, dataMap); // if object, single condition with key, op and value if(!Array.isArray(conditions) && typeof conditions === 'object') { if(conditions.resolution) { $(this).removeClass('d-none'); } else { $(this).addClass('d-none'); } } // else if array - means list of conditions with 'and' or 'or' separators - array size MUST be an odd number else if(Array.isArray(conditions)) { // goal is to reduce each item in the array into a single boolean - recursively reduceConditionsIntoResolutions(conditions); conditions = combineResolutionListsIntoSingleResolutions(conditions); if(conditions) { $(this).removeClass('d-none'); } else { $(this).addClass('d-none'); } } }); } addMCInitializer('dq-edit', initDQ, '.dq-edit-container'); }).call(window);