@webiny/app-headless-cms-workflows 0.0.0-unstable.0156a4c312

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (417) hide show
  1. package/Components/CmsEntriesList/CmsReviewMoveEntryAction.d.ts +2 -0
  2. package/Components/CmsEntriesList/CmsReviewMoveEntryAction.js +43 -0
  3. package/Components/CmsEntriesList/CmsReviewMoveEntryAction.js.map +1 -0
  4. package/Components/CmsEntriesList/CmsReviewMoveEntryAction.test.d.ts +1 -0
  5. package/Components/CmsEntriesList/CmsReviewMoveEntryAction.test.js +118 -0
  6. package/Components/CmsEntriesList/CmsReviewMoveEntryAction.test.js.map +1 -0
  7. package/Components/CmsEntriesList/CmsReviewScheduleEntryAction.d.ts +2 -0
  8. package/Components/CmsEntriesList/CmsReviewScheduleEntryAction.js +22 -0
  9. package/Components/CmsEntriesList/CmsReviewScheduleEntryAction.js.map +1 -0
  10. package/Components/CmsEntriesList/CmsReviewScheduleEntryAction.test.d.ts +1 -0
  11. package/Components/CmsEntriesList/CmsReviewScheduleEntryAction.test.js +98 -0
  12. package/Components/CmsEntriesList/CmsReviewScheduleEntryAction.test.js.map +1 -0
  13. package/Components/ContentEntryForm/CmsEntryReviewBar.d.ts +2 -0
  14. package/Components/ContentEntryForm/CmsEntryReviewBar.js +32 -0
  15. package/Components/ContentEntryForm/CmsEntryReviewBar.js.map +1 -0
  16. package/Components/ContentEntryForm/CmsEntryReviewBar.test.d.ts +1 -0
  17. package/Components/ContentEntryForm/CmsEntryReviewBar.test.js +128 -0
  18. package/Components/ContentEntryForm/CmsEntryReviewBar.test.js.map +1 -0
  19. package/Components/ContentEntryForm/CmsEntryReviewBlockedActions.d.ts +2 -0
  20. package/Components/ContentEntryForm/CmsEntryReviewBlockedActions.js +46 -0
  21. package/Components/ContentEntryForm/CmsEntryReviewBlockedActions.js.map +1 -0
  22. package/Components/ContentEntryForm/CmsEntryReviewBlockedActions.test.d.ts +1 -0
  23. package/Components/ContentEntryForm/CmsEntryReviewBlockedActions.test.js +222 -0
  24. package/Components/ContentEntryForm/CmsEntryReviewBlockedActions.test.js.map +1 -0
  25. package/Components/ContentEntryForm/CmsEntryReviewFormLock.d.ts +2 -0
  26. package/Components/ContentEntryForm/CmsEntryReviewFormLock.js +32 -0
  27. package/Components/ContentEntryForm/CmsEntryReviewFormLock.js.map +1 -0
  28. package/Components/ContentEntryForm/CmsEntryReviewFormLock.test.d.ts +1 -0
  29. package/Components/ContentEntryForm/CmsEntryReviewFormLock.test.js +94 -0
  30. package/Components/ContentEntryForm/CmsEntryReviewFormLock.test.js.map +1 -0
  31. package/Components/ContentEntryForm/CmsEntryReviewNewRevision.d.ts +2 -0
  32. package/Components/ContentEntryForm/CmsEntryReviewNewRevision.js +56 -0
  33. package/Components/ContentEntryForm/CmsEntryReviewNewRevision.js.map +1 -0
  34. package/Components/ContentEntryForm/CmsEntryReviewNewRevision.test.d.ts +1 -0
  35. package/Components/ContentEntryForm/CmsEntryReviewNewRevision.test.js +186 -0
  36. package/Components/ContentEntryForm/CmsEntryReviewNewRevision.test.js.map +1 -0
  37. package/Components/ContentEntryForm/CmsEntryReviewScheduleMenuItem.d.ts +2 -0
  38. package/Components/ContentEntryForm/CmsEntryReviewScheduleMenuItem.js +26 -0
  39. package/Components/ContentEntryForm/CmsEntryReviewScheduleMenuItem.js.map +1 -0
  40. package/Components/ContentEntryForm/CmsEntryReviewScheduleMenuItem.test.d.ts +1 -0
  41. package/Components/ContentEntryForm/CmsEntryReviewScheduleMenuItem.test.js +78 -0
  42. package/Components/ContentEntryForm/CmsEntryReviewScheduleMenuItem.test.js.map +1 -0
  43. package/Components/ContentEntryForm/getModelFieldLabels.d.ts +3 -0
  44. package/Components/ContentEntryForm/getModelFieldLabels.js +8 -0
  45. package/Components/ContentEntryForm/getModelFieldLabels.js.map +1 -0
  46. package/Components/ContentEntryForm/index.d.ts +5 -0
  47. package/Components/ContentEntryForm/index.js +5 -0
  48. package/Components/ContentReviews/CmsContentReviews.d.ts +2 -0
  49. package/Components/ContentReviews/CmsContentReviews.js +11 -0
  50. package/Components/ContentReviews/CmsContentReviews.js.map +1 -0
  51. package/Components/ContentReviews/CmsContentReviews.test.d.ts +1 -0
  52. package/Components/ContentReviews/CmsContentReviews.test.js +214 -0
  53. package/Components/ContentReviews/CmsContentReviews.test.js.map +1 -0
  54. package/Components/ContentReviews/CmsContentReviewsMount.d.ts +4 -0
  55. package/Components/ContentReviews/CmsContentReviewsMount.js +44 -0
  56. package/Components/ContentReviews/CmsContentReviewsMount.js.map +1 -0
  57. package/Components/ContentReviews/CmsContentReviewsSidebarItem.d.ts +2 -0
  58. package/Components/ContentReviews/CmsContentReviewsSidebarItem.js +20 -0
  59. package/Components/ContentReviews/CmsContentReviewsSidebarItem.js.map +1 -0
  60. package/Components/ContentReviews/CmsContentReviewsSidebarItem.test.d.ts +1 -0
  61. package/Components/ContentReviews/CmsContentReviewsSidebarItem.test.js +83 -0
  62. package/Components/ContentReviews/CmsContentReviewsSidebarItem.test.js.map +1 -0
  63. package/Components/ModelDelete/ModelBoundToWorkflowErrorData.d.ts +8 -0
  64. package/Components/ModelDelete/ModelBoundToWorkflowErrorData.js +0 -0
  65. package/Components/ModelDelete/ModelDeleteWorkflowCopy.d.ts +10 -0
  66. package/Components/ModelDelete/ModelDeleteWorkflowCopy.js +0 -0
  67. package/Components/ModelDelete/ModelDeleteWorkflowError.d.ts +2 -0
  68. package/Components/ModelDelete/ModelDeleteWorkflowError.js +34 -0
  69. package/Components/ModelDelete/ModelDeleteWorkflowError.js.map +1 -0
  70. package/Components/ModelDelete/ModelDeleteWorkflowError.test.d.ts +1 -0
  71. package/Components/ModelDelete/ModelDeleteWorkflowError.test.js +73 -0
  72. package/Components/ModelDelete/ModelDeleteWorkflowError.test.js.map +1 -0
  73. package/Components/ModelDelete/getModelDeleteWorkflowCopy.d.ts +3 -0
  74. package/Components/ModelDelete/getModelDeleteWorkflowCopy.js +17 -0
  75. package/Components/ModelDelete/getModelDeleteWorkflowCopy.js.map +1 -0
  76. package/Components/ModelDelete/getModelDeleteWorkflowCopy.test.d.ts +1 -0
  77. package/Components/ModelDelete/getModelDeleteWorkflowCopy.test.js +28 -0
  78. package/Components/ModelDelete/getModelDeleteWorkflowCopy.test.js.map +1 -0
  79. package/Components/ignoreAction.d.ts +1 -0
  80. package/Components/ignoreAction.js +4 -0
  81. package/Components/ignoreAction.js.map +1 -0
  82. package/LICENSE +21 -0
  83. package/README.md +11 -0
  84. package/Routes/CmsWorkflowEditor.d.ts +2 -0
  85. package/Routes/CmsWorkflowEditor.js +23 -0
  86. package/Routes/CmsWorkflowEditor.js.map +1 -0
  87. package/Routes/CmsWorkflowEditor.test.d.ts +1 -0
  88. package/Routes/CmsWorkflowEditor.test.js +141 -0
  89. package/Routes/CmsWorkflowEditor.test.js.map +1 -0
  90. package/Routes/index.d.ts +1 -0
  91. package/Routes/index.js +1 -0
  92. package/features/cache/CmsReviewCacheSyncHandler.d.ts +8 -0
  93. package/features/cache/CmsReviewCacheSyncHandler.js +14 -0
  94. package/features/cache/CmsReviewCacheSyncHandler.js.map +1 -0
  95. package/features/cache/CmsReviewCacheWriter.d.ts +14 -0
  96. package/features/cache/CmsReviewCacheWriter.js +39 -0
  97. package/features/cache/CmsReviewCacheWriter.js.map +1 -0
  98. package/features/cache/CmsReviewCacheWriter.test.d.ts +1 -0
  99. package/features/cache/CmsReviewCacheWriter.test.js +207 -0
  100. package/features/cache/CmsReviewCacheWriter.test.js.map +1 -0
  101. package/features/cache/CmsReviewEntriesCacheProviderDecorator.d.ts +12 -0
  102. package/features/cache/CmsReviewEntriesCacheProviderDecorator.js +17 -0
  103. package/features/cache/CmsReviewEntriesCacheProviderDecorator.js.map +1 -0
  104. package/features/cache/CmsReviewEntriesCacheProviderDecorator.test.d.ts +1 -0
  105. package/features/cache/CmsReviewEntriesCacheProviderDecorator.test.js +129 -0
  106. package/features/cache/CmsReviewEntriesCacheProviderDecorator.test.js.map +1 -0
  107. package/features/cache/ReviewPreservingEntriesCache.d.ts +18 -0
  108. package/features/cache/ReviewPreservingEntriesCache.js +54 -0
  109. package/features/cache/ReviewPreservingEntriesCache.js.map +1 -0
  110. package/features/cache/abstractions.d.ts +5 -0
  111. package/features/cache/abstractions.js +5 -0
  112. package/features/cache/abstractions.js.map +1 -0
  113. package/features/editorGateway/CmsWorkflowEditorGateway/CmsWorkflowEditorGateway.d.ts +26 -0
  114. package/features/editorGateway/CmsWorkflowEditorGateway/CmsWorkflowEditorGateway.js +104 -0
  115. package/features/editorGateway/CmsWorkflowEditorGateway/CmsWorkflowEditorGateway.js.map +1 -0
  116. package/features/editorGateway/CmsWorkflowEditorGateway/CmsWorkflowEditorGateway.test.d.ts +1 -0
  117. package/features/editorGateway/CmsWorkflowEditorGateway/CmsWorkflowEditorGateway.test.js +589 -0
  118. package/features/editorGateway/CmsWorkflowEditorGateway/CmsWorkflowEditorGateway.test.js.map +1 -0
  119. package/features/editorGateway/feature.d.ts +1 -0
  120. package/features/editorGateway/feature.js +11 -0
  121. package/features/editorGateway/feature.js.map +1 -0
  122. package/features/editorGateway/feature.test.d.ts +1 -0
  123. package/features/editorGateway/feature.test.js +272 -0
  124. package/features/editorGateway/feature.test.js.map +1 -0
  125. package/features/editorGateway/graphql/cmsEntryFolderExists.d.ts +1 -0
  126. package/features/editorGateway/graphql/cmsEntryFolderExists.js +16 -0
  127. package/features/editorGateway/graphql/cmsEntryFolderExists.js.map +1 -0
  128. package/features/editorGateway/graphql/deleteCmsEntryWorkflow.d.ts +1 -0
  129. package/features/editorGateway/graphql/deleteCmsEntryWorkflow.js +19 -0
  130. package/features/editorGateway/graphql/deleteCmsEntryWorkflow.js.map +1 -0
  131. package/features/editorGateway/graphql/getCmsEntryWorkflow.d.ts +1 -0
  132. package/features/editorGateway/graphql/getCmsEntryWorkflow.js +19 -0
  133. package/features/editorGateway/graphql/getCmsEntryWorkflow.js.map +1 -0
  134. package/features/editorGateway/graphql/inspectCmsEntryRouting.d.ts +1 -0
  135. package/features/editorGateway/graphql/inspectCmsEntryRouting.js +19 -0
  136. package/features/editorGateway/graphql/inspectCmsEntryRouting.js.map +1 -0
  137. package/features/editorGateway/graphql/listCmsEntryWorkflowModels.d.ts +1 -0
  138. package/features/editorGateway/graphql/listCmsEntryWorkflowModels.js +29 -0
  139. package/features/editorGateway/graphql/listCmsEntryWorkflowModels.js.map +1 -0
  140. package/features/editorGateway/graphql/storeCmsEntryWorkflow.d.ts +1 -0
  141. package/features/editorGateway/graphql/storeCmsEntryWorkflow.js +19 -0
  142. package/features/editorGateway/graphql/storeCmsEntryWorkflow.js.map +1 -0
  143. package/features/editorMounting/CmsWorkflowEditorAppAdapter.d.ts +25 -0
  144. package/features/editorMounting/CmsWorkflowEditorAppAdapter.js +51 -0
  145. package/features/editorMounting/CmsWorkflowEditorAppAdapter.js.map +1 -0
  146. package/features/editorMounting/CmsWorkflowEditorAppAdapter.test.d.ts +1 -0
  147. package/features/editorMounting/CmsWorkflowEditorAppAdapter.test.js +185 -0
  148. package/features/editorMounting/CmsWorkflowEditorAppAdapter.test.js.map +1 -0
  149. package/features/editorMounting/abstractions.d.ts +5 -0
  150. package/features/editorMounting/abstractions.js +5 -0
  151. package/features/editorMounting/abstractions.js.map +1 -0
  152. package/features/editorMounting/feature.d.ts +3 -0
  153. package/features/editorMounting/feature.js +19 -0
  154. package/features/editorMounting/feature.js.map +1 -0
  155. package/features/editorMounting/feature.test.d.ts +1 -0
  156. package/features/editorMounting/feature.test.js +100 -0
  157. package/features/editorMounting/feature.test.js.map +1 -0
  158. package/features/editorReview/CmsEntryReview.d.ts +8 -0
  159. package/features/editorReview/CmsEntryReview.js +14 -0
  160. package/features/editorReview/CmsEntryReview.js.map +1 -0
  161. package/features/editorReview/abstractions.d.ts +5 -0
  162. package/features/editorReview/abstractions.js +5 -0
  163. package/features/editorReview/abstractions.js.map +1 -0
  164. package/features/editorReview/feature.d.ts +3 -0
  165. package/features/editorReview/feature.js +17 -0
  166. package/features/editorReview/feature.js.map +1 -0
  167. package/features/editorReview/feature.test.d.ts +1 -0
  168. package/features/editorReview/feature.test.js +46 -0
  169. package/features/editorReview/feature.test.js.map +1 -0
  170. package/features/editorReview/useCmsEntryReview.d.ts +2 -0
  171. package/features/editorReview/useCmsEntryReview.js +8 -0
  172. package/features/editorReview/useCmsEntryReview.js.map +1 -0
  173. package/features/feature.d.ts +1 -0
  174. package/features/feature.js +15 -0
  175. package/features/feature.js.map +1 -0
  176. package/features/gateway/CmsReviewChangeMessageHandler.d.ts +8 -0
  177. package/features/gateway/CmsReviewChangeMessageHandler.js +16 -0
  178. package/features/gateway/CmsReviewChangeMessageHandler.js.map +1 -0
  179. package/features/gateway/CmsReviewContentAdapter/CmsReviewContentAdapter.d.ts +16 -0
  180. package/features/gateway/CmsReviewContentAdapter/CmsReviewContentAdapter.js +39 -0
  181. package/features/gateway/CmsReviewContentAdapter/CmsReviewContentAdapter.js.map +1 -0
  182. package/features/gateway/CmsReviewContentAdapter/CmsReviewContentAdapter.test.d.ts +1 -0
  183. package/features/gateway/CmsReviewContentAdapter/CmsReviewContentAdapter.test.js +83 -0
  184. package/features/gateway/CmsReviewContentAdapter/CmsReviewContentAdapter.test.js.map +1 -0
  185. package/features/gateway/CmsReviewContentAdapter/abstractions.d.ts +5 -0
  186. package/features/gateway/CmsReviewContentAdapter/abstractions.js +5 -0
  187. package/features/gateway/CmsReviewContentAdapter/abstractions.js.map +1 -0
  188. package/features/gateway/CmsReviewGateway/CmsReviewGateway.d.ts +52 -0
  189. package/features/gateway/CmsReviewGateway/CmsReviewGateway.js +221 -0
  190. package/features/gateway/CmsReviewGateway/CmsReviewGateway.js.map +1 -0
  191. package/features/gateway/CmsReviewGateway/CmsReviewGateway.test.d.ts +1 -0
  192. package/features/gateway/CmsReviewGateway/CmsReviewGateway.test.js +689 -0
  193. package/features/gateway/CmsReviewGateway/CmsReviewGateway.test.js.map +1 -0
  194. package/features/gateway/CmsReviewNotificationHandler.d.ts +8 -0
  195. package/features/gateway/CmsReviewNotificationHandler.js +16 -0
  196. package/features/gateway/CmsReviewNotificationHandler.js.map +1 -0
  197. package/features/gateway/CmsReviewRowProvider/CmsReviewRowProvider.d.ts +8 -0
  198. package/features/gateway/CmsReviewRowProvider/CmsReviewRowProvider.js +14 -0
  199. package/features/gateway/CmsReviewRowProvider/CmsReviewRowProvider.js.map +1 -0
  200. package/features/gateway/CmsReviewRowProvider/abstractions.d.ts +5 -0
  201. package/features/gateway/CmsReviewRowProvider/abstractions.js +5 -0
  202. package/features/gateway/CmsReviewRowProvider/abstractions.js.map +1 -0
  203. package/features/gateway/contentReviewsBindings.test.d.ts +1 -0
  204. package/features/gateway/contentReviewsBindings.test.js +125 -0
  205. package/features/gateway/contentReviewsBindings.test.js.map +1 -0
  206. package/features/gateway/feature.d.ts +4 -0
  207. package/features/gateway/feature.js +27 -0
  208. package/features/gateway/feature.js.map +1 -0
  209. package/features/gateway/feature.test.d.ts +1 -0
  210. package/features/gateway/feature.test.js +79 -0
  211. package/features/gateway/feature.test.js.map +1 -0
  212. package/features/gateway/graphql/CmsOperationResponse.d.ts +3 -0
  213. package/features/gateway/graphql/CmsOperationResponse.js +0 -0
  214. package/features/gateway/graphql/approveCmsEntryReviewStep.d.ts +1 -0
  215. package/features/gateway/graphql/approveCmsEntryReviewStep.js +18 -0
  216. package/features/gateway/graphql/approveCmsEntryReviewStep.js.map +1 -0
  217. package/features/gateway/graphql/cancelCmsEntryReview.d.ts +1 -0
  218. package/features/gateway/graphql/cancelCmsEntryReview.js +18 -0
  219. package/features/gateway/graphql/cancelCmsEntryReview.js.map +1 -0
  220. package/features/gateway/graphql/cancelCmsEntryReviewsForDelete.d.ts +1 -0
  221. package/features/gateway/graphql/cancelCmsEntryReviewsForDelete.js +28 -0
  222. package/features/gateway/graphql/cancelCmsEntryReviewsForDelete.js.map +1 -0
  223. package/features/gateway/graphql/getCmsEntryReview.d.ts +1 -0
  224. package/features/gateway/graphql/getCmsEntryReview.js +18 -0
  225. package/features/gateway/graphql/getCmsEntryReview.js.map +1 -0
  226. package/features/gateway/graphql/getCmsEntryReviewStepRun.d.ts +1 -0
  227. package/features/gateway/graphql/getCmsEntryReviewStepRun.js +18 -0
  228. package/features/gateway/graphql/getCmsEntryReviewStepRun.js.map +1 -0
  229. package/features/gateway/graphql/getCmsEntryTargetReview.d.ts +1 -0
  230. package/features/gateway/graphql/getCmsEntryTargetReview.js +18 -0
  231. package/features/gateway/graphql/getCmsEntryTargetReview.js.map +1 -0
  232. package/features/gateway/graphql/listCmsEntryBlockingReviews.d.ts +1 -0
  233. package/features/gateway/graphql/listCmsEntryBlockingReviews.js +18 -0
  234. package/features/gateway/graphql/listCmsEntryBlockingReviews.js.map +1 -0
  235. package/features/gateway/graphql/listCmsEntryReviewStepCandidates.d.ts +1 -0
  236. package/features/gateway/graphql/listCmsEntryReviewStepCandidates.js +18 -0
  237. package/features/gateway/graphql/listCmsEntryReviewStepCandidates.js.map +1 -0
  238. package/features/gateway/graphql/listCmsEntryReviews.d.ts +1 -0
  239. package/features/gateway/graphql/listCmsEntryReviews.js +34 -0
  240. package/features/gateway/graphql/listCmsEntryReviews.js.map +1 -0
  241. package/features/gateway/graphql/listCmsEntryStepCandidates.d.ts +1 -0
  242. package/features/gateway/graphql/listCmsEntryStepCandidates.js +28 -0
  243. package/features/gateway/graphql/listCmsEntryStepCandidates.js.map +1 -0
  244. package/features/gateway/graphql/listCmsEntryWorkflows.d.ts +1 -0
  245. package/features/gateway/graphql/listCmsEntryWorkflows.js +18 -0
  246. package/features/gateway/graphql/listCmsEntryWorkflows.js.map +1 -0
  247. package/features/gateway/graphql/reassignCmsEntryReviewStep.d.ts +1 -0
  248. package/features/gateway/graphql/reassignCmsEntryReviewStep.js +18 -0
  249. package/features/gateway/graphql/reassignCmsEntryReviewStep.js.map +1 -0
  250. package/features/gateway/graphql/rejectCmsEntryReviewStep.d.ts +1 -0
  251. package/features/gateway/graphql/rejectCmsEntryReviewStep.js +18 -0
  252. package/features/gateway/graphql/rejectCmsEntryReviewStep.js.map +1 -0
  253. package/features/gateway/graphql/requestCmsEntryReview.d.ts +1 -0
  254. package/features/gateway/graphql/requestCmsEntryReview.js +28 -0
  255. package/features/gateway/graphql/requestCmsEntryReview.js.map +1 -0
  256. package/features/gateway/graphql/restartCmsEntryReviewStep.d.ts +1 -0
  257. package/features/gateway/graphql/restartCmsEntryReviewStep.js +18 -0
  258. package/features/gateway/graphql/restartCmsEntryReviewStep.js.map +1 -0
  259. package/features/gateway/graphql/startCmsEntryReviewStep.d.ts +1 -0
  260. package/features/gateway/graphql/startCmsEntryReviewStep.js +18 -0
  261. package/features/gateway/graphql/startCmsEntryReviewStep.js.map +1 -0
  262. package/features/gateway/graphql/takeOverCmsEntryReviewStep.d.ts +1 -0
  263. package/features/gateway/graphql/takeOverCmsEntryReviewStep.js +22 -0
  264. package/features/gateway/graphql/takeOverCmsEntryReviewStep.js.map +1 -0
  265. package/features/trash/BulkDeletePresenterReviewDecorator.d.ts +20 -0
  266. package/features/trash/BulkDeletePresenterReviewDecorator.js +81 -0
  267. package/features/trash/BulkDeletePresenterReviewDecorator.js.map +1 -0
  268. package/features/trash/BulkDeletePresenterReviewDecorator.test.d.ts +1 -0
  269. package/features/trash/BulkDeletePresenterReviewDecorator.test.js +693 -0
  270. package/features/trash/BulkDeletePresenterReviewDecorator.test.js.map +1 -0
  271. package/features/trash/DeleteEntryRevisionUseCaseReviewDecorator.d.ts +13 -0
  272. package/features/trash/DeleteEntryRevisionUseCaseReviewDecorator.js +23 -0
  273. package/features/trash/DeleteEntryRevisionUseCaseReviewDecorator.js.map +1 -0
  274. package/features/trash/DeleteEntryRevisionUseCaseReviewDecorator.test.d.ts +1 -0
  275. package/features/trash/DeleteEntryRevisionUseCaseReviewDecorator.test.js +123 -0
  276. package/features/trash/DeleteEntryRevisionUseCaseReviewDecorator.test.js.map +1 -0
  277. package/features/trash/DeleteEntryUseCaseReviewDecorator.d.ts +13 -0
  278. package/features/trash/DeleteEntryUseCaseReviewDecorator.js +23 -0
  279. package/features/trash/DeleteEntryUseCaseReviewDecorator.js.map +1 -0
  280. package/features/trash/DeleteEntryUseCaseReviewDecorator.test.d.ts +1 -0
  281. package/features/trash/DeleteEntryUseCaseReviewDecorator.test.js +139 -0
  282. package/features/trash/DeleteEntryUseCaseReviewDecorator.test.js.map +1 -0
  283. package/features/trash/PermanentlyDeleteEntryUseCaseReviewDecorator.d.ts +13 -0
  284. package/features/trash/PermanentlyDeleteEntryUseCaseReviewDecorator.js +23 -0
  285. package/features/trash/PermanentlyDeleteEntryUseCaseReviewDecorator.js.map +1 -0
  286. package/features/trash/PermanentlyDeleteEntryUseCaseReviewDecorator.test.d.ts +1 -0
  287. package/features/trash/PermanentlyDeleteEntryUseCaseReviewDecorator.test.js +122 -0
  288. package/features/trash/PermanentlyDeleteEntryUseCaseReviewDecorator.test.js.map +1 -0
  289. package/features/trash/feature.d.ts +1 -0
  290. package/features/trash/feature.js +17 -0
  291. package/features/trash/feature.js.map +1 -0
  292. package/features/trash/feature.test.d.ts +1 -0
  293. package/features/trash/feature.test.js +213 -0
  294. package/features/trash/feature.test.js.map +1 -0
  295. package/index.d.ts +2 -0
  296. package/index.editor.test.d.ts +1 -0
  297. package/index.editor.test.js +149 -0
  298. package/index.editor.test.js.map +1 -0
  299. package/index.js +41 -0
  300. package/index.js.map +1 -0
  301. package/index.lists.test.d.ts +1 -0
  302. package/index.lists.test.js +172 -0
  303. package/index.lists.test.js.map +1 -0
  304. package/index.mount.test.d.ts +1 -0
  305. package/index.mount.test.js +49 -0
  306. package/index.mount.test.js.map +1 -0
  307. package/index.test.d.ts +1 -0
  308. package/index.test.js +414 -0
  309. package/index.test.js.map +1 -0
  310. package/package.json +54 -0
  311. package/presentation/CmsEntryContentReloader.d.ts +8 -0
  312. package/presentation/CmsEntryContentReloader.js +20 -0
  313. package/presentation/CmsEntryContentReloader.js.map +1 -0
  314. package/presentation/CmsEntryContentReloader.test.d.ts +1 -0
  315. package/presentation/CmsEntryContentReloader.test.js +118 -0
  316. package/presentation/CmsEntryContentReloader.test.js.map +1 -0
  317. package/presentation/CmsEntryFormPresenterReviewDecorator.d.ts +27 -0
  318. package/presentation/CmsEntryFormPresenterReviewDecorator.js +167 -0
  319. package/presentation/CmsEntryFormPresenterReviewDecorator.js.map +1 -0
  320. package/presentation/CmsEntryFormPresenterReviewDecorator.test.d.ts +1 -0
  321. package/presentation/CmsEntryFormPresenterReviewDecorator.test.js +601 -0
  322. package/presentation/CmsEntryFormPresenterReviewDecorator.test.js.map +1 -0
  323. package/presentation/CmsEntryUnsavedChanges.d.ts +7 -0
  324. package/presentation/CmsEntryUnsavedChanges.js +12 -0
  325. package/presentation/CmsEntryUnsavedChanges.js.map +1 -0
  326. package/presentation/CmsEntryUnsavedChanges.test.d.ts +1 -0
  327. package/presentation/CmsEntryUnsavedChanges.test.js +23 -0
  328. package/presentation/CmsEntryUnsavedChanges.test.js.map +1 -0
  329. package/presentation/CmsReviewFieldSelections.test.d.ts +1 -0
  330. package/presentation/CmsReviewFieldSelections.test.js +27 -0
  331. package/presentation/CmsReviewFieldSelections.test.js.map +1 -0
  332. package/presentation/CmsReviewGetEntryFieldSelection.d.ts +8 -0
  333. package/presentation/CmsReviewGetEntryFieldSelection.js +16 -0
  334. package/presentation/CmsReviewGetEntryFieldSelection.js.map +1 -0
  335. package/presentation/CmsReviewListEntriesFieldSelection.d.ts +8 -0
  336. package/presentation/CmsReviewListEntriesFieldSelection.js +16 -0
  337. package/presentation/CmsReviewListEntriesFieldSelection.js.map +1 -0
  338. package/presentation/CmsReviewTableRowMapperDecorator.d.ts +11 -0
  339. package/presentation/CmsReviewTableRowMapperDecorator.js +24 -0
  340. package/presentation/CmsReviewTableRowMapperDecorator.js.map +1 -0
  341. package/presentation/CmsReviewTableRowMapperDecorator.test.d.ts +1 -0
  342. package/presentation/CmsReviewTableRowMapperDecorator.test.js +120 -0
  343. package/presentation/CmsReviewTableRowMapperDecorator.test.js.map +1 -0
  344. package/presentation/CmsRevisionsListPresenterDecorator.d.ts +24 -0
  345. package/presentation/CmsRevisionsListPresenterDecorator.js +66 -0
  346. package/presentation/CmsRevisionsListPresenterDecorator.js.map +1 -0
  347. package/presentation/CmsRevisionsListPresenterDecorator.test.d.ts +1 -0
  348. package/presentation/CmsRevisionsListPresenterDecorator.test.js +174 -0
  349. package/presentation/CmsRevisionsListPresenterDecorator.test.js.map +1 -0
  350. package/presentation/contentReviews/CmsContentReviewsPresenter.d.ts +28 -0
  351. package/presentation/contentReviews/CmsContentReviewsPresenter.js +103 -0
  352. package/presentation/contentReviews/CmsContentReviewsPresenter.js.map +1 -0
  353. package/presentation/contentReviews/CmsContentReviewsPresenter.test.d.ts +1 -0
  354. package/presentation/contentReviews/CmsContentReviewsPresenter.test.js +238 -0
  355. package/presentation/contentReviews/CmsContentReviewsPresenter.test.js.map +1 -0
  356. package/presentation/contentReviews/abstractions.d.ts +31 -0
  357. package/presentation/contentReviews/abstractions.js +5 -0
  358. package/presentation/contentReviews/abstractions.js.map +1 -0
  359. package/presentation/contentReviews/feature.d.ts +3 -0
  360. package/presentation/contentReviews/feature.js +17 -0
  361. package/presentation/contentReviews/feature.js.map +1 -0
  362. package/presentation/contentReviews/toContentTypes.d.ts +3 -0
  363. package/presentation/contentReviews/toContentTypes.js +14 -0
  364. package/presentation/contentReviews/toContentTypes.js.map +1 -0
  365. package/presentation/contentReviews/toContentTypes.test.d.ts +1 -0
  366. package/presentation/contentReviews/toContentTypes.test.js +20 -0
  367. package/presentation/contentReviews/toContentTypes.test.js.map +1 -0
  368. package/presentation/feature.d.ts +1 -0
  369. package/presentation/feature.js +19 -0
  370. package/presentation/feature.js.map +1 -0
  371. package/presentation/getCmsEntryReviewContext.d.ts +4 -0
  372. package/presentation/getCmsEntryReviewContext.js +12 -0
  373. package/presentation/getCmsEntryReviewContext.js.map +1 -0
  374. package/presentation/getCmsEntryReviewInitParams.d.ts +13 -0
  375. package/presentation/getCmsEntryReviewInitParams.js +18 -0
  376. package/presentation/getCmsEntryReviewInitParams.js.map +1 -0
  377. package/presentation/getCmsEntryReviewInitParams.test.d.ts +1 -0
  378. package/presentation/getCmsEntryReviewInitParams.test.js +69 -0
  379. package/presentation/getCmsEntryReviewInitParams.test.js.map +1 -0
  380. package/routes.d.ts +11 -0
  381. package/routes.js +21 -0
  382. package/routes.js.map +1 -0
  383. package/testing/createEntry.d.ts +3 -0
  384. package/testing/createEntry.js +22 -0
  385. package/testing/createEntry.js.map +1 -0
  386. package/testing/createEntrySession.d.ts +9 -0
  387. package/testing/createEntrySession.js +29 -0
  388. package/testing/createEntrySession.js.map +1 -0
  389. package/testing/createFolder.d.ts +2 -0
  390. package/testing/createFolder.js +13 -0
  391. package/testing/createFolder.js.map +1 -0
  392. package/testing/createFormVm.d.ts +2 -0
  393. package/testing/createFormVm.js +22 -0
  394. package/testing/createFormVm.js.map +1 -0
  395. package/testing/models.d.ts +4 -0
  396. package/testing/models.js +23 -0
  397. package/testing/models.js.map +1 -0
  398. package/testing/renderEditorTree.d.ts +17 -0
  399. package/testing/renderEditorTree.js +93 -0
  400. package/testing/renderEditorTree.js.map +1 -0
  401. package/testing/reviewStates.d.ts +17 -0
  402. package/testing/reviewStates.js +65 -0
  403. package/testing/reviewStates.js.map +1 -0
  404. package/types.d.ts +10 -0
  405. package/types.js +0 -0
  406. package/utils/appName.d.ts +4 -0
  407. package/utils/appName.js +13 -0
  408. package/utils/appName.js.map +1 -0
  409. package/utils/isReviewableModel.d.ts +2 -0
  410. package/utils/isReviewableModel.js +7 -0
  411. package/utils/isReviewableModel.js.map +1 -0
  412. package/utils/renderModelIcon.d.ts +3 -0
  413. package/utils/renderModelIcon.js +19 -0
  414. package/utils/renderModelIcon.js.map +1 -0
  415. package/utils/renderModelIconOrFallback.d.ts +3 -0
  416. package/utils/renderModelIconOrFallback.js +17 -0
  417. package/utils/renderModelIconOrFallback.js.map +1 -0
@@ -0,0 +1,141 @@
1
+ import react from "react";
2
+ import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
3
+ import { cleanup, render, screen } from "@testing-library/react";
4
+ import { Container } from "@webiny/di";
5
+ import { DiContainerProvider } from "@webiny/app";
6
+ import { RouterWithConfig, useRouterConfig } from "@webiny/app/config/RouterConfig.js";
7
+ import { AdminConfig } from "@webiny/app-admin";
8
+ import { AdminConfigPlugin, AdminWithConfig, useAdminConfig } from "@webiny/app-admin/config/AdminConfig.js";
9
+ import { Route } from "@webiny/app/features/router/Route.js";
10
+ import { CompositionProvider } from "@webiny/react-composition";
11
+ import { createFakeAppAdapter } from "@webiny/app-workflows/editor/testing/fakeEditorAppAdapter.js";
12
+ import { findElements } from "@webiny/app-workflows/editor/testing/findElements.js";
13
+ import { WorkflowEditorView } from "@webiny/app-workflows/editor/presentation/editor/components/WorkflowEditorView.js";
14
+ import { CmsWorkflowEditorAppAdapter } from "../features/editorMounting/abstractions.js";
15
+ import { CmsWorkflowEditor } from "./CmsWorkflowEditor.js";
16
+ const permission = vi.hoisted(()=>({
17
+ editor: true
18
+ }));
19
+ vi.mock("@webiny/app-workflows/presentation/permissions/useWorkflowsPermission.js", ()=>({
20
+ useWorkflowsPermission: ()=>({
21
+ editor: permission.editor,
22
+ reassign: false
23
+ })
24
+ }));
25
+ vi.mock("@webiny/app-workflows/editor/presentation/editor/components/WorkflowEditorView.js", ()=>({
26
+ WorkflowEditorView: ()=>null
27
+ }));
28
+ vi.mock("@webiny/app-admin", async (importOriginal)=>{
29
+ const actual = await importOriginal();
30
+ return {
31
+ ...actual,
32
+ useRouter: ()=>({
33
+ getLink: (route)=>route.path
34
+ })
35
+ };
36
+ });
37
+ const captured = {
38
+ routes: [],
39
+ menus: []
40
+ };
41
+ const Probe = ()=>{
42
+ const routerConfig = useRouterConfig();
43
+ const adminConfig = useAdminConfig();
44
+ captured.routes = routerConfig.routes.map((item)=>({
45
+ name: item.route.name,
46
+ element: item.element
47
+ }));
48
+ captured.menus = adminConfig.menus.map((menu)=>({
49
+ name: menu.name,
50
+ parent: menu.parent ?? null,
51
+ element: /*#__PURE__*/ react.isValidElement(menu.element) ? menu.element : void 0
52
+ }));
53
+ const routeNames = captured.routes.map((item)=>item.name);
54
+ const menuNames = captured.menus.map((item)=>`${item.name}:${item.parent ?? ""}`);
55
+ return /*#__PURE__*/ react.createElement("div", {
56
+ "data-testid": "probe",
57
+ "data-routes": routeNames.join(","),
58
+ "data-menus": menuNames.join(",")
59
+ });
60
+ };
61
+ const app = createFakeAppAdapter("cms");
62
+ const { Menu: Menu } = AdminConfig;
63
+ const sentinelRoute = new Route({
64
+ name: "Test/Sentinel",
65
+ path: "/test/sentinel"
66
+ });
67
+ const mount = async ()=>{
68
+ const container = new Container();
69
+ container.registerInstance(CmsWorkflowEditorAppAdapter, app);
70
+ render(/*#__PURE__*/ react.createElement(DiContainerProvider, {
71
+ container: container
72
+ }, /*#__PURE__*/ react.createElement(CompositionProvider, null, /*#__PURE__*/ react.createElement(CmsWorkflowEditor, null), /*#__PURE__*/ react.createElement(AdminConfig, null, /*#__PURE__*/ react.createElement(Menu, {
73
+ name: "test.sentinel",
74
+ element: /*#__PURE__*/ react.createElement("div", null)
75
+ }), /*#__PURE__*/ react.createElement(AdminConfig.Route, {
76
+ route: sentinelRoute,
77
+ element: /*#__PURE__*/ react.createElement("div", null)
78
+ })), /*#__PURE__*/ react.createElement(AdminWithConfig, null, AdminConfigPlugin, /*#__PURE__*/ react.createElement(RouterWithConfig, null, /*#__PURE__*/ react.createElement(Probe, null))))));
79
+ const probe = await screen.findByTestId("probe");
80
+ await vi.waitFor(()=>{
81
+ expect(probe.getAttribute("data-menus")).toContain("test.sentinel");
82
+ });
83
+ return captured;
84
+ };
85
+ describe("CmsWorkflowEditor", ()=>{
86
+ beforeEach(()=>{
87
+ permission.editor = true;
88
+ captured.routes = [];
89
+ captured.menus = [];
90
+ });
91
+ afterEach(()=>{
92
+ cleanup();
93
+ });
94
+ it("registers the /cms/workflows route and the Headless CMS menu item for an editor", async ()=>{
95
+ const result = await mount();
96
+ const routeNames = result.routes.map((item)=>item.name);
97
+ const menuNames = result.menus.map((item)=>`${item.name}:${item.parent ?? ""}`);
98
+ expect(routeNames).toContain("Cms/ContentModels/Workflows");
99
+ expect(menuNames).toContain("headlessCMS.contentModels.workflows:headlessCMS");
100
+ });
101
+ it("links the menu item to /cms/workflows", async ()=>{
102
+ const result = await mount();
103
+ const menu = result.menus.find((item)=>"headlessCMS.contentModels.workflows" === item.name);
104
+ expect(menu?.element?.props.text).toBe("Workflows");
105
+ expect(menu?.element?.props.to).toBe("/cms/workflows");
106
+ });
107
+ it("gives the view the CMS review use cases and the CMS adapter, no editor use cases (R353)", async ()=>{
108
+ const result = await mount();
109
+ const route = result.routes.find((item)=>"Cms/ContentModels/Workflows" === item.name);
110
+ if (!route) throw new Error("The editor route is not registered.");
111
+ const views = findElements(route.element, WorkflowEditorView);
112
+ expect(views).toHaveLength(1);
113
+ expect(views[0].props).not.toHaveProperty("useCases");
114
+ expect(Object.keys(views[0].props)).toEqual([
115
+ "app",
116
+ "breadcrumbName"
117
+ ]);
118
+ expect(views[0].props.app).toBe(app);
119
+ });
120
+ it("names the breadcrumbs Headless CMS and Workflows", async ()=>{
121
+ const result = await mount();
122
+ const route = result.routes.find((item)=>"Cms/ContentModels/Workflows" === item.name);
123
+ if (!route) throw new Error("The editor route is not registered.");
124
+ const breadcrumbs = findElements(route.element, AdminConfig.Breadcrumb);
125
+ const texts = breadcrumbs.map((item)=>`${item.props.name}:${item.props.label}`);
126
+ expect(texts).toEqual([
127
+ "cms:Headless CMS",
128
+ "cms.workflows:Workflows"
129
+ ]);
130
+ });
131
+ it("registers the route but not the menu item without the editor permission", async ()=>{
132
+ permission.editor = false;
133
+ const result = await mount();
134
+ const routeNames = result.routes.map((item)=>item.name);
135
+ const menuNames = result.menus.map((item)=>item.name);
136
+ expect(routeNames).toContain("Cms/ContentModels/Workflows");
137
+ expect(menuNames).not.toContain("headlessCMS.contentModels.workflows");
138
+ });
139
+ });
140
+
141
+ //# sourceMappingURL=CmsWorkflowEditor.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Routes/CmsWorkflowEditor.test.js","sources":["../../src/Routes/CmsWorkflowEditor.test.tsx"],"sourcesContent":["import React from \"react\";\nimport { afterEach } from \"vitest\";\nimport { beforeEach } from \"vitest\";\nimport { describe } from \"vitest\";\nimport { expect } from \"vitest\";\nimport { it } from \"vitest\";\nimport { vi } from \"vitest\";\nimport { cleanup } from \"@testing-library/react\";\nimport { render } from \"@testing-library/react\";\nimport { screen } from \"@testing-library/react\";\nimport { Container } from \"@webiny/di\";\nimport { DiContainerProvider } from \"@webiny/app\";\nimport { RouterWithConfig } from \"@webiny/app/config/RouterConfig.js\";\nimport { useRouterConfig } from \"@webiny/app/config/RouterConfig.js\";\nimport { AdminConfig } from \"@webiny/app-admin\";\nimport { AdminConfigPlugin } from \"@webiny/app-admin/config/AdminConfig.js\";\nimport { AdminWithConfig } from \"@webiny/app-admin/config/AdminConfig.js\";\nimport { useAdminConfig } from \"@webiny/app-admin/config/AdminConfig.js\";\nimport { Route } from \"@webiny/app/features/router/Route.js\";\nimport { CompositionProvider } from \"@webiny/react-composition\";\nimport { createFakeAppAdapter } from \"@webiny/app-workflows/editor/testing/fakeEditorAppAdapter.js\";\nimport { findElements } from \"@webiny/app-workflows/editor/testing/findElements.js\";\nimport { WorkflowEditorView } from \"@webiny/app-workflows/editor/presentation/editor/components/WorkflowEditorView.js\";\nimport { CmsWorkflowEditorAppAdapter } from \"~/features/editorMounting/abstractions.js\";\nimport { CmsWorkflowEditor } from \"./CmsWorkflowEditor.js\";\n\ninterface RouteStub {\n path: string;\n}\n\nconst permission = vi.hoisted(() => {\n return { editor: true };\n});\n\nvi.mock(\"@webiny/app-workflows/presentation/permissions/useWorkflowsPermission.js\", () => {\n return {\n useWorkflowsPermission: () => {\n return { editor: permission.editor, reassign: false };\n }\n };\n});\n\nvi.mock(\"@webiny/app-workflows/editor/presentation/editor/components/WorkflowEditorView.js\", () => {\n return { WorkflowEditorView: () => null };\n});\n\nvi.mock(\"@webiny/app-admin\", async importOriginal => {\n const actual = await importOriginal<typeof import(\"@webiny/app-admin\")>();\n return {\n ...actual,\n useRouter: () => {\n return { getLink: (route: RouteStub) => route.path };\n }\n };\n});\n\ninterface CapturedRoute {\n name: string;\n element: React.ReactElement;\n}\n\ninterface CapturedMenu {\n name: string;\n parent: string | null;\n element: React.ReactElement<Record<string, unknown>> | undefined;\n}\n\ninterface Captured {\n routes: CapturedRoute[];\n menus: CapturedMenu[];\n}\n\nconst captured: Captured = { routes: [], menus: [] };\n\nconst Probe = () => {\n const routerConfig = useRouterConfig();\n const adminConfig = useAdminConfig();\n captured.routes = routerConfig.routes.map(item => {\n return { name: item.route.name, element: item.element };\n });\n captured.menus = adminConfig.menus.map(menu => {\n return {\n name: menu.name,\n parent: menu.parent ?? null,\n // A guard, not a cast: only an element whose props can be read is kept.\n element: React.isValidElement<Record<string, unknown>>(menu.element)\n ? menu.element\n : undefined\n };\n });\n const routeNames = captured.routes.map(item => item.name);\n const menuNames = captured.menus.map(item => `${item.name}:${item.parent ?? \"\"}`);\n\n return (\n <div\n data-testid=\"probe\"\n data-routes={routeNames.join(\",\")}\n data-menus={menuNames.join(\",\")}\n />\n );\n};\n\nconst app = createFakeAppAdapter(\"cms\");\n\nconst { Menu } = AdminConfig;\n\n// The router renders nothing without a route, so a sentinel keeps the probe mounted.\nconst sentinelRoute = new Route({ name: \"Test/Sentinel\", path: \"/test/sentinel\" });\n\n// The real mounting feature resolves the two tokens, which the test registers as instances.\nconst mount = async (): Promise<Captured> => {\n const container = new Container();\n container.registerInstance(CmsWorkflowEditorAppAdapter, app);\n\n render(\n <DiContainerProvider container={container}>\n <CompositionProvider>\n <CmsWorkflowEditor />\n <AdminConfig>\n <Menu name=\"test.sentinel\" element={<div />} />\n <AdminConfig.Route route={sentinelRoute} element={<div />} />\n </AdminConfig>\n <AdminWithConfig>\n {AdminConfigPlugin}\n <RouterWithConfig>\n <Probe />\n </RouterWithConfig>\n </AdminWithConfig>\n </CompositionProvider>\n </DiContainerProvider>\n );\n\n const probe = await screen.findByTestId(\"probe\");\n // The sentinel menu proves the configs flushed, so a missing editor route or menu is real.\n await vi.waitFor(() => {\n expect(probe.getAttribute(\"data-menus\")).toContain(\"test.sentinel\");\n });\n\n return captured;\n};\n\ndescribe(\"CmsWorkflowEditor\", () => {\n beforeEach(() => {\n permission.editor = true;\n captured.routes = [];\n captured.menus = [];\n });\n\n afterEach(() => {\n cleanup();\n });\n\n it(\"registers the /cms/workflows route and the Headless CMS menu item for an editor\", async () => {\n const result = await mount();\n const routeNames = result.routes.map(item => item.name);\n const menuNames = result.menus.map(item => `${item.name}:${item.parent ?? \"\"}`);\n\n expect(routeNames).toContain(\"Cms/ContentModels/Workflows\");\n expect(menuNames).toContain(\"headlessCMS.contentModels.workflows:headlessCMS\");\n });\n\n it(\"links the menu item to /cms/workflows\", async () => {\n const result = await mount();\n\n const menu = result.menus.find(item => item.name === \"headlessCMS.contentModels.workflows\");\n\n expect(menu?.element?.props.text).toBe(\"Workflows\");\n expect(menu?.element?.props.to).toBe(\"/cms/workflows\");\n });\n\n it(\"gives the view the CMS review use cases and the CMS adapter, no editor use cases (R353)\", async () => {\n const result = await mount();\n const route = result.routes.find(item => item.name === \"Cms/ContentModels/Workflows\");\n if (!route) {\n throw new Error(\"The editor route is not registered.\");\n }\n\n const views = findElements(route.element, WorkflowEditorView);\n\n expect(views).toHaveLength(1);\n expect(views[0].props).not.toHaveProperty(\"useCases\");\n expect(Object.keys(views[0].props)).toEqual([\"app\", \"breadcrumbName\"]);\n expect(views[0].props.app).toBe(app);\n });\n\n it(\"names the breadcrumbs Headless CMS and Workflows\", async () => {\n const result = await mount();\n const route = result.routes.find(item => item.name === \"Cms/ContentModels/Workflows\");\n if (!route) {\n throw new Error(\"The editor route is not registered.\");\n }\n\n const breadcrumbs = findElements(route.element, AdminConfig.Breadcrumb);\n const texts = breadcrumbs.map(item => `${item.props.name}:${item.props.label}`);\n\n expect(texts).toEqual([\"cms:Headless CMS\", \"cms.workflows:Workflows\"]);\n });\n\n it(\"registers the route but not the menu item without the editor permission\", async () => {\n permission.editor = false;\n\n const result = await mount();\n const routeNames = result.routes.map(item => item.name);\n const menuNames = result.menus.map(item => item.name);\n\n expect(routeNames).toContain(\"Cms/ContentModels/Workflows\");\n expect(menuNames).not.toContain(\"headlessCMS.contentModels.workflows\");\n });\n});\n"],"names":["permission","vi","importOriginal","actual","route","captured","Probe","routerConfig","useRouterConfig","adminConfig","useAdminConfig","item","menu","React","undefined","routeNames","menuNames","app","createFakeAppAdapter","Menu","AdminConfig","sentinelRoute","Route","mount","container","Container","CmsWorkflowEditorAppAdapter","render","DiContainerProvider","CompositionProvider","CmsWorkflowEditor","AdminWithConfig","AdminConfigPlugin","RouterWithConfig","probe","screen","expect","describe","beforeEach","afterEach","cleanup","it","result","Error","views","findElements","WorkflowEditorView","Object","breadcrumbs","texts"],"mappings":"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"}
@@ -0,0 +1 @@
1
+ export { CmsWorkflowEditor } from "./CmsWorkflowEditor.js";
@@ -0,0 +1 @@
1
+ export { CmsWorkflowEditor } from "./CmsWorkflowEditor.js";
@@ -0,0 +1,8 @@
1
+ import { ReviewCacheSyncHandler } from "@webiny/app-workflows/review/cache/ReviewCacheSyncHandler.js";
2
+ import { ReviewChangedHandler } from "@webiny/app-workflows/review/events/ReviewChangedHandler.js";
3
+ declare class CmsReviewCacheSyncHandlerImpl extends ReviewCacheSyncHandler implements ReviewChangedHandler.Interface {
4
+ }
5
+ export declare const CmsReviewCacheSyncHandler: typeof CmsReviewCacheSyncHandlerImpl & {
6
+ __abstraction: import("@webiny/di").Abstraction<import("@webiny/app/features/eventPublisher/abstractions.js").IEventHandler<import("@webiny/app-workflows/review/events/ReviewChangedEvent.js").ReviewChangedEvent>>;
7
+ };
8
+ export {};
@@ -0,0 +1,14 @@
1
+ import { ReviewCacheSyncHandler } from "@webiny/app-workflows/review/cache/ReviewCacheSyncHandler.js";
2
+ import { ReviewChangedHandler } from "@webiny/app-workflows/review/events/ReviewChangedHandler.js";
3
+ import { CmsReviewCacheWriter } from "./abstractions.js";
4
+ class CmsReviewCacheSyncHandlerImpl extends ReviewCacheSyncHandler {
5
+ }
6
+ const CmsReviewCacheSyncHandler = ReviewChangedHandler.createImplementation({
7
+ implementation: CmsReviewCacheSyncHandlerImpl,
8
+ dependencies: [
9
+ CmsReviewCacheWriter
10
+ ]
11
+ });
12
+ export { CmsReviewCacheSyncHandler };
13
+
14
+ //# sourceMappingURL=CmsReviewCacheSyncHandler.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"features/cache/CmsReviewCacheSyncHandler.js","sources":["../../../src/features/cache/CmsReviewCacheSyncHandler.ts"],"sourcesContent":["import { ReviewCacheSyncHandler } from \"@webiny/app-workflows/review/cache/ReviewCacheSyncHandler.js\";\nimport { ReviewChangedHandler } from \"@webiny/app-workflows/review/events/ReviewChangedHandler.js\";\nimport { CmsReviewCacheWriter } from \"./abstractions.js\";\n\n/*\n * The shared handler is never registered itself: `createImplementation` stores the abstraction and\n * dependencies on the class, so each app subclasses it once (R237).\n */\nclass CmsReviewCacheSyncHandlerImpl\n extends ReviewCacheSyncHandler\n implements ReviewChangedHandler.Interface {}\n\nexport const CmsReviewCacheSyncHandler = ReviewChangedHandler.createImplementation({\n implementation: CmsReviewCacheSyncHandlerImpl,\n dependencies: [CmsReviewCacheWriter]\n});\n"],"names":["CmsReviewCacheSyncHandlerImpl","ReviewCacheSyncHandler","CmsReviewCacheSyncHandler","ReviewChangedHandler","CmsReviewCacheWriter"],"mappings":";;;AAQA,MAAMA,sCACMC;AACmC;AAExC,MAAMC,4BAA4BC,qBAAqB,oBAAoB,CAAC;IAC/E,gBAAgBH;IAChB,cAAc;QAACI;KAAqB;AACxC"}
@@ -0,0 +1,14 @@
1
+ import { ContentEntriesCacheProvider } from "@webiny/app-headless-cms/features/contentEntry/abstractions.js";
2
+ import type { ReviewCacheRef } from "@webiny/app-workflows/review/cache/IReviewCacheWriter.js";
3
+ import type { SystemWorkflowValue } from "@webiny/app-workflows/review/domain/types.js";
4
+ import { CmsReviewCacheWriter as Abstraction } from "./abstractions.js";
5
+ declare class CmsReviewCacheWriterImpl implements Abstraction.Interface {
6
+ private readonly cacheProvider;
7
+ constructor(cacheProvider: ContentEntriesCacheProvider.Interface);
8
+ canHandle(namespace: string): boolean;
9
+ write(ref: ReviewCacheRef, workflow: SystemWorkflowValue | null): void;
10
+ }
11
+ export declare const CmsReviewCacheWriter: typeof CmsReviewCacheWriterImpl & {
12
+ __abstraction: import("@webiny/di").Abstraction<import("@webiny/app-workflows/review/cache/IReviewCacheWriter.js").IReviewCacheWriter>;
13
+ };
14
+ export {};
@@ -0,0 +1,39 @@
1
+ import { ContentEntriesCacheProvider } from "@webiny/app-headless-cms/features/contentEntry/abstractions.js";
2
+ import { isCmsAppName, parseAppName } from "../../utils/appName.js";
3
+ import { CmsReviewCacheWriter } from "./abstractions.js";
4
+ class CmsReviewCacheWriterImpl {
5
+ constructor(cacheProvider){
6
+ this.cacheProvider = cacheProvider;
7
+ }
8
+ canHandle(namespace) {
9
+ return isCmsAppName(namespace);
10
+ }
11
+ write(ref, workflow) {
12
+ const modelId = parseAppName(ref.namespace);
13
+ const cache = this.cacheProvider.get(modelId);
14
+ cache.updateItems((entry)=>{
15
+ if (entry.id !== ref.targetRevisionId) return entry;
16
+ const current = entry.meta;
17
+ const meta = {
18
+ ...entry.meta,
19
+ system: {
20
+ ...current.system,
21
+ workflow
22
+ }
23
+ };
24
+ return {
25
+ ...entry,
26
+ meta
27
+ };
28
+ });
29
+ }
30
+ }
31
+ const CmsReviewCacheWriter_CmsReviewCacheWriter = CmsReviewCacheWriter.createImplementation({
32
+ implementation: CmsReviewCacheWriterImpl,
33
+ dependencies: [
34
+ ContentEntriesCacheProvider
35
+ ]
36
+ });
37
+ export { CmsReviewCacheWriter_CmsReviewCacheWriter as CmsReviewCacheWriter };
38
+
39
+ //# sourceMappingURL=CmsReviewCacheWriter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"features/cache/CmsReviewCacheWriter.js","sources":["../../../src/features/cache/CmsReviewCacheWriter.ts"],"sourcesContent":["import { ContentEntriesCacheProvider } from \"@webiny/app-headless-cms/features/contentEntry/abstractions.js\";\nimport type { CmsContentEntry } from \"@webiny/app-headless-cms-common/types/index.js\";\nimport type { ReviewCacheRef } from \"@webiny/app-workflows/review/cache/IReviewCacheWriter.js\";\nimport type { SystemWorkflowValue } from \"@webiny/app-workflows/review/domain/types.js\";\nimport { isCmsAppName } from \"~/utils/appName.js\";\nimport { parseAppName } from \"~/utils/appName.js\";\nimport type { ICmsEntryMetaWithReview } from \"~/types.js\";\nimport { CmsReviewCacheWriter as Abstraction } from \"./abstractions.js\";\n\nclass CmsReviewCacheWriterImpl implements Abstraction.Interface {\n constructor(private readonly cacheProvider: ContentEntriesCacheProvider.Interface) {}\n\n canHandle(namespace: string): boolean {\n return isCmsAppName(namespace);\n }\n\n write(ref: ReviewCacheRef, workflow: SystemWorkflowValue | null): void {\n const modelId = parseAppName(ref.namespace);\n const cache = this.cacheProvider.get(modelId);\n\n cache.updateItems((entry: CmsContentEntry) => {\n // Only the revision the review belongs to is updated, never a newer one.\n if (entry.id !== ref.targetRevisionId) {\n return entry;\n }\n\n const current: ICmsEntryMetaWithReview = entry.meta;\n const meta: ICmsEntryMetaWithReview = {\n ...entry.meta,\n system: { ...current.system, workflow }\n };\n\n return { ...entry, meta };\n });\n }\n}\n\nexport const CmsReviewCacheWriter = Abstraction.createImplementation({\n implementation: CmsReviewCacheWriterImpl,\n dependencies: [ContentEntriesCacheProvider]\n});\n"],"names":["CmsReviewCacheWriterImpl","cacheProvider","namespace","isCmsAppName","ref","workflow","modelId","parseAppName","cache","entry","current","meta","CmsReviewCacheWriter","Abstraction","ContentEntriesCacheProvider"],"mappings":";;;AASA,MAAMA;IACF,YAA6BC,aAAoD,CAAE;aAAtDA,aAAa,GAAbA;IAAuD;IAEpF,UAAUC,SAAiB,EAAW;QAClC,OAAOC,aAAaD;IACxB;IAEA,MAAME,GAAmB,EAAEC,QAAoC,EAAQ;QACnE,MAAMC,UAAUC,aAAaH,IAAI,SAAS;QAC1C,MAAMI,QAAQ,IAAI,CAAC,aAAa,CAAC,GAAG,CAACF;QAErCE,MAAM,WAAW,CAAC,CAACC;YAEf,IAAIA,MAAM,EAAE,KAAKL,IAAI,gBAAgB,EACjC,OAAOK;YAGX,MAAMC,UAAmCD,MAAM,IAAI;YACnD,MAAME,OAAgC;gBAClC,GAAGF,MAAM,IAAI;gBACb,QAAQ;oBAAE,GAAGC,QAAQ,MAAM;oBAAEL;gBAAS;YAC1C;YAEA,OAAO;gBAAE,GAAGI,KAAK;gBAAEE;YAAK;QAC5B;IACJ;AACJ;AAEO,MAAMC,4CAAuBC,qBAAAA,oBAAgC,CAAC;IACjE,gBAAgBb;IAChB,cAAc;QAACc;KAA4B;AAC/C"}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,207 @@
1
+ import { beforeEach, describe, expect, it } from "vitest";
2
+ import { Container } from "@webiny/di";
3
+ import { ContentEntriesCacheProvider } from "@webiny/app-headless-cms/features/contentEntry/abstractions.js";
4
+ import { ContentEntriesCacheProvider as ContentEntriesCacheProvider_js_ContentEntriesCacheProvider } from "@webiny/app-headless-cms/features/contentEntry/ContentEntriesCacheProvider.js";
5
+ import { ReviewState } from "@webiny/app-workflows/review/domain/ReviewState.js";
6
+ import { StepState } from "@webiny/app-workflows/review/domain/StepState.js";
7
+ import { toSystemWorkflow } from "@webiny/app-workflows/review/domain/toSystemWorkflow.js";
8
+ import { ReviewChangedEvent } from "@webiny/app-workflows/review/events/ReviewChangedEvent.js";
9
+ import { ReviewChangedHandler } from "@webiny/app-workflows/review/events/ReviewChangedHandler.js";
10
+ import { ReviewCacheSyncHandler } from "@webiny/app-workflows/review/cache/ReviewCacheSyncHandler.js";
11
+ import { createReview } from "@webiny/app-workflows/review/testing/reviewFixtures.js";
12
+ import { CmsReviewCacheWriter } from "./abstractions.js";
13
+ import { CmsReviewCacheWriter as external_CmsReviewCacheWriter_js_CmsReviewCacheWriter } from "./CmsReviewCacheWriter.js";
14
+ import { CmsReviewCacheSyncHandler } from "./CmsReviewCacheSyncHandler.js";
15
+ const WORKFLOW = {
16
+ workflowId: "wf-1",
17
+ reviewState: ReviewState.InProgress,
18
+ stepId: "step-1",
19
+ stepName: "Legal review",
20
+ stepState: StepState.InReview
21
+ };
22
+ function createEntry(entryId, system, version = 1) {
23
+ return {
24
+ id: `${entryId}#000${version}`,
25
+ entryId,
26
+ meta: {
27
+ title: entryId,
28
+ status: "draft",
29
+ version: 1,
30
+ locked: false,
31
+ system
32
+ }
33
+ };
34
+ }
35
+ function getSystem(entry) {
36
+ return (entry?.meta).system;
37
+ }
38
+ let container;
39
+ function seedCache(modelId, entries) {
40
+ const provider = container.resolve(ContentEntriesCacheProvider);
41
+ provider.get(modelId).setItems(entries);
42
+ }
43
+ function readCache(modelId, entryId) {
44
+ const provider = container.resolve(ContentEntriesCacheProvider);
45
+ return provider.get(modelId).getItem((entry)=>entry.entryId === entryId);
46
+ }
47
+ beforeEach(()=>{
48
+ container = new Container();
49
+ container.register(ContentEntriesCacheProvider_js_ContentEntriesCacheProvider).inSingletonScope();
50
+ container.register(external_CmsReviewCacheWriter_js_CmsReviewCacheWriter);
51
+ container.register(CmsReviewCacheSyncHandler);
52
+ });
53
+ describe("CmsReviewCacheWriter", ()=>{
54
+ it("handles CMS namespaces only", ()=>{
55
+ const writer = container.resolve(CmsReviewCacheWriter);
56
+ expect(writer.canHandle("cms.article")).toBe(true);
57
+ expect(writer.canHandle("wb.page")).toBe(false);
58
+ expect(writer.canHandle("cms")).toBe(false);
59
+ });
60
+ it("writes meta.system.workflow into the matching entry only", ()=>{
61
+ seedCache("article", [
62
+ createEntry("entry-1", void 0),
63
+ createEntry("entry-2", void 0)
64
+ ]);
65
+ const writer = container.resolve(CmsReviewCacheWriter);
66
+ writer.write({
67
+ namespace: "cms.article",
68
+ targetId: "entry-1",
69
+ targetRevisionId: "entry-1#0001"
70
+ }, WORKFLOW);
71
+ expect(getSystem(readCache("article", "entry-1"))).toEqual({
72
+ workflow: WORKFLOW
73
+ });
74
+ expect(getSystem(readCache("article", "entry-2"))).toBeUndefined();
75
+ });
76
+ it("keeps the other meta fields and the other system keys", ()=>{
77
+ seedCache("article", [
78
+ createEntry("entry-1", {
79
+ other: "kept",
80
+ workflow: null
81
+ })
82
+ ]);
83
+ const writer = container.resolve(CmsReviewCacheWriter);
84
+ writer.write({
85
+ namespace: "cms.article",
86
+ targetId: "entry-1",
87
+ targetRevisionId: "entry-1#0001"
88
+ }, WORKFLOW);
89
+ const entry = readCache("article", "entry-1");
90
+ expect(getSystem(entry)).toEqual({
91
+ other: "kept",
92
+ workflow: WORKFLOW
93
+ });
94
+ expect(entry?.meta.title).toBe("entry-1");
95
+ expect(entry?.meta.status).toBe("draft");
96
+ });
97
+ it("clears the workflow when the review is gone", ()=>{
98
+ seedCache("article", [
99
+ createEntry("entry-1", {
100
+ workflow: WORKFLOW
101
+ })
102
+ ]);
103
+ const writer = container.resolve(CmsReviewCacheWriter);
104
+ writer.write({
105
+ namespace: "cms.article",
106
+ targetId: "entry-1",
107
+ targetRevisionId: "entry-1#0001"
108
+ }, null);
109
+ expect(getSystem(readCache("article", "entry-1"))).toEqual({
110
+ workflow: null
111
+ });
112
+ });
113
+ it("an older revision does not mark the latest row", ()=>{
114
+ seedCache("article", [
115
+ createEntry("entry-1", void 0, 2)
116
+ ]);
117
+ const writer = container.resolve(CmsReviewCacheWriter);
118
+ writer.write({
119
+ namespace: "cms.article",
120
+ targetId: "entry-1",
121
+ targetRevisionId: "entry-1#0001"
122
+ }, WORKFLOW);
123
+ expect(getSystem(readCache("article", "entry-1"))).toBeUndefined();
124
+ });
125
+ it("does not touch the cache of another model", ()=>{
126
+ seedCache("article", [
127
+ createEntry("entry-1", void 0)
128
+ ]);
129
+ seedCache("page", [
130
+ createEntry("entry-1", void 0)
131
+ ]);
132
+ const writer = container.resolve(CmsReviewCacheWriter);
133
+ writer.write({
134
+ namespace: "cms.article",
135
+ targetId: "entry-1",
136
+ targetRevisionId: "entry-1#0001"
137
+ }, WORKFLOW);
138
+ expect(getSystem(readCache("page", "entry-1"))).toBeUndefined();
139
+ });
140
+ });
141
+ describe("CmsReviewCacheSyncHandler", ()=>{
142
+ function resolveHandler() {
143
+ const handlers = container.resolveAll(ReviewChangedHandler);
144
+ expect(handlers).toHaveLength(1);
145
+ return handlers[0];
146
+ }
147
+ it("is registered as a subclass of the shared handler", ()=>{
148
+ const handler = resolveHandler();
149
+ expect(handler).toBeInstanceOf(ReviewCacheSyncHandler);
150
+ expect(handler.constructor).not.toBe(ReviewCacheSyncHandler);
151
+ });
152
+ it("stores toSystemWorkflow of the changed review", async ()=>{
153
+ seedCache("article", [
154
+ createEntry("entry-1", void 0)
155
+ ]);
156
+ const review = createReview({
157
+ namespace: "cms.article"
158
+ });
159
+ const expected = toSystemWorkflow(review);
160
+ const event = new ReviewChangedEvent({
161
+ namespace: "cms.article",
162
+ targetId: "entry-1",
163
+ targetRevisionId: "entry-1#0001",
164
+ review
165
+ });
166
+ await resolveHandler().handle(event);
167
+ expect(expected).not.toBeNull();
168
+ expect(expected?.workflowId).toBe(review.workflowId);
169
+ expect(getSystem(readCache("article", "entry-1"))).toEqual({
170
+ workflow: expected
171
+ });
172
+ });
173
+ it("clears the workflow when the event carries no review", async ()=>{
174
+ seedCache("article", [
175
+ createEntry("entry-1", {
176
+ workflow: WORKFLOW
177
+ })
178
+ ]);
179
+ const event = new ReviewChangedEvent({
180
+ namespace: "cms.article",
181
+ targetId: "entry-1",
182
+ targetRevisionId: "entry-1#0001",
183
+ review: null
184
+ });
185
+ await resolveHandler().handle(event);
186
+ expect(getSystem(readCache("article", "entry-1"))).toEqual({
187
+ workflow: null
188
+ });
189
+ });
190
+ it("ignores another app's namespace", async ()=>{
191
+ seedCache("article", [
192
+ createEntry("entry-1", void 0)
193
+ ]);
194
+ const event = new ReviewChangedEvent({
195
+ namespace: "wb.page",
196
+ targetId: "entry-1",
197
+ targetRevisionId: "entry-1#0001",
198
+ review: createReview({
199
+ namespace: "wb.page"
200
+ })
201
+ });
202
+ await resolveHandler().handle(event);
203
+ expect(getSystem(readCache("article", "entry-1"))).toBeUndefined();
204
+ });
205
+ });
206
+
207
+ //# sourceMappingURL=CmsReviewCacheWriter.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"features/cache/CmsReviewCacheWriter.test.js","sources":["../../../src/features/cache/CmsReviewCacheWriter.test.ts"],"sourcesContent":["import { beforeEach } from \"vitest\";\nimport { describe } from \"vitest\";\nimport { expect } from \"vitest\";\nimport { it } from \"vitest\";\nimport { Container } from \"@webiny/di\";\nimport { ContentEntriesCacheProvider as ContentEntriesCacheProviderAbstraction } from \"@webiny/app-headless-cms/features/contentEntry/abstractions.js\";\nimport { ContentEntriesCacheProvider } from \"@webiny/app-headless-cms/features/contentEntry/ContentEntriesCacheProvider.js\";\nimport type { CmsContentEntry } from \"@webiny/app-headless-cms-common/types/index.js\";\nimport { ReviewState } from \"@webiny/app-workflows/review/domain/ReviewState.js\";\nimport { StepState } from \"@webiny/app-workflows/review/domain/StepState.js\";\nimport { toSystemWorkflow } from \"@webiny/app-workflows/review/domain/toSystemWorkflow.js\";\nimport type { SystemWorkflowValue } from \"@webiny/app-workflows/review/domain/types.js\";\nimport { ReviewChangedEvent } from \"@webiny/app-workflows/review/events/ReviewChangedEvent.js\";\nimport { ReviewChangedHandler } from \"@webiny/app-workflows/review/events/ReviewChangedHandler.js\";\nimport { ReviewCacheSyncHandler } from \"@webiny/app-workflows/review/cache/ReviewCacheSyncHandler.js\";\nimport { createReview } from \"@webiny/app-workflows/review/testing/reviewFixtures.js\";\nimport { CmsReviewCacheWriter as Abstraction } from \"~/features/cache/abstractions.js\";\nimport { CmsReviewCacheWriter } from \"~/features/cache/CmsReviewCacheWriter.js\";\nimport { CmsReviewCacheSyncHandler } from \"~/features/cache/CmsReviewCacheSyncHandler.js\";\n\nconst WORKFLOW: SystemWorkflowValue = {\n workflowId: \"wf-1\",\n reviewState: ReviewState.InProgress,\n stepId: \"step-1\",\n stepName: \"Legal review\",\n stepState: StepState.InReview\n};\n\nfunction createEntry(\n entryId: string,\n system: Record<string, unknown> | undefined,\n version = 1\n): CmsContentEntry {\n return {\n id: `${entryId}#000${version}`,\n entryId,\n meta: { title: entryId, status: \"draft\", version: 1, locked: false, system }\n } as unknown as CmsContentEntry;\n}\n\nfunction getSystem(entry: CmsContentEntry | undefined): unknown {\n return (entry?.meta as unknown as { system?: unknown }).system;\n}\n\nlet container: Container;\n\nfunction seedCache(modelId: string, entries: CmsContentEntry[]): void {\n const provider = container.resolve(ContentEntriesCacheProviderAbstraction);\n provider.get(modelId).setItems(entries);\n}\n\nfunction readCache(modelId: string, entryId: string): CmsContentEntry | undefined {\n const provider = container.resolve(ContentEntriesCacheProviderAbstraction);\n return provider.get(modelId).getItem(entry => entry.entryId === entryId);\n}\n\nbeforeEach(() => {\n container = new Container();\n container.register(ContentEntriesCacheProvider).inSingletonScope();\n container.register(CmsReviewCacheWriter);\n container.register(CmsReviewCacheSyncHandler);\n});\n\ndescribe(\"CmsReviewCacheWriter\", () => {\n it(\"handles CMS namespaces only\", () => {\n const writer = container.resolve(Abstraction);\n\n expect(writer.canHandle(\"cms.article\")).toBe(true);\n expect(writer.canHandle(\"wb.page\")).toBe(false);\n expect(writer.canHandle(\"cms\")).toBe(false);\n });\n\n it(\"writes meta.system.workflow into the matching entry only\", () => {\n seedCache(\"article\", [\n createEntry(\"entry-1\", undefined),\n createEntry(\"entry-2\", undefined)\n ]);\n const writer = container.resolve(Abstraction);\n\n writer.write(\n { namespace: \"cms.article\", targetId: \"entry-1\", targetRevisionId: \"entry-1#0001\" },\n WORKFLOW\n );\n\n expect(getSystem(readCache(\"article\", \"entry-1\"))).toEqual({ workflow: WORKFLOW });\n expect(getSystem(readCache(\"article\", \"entry-2\"))).toBeUndefined();\n });\n\n it(\"keeps the other meta fields and the other system keys\", () => {\n seedCache(\"article\", [createEntry(\"entry-1\", { other: \"kept\", workflow: null })]);\n const writer = container.resolve(Abstraction);\n\n writer.write(\n { namespace: \"cms.article\", targetId: \"entry-1\", targetRevisionId: \"entry-1#0001\" },\n WORKFLOW\n );\n\n const entry = readCache(\"article\", \"entry-1\");\n expect(getSystem(entry)).toEqual({ other: \"kept\", workflow: WORKFLOW });\n expect(entry?.meta.title).toBe(\"entry-1\");\n expect(entry?.meta.status).toBe(\"draft\");\n });\n\n it(\"clears the workflow when the review is gone\", () => {\n seedCache(\"article\", [createEntry(\"entry-1\", { workflow: WORKFLOW })]);\n const writer = container.resolve(Abstraction);\n\n writer.write(\n { namespace: \"cms.article\", targetId: \"entry-1\", targetRevisionId: \"entry-1#0001\" },\n null\n );\n\n expect(getSystem(readCache(\"article\", \"entry-1\"))).toEqual({ workflow: null });\n });\n\n it(\"an older revision does not mark the latest row\", () => {\n seedCache(\"article\", [createEntry(\"entry-1\", undefined, 2)]);\n const writer = container.resolve(Abstraction);\n\n writer.write(\n { namespace: \"cms.article\", targetId: \"entry-1\", targetRevisionId: \"entry-1#0001\" },\n WORKFLOW\n );\n\n expect(getSystem(readCache(\"article\", \"entry-1\"))).toBeUndefined();\n });\n\n it(\"does not touch the cache of another model\", () => {\n seedCache(\"article\", [createEntry(\"entry-1\", undefined)]);\n seedCache(\"page\", [createEntry(\"entry-1\", undefined)]);\n const writer = container.resolve(Abstraction);\n\n writer.write(\n { namespace: \"cms.article\", targetId: \"entry-1\", targetRevisionId: \"entry-1#0001\" },\n WORKFLOW\n );\n\n expect(getSystem(readCache(\"page\", \"entry-1\"))).toBeUndefined();\n });\n});\n\ndescribe(\"CmsReviewCacheSyncHandler\", () => {\n function resolveHandler() {\n const handlers = container.resolveAll(ReviewChangedHandler);\n expect(handlers).toHaveLength(1);\n return handlers[0];\n }\n\n it(\"is registered as a subclass of the shared handler\", () => {\n const handler = resolveHandler();\n\n expect(handler).toBeInstanceOf(ReviewCacheSyncHandler);\n expect(handler.constructor).not.toBe(ReviewCacheSyncHandler);\n });\n\n it(\"stores toSystemWorkflow of the changed review\", async () => {\n seedCache(\"article\", [createEntry(\"entry-1\", undefined)]);\n const review = createReview({ namespace: \"cms.article\" });\n const expected = toSystemWorkflow(review);\n const event = new ReviewChangedEvent({\n namespace: \"cms.article\",\n targetId: \"entry-1\",\n targetRevisionId: \"entry-1#0001\",\n review\n });\n\n await resolveHandler().handle(event);\n\n expect(expected).not.toBeNull();\n expect(expected?.workflowId).toBe(review.workflowId);\n expect(getSystem(readCache(\"article\", \"entry-1\"))).toEqual({ workflow: expected });\n });\n\n it(\"clears the workflow when the event carries no review\", async () => {\n seedCache(\"article\", [createEntry(\"entry-1\", { workflow: WORKFLOW })]);\n const event = new ReviewChangedEvent({\n namespace: \"cms.article\",\n targetId: \"entry-1\",\n targetRevisionId: \"entry-1#0001\",\n review: null\n });\n\n await resolveHandler().handle(event);\n\n expect(getSystem(readCache(\"article\", \"entry-1\"))).toEqual({ workflow: null });\n });\n\n it(\"ignores another app's namespace\", async () => {\n seedCache(\"article\", [createEntry(\"entry-1\", undefined)]);\n const event = new ReviewChangedEvent({\n namespace: \"wb.page\",\n targetId: \"entry-1\",\n targetRevisionId: \"entry-1#0001\",\n review: createReview({ namespace: \"wb.page\" })\n });\n\n await resolveHandler().handle(event);\n\n expect(getSystem(readCache(\"article\", \"entry-1\"))).toBeUndefined();\n });\n});\n"],"names":["WORKFLOW","ReviewState","StepState","createEntry","entryId","system","version","getSystem","entry","container","seedCache","modelId","entries","provider","ContentEntriesCacheProviderAbstraction","readCache","beforeEach","Container","ContentEntriesCacheProvider","CmsReviewCacheWriter","CmsReviewCacheSyncHandler","describe","it","writer","Abstraction","expect","undefined","resolveHandler","handlers","ReviewChangedHandler","handler","ReviewCacheSyncHandler","review","createReview","expected","toSystemWorkflow","event","ReviewChangedEvent"],"mappings":"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"}
@@ -0,0 +1,12 @@
1
+ import type { IListCache } from "@webiny/app-admin/features/listCache/index.js";
2
+ import { ContentEntriesCacheProvider } from "@webiny/app-headless-cms/features/contentEntry/abstractions.js";
3
+ import type { CmsContentEntry } from "@webiny/app-headless-cms-common/types/index.js";
4
+ declare class CmsReviewEntriesCacheProvider implements ContentEntriesCacheProvider.Interface {
5
+ private readonly decoratee;
6
+ constructor(decoratee: ContentEntriesCacheProvider.Interface);
7
+ get(modelId: string): IListCache<CmsContentEntry>;
8
+ }
9
+ export declare const CmsReviewEntriesCacheProviderDecorator: typeof CmsReviewEntriesCacheProvider & {
10
+ __abstraction: import("@webiny/di").Abstraction<import("@webiny/app-headless-cms/features/contentEntry/abstractions.js").IContentEntriesCacheProvider>;
11
+ };
12
+ export {};
@@ -0,0 +1,17 @@
1
+ import { ContentEntriesCacheProvider } from "@webiny/app-headless-cms/features/contentEntry/abstractions.js";
2
+ import { ReviewPreservingEntriesCache } from "./ReviewPreservingEntriesCache.js";
3
+ class CmsReviewEntriesCacheProvider {
4
+ constructor(decoratee){
5
+ this.decoratee = decoratee;
6
+ }
7
+ get(modelId) {
8
+ return new ReviewPreservingEntriesCache(this.decoratee.get(modelId));
9
+ }
10
+ }
11
+ const CmsReviewEntriesCacheProviderDecorator = ContentEntriesCacheProvider.createDecorator({
12
+ decorator: CmsReviewEntriesCacheProvider,
13
+ dependencies: []
14
+ });
15
+ export { CmsReviewEntriesCacheProviderDecorator };
16
+
17
+ //# sourceMappingURL=CmsReviewEntriesCacheProviderDecorator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"features/cache/CmsReviewEntriesCacheProviderDecorator.js","sources":["../../../src/features/cache/CmsReviewEntriesCacheProviderDecorator.ts"],"sourcesContent":["import type { IListCache } from \"@webiny/app-admin/features/listCache/index.js\";\nimport { ContentEntriesCacheProvider } from \"@webiny/app-headless-cms/features/contentEntry/abstractions.js\";\nimport type { CmsContentEntry } from \"@webiny/app-headless-cms-common/types/index.js\";\nimport { ReviewPreservingEntriesCache } from \"./ReviewPreservingEntriesCache.js\";\n\nclass CmsReviewEntriesCacheProvider implements ContentEntriesCacheProvider.Interface {\n constructor(private readonly decoratee: ContentEntriesCacheProvider.Interface) {}\n\n get(modelId: string): IListCache<CmsContentEntry> {\n return new ReviewPreservingEntriesCache(this.decoratee.get(modelId));\n }\n}\n\nexport const CmsReviewEntriesCacheProviderDecorator = ContentEntriesCacheProvider.createDecorator({\n decorator: CmsReviewEntriesCacheProvider,\n dependencies: []\n});\n"],"names":["CmsReviewEntriesCacheProvider","decoratee","modelId","ReviewPreservingEntriesCache","CmsReviewEntriesCacheProviderDecorator","ContentEntriesCacheProvider"],"mappings":";;AAKA,MAAMA;IACF,YAA6BC,SAAgD,CAAE;aAAlDA,SAAS,GAATA;IAAmD;IAEhF,IAAIC,OAAe,EAA+B;QAC9C,OAAO,IAAIC,6BAA6B,IAAI,CAAC,SAAS,CAAC,GAAG,CAACD;IAC/D;AACJ;AAEO,MAAME,yCAAyCC,4BAA4B,eAAe,CAAC;IAC9F,WAAWL;IACX,cAAc,EAAE;AACpB"}