Last active
July 2, 2018 14:54
-
-
Save jimthedev/4fe3d5cafa1b9e22c5d99f6adea76366 to your computer and use it in GitHub Desktop.
precalculate.tree
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const expect = require("expect"); | |
const nav = { | |
children: [ | |
{ | |
text: "Home", | |
link: "/home", | |
children: [ | |
{ | |
text: "About", | |
link: "/home/about", | |
children: [ | |
{ | |
text: "About/Our History", | |
link: "/home/about/history" | |
} | |
] | |
}, | |
{ | |
text: "mypeople/deep", | |
link: "/mypeople/deep", | |
children: [ | |
{ | |
text: "Jim", | |
link: "/person/jim" | |
}, | |
{ | |
text: "Ariana", | |
link: "/person/ariana" | |
} | |
] | |
} | |
] | |
}, | |
{ | |
text: "Products", | |
link: "/products", | |
children: [ | |
{ | |
text: "someproducts", | |
children: [ | |
{ | |
text: "Lawn Mower", | |
link: "/products/lawn-mower" | |
} | |
] | |
} | |
] | |
} | |
] | |
}; | |
// Sanity check | |
expect(nav.children[0].link).toBe("/home"); | |
expect(nav.children[1].link).toBe("/products"); | |
/** | |
* Adds the link property of a node | |
* to that node's links array. | |
*/ | |
const addOwnLinkToOwnLinks = node => { | |
if (node.link) { | |
const { links, ...restOfNode } = node; | |
if (links && typeof links !== undefined) { | |
return { | |
links: [node.link, ...links], | |
...restOfNode | |
}; | |
} | |
return restOfNode; | |
} | |
return node; | |
}; | |
const testNodeWithoutChildrenOrLinks = { | |
text: "Home Page", | |
link: "/home" | |
}; | |
expect( | |
addOwnLinkToOwnLinks(testNodeWithoutChildrenOrLinks).links | |
).not.toBeDefined(); | |
expect(addOwnLinkToOwnLinks(testNodeWithoutChildrenOrLinks).text).toEqual( | |
"Home Page" | |
); | |
expect(addOwnLinkToOwnLinks(testNodeWithoutChildrenOrLinks).link).toEqual( | |
"/home" | |
); | |
const testNodeWithoutChildren = { | |
text: "Home Page", | |
link: "/home", | |
links: ["/home/hi"] | |
}; | |
expect(addOwnLinkToOwnLinks(testNodeWithoutChildren).links).toEqual( | |
expect.arrayContaining(["/home/hi"]) | |
); | |
expect(addOwnLinkToOwnLinks(testNodeWithoutChildren).links).toEqual( | |
expect.arrayContaining(["/home"]) | |
); | |
expect(addOwnLinkToOwnLinks(testNodeWithoutChildren).text).toEqual("Home Page"); | |
expect(addOwnLinkToOwnLinks(testNodeWithoutChildren).link).toEqual("/home"); | |
const testNode = { | |
text: "Home Page", | |
link: "/home", | |
links: ["/home/hi"] | |
}; | |
expect(addOwnLinkToOwnLinks(testNode).links).toEqual( | |
expect.arrayContaining(["/home", "/home/hi"]) | |
); | |
expect(addOwnLinkToOwnLinks(testNode).text).toEqual("Home Page"); | |
expect(addOwnLinkToOwnLinks(testNode).link).toEqual("/home"); | |
/** | |
* Add links, via breadth (reduce an array of nodes) | |
*/ | |
const reduceLinks = nodes => { | |
if (!nodes || !nodes.reduce) { | |
return []; | |
} | |
return nodes.reduce((a, newChildNode) => { | |
const newChildLinks = addOwnLinkToOwnLinks(newChildNode).links; | |
if (newChildLinks) { | |
return a.concat(newChildLinks); | |
} | |
return a; | |
}, []); | |
}; | |
expect(reduceLinks({ shouldBe: "array" }).length).toBe(0); | |
expect(reduceLinks([testNodeWithoutChildrenOrLinks]).length).toBe(0); | |
expect(reduceLinks([testNodeWithoutChildren]).length).toBe(2); | |
/** | |
* Recursively map over a node's children (depth) | |
*/ | |
const makeSubLinks = aNode => { | |
if (!aNode.children) { | |
return aNode; | |
} | |
// Loop through all nodes | |
return aNode.children.map(({ children, ...node }) => { | |
// Turn a node into an ideal node | |
const nodeWithLinks = { links: [], ...node }; | |
// Get the children, also include their sub links | |
const newChildren = makeSubLinks({ | |
children, | |
...node | |
}); | |
// Return the original node with its: | |
// - new links | |
// - children which also include sub links | |
return { | |
...node, | |
links: nodeWithLinks.links.concat(reduceLinks(newChildren)), | |
children: newChildren | |
}; | |
}); | |
}; | |
const linkList = makeSubLinks(nav); | |
console.log(JSON.stringify(linkList)); | |
// So to see if we should expand a given node, we simply use: | |
// | |
// if (node.links.indexOf(path) > -1 || node.link === path) { | |
// expandThisNode() | |
// } | |
// | |
// Please note that expandThisNode might just render an expanded node. | |
const result = [ | |
{ | |
text: "Home", | |
link: "/home", | |
links: [ | |
"/home/about", | |
"/home/about/history", | |
"/mypeople/deep", | |
"/person/jim", | |
"/person/ariana" | |
], | |
children: [ | |
{ | |
text: "About", | |
link: "/home/about", | |
links: ["/home/about/history"], | |
children: [ | |
{ | |
text: "About/Our History", | |
link: "/home/about/history", | |
links: [], | |
children: { text: "About/Our History", link: "/home/about/history" } | |
} | |
] | |
}, | |
{ | |
text: "mypeople/deep", | |
link: "/mypeople/deep", | |
links: ["/person/jim", "/person/ariana"], | |
children: [ | |
{ | |
text: "Jim", | |
link: "/person/jim", | |
links: [], | |
children: { text: "Jim", link: "/person/jim" } | |
}, | |
{ | |
text: "Ariana", | |
link: "/person/ariana", | |
links: [], | |
children: { text: "Ariana", link: "/person/ariana" } | |
} | |
] | |
} | |
] | |
}, | |
{ | |
text: "Products", | |
link: "/products", | |
links: ["/products/lawn-mower"], | |
children: [ | |
{ | |
text: "someproducts", | |
links: ["/products/lawn-mower"], | |
children: [ | |
{ | |
text: "Lawn Mower", | |
link: "/products/lawn-mower", | |
links: [], | |
children: { text: "Lawn Mower", link: "/products/lawn-mower" } | |
} | |
] | |
} | |
] | |
} | |
]; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment