all files / s-select/utils/ tree.js

100% Statements 31/31
100% Branches 14/14
100% Functions 3/3
100% Lines 30/30
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86                              56× 56×   56×     49× 49×   17×       32× 290×             290× 290×     290×       32× 290× 290×   290× 154×   136×       32×       136×               17×     188×   188× 170× 170×     188×      
import Ember from 'ember';
 
const {
  A,
  get,
  isEmpty,
  ObjectProxy
} = Ember;
 
/* Build a tree (nested objects) from a plain array
 * using `id` and `parentId` as references for the
 * relationships. The `name` property is expected
 * for rendering. Optionally, `valueKey` can be
 * passed for `id` and `labelKey` for `name`.
 * If the model is flat, it will return a list.
 */
export function buildTree(model, options) {
  let tree = {};
  let roots = A();
 
  if (isEmpty(model)) {
    return roots;
  }
 
  let element = model[0] || get(model, 'firstObject');
  if (typeof element !== 'object') {
    // Not a model of objects, hence it should be a flat list
    return buildFlatList(model);
  }
 
  // Add all nodes to tree
  model.forEach(node => {
    let child = {
      content: node,
      children: A(),
      isSelected: false,
      isVisible: true
    };
 
    child.id = get(node, options.valueKey || 'id');
    child.name = get(node, options.labelKey || 'name');
 
    // Proxy options to keep model intact
    tree[get(child, 'id')] = ObjectProxy.create(child);
  });
 
  // Connect all children to their parent
  model.forEach(node => {
    let child = tree[get(node, options.valueKey || 'id')];
    let parent = get(node, 'parentId');
 
    if (isEmpty(parent)) {
      roots.push(child);
    } else {
      tree[parent].children.push(child);
    }
  });
 
  return roots;
}
 
// Builds a list of proxies from a model of values
export function buildFlatList(model) {
  let list = model.map(node => ObjectProxy.create({
    content: node,
    id: node,
    name: node,
    isSelected: false,
    isVisible: true
  }));
 
  return A(list);
}
 
export function getDescendents(tree) {
  let descendents = A();
 
  tree.forEach(node => {
    descendents.pushObject(node);
    descendents.pushObjects(getDescendents(node.children));
  });
 
  return descendents;
}