Skip to content

Instantly share code, notes, and snippets.

@arackaf
Last active December 22, 2015 20:49
Show Gist options
  • Save arackaf/8067d6110cc522d7f486 to your computer and use it in GitHub Desktop.
Save arackaf/8067d6110cc522d7f486 to your computer and use it in GitHub Desktop.
function subjectsReducer(state = initialSubjectsState(), action = {}){
switch(action.type){
case LOAD_SUBJECTS_RESULTS:
return Object.assign({}, state, { list: stackAndGetTopLevelSubjects(action.subjects) });
case EDIT_SUBJECT:
var editingSubject = Object.assign({}, [...flattenedSubjects(state.list)].find(s => s._id == action._id)),
newSubjectParent;
var eligibleParents = [...flattenedSubjects(state.list)]
.filter(s => s._id !== action._id && (!new RegExp(`,${action._id},`).test(s.path)));
if (editingSubject.path == null){
newSubjectParent = null;
} else {
let hierarchy = editingSubject.path.split(',');
newSubjectParent = hierarchy[hierarchy.length - 2];
}
return Object.assign({}, state, { editSubjectsPacket: Object.assign({}, state.editSubjectsPacket, { newSubjectName: editingSubject.name, newSubjectParent, editingSubject, eligibleParents }) });
case UPDATE_SUBJECT_RESULTS:
if ((action.existingParent || null) == (action.newParent || null)) {
//parent's the same - update name and we're done
let existingSubjects = [...flattenedSubjects(state.list)],
tweakedSubjects = existingSubjects.map(s => s._id == action._id ? Object.assign({}, s, { name: action.newName }) : s);
return Object.assign({}, state, { list: stackAndGetTopLevelSubjects(tweakedSubjects) });
} else {
//new parent - the tree is now affected
//not the most efficient code ... flatten all subjects, rip out those that were affected, re-stack
let existingSubjects = [...flattenedSubjects(state.list)],
affectedIds = action.affectedSubjects.map(s => '' + s._id),
tweakedSubjects = existingSubjects.map(s => Object.assign({}, s)).filter(s => affectedIds.indexOf('' + s._id) == -1);
return Object.assign({}, state, { list: stackAndGetTopLevelSubjects(tweakedSubjects.concat(action.affectedSubjects)) });
}
}
return state;
}
function *flattenedSubjects(subjects){
for (let subject of subjects){
yield subject;
if (subject.children.length) {
yield* flattenedSubjects(subject.children);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment