var _ = require('lodash'); var actions = require('../actions'); var Tree = require('../../util/tree'); module.exports = function(oldProfile, action) { var newProfile = oldProfile || { items: [] }; switch(action.type) { case actions.common.LOAD_PROFILE_SUCCESS: newProfile = _.cloneDeep(action.profile); break; case actions.edit.MOVE_PROFILE_ITEM: newProfile = moveProfileItem(oldProfile, action.movedItem, action.targetItem); break; case actions.edit.REMOVE_PROFILE_ITEM: newProfile = removeProfileItem(oldProfile, action.removedItem); break; case actions.edit.ADD_PROFILE_ITEM: newProfile = addProfileItem(oldProfile, action.newItem, action.targetItem); break; case actions.edit.UPDATE_PROFILE_ITEM: newProfile = updateProfileItem(oldProfile, action.item, action.key, action.value); break; } return newProfile; }; function updateProfileItem(profile, targetItem, key, value) { var tree = new Tree(profile); var result = tree.find(targetItem); var itemPath = result.path; tree.update(itemPath.concat(key), {$set: value}); return tree.getState(); } function removeProfileItem(profile, removedItem) { var tree = new Tree(profile); var result = tree.find(removedItem); tree.del(result.path); return tree.getState(); } function moveProfileItem(profile, movedItem, targetItem) { var tree = new Tree(profile); var movedResult = tree.find(movedItem); var targetResult = tree.find(targetItem); // Remove item from current location tree.del(movedResult.path); var targetPath = targetResult ? targetResult.path : []; var targetItemsPath = targetPath.concat('items'); // Create "items" collection if not defined on target item if( !('items' in targetItem) ) { tree.update(targetItemsPath, { "$set": [] }); } // Add moved item to target tree.update(targetItemsPath, { "$push": [movedItem] }); return tree.getState(); } function addProfileItem(profile, newItem, targetItem) { var tree = new Tree(profile); var targetResult = tree.find(targetItem); var targetPath = targetResult ? targetResult.path : []; var targetItemsPath = targetPath.concat('items'); // Create "items" collection if not defined on target item if( !('items' in targetItem) ) { tree.update(targetItemsPath, { "$set": [] }); } // Add moved item to target tree.update(targetItemsPath, { "$push": [newItem] }); return tree.getState(); }