Advertisement
Guest User

Untitled

a guest
Nov 8th, 2020
122
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. import React from "react"
  2. import { graphql, useStaticQuery } from "gatsby"
  3.  
  4. // populates nodes with an array filled with each directory in slug
  5. const populateNodeDirectories = edges => {
  6.   return edges.map(({ node }) => {
  7.     node.directories = node.fields.slug
  8.       .split("/")
  9.       .filter(element => element.length > 0)
  10.  
  11.     return node
  12.   })
  13. }
  14.  
  15. const arraysEqual = (a, b) => {
  16.   if (a === b) return true
  17.   if (a == null || b == null) return false
  18.   if (a.length !== b.length) return false
  19.  
  20.   for (let i = 0; i < a.length; ++i) {
  21.     if (a[i] !== b[i]) return false
  22.   }
  23.   return true
  24. }
  25.  
  26. // determines order of slugs such that parents come before children
  27. const compareSlugs = (a, b) => {
  28.   const minDirCount = Math.min(a.directories.length, b.directories.length)
  29.  
  30.   for (let i = 0; i < minDirCount; i++) {
  31.     if (a.directories[i] < b.directories[i]) {
  32.       return -1
  33.     }
  34.  
  35.     if (a.directories[i] > b.directories[i]) {
  36.       return 1
  37.     }
  38.   }
  39.  
  40.   return a.directories.length - b.directories.length
  41. }
  42.  
  43. // Determines order of nodes for display. display_order is nullable and has
  44. // higher priority over title
  45. const compareDisplayOrder = (a, b) => {
  46.   const a_displayOrder = a.frontmatter.display_order
  47.   const b_displayOrder = b.frontmatter.display_order
  48.  
  49.   if (a_displayOrder === b_displayOrder) {
  50.     const a_title = a.frontmatter.title
  51.     const b_title = b.frontmatter.title
  52.  
  53.     if (a_title > b_title) {
  54.       return 1
  55.     }
  56.  
  57.     if (a_title < b_title) {
  58.       return -1
  59.     }
  60.   }
  61.  
  62.   if (a_displayOrder === null) {
  63.     return 1
  64.   }
  65.  
  66.   if (b_displayOrder === null) {
  67.     return -1
  68.   }
  69.  
  70.   if (a_displayOrder > b_displayOrder) {
  71.     return 1
  72.   }
  73.  
  74.   if (a_displayOrder < b_displayOrder) {
  75.     return -1
  76.   }
  77.  
  78.   return 0
  79. }
  80.  
  81. const findParentNode = (nodes, childNode) => {
  82.   const parentNode = nodes.find(node => {
  83.     return isParentNode(node, childNode)
  84.   })
  85.  
  86.   if (parentNode) {
  87.     return parentNode
  88.   } else {
  89.     // iterates through each node on current level and recursively runs for all
  90.     // children on those nodes until a parent node is found
  91.     for (let i = 0; i < nodes.length; i++) {
  92.       if (nodes[i].children instanceof Array) {
  93.         return findParentNode(nodes[i].children, childNode)
  94.       }
  95.     }
  96.   }
  97. }
  98.  
  99. const isParentNode = (parentNode, childNode) => {
  100.   return arraysEqual(
  101.     parentNode.directories,
  102.     childNode.directories.slice(0, childNode.directories.length - 1)
  103.   )
  104. }
  105.  
  106. const groupNodes = nodes => {
  107.   // requires nodes to be sorted by slug to work correctly
  108.   nodes.sort(compareSlugs)
  109.   let groupedNodes = []
  110.  
  111.   for (let i = 0; i < nodes.length; i++) {
  112.     if (nodes[i].directories.length === 0) {
  113.       // skip home index node
  114.     } else if (nodes[i].directories.length === 1) {
  115.       // add root level nodes
  116.       nodes[i].children = []
  117.       groupedNodes.push(nodes[i])
  118.     } else {
  119.       // find parent node for current node and add it as a child
  120.       const parentNode = findParentNode(groupedNodes, nodes[i])
  121.  
  122.       if (parentNode) {
  123.         nodes[i].children = []
  124.         parentNode.children.push(nodes[i])
  125.       }
  126.     }
  127.   }
  128.  
  129.   return groupedNodes
  130. }
  131.  
  132. const sortNodesByDisplayOrder = nodes => {
  133.   nodes.sort(compareDisplayOrder)
  134.  
  135.   for (let i = 0; i < nodes.length; i++) {
  136.     // iterates through each node on current level and recursively runs for all
  137.     // children on those nodes until each node and all their children are sorted
  138.     if (nodes[i].children instanceof Array) {
  139.       sortNodesByDisplayOrder(nodes[i].children)
  140.     }
  141.   }
  142.  
  143.   return nodes
  144. }
  145.  
  146. const getGroupedNodes = edges => {
  147.   let nodes = populateNodeDirectories(edges)
  148.   nodes = groupNodes(nodes)
  149.   nodes = sortNodesByDisplayOrder(nodes)
  150.  
  151.   return nodes
  152. }
  153.  
  154. const NavigationDrawer = () => {
  155.   const data = useStaticQuery(graphql`
  156.     query {
  157.       allMarkdownRemark {
  158.         edges {
  159.           node {
  160.             id
  161.             frontmatter {
  162.               title
  163.               display_order
  164.             }
  165.             fields {
  166.               slug
  167.             }
  168.           }
  169.         }
  170.       }
  171.     }
  172.   `)
  173.  
  174.   const nodes = getGroupedNodes(data.allMarkdownRemark.edges)
  175.  
  176.   {...}
  177. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement