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; case actions.edit.SELECT_PROFILE_ITEM: newProfile = selectProfileItem(oldProfile, action.item); break; } if(newProfile) tree.walk(newProfile, ensureItemKey); return newProfile; }; 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++; } }