Last active
July 28, 2017 16:36
-
-
Save Daymannovaes/df8ec50ea00948330c2255031dd8936b to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
function arrayDiffToHtmlTable(prevArray = [], currArray = []) { | |
let ALL_KEYS = getAllKeys(prevArray, currArray); | |
let mappedObjects = mapObjects(prevArray, currArray); | |
let table = '<table>' + buildTableHeader(); | |
for(let key of Object.keys(mappedObjects)) { | |
let prevObj = mappedObjects[key][0]; | |
let currObj = mappedObjects[key][1]; | |
table += buildHtmlRow(prevObj, currObj); | |
} | |
return `${table}</table>`; | |
function buildTableHeader() { | |
let row = '<tr>'; | |
row += ALL_KEYS.map(key => `<th>${key.replace(/\./g, '_')}</th>`).join(''); | |
return `${row}</tr>`; | |
} | |
function getAllKeys(prevArray, currArray) { | |
let array = prevArray.concat(currArray); | |
let keys = array.map(item => getKeysFromObject(item)); // array of array of keys | |
keys = [].concat.apply([], keys); // flatten in only one array | |
return [... new Set(keys)]; // return uniq keys | |
} | |
// getKeysFromObject({a:1, b:2, c:{d:3, e:{f:2, g:{h:5}}}}) should return ["a", "b", "c.d", "c.e.f", "c.e.g.h"] | |
function getKeysFromObject(object, base = '') { | |
let keys = []; | |
for(let prop of Object.keys(object)) { | |
if(typeof object[prop] === 'object') { | |
let propKeys = getKeysFromObject(object[prop], `${base}${prop}.`); | |
keys = keys.concat(propKeys); | |
} | |
else keys = keys.concat(base + prop); | |
} | |
return keys; | |
} | |
// should return in the form { [_id]: [prevObject, currObject] } for every row | |
// if prevObject is null (i.e., currObject is totally new), it returns [null, currObject] for that row | |
function mapObjects(prevArray, currArray) { | |
let map = {}; | |
prevArray.forEach(item => map[item._id] = [item]); | |
currArray.forEach(item => { | |
if(!map[item._id]) map[item._id] = [null]; | |
map[item._id].push(item); | |
}); | |
return map; | |
} | |
function buildHtmlRow(prevObj, currObj) { | |
let row = '<tr>'; | |
if(!prevObj) { | |
ALL_KEYS.forEach(key => { | |
let value = getObjectValue(currObj, key); | |
row += `<td><strong>${value || ''}</strong></td>`; | |
}); | |
} else { | |
ALL_KEYS.forEach(key => { | |
let prevValue = getObjectValue(prevObj, key); | |
let currValue = getObjectValue(currObj, key); | |
if(nullOrUndefined(prevValue) && nullOrUndefined(currValue)) row += `<td></td>`; | |
else if(prevValue && nullOrUndefined(currValue)) row += `<td><strong>DELETED<strong></td>`; | |
else if(prevValue === currValue) row += `<td>${currValue}</td>`; | |
else if(prevValue !== currValue) row += `<td><strong>${currValue}</strong></td>`; | |
}); | |
} | |
return `${row}</tr>`; | |
} | |
// you can use getObjectValue({ meta: { subKey1: 123 } }, 'meta.subKey1') | |
function getObjectValue(object, prop) { | |
if(!object) return null; | |
let parts = prop.split('.'); | |
if(parts.length === 1) return object[prop]; | |
let baseProp = parts[0]; | |
return getObjectValue(object[baseProp], parts.splice(1).join('.')); | |
} | |
function nullOrUndefined(value) { | |
return value === null || typeof value === 'undefined'; | |
} | |
} | |
module.exports.arrayDiffToHtmlTable = arrayDiffToHtmlTable; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment