nodes.js 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209
  1. import Vue from 'vue'
  2. import api from '@/api'
  3. import {
  4. DATA_LEVELS,
  5. ID_VARIANTS,
  6. VARIANT_IDS,
  7. RELATIONS,
  8. reduceQueryIds,
  9. reduceQueryLevels,
  10. formatDate
  11. } from '@/store/utils'
  12. import {
  13. AllNodesOfVariant
  14. } from '@/api/queries'
  15. export default {
  16. state: {
  17. debug: localStorage.getItem('debug') === 'true',
  18. nodes: {},
  19. history: [],
  20. optionsVisible: true,
  21. // IDS
  22. ids: {
  23. // depart: undefined,
  24. // kit: undefined,
  25. // creation: undefined
  26. }
  27. },
  28. mutations: {
  29. 'SET_ALL_NODES_IDS' (state, [variant, nodes]) {
  30. Vue.set(state.ids, variant, nodes.map(({ id }) => id))
  31. },
  32. 'ADD_NODES' (state, [nodes, dataLevel]) {
  33. function addNode (node, level) {
  34. const stateNode = node.id in state.nodes ? state.nodes[node.id] : undefined
  35. if (node.type === 'Creation') {
  36. node.variant = [{ id: 0 }]
  37. if (node.files && node.files.length) {
  38. const creationFile = node.files.shift()
  39. if (!node.files.length) node.files = null
  40. const mime = creationFile.filemime
  41. if (mime === 'application/pdf') {
  42. node.mediaItem = {
  43. type: 'iframe',
  44. src: creationFile.url + '#toolbar=0&navpanes=0&statusbar=0'
  45. }
  46. } else if (mime === 'text/html') {
  47. node.mediaItem = { type: 'iframe', src: creationFile.url }
  48. } else if (['audio', 'video'].some(type => mime.includes(type))) {
  49. node.mediaItem = {
  50. type: mime.includes('audio') ? 'audio' : 'video',
  51. src: creationFile.url
  52. }
  53. } else if (node.piece && node.piece.url) {
  54. node.mediaItem = { type: 'iframe', src: node.piece.url }
  55. }
  56. } else if (node.piece && node.piece.url) {
  57. node.mediaItem = { type: 'iframe', src: node.piece.url }
  58. }
  59. if (node.images && node.images.length) {
  60. node.image = node.images.shift()
  61. }
  62. }
  63. if (node.date) {
  64. node.date.start = formatDate(node.date.start)
  65. }
  66. if ('creations' in node) {
  67. if (node.creations) {
  68. if (!Array.isArray(node.children)) {
  69. node.children = []
  70. }
  71. node.creations.forEach(item => {
  72. item.variant = [{ id: 0 }]
  73. node.children.push(item)
  74. })
  75. }
  76. delete node.creations
  77. }
  78. if (node.variant === null || Array.isArray(node.variant)) {
  79. node.variant = node.variant !== null ? ID_VARIANTS[node.variant[0].id] : 'dark'
  80. }
  81. if (node.type) {
  82. node.type = node.type === 'Textref' ? 'ref' : 'prod'
  83. }
  84. if (node.tags) {
  85. node.tags = node.tags.map(tag => {
  86. return { ...tag, name: tag.name[0].toUpperCase() + tag.name.slice(1) }
  87. })
  88. }
  89. for (const relation of RELATIONS) {
  90. if (relation in node && node[relation]) {
  91. node[relation] = node[relation].map(subNode => {
  92. if (!(subNode.id in state.nodes)) {
  93. addNode(subNode, -1)
  94. }
  95. return state.nodes[subNode.id]
  96. })
  97. }
  98. if (node[relation] === null) {
  99. node[relation] = []
  100. }
  101. }
  102. if (node.notes) {
  103. node.notes.forEach(note => {
  104. if (note.links && note.links.length) {
  105. note.links = note.links.map(link => {
  106. if (!(link.id in state.nodes) || state.nodes[link.id].dataLevel < 1) {
  107. addNode(link, -1)
  108. }
  109. return state.nodes[link.id]
  110. })
  111. }
  112. })
  113. }
  114. if (!stateNode || stateNode.dataLevel < level) {
  115. node.dataLevel = level
  116. }
  117. if (stateNode === undefined) {
  118. Vue.set(state.nodes, node.id, node)
  119. } else {
  120. for (const key in node) {
  121. Vue.set(state.nodes[node.id], key, node[key])
  122. }
  123. }
  124. }
  125. for (const node of nodes) {
  126. addNode(node, dataLevel)
  127. }
  128. },
  129. 'ADD_HISTORY_ENTRIES' (state, ids) {
  130. for (const id of ids) {
  131. if (!state.history.includes(id)) {
  132. state.history.push(id)
  133. }
  134. }
  135. },
  136. 'UPDATE_OPTIONS_VISIBILITY' (state, visible) {
  137. state.optionsVisible = visible
  138. }
  139. },
  140. actions: {
  141. async 'GET_ALL_NODES_IDS' ({ state, commit }, { variant, dataLevel = 'initial' }) {
  142. if (state.ids[variant] === undefined) {
  143. const levels = reduceQueryLevels(DATA_LEVELS[dataLevel])
  144. await api.queryAllNodes(VARIANT_IDS[variant], levels).then(({ nodes }) => {
  145. commit('SET_ALL_NODES_IDS', [variant, nodes])
  146. commit('ADD_NODES', [nodes, DATA_LEVELS[dataLevel]])
  147. })
  148. }
  149. return state.ids[variant]
  150. },
  151. async 'GET_NODES' ({ state, commit, getters }, { ids, dataLevel = 'partial' }) {
  152. const { idsToQuery, levelsToQuery } = reduceQueryIds(ids, dataLevel, state.nodes)
  153. if (idsToQuery) {
  154. await api.queryNodes(idsToQuery, levelsToQuery).then(data => {
  155. commit('ADD_NODES', [data.nodes, DATA_LEVELS[dataLevel]])
  156. })
  157. }
  158. return getters.nodes(ids)
  159. },
  160. async 'GET_NODE' ({ state, commit, getters }, { id, dataLevel = 'full' }) {
  161. const lvl = DATA_LEVELS[dataLevel]
  162. const nodeLvl = id in state.nodes ? state.nodes[id].dataLevel : -1
  163. if (nodeLvl < lvl) {
  164. const levelsToQuery = Array(lvl - nodeLvl).fill(nodeLvl + 1).map((v, i) => v + i)
  165. await api.queryNode(id, levelsToQuery).then(data => {
  166. commit('ADD_NODES', [[data.node], lvl])
  167. })
  168. }
  169. return getters.node(id)
  170. }
  171. },
  172. getters: {
  173. debug: state => state.debug,
  174. allNodes: state => state.nodes,
  175. // Args getters
  176. nodes: state => ids => ids.map(id => state.nodes[id]),
  177. node: state => id => state.nodes[id],
  178. optionsVisible: state => state.optionsVisible,
  179. history: state => {
  180. return state.history.map(id => state.nodes[id]).filter(node => {
  181. return node.dataLevel > 0
  182. })
  183. }
  184. }
  185. }