Meilleure gestion arbre immutable

This commit is contained in:
2015-11-03 17:45:37 +01:00
parent d8a0136a99
commit 519ec99264
11 changed files with 236 additions and 114 deletions

View File

@ -1,4 +1,5 @@
var Util = require('../../util');
var Tree = require('../../util/tree');
var logger = Util.Logger;
var path = require('path');
var _ = require('lodash');
@ -111,10 +112,33 @@ exports.selectProfileItem = function(item) {
};
exports.updateProfileItem = function(item, key, value) {
return {
type: UPDATE_PROFILE_ITEM,
item: item,
key: key,
value: value
return function(dispatch, getState) {
var state = getState();
var selectedPath, tree;
// If the item is selected, save its path
if(state.selectedItem === item) {
tree = new Tree(state.profile);
var result = tree.find(item);
selectedPath = result.path;
}
dispatch({
type: UPDATE_PROFILE_ITEM,
item: item,
key: key,
value: value
});
// Re-select item if needed
if(selectedPath) {
state = getState();
tree = new Tree(state.profile);
var selectedItem = tree.get(selectedPath);
dispatch(exports.selectProfileItem(selectedItem));
}
};
};

View File

@ -10,7 +10,7 @@ var createStore = redux.applyMiddleware(
var appReducer = redux.combineReducers({
profile: reducers.profile,
processOpts: reducers.processOpts,
selectedItem: reducers.selectedItem,
desktopApps: reducers.desktopApps,
theme: reducers.theme
});

View File

@ -1,3 +1,4 @@
exports.desktopApps = require('./desktop-apps');
exports.profile = require('./profile');
exports.theme = require('./theme');
exports.selectedItem = require('./selected-item');

View File

@ -1,6 +1,6 @@
var _ = require('lodash');
var actions = require('../actions');
var tree = require('../../util/tree');
var Tree = require('../../util/tree');
module.exports = function(oldProfile, action) {
@ -28,84 +28,76 @@ module.exports = function(oldProfile, action) {
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(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 updateProfileItem(oldProfile, targetItem, key, value) {
var newProfile = _.cloneDeep(oldProfile);
var item = tree.find(newProfile, targetItem).item;
item[key] = value;
return newProfile;
function removeProfileItem(profile, removedItem) {
var tree = new Tree(profile);
var result = tree.find(removedItem);
tree.del(result.path);
return tree.getState();
}
function removeProfileItem(oldProfile, removedItem) {
function moveProfileItem(profile, movedItem, targetItem) {
var newProfile = _.cloneDeep(oldProfile);
var parent = tree.find(newProfile, removedItem).parent;
var tree = new Tree(profile);
parent.items = _.reject(parent.items, function(item) {
return _.isEqual(item, removedItem);
});
var movedResult = tree.find(movedItem);
var targetResult = tree.find(targetItem);
return newProfile;
// Remove item from current location
tree.del(movedResult.path);
}
var targetPath = targetResult ? targetResult.path : [];
var targetItemsPath = targetPath.concat('items');
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++;
// 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();
}

View File

@ -0,0 +1,17 @@
var actions = require('../actions');
module.exports = function(selectedItem, action) {
switch(action.type) {
case actions.edit.SELECT_PROFILE_ITEM:
selectedItem = action.item;
break;
default:
return selectedItem || null;
}
return selectedItem;
};