You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

231 lines
5.8 KiB

  1. const Model = require('objection').Model
  2. const _ = require('lodash')
  3. /* global WIKI */
  4. /**
  5. * Page History model
  6. */
  7. module.exports = class PageHistory extends Model {
  8. static get tableName() { return 'pageHistory' }
  9. static get jsonSchema () {
  10. return {
  11. type: 'object',
  12. required: ['path', 'title'],
  13. properties: {
  14. id: {type: 'integer'},
  15. path: {type: 'string'},
  16. hash: {type: 'string'},
  17. title: {type: 'string'},
  18. description: {type: 'string'},
  19. isPublished: {type: 'boolean'},
  20. publishStartDate: {type: 'string'},
  21. publishEndDate: {type: 'string'},
  22. content: {type: 'string'},
  23. contentType: {type: 'string'},
  24. createdAt: {type: 'string'}
  25. }
  26. }
  27. }
  28. static get relationMappings() {
  29. return {
  30. tags: {
  31. relation: Model.ManyToManyRelation,
  32. modelClass: require('./tags'),
  33. join: {
  34. from: 'pageHistory.id',
  35. through: {
  36. from: 'pageHistoryTags.pageId',
  37. to: 'pageHistoryTags.tagId'
  38. },
  39. to: 'tags.id'
  40. }
  41. },
  42. page: {
  43. relation: Model.BelongsToOneRelation,
  44. modelClass: require('./pages'),
  45. join: {
  46. from: 'pageHistory.pageId',
  47. to: 'pages.id'
  48. }
  49. },
  50. author: {
  51. relation: Model.BelongsToOneRelation,
  52. modelClass: require('./users'),
  53. join: {
  54. from: 'pageHistory.authorId',
  55. to: 'users.id'
  56. }
  57. },
  58. editor: {
  59. relation: Model.BelongsToOneRelation,
  60. modelClass: require('./editors'),
  61. join: {
  62. from: 'pageHistory.editorKey',
  63. to: 'editors.key'
  64. }
  65. },
  66. locale: {
  67. relation: Model.BelongsToOneRelation,
  68. modelClass: require('./locales'),
  69. join: {
  70. from: 'pageHistory.localeCode',
  71. to: 'locales.code'
  72. }
  73. }
  74. }
  75. }
  76. $beforeInsert() {
  77. this.createdAt = new Date().toISOString()
  78. }
  79. /**
  80. * Create Page Version
  81. */
  82. static async addVersion(opts) {
  83. await WIKI.models.pageHistory.query().insert({
  84. pageId: opts.id,
  85. authorId: opts.authorId,
  86. content: opts.content,
  87. contentType: opts.contentType,
  88. description: opts.description,
  89. editorKey: opts.editorKey,
  90. hash: opts.hash,
  91. isPrivate: (opts.isPrivate === true || opts.isPrivate === 1),
  92. isPublished: (opts.isPublished === true || opts.isPublished === 1),
  93. localeCode: opts.localeCode,
  94. path: opts.path,
  95. publishEndDate: opts.publishEndDate || '',
  96. publishStartDate: opts.publishStartDate || '',
  97. title: opts.title,
  98. action: opts.action || 'updated',
  99. versionDate: opts.versionDate
  100. })
  101. }
  102. /**
  103. * Get Page Version
  104. */
  105. static async getVersion({ pageId, versionId }) {
  106. const version = await WIKI.models.pageHistory.query()
  107. .column([
  108. 'pageHistory.path',
  109. 'pageHistory.title',
  110. 'pageHistory.description',
  111. 'pageHistory.isPrivate',
  112. 'pageHistory.isPublished',
  113. 'pageHistory.publishStartDate',
  114. 'pageHistory.publishEndDate',
  115. 'pageHistory.content',
  116. 'pageHistory.contentType',
  117. 'pageHistory.createdAt',
  118. 'pageHistory.action',
  119. 'pageHistory.authorId',
  120. 'pageHistory.pageId',
  121. 'pageHistory.versionDate',
  122. {
  123. versionId: 'pageHistory.id',
  124. editor: 'pageHistory.editorKey',
  125. locale: 'pageHistory.localeCode',
  126. authorName: 'author.name'
  127. }
  128. ])
  129. .joinRelated('author')
  130. .where({
  131. 'pageHistory.id': versionId,
  132. 'pageHistory.pageId': pageId
  133. }).first()
  134. if (version) {
  135. return {
  136. ...version,
  137. updatedAt: version.createdAt || null,
  138. tags: []
  139. }
  140. } else {
  141. return null
  142. }
  143. }
  144. /**
  145. * Get History Trail of a Page
  146. */
  147. static async getHistory({ pageId, offsetPage = 0, offsetSize = 100 }) {
  148. const history = await WIKI.models.pageHistory.query()
  149. .column([
  150. 'pageHistory.id',
  151. 'pageHistory.path',
  152. 'pageHistory.authorId',
  153. 'pageHistory.action',
  154. 'pageHistory.versionDate',
  155. {
  156. authorName: 'author.name'
  157. }
  158. ])
  159. .joinRelated('author')
  160. .where({
  161. 'pageHistory.pageId': pageId
  162. })
  163. .orderBy('pageHistory.versionDate', 'desc')
  164. .page(offsetPage, offsetSize)
  165. let prevPh = null
  166. const upperLimit = (offsetPage + 1) * offsetSize
  167. if (history.total >= upperLimit) {
  168. prevPh = await WIKI.models.pageHistory.query()
  169. .column([
  170. 'pageHistory.id',
  171. 'pageHistory.path',
  172. 'pageHistory.authorId',
  173. 'pageHistory.action',
  174. 'pageHistory.versionDate',
  175. {
  176. authorName: 'author.name'
  177. }
  178. ])
  179. .joinRelated('author')
  180. .where({
  181. 'pageHistory.pageId': pageId
  182. })
  183. .orderBy('pageHistory.versionDate', 'desc')
  184. .offset((offsetPage + 1) * offsetSize)
  185. .limit(1)
  186. .first()
  187. }
  188. return {
  189. trail: _.reduce(_.reverse(history.results), (res, ph) => {
  190. let actionType = 'edit'
  191. let valueBefore = null
  192. let valueAfter = null
  193. if (!prevPh && history.total < upperLimit) {
  194. actionType = 'initial'
  195. } else if (_.get(prevPh, 'path', '') !== ph.path) {
  196. actionType = 'move'
  197. valueBefore = _.get(prevPh, 'path', '')
  198. valueAfter = ph.path
  199. }
  200. res.unshift({
  201. versionId: ph.id,
  202. authorId: ph.authorId,
  203. authorName: ph.authorName,
  204. actionType,
  205. valueBefore,
  206. valueAfter,
  207. versionDate: ph.versionDate
  208. })
  209. prevPh = ph
  210. return res
  211. }, []),
  212. total: history.total
  213. }
  214. }
  215. }