var _ = require('lodash'); var actions = require('../actions'); var tree = require('../../util/tree'); module.exports = function(oldProfile, action) { switch(action.type) { case actions.common.LOAD_PROFILE_SUCCESS: var newProfile = _.cloneDeep(action.profile); tree.walk(newProfile, ensureItemKey); return newProfile; case actions.edit.MOVE_PROFILE_ITEM: return moveProfileItem(oldProfile, action.movedItem, action.targetItem); case actions.edit.REMOVE_PROFILE_ITEM: return removeProfileItem(oldProfile, action.removedItem); case actions.edit.ADD_PROFILE_ITEM: return addProfileItem(oldProfile, action.newItem, action.targetItem); case actions.edit.UPDATE_PROFILE_ITEM: return updateProfileItem(oldProfile, action.item, action.key, action.value); case actions.edit.SELECT_PROFILE_ITEM: return selectProfileItem(oldProfile, action.item); default: return oldProfile || null; } }; function selectProfileItem(oldProfile, item) { var newProfile = _.cloneDeep(oldProfile); tree.walk(newProfile, function(currentItem) { delete currentItem.selected; if( _.isEqual(currentItem, item) ) { currentItem.selected = true; } }); return newProfile; } function updateProfileItem(oldProfile, targetItem, key, value) { var newProfile = _.cloneDeep(oldProfile); var item = tree.find(newProfile, targetItem).item; item[key] = value; return newProfile; } function removeProfileItem(oldProfile, removedItem) { var newProfile = _.cloneDeep(oldProfile); var parent = tree.find(newProfile, removedItem).parent; parent.items = _.reject(parent.items, function(item) { return _.isEqual(item, removedItem); }); return newProfile; } function moveProfileItem(oldProfile, movedItem, targetItem) { var newProfile = _.cloneDeep(oldProfile); var previousParent = tree.find(newProfile, movedItem).parent; var newParent = tree.find(newProfile, targetItem).item; previousParent.items = _.reject(previousParent.items, function(item) { return _.isEqual(item, movedItem); }); newParent.items = newParent.items || []; newParent.items.push(_.cloneDeep(movedItem)); return newProfile; } function addProfileItem(oldProfile, newItem, targetItem) { var newProfile = _.cloneDeep(oldProfile); var newParent = tree.find(newProfile, targetItem).item; newParent.items = newParent.items || []; newItem = _.cloneDeep(newItem); ensureItemKey(newItem); newParent.items.push(newItem); return newProfile; } var _inc = 0; function ensureItemKey(item) { if( item && !('_key' in item) ) { item._key = 'item_'+Date.now()+'_'+_inc++; } }