@focus-reactive/payload-plugin-comments 1.0.0

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 (387) hide show
  1. package/README.md +563 -0
  2. package/dist/collection/access/isAuth.d.ts +3 -0
  3. package/dist/collection/access/isAuth.d.ts.map +1 -0
  4. package/dist/collection/access/isAuth.js +8 -0
  5. package/dist/collection/access/isAuth.js.map +1 -0
  6. package/dist/collection/hooks/setAuthorBeforeCreate.d.ts +3 -0
  7. package/dist/collection/hooks/setAuthorBeforeCreate.d.ts.map +1 -0
  8. package/dist/collection/hooks/setAuthorBeforeCreate.js +10 -0
  9. package/dist/collection/hooks/setAuthorBeforeCreate.js.map +1 -0
  10. package/dist/collection/hooks/setTenantBeforeCreate.d.ts +3 -0
  11. package/dist/collection/hooks/setTenantBeforeCreate.d.ts.map +1 -0
  12. package/dist/collection/hooks/setTenantBeforeCreate.js +24 -0
  13. package/dist/collection/hooks/setTenantBeforeCreate.js.map +1 -0
  14. package/dist/collection/index.d.ts +4 -0
  15. package/dist/collection/index.d.ts.map +1 -0
  16. package/dist/collection/index.js +139 -0
  17. package/dist/collection/index.js.map +1 -0
  18. package/dist/components/Avatar/index.d.ts +11 -0
  19. package/dist/components/Avatar/index.d.ts.map +1 -0
  20. package/dist/components/Avatar/index.js +11 -0
  21. package/dist/components/Avatar/index.js.map +1 -0
  22. package/dist/components/CommentEditor/ActionPanel.d.ts +8 -0
  23. package/dist/components/CommentEditor/ActionPanel.d.ts.map +1 -0
  24. package/dist/components/CommentEditor/ActionPanel.js +17 -0
  25. package/dist/components/CommentEditor/ActionPanel.js.map +1 -0
  26. package/dist/components/CommentEditor/index.d.ts +23 -0
  27. package/dist/components/CommentEditor/index.d.ts.map +1 -0
  28. package/dist/components/CommentEditor/index.js +265 -0
  29. package/dist/components/CommentEditor/index.js.map +1 -0
  30. package/dist/components/CommentItem/ToolsPanel.d.ts +9 -0
  31. package/dist/components/CommentItem/ToolsPanel.d.ts.map +1 -0
  32. package/dist/components/CommentItem/ToolsPanel.js +22 -0
  33. package/dist/components/CommentItem/ToolsPanel.js.map +1 -0
  34. package/dist/components/CommentItem/index.d.ts +8 -0
  35. package/dist/components/CommentItem/index.d.ts.map +1 -0
  36. package/dist/components/CommentItem/index.js +65 -0
  37. package/dist/components/CommentItem/index.js.map +1 -0
  38. package/dist/components/CommentsDrawer/components/Header.d.ts +6 -0
  39. package/dist/components/CommentsDrawer/components/Header.d.ts.map +1 -0
  40. package/dist/components/CommentsDrawer/components/Header.js +46 -0
  41. package/dist/components/CommentsDrawer/components/Header.js.map +1 -0
  42. package/dist/components/CommentsDrawer/index.d.ts +6 -0
  43. package/dist/components/CommentsDrawer/index.d.ts.map +1 -0
  44. package/dist/components/CommentsDrawer/index.js +30 -0
  45. package/dist/components/CommentsDrawer/index.js.map +1 -0
  46. package/dist/components/CommentsHeaderButton/index.d.ts +2 -0
  47. package/dist/components/CommentsHeaderButton/index.d.ts.map +1 -0
  48. package/dist/components/CommentsHeaderButton/index.js +19 -0
  49. package/dist/components/CommentsHeaderButton/index.js.map +1 -0
  50. package/dist/components/CommentsPanel/components/CollapsibleGroup.d.ts +10 -0
  51. package/dist/components/CommentsPanel/components/CollapsibleGroup.d.ts.map +1 -0
  52. package/dist/components/CommentsPanel/components/CollapsibleGroup.js +68 -0
  53. package/dist/components/CommentsPanel/components/CollapsibleGroup.js.map +1 -0
  54. package/dist/components/CommentsPanel/components/DocumentView.d.ts +9 -0
  55. package/dist/components/CommentsPanel/components/DocumentView.d.ts.map +1 -0
  56. package/dist/components/CommentsPanel/components/DocumentView.js +28 -0
  57. package/dist/components/CommentsPanel/components/DocumentView.js.map +1 -0
  58. package/dist/components/CommentsPanel/components/FieldGroupSection.d.ts +11 -0
  59. package/dist/components/CommentsPanel/components/FieldGroupSection.d.ts.map +1 -0
  60. package/dist/components/CommentsPanel/components/FieldGroupSection.js +62 -0
  61. package/dist/components/CommentsPanel/components/FieldGroupSection.js.map +1 -0
  62. package/dist/components/CommentsPanel/components/GlobalDocumentView.d.ts +9 -0
  63. package/dist/components/CommentsPanel/components/GlobalDocumentView.d.ts.map +1 -0
  64. package/dist/components/CommentsPanel/components/GlobalDocumentView.js +20 -0
  65. package/dist/components/CommentsPanel/components/GlobalDocumentView.js.map +1 -0
  66. package/dist/components/CommentsPanel/components/GlobalView.d.ts +9 -0
  67. package/dist/components/CommentsPanel/components/GlobalView.d.ts.map +1 -0
  68. package/dist/components/CommentsPanel/components/GlobalView.js +62 -0
  69. package/dist/components/CommentsPanel/components/GlobalView.js.map +1 -0
  70. package/dist/components/CommentsPanel/constants.d.ts +3 -0
  71. package/dist/components/CommentsPanel/constants.d.ts.map +1 -0
  72. package/dist/components/CommentsPanel/constants.js +9 -0
  73. package/dist/components/CommentsPanel/constants.js.map +1 -0
  74. package/dist/components/CommentsPanel/hooks/useCollapseState.d.ts +2 -0
  75. package/dist/components/CommentsPanel/hooks/useCollapseState.d.ts.map +1 -0
  76. package/dist/components/CommentsPanel/hooks/useCollapseState.js +44 -0
  77. package/dist/components/CommentsPanel/hooks/useCollapseState.js.map +1 -0
  78. package/dist/components/CommentsPanel/hooks/useScrollToTargetFieldGroup.d.ts +2 -0
  79. package/dist/components/CommentsPanel/hooks/useScrollToTargetFieldGroup.d.ts.map +1 -0
  80. package/dist/components/CommentsPanel/hooks/useScrollToTargetFieldGroup.js +35 -0
  81. package/dist/components/CommentsPanel/hooks/useScrollToTargetFieldGroup.js.map +1 -0
  82. package/dist/components/CommentsPanel/index.d.ts +6 -0
  83. package/dist/components/CommentsPanel/index.d.ts.map +1 -0
  84. package/dist/components/CommentsPanel/index.js +32 -0
  85. package/dist/components/CommentsPanel/index.js.map +1 -0
  86. package/dist/components/CommentsPanel/types.d.ts +4 -0
  87. package/dist/components/CommentsPanel/types.d.ts.map +1 -0
  88. package/dist/components/CommentsPanel/types.js +1 -0
  89. package/dist/components/CommentsPanel/types.js.map +1 -0
  90. package/dist/components/CommentsPanel/utils/createCollapsibleGroupKey.d.ts +10 -0
  91. package/dist/components/CommentsPanel/utils/createCollapsibleGroupKey.d.ts.map +1 -0
  92. package/dist/components/CommentsPanel/utils/createCollapsibleGroupKey.js +15 -0
  93. package/dist/components/CommentsPanel/utils/createCollapsibleGroupKey.js.map +1 -0
  94. package/dist/components/CommentsPanel/utils/filterComments.d.ts +9 -0
  95. package/dist/components/CommentsPanel/utils/filterComments.d.ts.map +1 -0
  96. package/dist/components/CommentsPanel/utils/filterComments.js +17 -0
  97. package/dist/components/CommentsPanel/utils/filterComments.js.map +1 -0
  98. package/dist/components/CommentsPanel/utils/groupCommentsByFieldPath.d.ts +4 -0
  99. package/dist/components/CommentsPanel/utils/groupCommentsByFieldPath.d.ts.map +1 -0
  100. package/dist/components/CommentsPanel/utils/groupCommentsByFieldPath.js +14 -0
  101. package/dist/components/CommentsPanel/utils/groupCommentsByFieldPath.js.map +1 -0
  102. package/dist/components/CommentsPanel/utils/groupCommentsGlobally.d.ts +18 -0
  103. package/dist/components/CommentsPanel/utils/groupCommentsGlobally.d.ts.map +1 -0
  104. package/dist/components/CommentsPanel/utils/groupCommentsGlobally.js +58 -0
  105. package/dist/components/CommentsPanel/utils/groupCommentsGlobally.js.map +1 -0
  106. package/dist/components/CommentsPanel/utils/resolveEntityLabel.d.ts +3 -0
  107. package/dist/components/CommentsPanel/utils/resolveEntityLabel.d.ts.map +1 -0
  108. package/dist/components/CommentsPanel/utils/resolveEntityLabel.js +14 -0
  109. package/dist/components/CommentsPanel/utils/resolveEntityLabel.js.map +1 -0
  110. package/dist/components/CommentsPanel/utils/resolveFieldLabel.d.ts +11 -0
  111. package/dist/components/CommentsPanel/utils/resolveFieldLabel.d.ts.map +1 -0
  112. package/dist/components/CommentsPanel/utils/resolveFieldLabel.js +9 -0
  113. package/dist/components/CommentsPanel/utils/resolveFieldLabel.js.map +1 -0
  114. package/dist/components/CommentsPanel/utils/sortGroupsByCreatedAt.d.ts +4 -0
  115. package/dist/components/CommentsPanel/utils/sortGroupsByCreatedAt.d.ts.map +1 -0
  116. package/dist/components/CommentsPanel/utils/sortGroupsByCreatedAt.js +11 -0
  117. package/dist/components/CommentsPanel/utils/sortGroupsByCreatedAt.js.map +1 -0
  118. package/dist/components/FieldCommentLabel/AddCommentPopup.d.ts +8 -0
  119. package/dist/components/FieldCommentLabel/AddCommentPopup.d.ts.map +1 -0
  120. package/dist/components/FieldCommentLabel/AddCommentPopup.js +50 -0
  121. package/dist/components/FieldCommentLabel/AddCommentPopup.js.map +1 -0
  122. package/dist/components/FieldCommentLabel/hooks/useStablePath.d.ts +2 -0
  123. package/dist/components/FieldCommentLabel/hooks/useStablePath.d.ts.map +1 -0
  124. package/dist/components/FieldCommentLabel/hooks/useStablePath.js +12 -0
  125. package/dist/components/FieldCommentLabel/hooks/useStablePath.js.map +1 -0
  126. package/dist/components/FieldCommentLabel/index.d.ts +11 -0
  127. package/dist/components/FieldCommentLabel/index.d.ts.map +1 -0
  128. package/dist/components/FieldCommentLabel/index.js +64 -0
  129. package/dist/components/FieldCommentLabel/index.js.map +1 -0
  130. package/dist/components/FieldCommentLabel/types.d.ts +4 -0
  131. package/dist/components/FieldCommentLabel/types.d.ts.map +1 -0
  132. package/dist/components/FieldCommentLabel/types.js +1 -0
  133. package/dist/components/FieldCommentLabel/types.js.map +1 -0
  134. package/dist/components/FieldCommentLabel/utils/buildStablePath.d.ts +2 -0
  135. package/dist/components/FieldCommentLabel/utils/buildStablePath.d.ts.map +1 -0
  136. package/dist/components/FieldCommentLabel/utils/buildStablePath.js +19 -0
  137. package/dist/components/FieldCommentLabel/utils/buildStablePath.js.map +1 -0
  138. package/dist/components/FieldCommentLabel/utils/exludeComments.d.ts +3 -0
  139. package/dist/components/FieldCommentLabel/utils/exludeComments.d.ts.map +1 -0
  140. package/dist/components/FieldCommentLabel/utils/exludeComments.js +12 -0
  141. package/dist/components/FieldCommentLabel/utils/exludeComments.js.map +1 -0
  142. package/dist/components/FieldCommentLabel/utils/resolveLabel.d.ts +3 -0
  143. package/dist/components/FieldCommentLabel/utils/resolveLabel.d.ts.map +1 -0
  144. package/dist/components/FieldCommentLabel/utils/resolveLabel.js +9 -0
  145. package/dist/components/FieldCommentLabel/utils/resolveLabel.js.map +1 -0
  146. package/dist/components/IconButton/index.d.ts +12 -0
  147. package/dist/components/IconButton/index.d.ts.map +1 -0
  148. package/dist/components/IconButton/index.js +38 -0
  149. package/dist/components/IconButton/index.js.map +1 -0
  150. package/dist/components/MentionDropdown.d.ts +11 -0
  151. package/dist/components/MentionDropdown.d.ts.map +1 -0
  152. package/dist/components/MentionDropdown.js +53 -0
  153. package/dist/components/MentionDropdown.js.map +1 -0
  154. package/dist/components/MentionLabel/index.d.ts +7 -0
  155. package/dist/components/MentionLabel/index.d.ts.map +1 -0
  156. package/dist/components/MentionLabel/index.js +21 -0
  157. package/dist/components/MentionLabel/index.js.map +1 -0
  158. package/dist/config.d.ts +4 -0
  159. package/dist/config.d.ts.map +1 -0
  160. package/dist/config.js +17 -0
  161. package/dist/config.js.map +1 -0
  162. package/dist/constants.d.ts +9 -0
  163. package/dist/constants.d.ts.map +1 -0
  164. package/dist/constants.js +22 -0
  165. package/dist/constants.js.map +1 -0
  166. package/dist/hooks/useRelativeDate.d.ts +2 -0
  167. package/dist/hooks/useRelativeDate.d.ts.map +1 -0
  168. package/dist/hooks/useRelativeDate.js +11 -0
  169. package/dist/hooks/useRelativeDate.js.map +1 -0
  170. package/dist/index.d.ts +5 -0
  171. package/dist/index.d.ts.map +1 -0
  172. package/dist/index.js +7 -0
  173. package/dist/index.js.map +1 -0
  174. package/dist/plugin.d.ts +4 -0
  175. package/dist/plugin.d.ts.map +1 -0
  176. package/dist/plugin.js +60 -0
  177. package/dist/plugin.js.map +1 -0
  178. package/dist/providers/CommentsDrawerProvider/index.d.ts +14 -0
  179. package/dist/providers/CommentsDrawerProvider/index.d.ts.map +1 -0
  180. package/dist/providers/CommentsDrawerProvider/index.js +28 -0
  181. package/dist/providers/CommentsDrawerProvider/index.js.map +1 -0
  182. package/dist/providers/CommentsProvider/index.d.ts +39 -0
  183. package/dist/providers/CommentsProvider/index.d.ts.map +1 -0
  184. package/dist/providers/CommentsProvider/index.js +237 -0
  185. package/dist/providers/CommentsProvider/index.js.map +1 -0
  186. package/dist/providers/CommentsProvider/mergeDocumentTitles.d.ts +3 -0
  187. package/dist/providers/CommentsProvider/mergeDocumentTitles.d.ts.map +1 -0
  188. package/dist/providers/CommentsProvider/mergeDocumentTitles.js +10 -0
  189. package/dist/providers/CommentsProvider/mergeDocumentTitles.js.map +1 -0
  190. package/dist/providers/CommentsProviderWrapper/index.d.ts +7 -0
  191. package/dist/providers/CommentsProviderWrapper/index.d.ts.map +1 -0
  192. package/dist/providers/CommentsProviderWrapper/index.js +16 -0
  193. package/dist/providers/CommentsProviderWrapper/index.js.map +1 -0
  194. package/dist/providers/GlobalCommentsLoader/GlobalCommentsHydrator.d.ts +13 -0
  195. package/dist/providers/GlobalCommentsLoader/GlobalCommentsHydrator.d.ts.map +1 -0
  196. package/dist/providers/GlobalCommentsLoader/GlobalCommentsHydrator.js +22 -0
  197. package/dist/providers/GlobalCommentsLoader/GlobalCommentsHydrator.js.map +1 -0
  198. package/dist/providers/GlobalCommentsLoader/index.d.ts +10 -0
  199. package/dist/providers/GlobalCommentsLoader/index.d.ts.map +1 -0
  200. package/dist/providers/GlobalCommentsLoader/index.js +31 -0
  201. package/dist/providers/GlobalCommentsLoader/index.js.map +1 -0
  202. package/dist/services/createComment.d.ts +12 -0
  203. package/dist/services/createComment.d.ts.map +1 -0
  204. package/dist/services/createComment.js +83 -0
  205. package/dist/services/createComment.js.map +1 -0
  206. package/dist/services/deleteComment.d.ts +3 -0
  207. package/dist/services/deleteComment.d.ts.map +1 -0
  208. package/dist/services/deleteComment.js +34 -0
  209. package/dist/services/deleteComment.js.map +1 -0
  210. package/dist/services/fetchMentionableUsers.d.ts +3 -0
  211. package/dist/services/fetchMentionableUsers.d.ts.map +1 -0
  212. package/dist/services/fetchMentionableUsers.js +46 -0
  213. package/dist/services/fetchMentionableUsers.js.map +1 -0
  214. package/dist/services/fieldLabels/fetchFieldLabels.d.ts +3 -0
  215. package/dist/services/fieldLabels/fetchFieldLabels.d.ts.map +1 -0
  216. package/dist/services/fieldLabels/fetchFieldLabels.js +74 -0
  217. package/dist/services/fieldLabels/fetchFieldLabels.js.map +1 -0
  218. package/dist/services/fieldLabels/utils/groupFieldPathsByDocument.d.ts +5 -0
  219. package/dist/services/fieldLabels/utils/groupFieldPathsByDocument.d.ts.map +1 -0
  220. package/dist/services/fieldLabels/utils/groupFieldPathsByDocument.js +21 -0
  221. package/dist/services/fieldLabels/utils/groupFieldPathsByDocument.js.map +1 -0
  222. package/dist/services/fieldLabels/utils/resolveFieldPath.d.ts +4 -0
  223. package/dist/services/fieldLabels/utils/resolveFieldPath.d.ts.map +1 -0
  224. package/dist/services/fieldLabels/utils/resolveFieldPath.js +66 -0
  225. package/dist/services/fieldLabels/utils/resolveFieldPath.js.map +1 -0
  226. package/dist/services/fieldLabels/utils/schemaUtils.d.ts +6 -0
  227. package/dist/services/fieldLabels/utils/schemaUtils.d.ts.map +1 -0
  228. package/dist/services/fieldLabels/utils/schemaUtils.js +60 -0
  229. package/dist/services/fieldLabels/utils/schemaUtils.js.map +1 -0
  230. package/dist/services/findAllComments.d.ts +11 -0
  231. package/dist/services/findAllComments.d.ts.map +1 -0
  232. package/dist/services/findAllComments.js +47 -0
  233. package/dist/services/findAllComments.js.map +1 -0
  234. package/dist/services/getCurrentTenantId.d.ts +3 -0
  235. package/dist/services/getCurrentTenantId.d.ts.map +1 -0
  236. package/dist/services/getCurrentTenantId.js +13 -0
  237. package/dist/services/getCurrentTenantId.js.map +1 -0
  238. package/dist/services/getDocumentTitles.d.ts +3 -0
  239. package/dist/services/getDocumentTitles.d.ts.map +1 -0
  240. package/dist/services/getDocumentTitles.js +61 -0
  241. package/dist/services/getDocumentTitles.js.map +1 -0
  242. package/dist/services/getEntitiesLabels.d.ts +3 -0
  243. package/dist/services/getEntitiesLabels.d.ts.map +1 -0
  244. package/dist/services/getEntitiesLabels.js +14 -0
  245. package/dist/services/getEntitiesLabels.js.map +1 -0
  246. package/dist/services/resolveComment.d.ts +3 -0
  247. package/dist/services/resolveComment.d.ts.map +1 -0
  248. package/dist/services/resolveComment.js +41 -0
  249. package/dist/services/resolveComment.js.map +1 -0
  250. package/dist/services/sendMentionEmails.d.ts +11 -0
  251. package/dist/services/sendMentionEmails.d.ts.map +1 -0
  252. package/dist/services/sendMentionEmails.js +73 -0
  253. package/dist/services/sendMentionEmails.js.map +1 -0
  254. package/dist/services/syncAllCommentsData.d.ts +12 -0
  255. package/dist/services/syncAllCommentsData.d.ts.map +1 -0
  256. package/dist/services/syncAllCommentsData.js +48 -0
  257. package/dist/services/syncAllCommentsData.js.map +1 -0
  258. package/dist/styles.css +2 -0
  259. package/dist/translations/en.d.ts +5 -0
  260. package/dist/translations/en.d.ts.map +1 -0
  261. package/dist/translations/en.js +36 -0
  262. package/dist/translations/en.js.map +1 -0
  263. package/dist/translations/types.d.ts +32 -0
  264. package/dist/translations/types.d.ts.map +1 -0
  265. package/dist/translations/types.js +1 -0
  266. package/dist/translations/types.js.map +1 -0
  267. package/dist/types/base.d.ts +10 -0
  268. package/dist/types/base.d.ts.map +1 -0
  269. package/dist/types/base.js +1 -0
  270. package/dist/types/base.js.map +1 -0
  271. package/dist/types/collection.d.ts +2 -0
  272. package/dist/types/collection.d.ts.map +1 -0
  273. package/dist/types/collection.js +1 -0
  274. package/dist/types/collection.js.map +1 -0
  275. package/dist/types/comment.d.ts +23 -0
  276. package/dist/types/comment.d.ts.map +1 -0
  277. package/dist/types/comment.js +1 -0
  278. package/dist/types/comment.js.map +1 -0
  279. package/dist/types/config.d.ts +112 -0
  280. package/dist/types/config.d.ts.map +1 -0
  281. package/dist/types/config.js +1 -0
  282. package/dist/types/config.js.map +1 -0
  283. package/dist/types/entity.d.ts +15 -0
  284. package/dist/types/entity.d.ts.map +1 -0
  285. package/dist/types/entity.js +1 -0
  286. package/dist/types/entity.js.map +1 -0
  287. package/dist/types/general.d.ts +10 -0
  288. package/dist/types/general.d.ts.map +1 -0
  289. package/dist/types/general.js +1 -0
  290. package/dist/types/general.js.map +1 -0
  291. package/dist/types/index.d.ts +8 -0
  292. package/dist/types/index.d.ts.map +1 -0
  293. package/dist/types/index.js +1 -0
  294. package/dist/types/index.js.map +1 -0
  295. package/dist/types/user.d.ts +6 -0
  296. package/dist/types/user.d.ts.map +1 -0
  297. package/dist/types/user.js +1 -0
  298. package/dist/types/user.js.map +1 -0
  299. package/dist/utils/comment/extractVisibleComments.d.ts +13 -0
  300. package/dist/utils/comment/extractVisibleComments.d.ts.map +1 -0
  301. package/dist/utils/comment/extractVisibleComments.js +17 -0
  302. package/dist/utils/comment/extractVisibleComments.js.map +1 -0
  303. package/dist/utils/comment/filterCommentsByLocale.d.ts +3 -0
  304. package/dist/utils/comment/filterCommentsByLocale.d.ts.map +1 -0
  305. package/dist/utils/comment/filterCommentsByLocale.js +12 -0
  306. package/dist/utils/comment/filterCommentsByLocale.js.map +1 -0
  307. package/dist/utils/comment/renderCommentText.d.ts +12 -0
  308. package/dist/utils/comment/renderCommentText.d.ts.map +1 -0
  309. package/dist/utils/comment/renderCommentText.js +38 -0
  310. package/dist/utils/comment/renderCommentText.js.map +1 -0
  311. package/dist/utils/comment/serializeEditor.d.ts +2 -0
  312. package/dist/utils/comment/serializeEditor.d.ts.map +1 -0
  313. package/dist/utils/comment/serializeEditor.js +30 -0
  314. package/dist/utils/comment/serializeEditor.js.map +1 -0
  315. package/dist/utils/config/injectFieldCommentComponents.d.ts +4 -0
  316. package/dist/utils/config/injectFieldCommentComponents.d.ts.map +1 -0
  317. package/dist/utils/config/injectFieldCommentComponents.js +80 -0
  318. package/dist/utils/config/injectFieldCommentComponents.js.map +1 -0
  319. package/dist/utils/config/mergeTranslations.d.ts +3 -0
  320. package/dist/utils/config/mergeTranslations.d.ts.map +1 -0
  321. package/dist/utils/config/mergeTranslations.js +29 -0
  322. package/dist/utils/config/mergeTranslations.js.map +1 -0
  323. package/dist/utils/config/normalizeCollections.d.ts +7 -0
  324. package/dist/utils/config/normalizeCollections.d.ts.map +1 -0
  325. package/dist/utils/config/normalizeCollections.js +15 -0
  326. package/dist/utils/config/normalizeCollections.js.map +1 -0
  327. package/dist/utils/config/overrideCollections.d.ts +3 -0
  328. package/dist/utils/config/overrideCollections.d.ts.map +1 -0
  329. package/dist/utils/config/overrideCollections.js +38 -0
  330. package/dist/utils/config/overrideCollections.js.map +1 -0
  331. package/dist/utils/config/overrideCommentsCollection.d.ts +4 -0
  332. package/dist/utils/config/overrideCommentsCollection.d.ts.map +1 -0
  333. package/dist/utils/config/overrideCommentsCollection.js +14 -0
  334. package/dist/utils/config/overrideCommentsCollection.js.map +1 -0
  335. package/dist/utils/config/overrideGlobals.d.ts +3 -0
  336. package/dist/utils/config/overrideGlobals.d.ts.map +1 -0
  337. package/dist/utils/config/overrideGlobals.js +8 -0
  338. package/dist/utils/config/overrideGlobals.js.map +1 -0
  339. package/dist/utils/error/getDefaultErrorMessage.d.ts +2 -0
  340. package/dist/utils/error/getDefaultErrorMessage.d.ts.map +1 -0
  341. package/dist/utils/error/getDefaultErrorMessage.js +9 -0
  342. package/dist/utils/error/getDefaultErrorMessage.js.map +1 -0
  343. package/dist/utils/general/cn.d.ts +3 -0
  344. package/dist/utils/general/cn.d.ts.map +1 -0
  345. package/dist/utils/general/cn.js +9 -0
  346. package/dist/utils/general/cn.js.map +1 -0
  347. package/dist/utils/general/formatRelativeDate.d.ts +2 -0
  348. package/dist/utils/general/formatRelativeDate.d.ts.map +1 -0
  349. package/dist/utils/general/formatRelativeDate.js +28 -0
  350. package/dist/utils/general/formatRelativeDate.js.map +1 -0
  351. package/dist/utils/general/getURL.d.ts +2 -0
  352. package/dist/utils/general/getURL.d.ts.map +1 -0
  353. package/dist/utils/general/getURL.js +13 -0
  354. package/dist/utils/general/getURL.js.map +1 -0
  355. package/dist/utils/general/getValueByPath.d.ts +4 -0
  356. package/dist/utils/general/getValueByPath.d.ts.map +1 -0
  357. package/dist/utils/general/getValueByPath.js +19 -0
  358. package/dist/utils/general/getValueByPath.js.map +1 -0
  359. package/dist/utils/mention/isSelfMention.d.ts +4 -0
  360. package/dist/utils/mention/isSelfMention.d.ts.map +1 -0
  361. package/dist/utils/mention/isSelfMention.js +7 -0
  362. package/dist/utils/mention/isSelfMention.js.map +1 -0
  363. package/dist/utils/mention/parseMentionIds.d.ts +2 -0
  364. package/dist/utils/mention/parseMentionIds.d.ts.map +1 -0
  365. package/dist/utils/mention/parseMentionIds.js +13 -0
  366. package/dist/utils/mention/parseMentionIds.js.map +1 -0
  367. package/dist/utils/mode/defineModeByPathname.d.ts +11 -0
  368. package/dist/utils/mode/defineModeByPathname.d.ts.map +1 -0
  369. package/dist/utils/mode/defineModeByPathname.js +39 -0
  370. package/dist/utils/mode/defineModeByPathname.js.map +1 -0
  371. package/dist/utils/path/detectPluginBasePath.d.ts +2 -0
  372. package/dist/utils/path/detectPluginBasePath.d.ts.map +1 -0
  373. package/dist/utils/path/detectPluginBasePath.js +8 -0
  374. package/dist/utils/path/detectPluginBasePath.js.map +1 -0
  375. package/dist/utils/path/getComponentPath.d.ts +15 -0
  376. package/dist/utils/path/getComponentPath.d.ts.map +1 -0
  377. package/dist/utils/path/getComponentPath.js +22 -0
  378. package/dist/utils/path/getComponentPath.js.map +1 -0
  379. package/dist/utils/payload/extractPayload.d.ts +3 -0
  380. package/dist/utils/payload/extractPayload.d.ts.map +1 -0
  381. package/dist/utils/payload/extractPayload.js +9 -0
  382. package/dist/utils/payload/extractPayload.js.map +1 -0
  383. package/dist/utils/user/resolveUsername.d.ts +4 -0
  384. package/dist/utils/user/resolveUsername.d.ts.map +1 -0
  385. package/dist/utils/user/resolveUsername.js +14 -0
  386. package/dist/utils/user/resolveUsername.js.map +1 -0
  387. package/package.json +113 -0
package/README.md ADDED
@@ -0,0 +1,563 @@
1
+ # @focus-reactive/payload-plugin-comments
2
+
3
+ [![npm](https://img.shields.io/npm/v/@focus-reactive/payload-plugin-comments)](https://www.npmjs.com/package/@focus-reactive/payload-plugin-comments)
4
+
5
+ A collaborative commenting plugin for [Payload CMS](https://payloadcms.com/) v3. Adds a full-featured comments system to the Payload admin panel — supporting document-level and field-level comments on both collections and globals, @mentions with email notifications, comment resolution, multi-tenancy, and locale-aware filtering.
6
+
7
+ ## Table of Contents
8
+
9
+ - [AI Integration Prompt](#ai-integration-prompt)
10
+ - [UI Screenshots](#ui-screenshots)
11
+ - [Features](#features)
12
+ - [Prerequisites](#prerequisites)
13
+ - [Installation](#installation)
14
+ - [Setup](#setup)
15
+ - [Configuration](#configuration)
16
+ - [Translations](#translations)
17
+ - [Environment Variables](#environment-variables)
18
+ - [Architecture Overview](#architecture-overview)
19
+ - [Exports Reference](#exports-reference)
20
+ - [Available Scripts](#available-scripts)
21
+ - [Contributing](#contributing)
22
+ - [License](#license)
23
+
24
+ ---
25
+
26
+ ## AI Integration Prompt
27
+
28
+ > Copy and paste this prompt into your AI assistant (Cursor, Claude, etc.) to integrate the plugin into an existing Payload v3 project.
29
+
30
+ ```
31
+ I want to add a collaborative commenting system to my Payload CMS v3 project using @focus-reactive/payload-plugin-comments.
32
+
33
+ ## How it works
34
+
35
+ The plugin injects into every collection and global:
36
+ - A field-level comment badge on every field label — shows comment count, opens a popup to post
37
+ - A document-level comments drawer (sidebar) scoped to the current document
38
+ - A global comments panel (header button) listing all comments across every document and global
39
+
40
+ Comments are stored in an auto-generated `comments` collection (hidden from the sidebar). Each comment records:
41
+ - documentId / collectionSlug / globalSlug — what it belongs to
42
+ - fieldPath — dot-notation field path (null = document-level)
43
+ - locale — for field-level comments (null = shown in all locales)
44
+ - text — may contain @(userId) mention tokens
45
+ - author, mentions, isResolved, resolvedBy, resolvedAt
46
+ - tenant (optional, when multi-tenancy is enabled)
47
+
48
+ @mentions use autocomplete from the users collection. Mentioned users receive email notifications via Resend.
49
+ Comments are automatically deleted when their parent document is deleted.
50
+
51
+ ## Installation
52
+
53
+ pnpm add @focus-reactive/payload-plugin-comments
54
+
55
+ ## Step 1 — Register the plugin in payload.config.ts
56
+
57
+ import { buildConfig } from 'payload'
58
+ import { commentsPlugin } from '@focus-reactive/payload-plugin-comments'
59
+
60
+ export default buildConfig({
61
+ plugins: [
62
+ commentsPlugin({
63
+ // Optional: specify which field to use as document title in the UI
64
+ collections: [
65
+ { slug: 'pages', titleField: 'title' },
66
+ { slug: 'products', titleField: 'name' },
67
+ ],
68
+ // Optional: customize the display name field on users
69
+ usernameFieldPath: 'name', // default
70
+ }),
71
+ ],
72
+ })
73
+
74
+ ## Step 2 — Import the stylesheet
75
+
76
+ In your global CSS or admin layout:
77
+
78
+ @import "@focus-reactive/payload-plugin-comments/styles.css";
79
+
80
+ Or in a TypeScript/JS file:
81
+
82
+ import "@focus-reactive/payload-plugin-comments/styles.css";
83
+
84
+ ## Step 3 — Regenerate the import map
85
+
86
+ Run this after adding the plugin so Payload registers the plugin's admin components:
87
+
88
+ npx payload generate:importmap
89
+
90
+ (Or the equivalent for your package manager: pnpm payload generate:importmap / bunx payload generate:importmap)
91
+ If you skip this step the comment badges, drawer, and header button will not appear in the admin UI.
92
+
93
+ ## Step 4 — Create and run a migration (SQL adapters only)
94
+
95
+ The plugin adds a `comments` collection to your database. If you use PostgreSQL or SQLite, create and apply a migration:
96
+
97
+ npx payload migrate:create create_comments
98
+ npx payload migrate
99
+
100
+ Skip this step if you use the MongoDB adapter.
101
+
102
+ ## Optional: Multi-tenancy
103
+
104
+ commentsPlugin({
105
+ tenant: {
106
+ enabled: true,
107
+ collectionSlug: 'tenants', // default
108
+ documentTenantField: 'tenant', // default
109
+ },
110
+ })
111
+
112
+ ## Optional: Collection overrides
113
+
114
+ commentsPlugin({
115
+ overrides: {
116
+ access: { /* custom access control */ },
117
+ fields: (defaultFields) => [...defaultFields],
118
+ hooks: {
119
+ afterChange: [async ({ doc }) => { /* ... */ }],
120
+ },
121
+ },
122
+ })
123
+
124
+ ## Environment variables (for email notifications)
125
+
126
+ RESEND_API_KEY=re_xxxxxxxxxxxxxxxx
127
+ RESEND_FROM_EMAIL=comments@yourdomain.com
128
+
129
+ ## Important notes
130
+
131
+ - All collections and globals automatically get field-level comments — `collections` config only sets UI metadata (titleField).
132
+ - Comments on globals use globalSlug instead of collectionSlug/documentId.
133
+ - Field-level comments are locale-scoped; document-level comments show in all locales.
134
+ - The `comments` collection is hidden from the admin sidebar by default.
135
+ - Auto-cleanup: when a document is deleted, all its comments are deleted too.
136
+ - usernameFieldPath supports dot-notation (e.g. "profile.displayName").
137
+ - If RESEND_FROM_EMAIL is not set, mention emails are silently skipped.
138
+ ```
139
+
140
+ ---
141
+
142
+ ## UI Screenshots
143
+
144
+ ### Global Comments Panel
145
+
146
+ A header button in the Payload admin opens a drawer listing all comments across every document and collection.
147
+
148
+ ![Global comments panel](https://github.com/user-attachments/assets/ff1dd13c-42a8-4434-825f-8903e75d840c)
149
+
150
+ ### Document Comments Panel
151
+
152
+ When viewing a document, a side panel shows all comments scoped to that document with filter tabs (Open / Resolved / Mentioned me).
153
+
154
+ ![Document comments panel](https://github.com/user-attachments/assets/3525ff5e-eb80-48dc-936e-0da3b317ffbb)
155
+
156
+ ### Field Comment Popup
157
+
158
+ Clicking the comment badge on a field label opens a popup where you can write and post a new comment for that specific field.
159
+
160
+ ![Field comment popup](https://github.com/user-attachments/assets/259c7dc6-5b0e-4bcd-9d49-b7e520682f01)
161
+
162
+ ### Field Label Button — Two States
163
+
164
+ The comment button embedded in the field label has two visual states: no comments (inactive, appears on hover) and one or more open comments (active, showing the count badge).
165
+
166
+ | Inactive (no comments) | Active (has comments) |
167
+ | ----------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------- |
168
+ | ![Field label button — inactive](https://github.com/user-attachments/assets/f540d6a4-c4e9-473f-883c-c34803da4d2f) | ![Field label button — active](https://github.com/user-attachments/assets/dcfbe20e-7b6e-4fa4-9d30-a0e8bd44b7c0) |
169
+ | |
170
+
171
+ ---
172
+
173
+ ## Features
174
+
175
+ - **Document-level comments** — Leave comments on any document in any collection or global
176
+ - **Field-level comments** — Comment directly on individual fields; the field label shows a badge with the comment count
177
+ - **Global support** — Field-level and document-level comments work on Payload Globals, not just collections
178
+ - **@mention users** — Mention other users in comments using `@name` autocomplete
179
+ - **Email notifications** — Mentioned users receive email notifications via [Resend](https://resend.com/)
180
+ - **Resolve comments** — Mark comments as resolved/unresolved; filter by open, resolved, or mentioned
181
+ - **Global comments panel** — A header button opens a drawer showing all comments across all documents and globals
182
+ - **Optimistic UI** — Comments appear instantly before the server confirms
183
+ - **Multi-tenancy** — Scope comments to tenants via `@payloadcms/plugin-multi-tenant`
184
+ - **Locale-aware** — Field-level comments are tied to a locale; document-level comments are shown in all locales
185
+ - **Auto-cleanup** — Comments are automatically deleted when their parent document is deleted
186
+ - **i18n / Translations** — All UI strings are translatable; ship your own locale overrides alongside the built-in English defaults
187
+
188
+ ---
189
+
190
+ ## Prerequisites
191
+
192
+ - Node.js 20 or higher
193
+ - A working [Payload CMS v3](https://payloadcms.com/docs/getting-started/installation) project with Next.js
194
+ - pnpm (recommended)
195
+ - A [Resend](https://resend.com/) account (required only for mention email notifications)
196
+
197
+ ---
198
+
199
+ ## Installation
200
+
201
+ ```bash
202
+ pnpm add @focus-reactive/payload-plugin-comments
203
+ ```
204
+
205
+ ```bash
206
+ npm install @focus-reactive/payload-plugin-comments
207
+ # or
208
+ yarn add @focus-reactive/payload-plugin-comments
209
+ ```
210
+
211
+ **Peer dependencies:** `payload ^3.0.0`, `@payloadcms/ui ^3.0.0`. `next ^14 || ^15`, `react ^18 || ^19`, `react-dom`, and `@payloadcms/plugin-multi-tenant` are optional.
212
+
213
+ ---
214
+
215
+ ## Setup
216
+
217
+ ### 1. Add the plugin to your Payload config
218
+
219
+ ```ts
220
+ // payload.config.ts
221
+ import { buildConfig } from "payload";
222
+ import { commentsPlugin } from "@focus-reactive/payload-plugin-comments";
223
+
224
+ export default buildConfig({
225
+ plugins: [
226
+ commentsPlugin({
227
+ // Optional: customize which field is used as the document title in the UI
228
+ collections: [
229
+ { slug: "pages", titleField: "title" },
230
+ { slug: "products", titleField: "name" },
231
+ ],
232
+ }),
233
+ ],
234
+ // ... rest of your config
235
+ });
236
+ ```
237
+
238
+ ### 2. Import the styles
239
+
240
+ Add the plugin's stylesheet to your global CSS or admin layout:
241
+
242
+ ```css
243
+ /* global CSS */
244
+ @import "@focus-reactive/payload-plugin-comments/styles.css";
245
+ ```
246
+
247
+ Or import it in a layout/page file:
248
+
249
+ ```ts
250
+ import "@focus-reactive/payload-plugin-comments/styles.css";
251
+ ```
252
+
253
+ ### 3. Regenerate the import map
254
+
255
+ Payload needs its import map regenerated whenever you add or remove a plugin that registers admin components. Run:
256
+
257
+ ```bash
258
+ npx payload generate:importmap
259
+ ```
260
+
261
+ This command works regardless of your package manager (`npm`, `pnpm`, `yarn`, `bun`). Alternatively use the equivalent for your package manager:
262
+
263
+ ```bash
264
+ pnpm payload generate:importmap
265
+ # yarn payload generate:importmap
266
+ # bunx payload generate:importmap
267
+ ```
268
+
269
+ If you skip this step the plugin's admin components (comment badges, drawer, header button) will not appear in the Payload admin UI.
270
+
271
+ ### 4. Create and run a migration
272
+
273
+ The plugin adds a `comments` collection to your database. If you use a SQL adapter (PostgreSQL, SQLite), create and apply a migration:
274
+
275
+ ```bash
276
+ npx payload migrate:create create_comments
277
+ npx payload migrate
278
+ ```
279
+
280
+ Skip this step if you use the MongoDB adapter — Payload creates collections automatically.
281
+
282
+ ---
283
+
284
+ ## Configuration
285
+
286
+ The `commentsPlugin` factory accepts an optional `CommentsPluginConfig` object:
287
+
288
+ ```ts
289
+ commentsPlugin(config?: CommentsPluginConfig)
290
+ ```
291
+
292
+ ### `CommentsPluginConfig`
293
+
294
+ | Option | Type | Default | Description |
295
+ | ------------------- | --------------------- | -------- | ----------------------------------------------------------------------------------- |
296
+ | `collections` | `CollectionEntry[]` | — | UI metadata for collections (title field). All collections get comments regardless. |
297
+ | `enabled` | `boolean` | `true` | Set to `false` to disable the plugin entirely |
298
+ | `tenant` | `TenantPluginConfig` | — | Multi-tenancy settings (see below) |
299
+ | `overrides` | `CollectionOverrides` | — | Customize the generated `comments` collection |
300
+ | `translations` | `Translations` | — | Override UI strings per locale (see below) |
301
+ | `usernameFieldPath` | `string` | `"name"` | Dot-notation path to the display name field on the users collection |
302
+
303
+ ### `CollectionEntry`
304
+
305
+ Each entry in `collections` is an object that provides UI metadata for a specific collection:
306
+
307
+ ```ts
308
+ interface CollectionEntry {
309
+ slug: string;
310
+ titleField?: string; // Field used as document title in the UI. Default: "id"
311
+ }
312
+ ```
313
+
314
+ > **Note:** You do not need to list every collection. All collections (and all globals) automatically support comments. The `collections` array only sets display metadata like the title field.
315
+
316
+ **Examples:**
317
+
318
+ ```ts
319
+ commentsPlugin({
320
+ collections: [
321
+ { slug: "pages", titleField: "title" },
322
+ { slug: "products", titleField: "name" },
323
+ ],
324
+ });
325
+ ```
326
+
327
+ ### `usernameFieldPath`
328
+
329
+ Specifies which field on the `users` collection is used as the display name in comment UI and @mention autocomplete. Supports dot-notation for nested fields.
330
+
331
+ ```ts
332
+ commentsPlugin({
333
+ usernameFieldPath: "name", // default
334
+ // usernameFieldPath: "firstName",
335
+ // usernameFieldPath: "profile.displayName",
336
+ });
337
+ ```
338
+
339
+ ### `TenantPluginConfig`
340
+
341
+ Configure multi-tenancy when using `@payloadcms/plugin-multi-tenant`:
342
+
343
+ | Option | Type | Default | Description |
344
+ | --------------------- | --------- | ----------- | ------------------------------------------------------------- |
345
+ | `enabled` | `boolean` | `false` | Enable tenant scoping |
346
+ | `collectionSlug` | `string` | `"tenants"` | Slug of the tenants collection |
347
+ | `documentTenantField` | `string` | `"tenant"` | Field on document collections that holds the tenant reference |
348
+
349
+ **Example:**
350
+
351
+ ```ts
352
+ commentsPlugin({
353
+ tenant: {
354
+ enabled: true,
355
+ collectionSlug: "tenants",
356
+ documentTenantField: "tenant",
357
+ },
358
+ });
359
+ ```
360
+
361
+ ### Collection Overrides
362
+
363
+ Use `overrides` to customize the generated `comments` collection — for example, to extend access control or add custom fields:
364
+
365
+ ```ts
366
+ commentsPlugin({
367
+ overrides: {
368
+ access: {
369
+ // Override the default "authenticated only" access
370
+ },
371
+ fields: (defaultFields) => [...defaultFields],
372
+ hooks: {
373
+ afterChange: [
374
+ async ({ doc }) => {
375
+ console.log("Comment changed:", doc.id);
376
+ },
377
+ ],
378
+ },
379
+ },
380
+ });
381
+ ```
382
+
383
+ ---
384
+
385
+ ## Translations
386
+
387
+ Use `translations` to override any UI string for one or more locales. Each key is a locale code; the value is a partial object of the `CommentsTranslations` shape — keys you omit fall back to the built-in English defaults.
388
+
389
+ ```ts
390
+ commentsPlugin({
391
+ translations: {
392
+ fr: {
393
+ label: "Commentaires",
394
+ add: "Ajouter un commentaire",
395
+ writeComment: "Écrire un commentaire",
396
+ comment: "Commenter",
397
+ cancel: "Annuler",
398
+ resolve: "Résoudre",
399
+ reopen: "Rouvrir",
400
+ delete: "Supprimer",
401
+ filterOpen: "Ouverts",
402
+ filterResolved: "Résolus",
403
+ filterMentioned: "Me mentionnent",
404
+ },
405
+ },
406
+ });
407
+ ```
408
+
409
+ All translatable keys (with their English defaults):
410
+
411
+ | Key | Default (English) |
412
+ | --------------------- | ------------------------------ |
413
+ | `label` | `"Comments"` |
414
+ | `openComments_one` | `"{{count}} open comment"` |
415
+ | `openComments_other` | `"{{count}} open comments"` |
416
+ | `add` | `"Add comment"` |
417
+ | `writeComment` | `"Write a comment"` |
418
+ | `comment` | `"Comment"` |
419
+ | `cancel` | `"Cancel"` |
420
+ | `posting` | `"Posting…"` |
421
+ | `resolve` | `"Resolve"` |
422
+ | `reopen` | `"Reopen"` |
423
+ | `delete` | `"Delete"` |
424
+ | `general` | `"General"` |
425
+ | `close` | `"Close"` |
426
+ | `syncingComments` | `"Syncing comments"` |
427
+ | `openCommentsAria` | `"Open comments"` |
428
+ | `failedToPost` | `"Failed to post comment"` |
429
+ | `failedToUpdate` | `"Failed to update comment"` |
430
+ | `failedToDelete` | `"Failed to delete comment"` |
431
+ | `failedToAdd` | `"Failed to add comment"` |
432
+ | `unknownAuthor` | `"Unknown"` |
433
+ | `deletedUser` | `"Deleted user"` |
434
+ | `noOpenComments` | `"No open comments"` |
435
+ | `noResolvedComments` | `"No resolved comments"` |
436
+ | `noMentionedComments` | `"No comments mentioning you"` |
437
+ | `filterOpen` | `"Open"` |
438
+ | `filterResolved` | `"Resolved"` |
439
+ | `filterMentioned` | `"Mentioned me"` |
440
+ | `noMentionMatches` | `"No matches"` |
441
+
442
+ The `CommentsTranslations` type is exported from the package so you can type your translation objects:
443
+
444
+ ```ts
445
+ import type { CommentsTranslations } from "@focus-reactive/payload-plugin-comments";
446
+
447
+ const myTranslations: Record<string, Partial<CommentsTranslations>> = {
448
+ fr: { label: "Commentaires" },
449
+ de: { label: "Kommentare" },
450
+ };
451
+
452
+ commentsPlugin({ translations: myTranslations });
453
+ ```
454
+
455
+ ---
456
+
457
+ ## Environment Variables
458
+
459
+ ### Required for email notifications
460
+
461
+ | Variable | Description | Example |
462
+ | ------------------- | ---------------------------------------------- | ------------------------- |
463
+ | `RESEND_API_KEY` | Your Resend API key | `re_xxxxxxxxxxxxxxxx` |
464
+ | `RESEND_FROM_EMAIL` | Sender email address for mention notifications | `comments@yourdomain.com` |
465
+
466
+ If `RESEND_FROM_EMAIL` is not set, mention email notifications are silently skipped and an error is logged to the console.
467
+
468
+ **.env.local example:**
469
+
470
+ ```env
471
+ RESEND_API_KEY=re_xxxxxxxxxxxxxxxx
472
+ RESEND_FROM_EMAIL=comments@yourdomain.com
473
+ ```
474
+
475
+ ---
476
+
477
+ ## Architecture Overview
478
+
479
+ ### How It Works
480
+
481
+ **Plugin initialization** (`plugin.ts`):
482
+
483
+ 1. The plugin receives a `CommentsPluginConfig` and returns a standard Payload `Plugin` function.
484
+ 2. It creates a `comments` collection (hidden from the admin sidebar by default).
485
+ 3. It patches **every collection** to inject `FieldCommentLabel` into each field's admin label and registers an `afterDelete` hook that cascade-deletes comments when a document is removed.
486
+ 4. It patches **every global** to inject `FieldCommentLabel` into each field's admin label.
487
+ 5. It registers two admin providers (`CommentsProviderWrapper`, `GlobalCommentsLoader`) and one admin action (`CommentsHeaderButton`).
488
+
489
+ **Data loading** (`GlobalCommentsLoader`):
490
+
491
+ - This server component runs on every admin page load.
492
+ - It fetches all comments, document titles, mentionable users, field labels, collection labels, and global labels in parallel.
493
+ - Results are passed to `GlobalCommentsHydrator` (a client component) which hydrates the `CommentsContext`.
494
+
495
+ **State management** (`CommentsProvider`):
496
+
497
+ - Holds `allComments` in React state with optimistic updates via `useOptimistic`.
498
+ - `visibleComments` is derived: filtered to the current document/collection/global/locale based on the Next.js `pathname`.
499
+ - Exposes `addComment`, `removeComment`, `resolveComment`, and `syncComments` mutations.
500
+
501
+ **Field-level comments** (`FieldCommentLabel`):
502
+
503
+ - The plugin overrides the `Label` component for every named field in every configured collection and global.
504
+ - The label reads comments from context and filters by field path, showing a badge with the count.
505
+ - Clicking the badge opens the comments drawer pre-scrolled to that field's comment group.
506
+
507
+ **Comments collection schema:**
508
+
509
+ | Field | Type | Description |
510
+ | ---------------- | ----------------------- | ------------------------------------------------------------------ |
511
+ | `documentId` | number | ID of the document being commented on (null for globals) |
512
+ | `collectionSlug` | text | Slug of the collection (null for global comments) |
513
+ | `globalSlug` | text | Slug of the Payload global (null for collection document comments) |
514
+ | `fieldPath` | text | Dot-notation path of the field (null = document-level) |
515
+ | `locale` | text | Locale of the comment (null = shown in all locales) |
516
+ | `text` | textarea | Comment body (may contain `@(userId)` mention tokens) |
517
+ | `mentions` | array → relationship | Users mentioned in this comment |
518
+ | `author` | relationship → users | Comment author (set automatically) |
519
+ | `isResolved` | checkbox | Whether the comment is resolved |
520
+ | `resolvedBy` | relationship → users | Who resolved it |
521
+ | `resolvedAt` | date | When it was resolved |
522
+ | `tenant` | relationship (optional) | Tenant scope (when multi-tenancy is enabled) |
523
+
524
+ ---
525
+
526
+ ## Exports Reference
527
+
528
+ | Import path | Exports |
529
+ | ---------------------------------------------------- | -------------------------------------------------------------------------------------------------- |
530
+ | `@focus-reactive/payload-plugin-comments` | `commentsPlugin`, `CommentsPluginConfig` (type), `CommentsTranslations` (type), `setPayloadConfig` |
531
+ | `@focus-reactive/payload-plugin-comments/styles.css` | Plugin stylesheet (Tailwind-compiled CSS) |
532
+
533
+ ---
534
+
535
+ ## Available Scripts
536
+
537
+ Run these from the project root with `pnpm`:
538
+
539
+ | Command | Description |
540
+ | ------------------- | -------------------------------------------------------------- |
541
+ | `pnpm build` | Build the plugin to `dist/` (tsup + Tailwind CSS minification) |
542
+ | `pnpm dev` | Build in watch mode — rebuilds on file changes |
543
+ | `pnpm lint` | Run ESLint on `src/` |
544
+ | `pnpm lint:fix` | Run ESLint with auto-fix |
545
+ | `pnpm format` | Format `src/` with Prettier |
546
+ | `pnpm format:check` | Check formatting without writing |
547
+
548
+ ---
549
+
550
+ ## Contributing
551
+
552
+ 1. Fork the repository and create a feature branch.
553
+ 2. Install dependencies: `pnpm install`
554
+ 3. Start the build watcher: `pnpm dev`
555
+ 4. Make your changes in `src/`.
556
+ 5. Run `pnpm lint` and `pnpm format:check` before submitting.
557
+ 6. Open a pull request against `main`.
558
+
559
+ ---
560
+
561
+ ## License
562
+
563
+ MIT © [Focus Reactive](https://focusreactive.com/)
@@ -0,0 +1,3 @@
1
+ import type { Access } from "payload";
2
+ export declare const isAuth: Access;
3
+ //# sourceMappingURL=isAuth.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"isAuth.d.ts","sourceRoot":"","sources":["../../../src/collection/access/isAuth.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AAEtC,eAAO,MAAM,MAAM,EAAE,MAIpB,CAAC"}
@@ -0,0 +1,8 @@
1
+ const isAuth = ({ req: { user } }) => {
2
+ if (!user) return false;
3
+ return true;
4
+ };
5
+ export {
6
+ isAuth
7
+ };
8
+ //# sourceMappingURL=isAuth.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/collection/access/isAuth.ts"],"sourcesContent":["import type { Access } from \"payload\";\n\nexport const isAuth: Access = ({ req: { user } }) => {\n if (!user) return false;\n\n return true;\n};\n"],"mappings":"AAEO,MAAM,SAAiB,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM;AACnD,MAAI,CAAC,KAAM,QAAO;AAElB,SAAO;AACT;","names":[]}
@@ -0,0 +1,3 @@
1
+ import type { CollectionBeforeChangeHook } from "payload";
2
+ export declare const setAuthorBeforeCreate: CollectionBeforeChangeHook;
3
+ //# sourceMappingURL=setAuthorBeforeCreate.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"setAuthorBeforeCreate.d.ts","sourceRoot":"","sources":["../../../src/collection/hooks/setAuthorBeforeCreate.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,SAAS,CAAC;AAE1D,eAAO,MAAM,qBAAqB,EAAE,0BAMnC,CAAC"}
@@ -0,0 +1,10 @@
1
+ const setAuthorBeforeCreate = async ({ data, req, operation }) => {
2
+ if (operation === "create" && req.user && !data.author) {
3
+ data.author = req.user.id;
4
+ }
5
+ return data;
6
+ };
7
+ export {
8
+ setAuthorBeforeCreate
9
+ };
10
+ //# sourceMappingURL=setAuthorBeforeCreate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/collection/hooks/setAuthorBeforeCreate.ts"],"sourcesContent":["import type { CollectionBeforeChangeHook } from \"payload\";\n\nexport const setAuthorBeforeCreate: CollectionBeforeChangeHook = async ({ data, req, operation }) => {\n if (operation === \"create\" && req.user && !data.author) {\n data.author = req.user.id;\n }\n\n return data;\n};\n"],"mappings":"AAEO,MAAM,wBAAoD,OAAO,EAAE,MAAM,KAAK,UAAU,MAAM;AACnG,MAAI,cAAc,YAAY,IAAI,QAAQ,CAAC,KAAK,QAAQ;AACtD,SAAK,SAAS,IAAI,KAAK;AAAA,EACzB;AAEA,SAAO;AACT;","names":[]}
@@ -0,0 +1,3 @@
1
+ import type { CollectionBeforeChangeHook } from "payload";
2
+ export declare const setTenantBeforeCreate: CollectionBeforeChangeHook;
3
+ //# sourceMappingURL=setTenantBeforeCreate.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"setTenantBeforeCreate.d.ts","sourceRoot":"","sources":["../../../src/collection/hooks/setTenantBeforeCreate.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,0BAA0B,EAAkB,MAAM,SAAS,CAAC;AAG1E,eAAO,MAAM,qBAAqB,EAAE,0BAwBnC,CAAC"}
@@ -0,0 +1,24 @@
1
+ const setTenantBeforeCreate = async ({ data, req, operation }) => {
2
+ if (operation !== "create") return data;
3
+ const pluginConfig = req.payload.config.admin?.custom?.commentsPlugin;
4
+ const tenantConfig = pluginConfig?.tenant;
5
+ if (!tenantConfig?.enabled) return data;
6
+ const documentTenantField = tenantConfig.documentTenantField ?? "tenant";
7
+ try {
8
+ const doc = await req.payload.findByID({
9
+ collection: data.collectionSlug,
10
+ id: data.documentId,
11
+ depth: 0,
12
+ req
13
+ });
14
+ data.tenant = doc?.[documentTenantField] ?? null;
15
+ } catch (err) {
16
+ req.payload.logger.error({ err, msg: "setTenantBeforeCreate: failed to resolve tenant" });
17
+ data.tenant = null;
18
+ }
19
+ return data;
20
+ };
21
+ export {
22
+ setTenantBeforeCreate
23
+ };
24
+ //# sourceMappingURL=setTenantBeforeCreate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/collection/hooks/setTenantBeforeCreate.ts"],"sourcesContent":["import type { CollectionBeforeChangeHook, CollectionSlug } from \"payload\";\nimport type { CommentsPluginConfigStorage } from \"../../types\";\n\nexport const setTenantBeforeCreate: CollectionBeforeChangeHook = async ({ data, req, operation }) => {\n if (operation !== \"create\") return data;\n\n const pluginConfig = req.payload.config.admin?.custom?.commentsPlugin as CommentsPluginConfigStorage | undefined;\n\n const tenantConfig = pluginConfig?.tenant;\n if (!tenantConfig?.enabled) return data;\n\n const documentTenantField = tenantConfig.documentTenantField ?? \"tenant\";\n\n try {\n const doc = await req.payload.findByID({\n collection: data.collectionSlug as CollectionSlug,\n id: data.documentId as string | number,\n depth: 0,\n req,\n });\n data.tenant = (doc as unknown as Record<string, unknown>)?.[documentTenantField] ?? null;\n } catch (err) {\n req.payload.logger.error({ err, msg: \"setTenantBeforeCreate: failed to resolve tenant\" });\n data.tenant = null;\n }\n\n return data;\n};\n"],"mappings":"AAGO,MAAM,wBAAoD,OAAO,EAAE,MAAM,KAAK,UAAU,MAAM;AACnG,MAAI,cAAc,SAAU,QAAO;AAEnC,QAAM,eAAe,IAAI,QAAQ,OAAO,OAAO,QAAQ;AAEvD,QAAM,eAAe,cAAc;AACnC,MAAI,CAAC,cAAc,QAAS,QAAO;AAEnC,QAAM,sBAAsB,aAAa,uBAAuB;AAEhE,MAAI;AACF,UAAM,MAAM,MAAM,IAAI,QAAQ,SAAS;AAAA,MACrC,YAAY,KAAK;AAAA,MACjB,IAAI,KAAK;AAAA,MACT,OAAO;AAAA,MACP;AAAA,IACF,CAAC;AACD,SAAK,SAAU,MAA6C,mBAAmB,KAAK;AAAA,EACtF,SAAS,KAAK;AACZ,QAAI,QAAQ,OAAO,MAAM,EAAE,KAAK,KAAK,kDAAkD,CAAC;AACxF,SAAK,SAAS;AAAA,EAChB;AAEA,SAAO;AACT;","names":[]}
@@ -0,0 +1,4 @@
1
+ import type { CollectionConfig } from "payload";
2
+ import type { TenantPluginConfig } from "../types";
3
+ export declare const baseCollection: (tenantConfig?: TenantPluginConfig) => CollectionConfig;
4
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/collection/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAkB,MAAM,SAAS,CAAC;AAIhE,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,UAAU,CAAC;AAGnD,eAAO,MAAM,cAAc,kBAAmB,kBAAkB,KAAG,gBAoIjE,CAAC"}