navigation.mjs 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131
  1. import { generateError, generateSuccess } from '../../helpers/graph.mjs'
  2. import { isNil } from 'lodash-es'
  3. export default {
  4. Query: {
  5. async navigationById (obj, args, context, info) {
  6. return WIKI.db.navigation.getNav({ id: args.id, cache: true, userGroups: context.req.user?.groups })
  7. }
  8. },
  9. Mutation: {
  10. async updateNavigation (obj, args, context) {
  11. try {
  12. let updateInherited = false
  13. let updateInheritedNavId = null
  14. let updateNavId = null
  15. let ancestorNavId = null
  16. const treeEntry = await WIKI.db.knex('tree').where('id', args.pageId).first()
  17. if (!treeEntry) {
  18. throw new Error('Invalid ID')
  19. }
  20. const currentNavId = treeEntry.folderPath === '' && treeEntry.fileName === 'home' ? treeEntry.siteId : treeEntry.id
  21. const treeEntryPath = treeEntry.folderPath ? `${treeEntry.folderPath}.${treeEntry.fileName}` : treeEntry.fileName
  22. // -> Create / Update Nav Menu Items
  23. if (!isNil(args.items)) {
  24. await WIKI.db.knex('navigation').insert({
  25. id: currentNavId,
  26. items: JSON.stringify(args.items),
  27. siteId: treeEntry.siteId
  28. }).onConflict('id').merge({
  29. items: JSON.stringify(args.items)
  30. })
  31. }
  32. // -> Find ancestor nav ID
  33. const ancNavResult = await WIKI.db.knex.raw(`
  34. SELECT "navigationId", "navigationMode", nlevel("folderPath" || "fileName") AS levels
  35. FROM tree
  36. WHERE ("folderPath" || "fileName") @> :currentPath
  37. AND "navigationMode" IN ('override', 'hide')
  38. ORDER BY levels DESC
  39. LIMIT 1
  40. `, {
  41. currentPath: treeEntry.folderPath
  42. })
  43. if (ancNavResult.rowCount > 0) {
  44. ancestorNavId = ancNavResult.rows[0]?.navigationId
  45. } else {
  46. ancestorNavId = treeEntry.siteId
  47. }
  48. // -> Update mode
  49. switch (args.mode) {
  50. case 'inherit': {
  51. updateNavId = ancestorNavId
  52. if (['override', 'hide'].includes(treeEntry.navigationMode)) {
  53. updateInherited = true
  54. updateInheritedNavId = ancestorNavId
  55. }
  56. break
  57. }
  58. case 'override': {
  59. updateNavId = treeEntry.id
  60. updateInherited = true
  61. updateInheritedNavId = treeEntry.id
  62. break
  63. }
  64. case 'overrideExact': {
  65. updateNavId = treeEntry.id
  66. if (['override', 'hide'].includes(treeEntry.navigationMode)) {
  67. updateInherited = true
  68. updateInheritedNavId = ancestorNavId
  69. }
  70. break
  71. }
  72. case 'hide': {
  73. updateInherited = true
  74. updateNavId = null
  75. break
  76. }
  77. case 'hideExact': {
  78. updateNavId = null
  79. if (['override', 'hide'].includes(treeEntry.navigationMode)) {
  80. updateInherited = true
  81. updateInheritedNavId = ancestorNavId
  82. }
  83. break
  84. }
  85. }
  86. // -> Set for current path
  87. await WIKI.db.knex('tree').where('id', treeEntry.id).update({ navigationMode: args.mode, navigationId: updateNavId })
  88. // -> Update nodes that inherit from current
  89. if (updateInherited) {
  90. await WIKI.db.knex.raw(`
  91. UPDATE tree tt
  92. SET "navigationId" = :navId
  93. WHERE type IN ('page', 'folder')
  94. AND "folderPath" <@ :overridePath
  95. AND "navigationMode" = 'inherit'
  96. AND NOT EXISTS (
  97. SELECT 1
  98. FROM tree tc
  99. WHERE type IN ('page', 'folder')
  100. AND tc."folderPath" <@ :overridePath
  101. AND tc."folderPath" @> tt."folderPath"
  102. AND tc."navigationMode" IN ('override', 'hide')
  103. )
  104. `, {
  105. navId: updateInheritedNavId,
  106. overridePath: treeEntryPath
  107. })
  108. }
  109. // for (const tree of args.tree) {
  110. // await WIKI.cache.set(`nav:sidebar:${tree.locale}`, tree.items, 300)
  111. // }
  112. return {
  113. operation: generateSuccess('Navigation updated successfully'),
  114. navigationMode: args.mode,
  115. navigationId: updateNavId
  116. }
  117. } catch (err) {
  118. return generateError(err)
  119. }
  120. }
  121. }
  122. }