@focus-reactive/payload-plugin-comments 1.1.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.
- package/README.md +562 -0
- package/dist/collection/access/isAuth.d.ts +3 -0
- package/dist/collection/access/isAuth.d.ts.map +1 -0
- package/dist/collection/access/isAuth.js +8 -0
- package/dist/collection/access/isAuth.js.map +1 -0
- package/dist/collection/hooks/setAuthorBeforeCreate.d.ts +3 -0
- package/dist/collection/hooks/setAuthorBeforeCreate.d.ts.map +1 -0
- package/dist/collection/hooks/setAuthorBeforeCreate.js +10 -0
- package/dist/collection/hooks/setAuthorBeforeCreate.js.map +1 -0
- package/dist/collection/hooks/setTenantBeforeCreate.d.ts +3 -0
- package/dist/collection/hooks/setTenantBeforeCreate.d.ts.map +1 -0
- package/dist/collection/hooks/setTenantBeforeCreate.js +24 -0
- package/dist/collection/hooks/setTenantBeforeCreate.js.map +1 -0
- package/dist/collection/index.d.ts +4 -0
- package/dist/collection/index.d.ts.map +1 -0
- package/dist/collection/index.js +139 -0
- package/dist/collection/index.js.map +1 -0
- package/dist/components/Avatar/index.d.ts +11 -0
- package/dist/components/Avatar/index.d.ts.map +1 -0
- package/dist/components/Avatar/index.js +11 -0
- package/dist/components/Avatar/index.js.map +1 -0
- package/dist/components/CommentEditor/ActionPanel.d.ts +8 -0
- package/dist/components/CommentEditor/ActionPanel.d.ts.map +1 -0
- package/dist/components/CommentEditor/ActionPanel.js +17 -0
- package/dist/components/CommentEditor/ActionPanel.js.map +1 -0
- package/dist/components/CommentEditor/index.d.ts +23 -0
- package/dist/components/CommentEditor/index.d.ts.map +1 -0
- package/dist/components/CommentEditor/index.js +265 -0
- package/dist/components/CommentEditor/index.js.map +1 -0
- package/dist/components/CommentItem/ToolsPanel.d.ts +9 -0
- package/dist/components/CommentItem/ToolsPanel.d.ts.map +1 -0
- package/dist/components/CommentItem/ToolsPanel.js +22 -0
- package/dist/components/CommentItem/ToolsPanel.js.map +1 -0
- package/dist/components/CommentItem/index.d.ts +8 -0
- package/dist/components/CommentItem/index.d.ts.map +1 -0
- package/dist/components/CommentItem/index.js +65 -0
- package/dist/components/CommentItem/index.js.map +1 -0
- package/dist/components/CommentsDrawer/components/Header.d.ts +6 -0
- package/dist/components/CommentsDrawer/components/Header.d.ts.map +1 -0
- package/dist/components/CommentsDrawer/components/Header.js +46 -0
- package/dist/components/CommentsDrawer/components/Header.js.map +1 -0
- package/dist/components/CommentsDrawer/index.d.ts +6 -0
- package/dist/components/CommentsDrawer/index.d.ts.map +1 -0
- package/dist/components/CommentsDrawer/index.js +30 -0
- package/dist/components/CommentsDrawer/index.js.map +1 -0
- package/dist/components/CommentsHeaderButton/index.d.ts +2 -0
- package/dist/components/CommentsHeaderButton/index.d.ts.map +1 -0
- package/dist/components/CommentsHeaderButton/index.js +19 -0
- package/dist/components/CommentsHeaderButton/index.js.map +1 -0
- package/dist/components/CommentsPanel/components/CollapsibleGroup.d.ts +10 -0
- package/dist/components/CommentsPanel/components/CollapsibleGroup.d.ts.map +1 -0
- package/dist/components/CommentsPanel/components/CollapsibleGroup.js +68 -0
- package/dist/components/CommentsPanel/components/CollapsibleGroup.js.map +1 -0
- package/dist/components/CommentsPanel/components/DocumentView.d.ts +9 -0
- package/dist/components/CommentsPanel/components/DocumentView.d.ts.map +1 -0
- package/dist/components/CommentsPanel/components/DocumentView.js +20 -0
- package/dist/components/CommentsPanel/components/DocumentView.js.map +1 -0
- package/dist/components/CommentsPanel/components/FieldGroupSection.d.ts +11 -0
- package/dist/components/CommentsPanel/components/FieldGroupSection.d.ts.map +1 -0
- package/dist/components/CommentsPanel/components/FieldGroupSection.js +62 -0
- package/dist/components/CommentsPanel/components/FieldGroupSection.js.map +1 -0
- package/dist/components/CommentsPanel/components/GlobalDocumentView.d.ts +9 -0
- package/dist/components/CommentsPanel/components/GlobalDocumentView.d.ts.map +1 -0
- package/dist/components/CommentsPanel/components/GlobalDocumentView.js +20 -0
- package/dist/components/CommentsPanel/components/GlobalDocumentView.js.map +1 -0
- package/dist/components/CommentsPanel/components/GlobalView.d.ts +9 -0
- package/dist/components/CommentsPanel/components/GlobalView.d.ts.map +1 -0
- package/dist/components/CommentsPanel/components/GlobalView.js +62 -0
- package/dist/components/CommentsPanel/components/GlobalView.js.map +1 -0
- package/dist/components/CommentsPanel/constants.d.ts +3 -0
- package/dist/components/CommentsPanel/constants.d.ts.map +1 -0
- package/dist/components/CommentsPanel/constants.js +9 -0
- package/dist/components/CommentsPanel/constants.js.map +1 -0
- package/dist/components/CommentsPanel/hooks/useCollapseState.d.ts +2 -0
- package/dist/components/CommentsPanel/hooks/useCollapseState.d.ts.map +1 -0
- package/dist/components/CommentsPanel/hooks/useCollapseState.js +44 -0
- package/dist/components/CommentsPanel/hooks/useCollapseState.js.map +1 -0
- package/dist/components/CommentsPanel/hooks/useScrollToTargetFieldGroup.d.ts +2 -0
- package/dist/components/CommentsPanel/hooks/useScrollToTargetFieldGroup.d.ts.map +1 -0
- package/dist/components/CommentsPanel/hooks/useScrollToTargetFieldGroup.js +35 -0
- package/dist/components/CommentsPanel/hooks/useScrollToTargetFieldGroup.js.map +1 -0
- package/dist/components/CommentsPanel/index.d.ts +6 -0
- package/dist/components/CommentsPanel/index.d.ts.map +1 -0
- package/dist/components/CommentsPanel/index.js +32 -0
- package/dist/components/CommentsPanel/index.js.map +1 -0
- package/dist/components/CommentsPanel/types.d.ts +4 -0
- package/dist/components/CommentsPanel/types.d.ts.map +1 -0
- package/dist/components/CommentsPanel/types.js +1 -0
- package/dist/components/CommentsPanel/types.js.map +1 -0
- package/dist/components/CommentsPanel/utils/createCollapsibleGroupKey.d.ts +10 -0
- package/dist/components/CommentsPanel/utils/createCollapsibleGroupKey.d.ts.map +1 -0
- package/dist/components/CommentsPanel/utils/createCollapsibleGroupKey.js +15 -0
- package/dist/components/CommentsPanel/utils/createCollapsibleGroupKey.js.map +1 -0
- package/dist/components/CommentsPanel/utils/filterComments.d.ts +9 -0
- package/dist/components/CommentsPanel/utils/filterComments.d.ts.map +1 -0
- package/dist/components/CommentsPanel/utils/filterComments.js +17 -0
- package/dist/components/CommentsPanel/utils/filterComments.js.map +1 -0
- package/dist/components/CommentsPanel/utils/groupCommentsByFieldPath.d.ts +4 -0
- package/dist/components/CommentsPanel/utils/groupCommentsByFieldPath.d.ts.map +1 -0
- package/dist/components/CommentsPanel/utils/groupCommentsByFieldPath.js +14 -0
- package/dist/components/CommentsPanel/utils/groupCommentsByFieldPath.js.map +1 -0
- package/dist/components/CommentsPanel/utils/groupCommentsGlobally.d.ts +18 -0
- package/dist/components/CommentsPanel/utils/groupCommentsGlobally.d.ts.map +1 -0
- package/dist/components/CommentsPanel/utils/groupCommentsGlobally.js +58 -0
- package/dist/components/CommentsPanel/utils/groupCommentsGlobally.js.map +1 -0
- package/dist/components/CommentsPanel/utils/resolveEntityLabel.d.ts +3 -0
- package/dist/components/CommentsPanel/utils/resolveEntityLabel.d.ts.map +1 -0
- package/dist/components/CommentsPanel/utils/resolveEntityLabel.js +14 -0
- package/dist/components/CommentsPanel/utils/resolveEntityLabel.js.map +1 -0
- package/dist/components/CommentsPanel/utils/resolveFieldLabel.d.ts +11 -0
- package/dist/components/CommentsPanel/utils/resolveFieldLabel.d.ts.map +1 -0
- package/dist/components/CommentsPanel/utils/resolveFieldLabel.js +9 -0
- package/dist/components/CommentsPanel/utils/resolveFieldLabel.js.map +1 -0
- package/dist/components/CommentsPanel/utils/sortGroupsByCreatedAt.d.ts +4 -0
- package/dist/components/CommentsPanel/utils/sortGroupsByCreatedAt.d.ts.map +1 -0
- package/dist/components/CommentsPanel/utils/sortGroupsByCreatedAt.js +11 -0
- package/dist/components/CommentsPanel/utils/sortGroupsByCreatedAt.js.map +1 -0
- package/dist/components/FieldCommentLabel/AddCommentPopup.d.ts +8 -0
- package/dist/components/FieldCommentLabel/AddCommentPopup.d.ts.map +1 -0
- package/dist/components/FieldCommentLabel/AddCommentPopup.js +50 -0
- package/dist/components/FieldCommentLabel/AddCommentPopup.js.map +1 -0
- package/dist/components/FieldCommentLabel/hooks/useStablePath.d.ts +2 -0
- package/dist/components/FieldCommentLabel/hooks/useStablePath.d.ts.map +1 -0
- package/dist/components/FieldCommentLabel/hooks/useStablePath.js +12 -0
- package/dist/components/FieldCommentLabel/hooks/useStablePath.js.map +1 -0
- package/dist/components/FieldCommentLabel/index.d.ts +11 -0
- package/dist/components/FieldCommentLabel/index.d.ts.map +1 -0
- package/dist/components/FieldCommentLabel/index.js +64 -0
- package/dist/components/FieldCommentLabel/index.js.map +1 -0
- package/dist/components/FieldCommentLabel/types.d.ts +4 -0
- package/dist/components/FieldCommentLabel/types.d.ts.map +1 -0
- package/dist/components/FieldCommentLabel/types.js +1 -0
- package/dist/components/FieldCommentLabel/types.js.map +1 -0
- package/dist/components/FieldCommentLabel/utils/buildStablePath.d.ts +2 -0
- package/dist/components/FieldCommentLabel/utils/buildStablePath.d.ts.map +1 -0
- package/dist/components/FieldCommentLabel/utils/buildStablePath.js +19 -0
- package/dist/components/FieldCommentLabel/utils/buildStablePath.js.map +1 -0
- package/dist/components/FieldCommentLabel/utils/exludeComments.d.ts +3 -0
- package/dist/components/FieldCommentLabel/utils/exludeComments.d.ts.map +1 -0
- package/dist/components/FieldCommentLabel/utils/exludeComments.js +12 -0
- package/dist/components/FieldCommentLabel/utils/exludeComments.js.map +1 -0
- package/dist/components/FieldCommentLabel/utils/resolveLabel.d.ts +3 -0
- package/dist/components/FieldCommentLabel/utils/resolveLabel.d.ts.map +1 -0
- package/dist/components/FieldCommentLabel/utils/resolveLabel.js +9 -0
- package/dist/components/FieldCommentLabel/utils/resolveLabel.js.map +1 -0
- package/dist/components/IconButton/index.d.ts +12 -0
- package/dist/components/IconButton/index.d.ts.map +1 -0
- package/dist/components/IconButton/index.js +38 -0
- package/dist/components/IconButton/index.js.map +1 -0
- package/dist/components/MentionDropdown.d.ts +11 -0
- package/dist/components/MentionDropdown.d.ts.map +1 -0
- package/dist/components/MentionDropdown.js +53 -0
- package/dist/components/MentionDropdown.js.map +1 -0
- package/dist/components/MentionLabel/index.d.ts +7 -0
- package/dist/components/MentionLabel/index.d.ts.map +1 -0
- package/dist/components/MentionLabel/index.js +21 -0
- package/dist/components/MentionLabel/index.js.map +1 -0
- package/dist/config.d.ts +4 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +17 -0
- package/dist/config.js.map +1 -0
- package/dist/constants.d.ts +9 -0
- package/dist/constants.d.ts.map +1 -0
- package/dist/constants.js +22 -0
- package/dist/constants.js.map +1 -0
- package/dist/hooks/useRelativeDate.d.ts +2 -0
- package/dist/hooks/useRelativeDate.d.ts.map +1 -0
- package/dist/hooks/useRelativeDate.js +11 -0
- package/dist/hooks/useRelativeDate.js.map +1 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +7 -0
- package/dist/index.js.map +1 -0
- package/dist/plugin.d.ts +4 -0
- package/dist/plugin.d.ts.map +1 -0
- package/dist/plugin.js +60 -0
- package/dist/plugin.js.map +1 -0
- package/dist/providers/CommentsDrawerProvider/index.d.ts +14 -0
- package/dist/providers/CommentsDrawerProvider/index.d.ts.map +1 -0
- package/dist/providers/CommentsDrawerProvider/index.js +28 -0
- package/dist/providers/CommentsDrawerProvider/index.js.map +1 -0
- package/dist/providers/CommentsProvider/index.d.ts +39 -0
- package/dist/providers/CommentsProvider/index.d.ts.map +1 -0
- package/dist/providers/CommentsProvider/index.js +237 -0
- package/dist/providers/CommentsProvider/index.js.map +1 -0
- package/dist/providers/CommentsProvider/mergeDocumentTitles.d.ts +3 -0
- package/dist/providers/CommentsProvider/mergeDocumentTitles.d.ts.map +1 -0
- package/dist/providers/CommentsProvider/mergeDocumentTitles.js +10 -0
- package/dist/providers/CommentsProvider/mergeDocumentTitles.js.map +1 -0
- package/dist/providers/CommentsProviderWrapper/index.d.ts +7 -0
- package/dist/providers/CommentsProviderWrapper/index.d.ts.map +1 -0
- package/dist/providers/CommentsProviderWrapper/index.js +16 -0
- package/dist/providers/CommentsProviderWrapper/index.js.map +1 -0
- package/dist/providers/GlobalCommentsLoader/GlobalCommentsHydrator.d.ts +13 -0
- package/dist/providers/GlobalCommentsLoader/GlobalCommentsHydrator.d.ts.map +1 -0
- package/dist/providers/GlobalCommentsLoader/GlobalCommentsHydrator.js +22 -0
- package/dist/providers/GlobalCommentsLoader/GlobalCommentsHydrator.js.map +1 -0
- package/dist/providers/GlobalCommentsLoader/index.d.ts +10 -0
- package/dist/providers/GlobalCommentsLoader/index.d.ts.map +1 -0
- package/dist/providers/GlobalCommentsLoader/index.js +31 -0
- package/dist/providers/GlobalCommentsLoader/index.js.map +1 -0
- package/dist/services/createComment.d.ts +12 -0
- package/dist/services/createComment.d.ts.map +1 -0
- package/dist/services/createComment.js +83 -0
- package/dist/services/createComment.js.map +1 -0
- package/dist/services/deleteComment.d.ts +3 -0
- package/dist/services/deleteComment.d.ts.map +1 -0
- package/dist/services/deleteComment.js +34 -0
- package/dist/services/deleteComment.js.map +1 -0
- package/dist/services/fetchMentionableUsers.d.ts +3 -0
- package/dist/services/fetchMentionableUsers.d.ts.map +1 -0
- package/dist/services/fetchMentionableUsers.js +46 -0
- package/dist/services/fetchMentionableUsers.js.map +1 -0
- package/dist/services/fieldLabels/fetchFieldLabels.d.ts +3 -0
- package/dist/services/fieldLabels/fetchFieldLabels.d.ts.map +1 -0
- package/dist/services/fieldLabels/fetchFieldLabels.js +74 -0
- package/dist/services/fieldLabels/fetchFieldLabels.js.map +1 -0
- package/dist/services/fieldLabels/utils/groupFieldPathsByDocument.d.ts +5 -0
- package/dist/services/fieldLabels/utils/groupFieldPathsByDocument.d.ts.map +1 -0
- package/dist/services/fieldLabels/utils/groupFieldPathsByDocument.js +21 -0
- package/dist/services/fieldLabels/utils/groupFieldPathsByDocument.js.map +1 -0
- package/dist/services/fieldLabels/utils/resolveFieldPath.d.ts +4 -0
- package/dist/services/fieldLabels/utils/resolveFieldPath.d.ts.map +1 -0
- package/dist/services/fieldLabels/utils/resolveFieldPath.js +66 -0
- package/dist/services/fieldLabels/utils/resolveFieldPath.js.map +1 -0
- package/dist/services/fieldLabels/utils/schemaUtils.d.ts +6 -0
- package/dist/services/fieldLabels/utils/schemaUtils.d.ts.map +1 -0
- package/dist/services/fieldLabels/utils/schemaUtils.js +60 -0
- package/dist/services/fieldLabels/utils/schemaUtils.js.map +1 -0
- package/dist/services/findAllComments.d.ts +11 -0
- package/dist/services/findAllComments.d.ts.map +1 -0
- package/dist/services/findAllComments.js +47 -0
- package/dist/services/findAllComments.js.map +1 -0
- package/dist/services/getCurrentTenantId.d.ts +3 -0
- package/dist/services/getCurrentTenantId.d.ts.map +1 -0
- package/dist/services/getCurrentTenantId.js +13 -0
- package/dist/services/getCurrentTenantId.js.map +1 -0
- package/dist/services/getDocumentTitles.d.ts +3 -0
- package/dist/services/getDocumentTitles.d.ts.map +1 -0
- package/dist/services/getDocumentTitles.js +61 -0
- package/dist/services/getDocumentTitles.js.map +1 -0
- package/dist/services/getEntitiesLabels.d.ts +3 -0
- package/dist/services/getEntitiesLabels.d.ts.map +1 -0
- package/dist/services/getEntitiesLabels.js +14 -0
- package/dist/services/getEntitiesLabels.js.map +1 -0
- package/dist/services/resolveComment.d.ts +3 -0
- package/dist/services/resolveComment.d.ts.map +1 -0
- package/dist/services/resolveComment.js +41 -0
- package/dist/services/resolveComment.js.map +1 -0
- package/dist/services/sendMentionEmails.d.ts +11 -0
- package/dist/services/sendMentionEmails.d.ts.map +1 -0
- package/dist/services/sendMentionEmails.js +73 -0
- package/dist/services/sendMentionEmails.js.map +1 -0
- package/dist/services/syncAllCommentsData.d.ts +12 -0
- package/dist/services/syncAllCommentsData.d.ts.map +1 -0
- package/dist/services/syncAllCommentsData.js +48 -0
- package/dist/services/syncAllCommentsData.js.map +1 -0
- package/dist/styles.css +2 -0
- package/dist/translations/en.d.ts +5 -0
- package/dist/translations/en.d.ts.map +1 -0
- package/dist/translations/en.js +36 -0
- package/dist/translations/en.js.map +1 -0
- package/dist/translations/types.d.ts +32 -0
- package/dist/translations/types.d.ts.map +1 -0
- package/dist/translations/types.js +1 -0
- package/dist/translations/types.js.map +1 -0
- package/dist/types/base.d.ts +10 -0
- package/dist/types/base.d.ts.map +1 -0
- package/dist/types/base.js +1 -0
- package/dist/types/base.js.map +1 -0
- package/dist/types/collection.d.ts +2 -0
- package/dist/types/collection.d.ts.map +1 -0
- package/dist/types/collection.js +1 -0
- package/dist/types/collection.js.map +1 -0
- package/dist/types/comment.d.ts +23 -0
- package/dist/types/comment.d.ts.map +1 -0
- package/dist/types/comment.js +1 -0
- package/dist/types/comment.js.map +1 -0
- package/dist/types/config.d.ts +112 -0
- package/dist/types/config.d.ts.map +1 -0
- package/dist/types/config.js +1 -0
- package/dist/types/config.js.map +1 -0
- package/dist/types/entity.d.ts +15 -0
- package/dist/types/entity.d.ts.map +1 -0
- package/dist/types/entity.js +1 -0
- package/dist/types/entity.js.map +1 -0
- package/dist/types/general.d.ts +10 -0
- package/dist/types/general.d.ts.map +1 -0
- package/dist/types/general.js +1 -0
- package/dist/types/general.js.map +1 -0
- package/dist/types/index.d.ts +8 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +1 -0
- package/dist/types/index.js.map +1 -0
- package/dist/types/user.d.ts +6 -0
- package/dist/types/user.d.ts.map +1 -0
- package/dist/types/user.js +1 -0
- package/dist/types/user.js.map +1 -0
- package/dist/utils/comment/extractVisibleComments.d.ts +13 -0
- package/dist/utils/comment/extractVisibleComments.d.ts.map +1 -0
- package/dist/utils/comment/extractVisibleComments.js +17 -0
- package/dist/utils/comment/extractVisibleComments.js.map +1 -0
- package/dist/utils/comment/filterCommentsByLocale.d.ts +3 -0
- package/dist/utils/comment/filterCommentsByLocale.d.ts.map +1 -0
- package/dist/utils/comment/filterCommentsByLocale.js +12 -0
- package/dist/utils/comment/filterCommentsByLocale.js.map +1 -0
- package/dist/utils/comment/renderCommentText.d.ts +12 -0
- package/dist/utils/comment/renderCommentText.d.ts.map +1 -0
- package/dist/utils/comment/renderCommentText.js +38 -0
- package/dist/utils/comment/renderCommentText.js.map +1 -0
- package/dist/utils/comment/serializeEditor.d.ts +2 -0
- package/dist/utils/comment/serializeEditor.d.ts.map +1 -0
- package/dist/utils/comment/serializeEditor.js +30 -0
- package/dist/utils/comment/serializeEditor.js.map +1 -0
- package/dist/utils/config/injectFieldCommentComponents.d.ts +4 -0
- package/dist/utils/config/injectFieldCommentComponents.d.ts.map +1 -0
- package/dist/utils/config/injectFieldCommentComponents.js +80 -0
- package/dist/utils/config/injectFieldCommentComponents.js.map +1 -0
- package/dist/utils/config/mergeTranslations.d.ts +3 -0
- package/dist/utils/config/mergeTranslations.d.ts.map +1 -0
- package/dist/utils/config/mergeTranslations.js +29 -0
- package/dist/utils/config/mergeTranslations.js.map +1 -0
- package/dist/utils/config/normalizeCollections.d.ts +7 -0
- package/dist/utils/config/normalizeCollections.d.ts.map +1 -0
- package/dist/utils/config/normalizeCollections.js +15 -0
- package/dist/utils/config/normalizeCollections.js.map +1 -0
- package/dist/utils/config/overrideCollections.d.ts +3 -0
- package/dist/utils/config/overrideCollections.d.ts.map +1 -0
- package/dist/utils/config/overrideCollections.js +38 -0
- package/dist/utils/config/overrideCollections.js.map +1 -0
- package/dist/utils/config/overrideCommentsCollection.d.ts +4 -0
- package/dist/utils/config/overrideCommentsCollection.d.ts.map +1 -0
- package/dist/utils/config/overrideCommentsCollection.js +14 -0
- package/dist/utils/config/overrideCommentsCollection.js.map +1 -0
- package/dist/utils/config/overrideGlobals.d.ts +3 -0
- package/dist/utils/config/overrideGlobals.d.ts.map +1 -0
- package/dist/utils/config/overrideGlobals.js +8 -0
- package/dist/utils/config/overrideGlobals.js.map +1 -0
- package/dist/utils/error/getDefaultErrorMessage.d.ts +2 -0
- package/dist/utils/error/getDefaultErrorMessage.d.ts.map +1 -0
- package/dist/utils/error/getDefaultErrorMessage.js +9 -0
- package/dist/utils/error/getDefaultErrorMessage.js.map +1 -0
- package/dist/utils/general/cn.d.ts +3 -0
- package/dist/utils/general/cn.d.ts.map +1 -0
- package/dist/utils/general/cn.js +9 -0
- package/dist/utils/general/cn.js.map +1 -0
- package/dist/utils/general/formatRelativeDate.d.ts +2 -0
- package/dist/utils/general/formatRelativeDate.d.ts.map +1 -0
- package/dist/utils/general/formatRelativeDate.js +28 -0
- package/dist/utils/general/formatRelativeDate.js.map +1 -0
- package/dist/utils/general/getURL.d.ts +2 -0
- package/dist/utils/general/getURL.d.ts.map +1 -0
- package/dist/utils/general/getURL.js +13 -0
- package/dist/utils/general/getURL.js.map +1 -0
- package/dist/utils/general/getValueByPath.d.ts +4 -0
- package/dist/utils/general/getValueByPath.d.ts.map +1 -0
- package/dist/utils/general/getValueByPath.js +19 -0
- package/dist/utils/general/getValueByPath.js.map +1 -0
- package/dist/utils/mention/isSelfMention.d.ts +4 -0
- package/dist/utils/mention/isSelfMention.d.ts.map +1 -0
- package/dist/utils/mention/isSelfMention.js +7 -0
- package/dist/utils/mention/isSelfMention.js.map +1 -0
- package/dist/utils/mention/parseMentionIds.d.ts +2 -0
- package/dist/utils/mention/parseMentionIds.d.ts.map +1 -0
- package/dist/utils/mention/parseMentionIds.js +13 -0
- package/dist/utils/mention/parseMentionIds.js.map +1 -0
- package/dist/utils/mode/defineModeByPathname.d.ts +11 -0
- package/dist/utils/mode/defineModeByPathname.d.ts.map +1 -0
- package/dist/utils/mode/defineModeByPathname.js +39 -0
- package/dist/utils/mode/defineModeByPathname.js.map +1 -0
- package/dist/utils/path/detectPluginBasePath.d.ts +2 -0
- package/dist/utils/path/detectPluginBasePath.d.ts.map +1 -0
- package/dist/utils/path/detectPluginBasePath.js +8 -0
- package/dist/utils/path/detectPluginBasePath.js.map +1 -0
- package/dist/utils/path/getComponentPath.d.ts +15 -0
- package/dist/utils/path/getComponentPath.d.ts.map +1 -0
- package/dist/utils/path/getComponentPath.js +22 -0
- package/dist/utils/path/getComponentPath.js.map +1 -0
- package/dist/utils/payload/extractPayload.d.ts +3 -0
- package/dist/utils/payload/extractPayload.d.ts.map +1 -0
- package/dist/utils/payload/extractPayload.js +9 -0
- package/dist/utils/payload/extractPayload.js.map +1 -0
- package/dist/utils/user/resolveUsername.d.ts +4 -0
- package/dist/utils/user/resolveUsername.d.ts.map +1 -0
- package/dist/utils/user/resolveUsername.js +14 -0
- package/dist/utils/user/resolveUsername.js.map +1 -0
- package/package.json +113 -0
package/README.md
ADDED
|
@@ -0,0 +1,562 @@
|
|
|
1
|
+
# @focus-reactive/payload-plugin-comments
|
|
2
|
+
|
|
3
|
+
[](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
|
+

|
|
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
|
+

|
|
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
|
+

|
|
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
|
+
|  |  |
|
|
169
|
+
|
|
170
|
+
---
|
|
171
|
+
|
|
172
|
+
## Features
|
|
173
|
+
|
|
174
|
+
- **Document-level comments** — Leave comments on any document in any collection or global
|
|
175
|
+
- **Field-level comments** — Comment directly on individual fields; the field label shows a badge with the comment count
|
|
176
|
+
- **Global support** — Field-level and document-level comments work on Payload Globals, not just collections
|
|
177
|
+
- **@mention users** — Mention other users in comments using `@name` autocomplete
|
|
178
|
+
- **Email notifications** — Mentioned users receive email notifications via [Resend](https://resend.com/)
|
|
179
|
+
- **Resolve comments** — Mark comments as resolved/unresolved; filter by open, resolved, or mentioned
|
|
180
|
+
- **Global comments panel** — A header button opens a drawer showing all comments across all documents and globals
|
|
181
|
+
- **Optimistic UI** — Comments appear instantly before the server confirms
|
|
182
|
+
- **Multi-tenancy** — Scope comments to tenants via `@payloadcms/plugin-multi-tenant`
|
|
183
|
+
- **Locale-aware** — Field-level comments are tied to a locale; document-level comments are shown in all locales
|
|
184
|
+
- **Auto-cleanup** — Comments are automatically deleted when their parent document is deleted
|
|
185
|
+
- **i18n / Translations** — All UI strings are translatable; ship your own locale overrides alongside the built-in English defaults
|
|
186
|
+
|
|
187
|
+
---
|
|
188
|
+
|
|
189
|
+
## Prerequisites
|
|
190
|
+
|
|
191
|
+
- Node.js 20 or higher
|
|
192
|
+
- A working [Payload CMS v3](https://payloadcms.com/docs/getting-started/installation) project with Next.js
|
|
193
|
+
- pnpm (recommended)
|
|
194
|
+
- A [Resend](https://resend.com/) account (required only for mention email notifications)
|
|
195
|
+
|
|
196
|
+
---
|
|
197
|
+
|
|
198
|
+
## Installation
|
|
199
|
+
|
|
200
|
+
```bash
|
|
201
|
+
pnpm add @focus-reactive/payload-plugin-comments
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
```bash
|
|
205
|
+
npm install @focus-reactive/payload-plugin-comments
|
|
206
|
+
# or
|
|
207
|
+
yarn add @focus-reactive/payload-plugin-comments
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
**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.
|
|
211
|
+
|
|
212
|
+
---
|
|
213
|
+
|
|
214
|
+
## Setup
|
|
215
|
+
|
|
216
|
+
### 1. Add the plugin to your Payload config
|
|
217
|
+
|
|
218
|
+
```ts
|
|
219
|
+
// payload.config.ts
|
|
220
|
+
import { buildConfig } from "payload";
|
|
221
|
+
import { commentsPlugin } from "@focus-reactive/payload-plugin-comments";
|
|
222
|
+
|
|
223
|
+
export default buildConfig({
|
|
224
|
+
plugins: [
|
|
225
|
+
commentsPlugin({
|
|
226
|
+
// Optional: customize which field is used as the document title in the UI
|
|
227
|
+
collections: [
|
|
228
|
+
{ slug: "pages", titleField: "title" },
|
|
229
|
+
{ slug: "products", titleField: "name" },
|
|
230
|
+
],
|
|
231
|
+
}),
|
|
232
|
+
],
|
|
233
|
+
// ... rest of your config
|
|
234
|
+
});
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
### 2. Import the styles
|
|
238
|
+
|
|
239
|
+
Add the plugin's stylesheet to your global CSS or admin layout:
|
|
240
|
+
|
|
241
|
+
```css
|
|
242
|
+
/* global CSS */
|
|
243
|
+
@import "@focus-reactive/payload-plugin-comments/styles.css";
|
|
244
|
+
```
|
|
245
|
+
|
|
246
|
+
Or import it in a layout/page file:
|
|
247
|
+
|
|
248
|
+
```ts
|
|
249
|
+
import "@focus-reactive/payload-plugin-comments/styles.css";
|
|
250
|
+
```
|
|
251
|
+
|
|
252
|
+
### 3. Regenerate the import map
|
|
253
|
+
|
|
254
|
+
Payload needs its import map regenerated whenever you add or remove a plugin that registers admin components. Run:
|
|
255
|
+
|
|
256
|
+
```bash
|
|
257
|
+
npx payload generate:importmap
|
|
258
|
+
```
|
|
259
|
+
|
|
260
|
+
This command works regardless of your package manager (`npm`, `pnpm`, `yarn`, `bun`). Alternatively use the equivalent for your package manager:
|
|
261
|
+
|
|
262
|
+
```bash
|
|
263
|
+
pnpm payload generate:importmap
|
|
264
|
+
# yarn payload generate:importmap
|
|
265
|
+
# bunx payload generate:importmap
|
|
266
|
+
```
|
|
267
|
+
|
|
268
|
+
If you skip this step the plugin's admin components (comment badges, drawer, header button) will not appear in the Payload admin UI.
|
|
269
|
+
|
|
270
|
+
### 4. Create and run a migration
|
|
271
|
+
|
|
272
|
+
The plugin adds a `comments` collection to your database. If you use a SQL adapter (PostgreSQL, SQLite), create and apply a migration:
|
|
273
|
+
|
|
274
|
+
```bash
|
|
275
|
+
npx payload migrate:create create_comments
|
|
276
|
+
npx payload migrate
|
|
277
|
+
```
|
|
278
|
+
|
|
279
|
+
Skip this step if you use the MongoDB adapter — Payload creates collections automatically.
|
|
280
|
+
|
|
281
|
+
---
|
|
282
|
+
|
|
283
|
+
## Configuration
|
|
284
|
+
|
|
285
|
+
The `commentsPlugin` factory accepts an optional `CommentsPluginConfig` object:
|
|
286
|
+
|
|
287
|
+
```ts
|
|
288
|
+
commentsPlugin(config?: CommentsPluginConfig)
|
|
289
|
+
```
|
|
290
|
+
|
|
291
|
+
### `CommentsPluginConfig`
|
|
292
|
+
|
|
293
|
+
| Option | Type | Default | Description |
|
|
294
|
+
| ------------------- | --------------------- | -------- | ----------------------------------------------------------------------------------- |
|
|
295
|
+
| `collections` | `CollectionEntry[]` | — | UI metadata for collections (title field). All collections get comments regardless. |
|
|
296
|
+
| `enabled` | `boolean` | `true` | Set to `false` to disable the plugin entirely |
|
|
297
|
+
| `tenant` | `TenantPluginConfig` | — | Multi-tenancy settings (see below) |
|
|
298
|
+
| `overrides` | `CollectionOverrides` | — | Customize the generated `comments` collection |
|
|
299
|
+
| `translations` | `Translations` | — | Override UI strings per locale (see below) |
|
|
300
|
+
| `usernameFieldPath` | `string` | `"name"` | Dot-notation path to the display name field on the users collection |
|
|
301
|
+
|
|
302
|
+
### `CollectionEntry`
|
|
303
|
+
|
|
304
|
+
Each entry in `collections` is an object that provides UI metadata for a specific collection:
|
|
305
|
+
|
|
306
|
+
```ts
|
|
307
|
+
interface CollectionEntry {
|
|
308
|
+
slug: string;
|
|
309
|
+
titleField?: string; // Field used as document title in the UI. Default: "id"
|
|
310
|
+
}
|
|
311
|
+
```
|
|
312
|
+
|
|
313
|
+
> **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.
|
|
314
|
+
|
|
315
|
+
**Examples:**
|
|
316
|
+
|
|
317
|
+
```ts
|
|
318
|
+
commentsPlugin({
|
|
319
|
+
collections: [
|
|
320
|
+
{ slug: "pages", titleField: "title" },
|
|
321
|
+
{ slug: "products", titleField: "name" },
|
|
322
|
+
],
|
|
323
|
+
});
|
|
324
|
+
```
|
|
325
|
+
|
|
326
|
+
### `usernameFieldPath`
|
|
327
|
+
|
|
328
|
+
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.
|
|
329
|
+
|
|
330
|
+
```ts
|
|
331
|
+
commentsPlugin({
|
|
332
|
+
usernameFieldPath: "name", // default
|
|
333
|
+
// usernameFieldPath: "firstName",
|
|
334
|
+
// usernameFieldPath: "profile.displayName",
|
|
335
|
+
});
|
|
336
|
+
```
|
|
337
|
+
|
|
338
|
+
### `TenantPluginConfig`
|
|
339
|
+
|
|
340
|
+
Configure multi-tenancy when using `@payloadcms/plugin-multi-tenant`:
|
|
341
|
+
|
|
342
|
+
| Option | Type | Default | Description |
|
|
343
|
+
| --------------------- | --------- | ----------- | ------------------------------------------------------------- |
|
|
344
|
+
| `enabled` | `boolean` | `false` | Enable tenant scoping |
|
|
345
|
+
| `collectionSlug` | `string` | `"tenants"` | Slug of the tenants collection |
|
|
346
|
+
| `documentTenantField` | `string` | `"tenant"` | Field on document collections that holds the tenant reference |
|
|
347
|
+
|
|
348
|
+
**Example:**
|
|
349
|
+
|
|
350
|
+
```ts
|
|
351
|
+
commentsPlugin({
|
|
352
|
+
tenant: {
|
|
353
|
+
enabled: true,
|
|
354
|
+
collectionSlug: "tenants",
|
|
355
|
+
documentTenantField: "tenant",
|
|
356
|
+
},
|
|
357
|
+
});
|
|
358
|
+
```
|
|
359
|
+
|
|
360
|
+
### Collection Overrides
|
|
361
|
+
|
|
362
|
+
Use `overrides` to customize the generated `comments` collection — for example, to extend access control or add custom fields:
|
|
363
|
+
|
|
364
|
+
```ts
|
|
365
|
+
commentsPlugin({
|
|
366
|
+
overrides: {
|
|
367
|
+
access: {
|
|
368
|
+
// Override the default "authenticated only" access
|
|
369
|
+
},
|
|
370
|
+
fields: (defaultFields) => [...defaultFields],
|
|
371
|
+
hooks: {
|
|
372
|
+
afterChange: [
|
|
373
|
+
async ({ doc }) => {
|
|
374
|
+
console.log("Comment changed:", doc.id);
|
|
375
|
+
},
|
|
376
|
+
],
|
|
377
|
+
},
|
|
378
|
+
},
|
|
379
|
+
});
|
|
380
|
+
```
|
|
381
|
+
|
|
382
|
+
---
|
|
383
|
+
|
|
384
|
+
## Translations
|
|
385
|
+
|
|
386
|
+
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.
|
|
387
|
+
|
|
388
|
+
```ts
|
|
389
|
+
commentsPlugin({
|
|
390
|
+
translations: {
|
|
391
|
+
fr: {
|
|
392
|
+
label: "Commentaires",
|
|
393
|
+
add: "Ajouter un commentaire",
|
|
394
|
+
writeComment: "Écrire un commentaire",
|
|
395
|
+
comment: "Commenter",
|
|
396
|
+
cancel: "Annuler",
|
|
397
|
+
resolve: "Résoudre",
|
|
398
|
+
reopen: "Rouvrir",
|
|
399
|
+
delete: "Supprimer",
|
|
400
|
+
filterOpen: "Ouverts",
|
|
401
|
+
filterResolved: "Résolus",
|
|
402
|
+
filterMentioned: "Me mentionnent",
|
|
403
|
+
},
|
|
404
|
+
},
|
|
405
|
+
});
|
|
406
|
+
```
|
|
407
|
+
|
|
408
|
+
All translatable keys (with their English defaults):
|
|
409
|
+
|
|
410
|
+
| Key | Default (English) |
|
|
411
|
+
| --------------------- | ------------------------------ |
|
|
412
|
+
| `label` | `"Comments"` |
|
|
413
|
+
| `openComments_one` | `"{{count}} open comment"` |
|
|
414
|
+
| `openComments_other` | `"{{count}} open comments"` |
|
|
415
|
+
| `add` | `"Add comment"` |
|
|
416
|
+
| `writeComment` | `"Write a comment"` |
|
|
417
|
+
| `comment` | `"Comment"` |
|
|
418
|
+
| `cancel` | `"Cancel"` |
|
|
419
|
+
| `posting` | `"Posting…"` |
|
|
420
|
+
| `resolve` | `"Resolve"` |
|
|
421
|
+
| `reopen` | `"Reopen"` |
|
|
422
|
+
| `delete` | `"Delete"` |
|
|
423
|
+
| `general` | `"General"` |
|
|
424
|
+
| `close` | `"Close"` |
|
|
425
|
+
| `syncingComments` | `"Syncing comments"` |
|
|
426
|
+
| `openCommentsAria` | `"Open comments"` |
|
|
427
|
+
| `failedToPost` | `"Failed to post comment"` |
|
|
428
|
+
| `failedToUpdate` | `"Failed to update comment"` |
|
|
429
|
+
| `failedToDelete` | `"Failed to delete comment"` |
|
|
430
|
+
| `failedToAdd` | `"Failed to add comment"` |
|
|
431
|
+
| `unknownAuthor` | `"Unknown"` |
|
|
432
|
+
| `deletedUser` | `"Deleted user"` |
|
|
433
|
+
| `noOpenComments` | `"No open comments"` |
|
|
434
|
+
| `noResolvedComments` | `"No resolved comments"` |
|
|
435
|
+
| `noMentionedComments` | `"No comments mentioning you"` |
|
|
436
|
+
| `filterOpen` | `"Open"` |
|
|
437
|
+
| `filterResolved` | `"Resolved"` |
|
|
438
|
+
| `filterMentioned` | `"Mentioned me"` |
|
|
439
|
+
| `noMentionMatches` | `"No matches"` |
|
|
440
|
+
|
|
441
|
+
The `CommentsTranslations` type is exported from the package so you can type your translation objects:
|
|
442
|
+
|
|
443
|
+
```ts
|
|
444
|
+
import type { CommentsTranslations } from "@focus-reactive/payload-plugin-comments";
|
|
445
|
+
|
|
446
|
+
const myTranslations: Record<string, Partial<CommentsTranslations>> = {
|
|
447
|
+
fr: { label: "Commentaires" },
|
|
448
|
+
de: { label: "Kommentare" },
|
|
449
|
+
};
|
|
450
|
+
|
|
451
|
+
commentsPlugin({ translations: myTranslations });
|
|
452
|
+
```
|
|
453
|
+
|
|
454
|
+
---
|
|
455
|
+
|
|
456
|
+
## Environment Variables
|
|
457
|
+
|
|
458
|
+
### Required for email notifications
|
|
459
|
+
|
|
460
|
+
| Variable | Description | Example |
|
|
461
|
+
| ------------------- | ---------------------------------------------- | ------------------------- |
|
|
462
|
+
| `RESEND_API_KEY` | Your Resend API key | `re_xxxxxxxxxxxxxxxx` |
|
|
463
|
+
| `RESEND_FROM_EMAIL` | Sender email address for mention notifications | `comments@yourdomain.com` |
|
|
464
|
+
|
|
465
|
+
If `RESEND_FROM_EMAIL` is not set, mention email notifications are silently skipped and an error is logged to the console.
|
|
466
|
+
|
|
467
|
+
**.env.local example:**
|
|
468
|
+
|
|
469
|
+
```env
|
|
470
|
+
RESEND_API_KEY=re_xxxxxxxxxxxxxxxx
|
|
471
|
+
RESEND_FROM_EMAIL=comments@yourdomain.com
|
|
472
|
+
```
|
|
473
|
+
|
|
474
|
+
---
|
|
475
|
+
|
|
476
|
+
## Architecture Overview
|
|
477
|
+
|
|
478
|
+
### How It Works
|
|
479
|
+
|
|
480
|
+
**Plugin initialization** (`plugin.ts`):
|
|
481
|
+
|
|
482
|
+
1. The plugin receives a `CommentsPluginConfig` and returns a standard Payload `Plugin` function.
|
|
483
|
+
2. It creates a `comments` collection (hidden from the admin sidebar by default).
|
|
484
|
+
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.
|
|
485
|
+
4. It patches **every global** to inject `FieldCommentLabel` into each field's admin label.
|
|
486
|
+
5. It registers two admin providers (`CommentsProviderWrapper`, `GlobalCommentsLoader`) and one admin action (`CommentsHeaderButton`).
|
|
487
|
+
|
|
488
|
+
**Data loading** (`GlobalCommentsLoader`):
|
|
489
|
+
|
|
490
|
+
- This server component runs on every admin page load.
|
|
491
|
+
- It fetches all comments, document titles, mentionable users, field labels, collection labels, and global labels in parallel.
|
|
492
|
+
- Results are passed to `GlobalCommentsHydrator` (a client component) which hydrates the `CommentsContext`.
|
|
493
|
+
|
|
494
|
+
**State management** (`CommentsProvider`):
|
|
495
|
+
|
|
496
|
+
- Holds `allComments` in React state with optimistic updates via `useOptimistic`.
|
|
497
|
+
- `visibleComments` is derived: filtered to the current document/collection/global/locale based on the Next.js `pathname`.
|
|
498
|
+
- Exposes `addComment`, `removeComment`, `resolveComment`, and `syncComments` mutations.
|
|
499
|
+
|
|
500
|
+
**Field-level comments** (`FieldCommentLabel`):
|
|
501
|
+
|
|
502
|
+
- The plugin overrides the `Label` component for every named field in every configured collection and global.
|
|
503
|
+
- The label reads comments from context and filters by field path, showing a badge with the count.
|
|
504
|
+
- Clicking the badge opens the comments drawer pre-scrolled to that field's comment group.
|
|
505
|
+
|
|
506
|
+
**Comments collection schema:**
|
|
507
|
+
|
|
508
|
+
| Field | Type | Description |
|
|
509
|
+
| ---------------- | ----------------------- | ------------------------------------------------------------------ |
|
|
510
|
+
| `documentId` | number | ID of the document being commented on (null for globals) |
|
|
511
|
+
| `collectionSlug` | text | Slug of the collection (null for global comments) |
|
|
512
|
+
| `globalSlug` | text | Slug of the Payload global (null for collection document comments) |
|
|
513
|
+
| `fieldPath` | text | Dot-notation path of the field (null = document-level) |
|
|
514
|
+
| `locale` | text | Locale of the comment (null = shown in all locales) |
|
|
515
|
+
| `text` | textarea | Comment body (may contain `@(userId)` mention tokens) |
|
|
516
|
+
| `mentions` | array → relationship | Users mentioned in this comment |
|
|
517
|
+
| `author` | relationship → users | Comment author (set automatically) |
|
|
518
|
+
| `isResolved` | checkbox | Whether the comment is resolved |
|
|
519
|
+
| `resolvedBy` | relationship → users | Who resolved it |
|
|
520
|
+
| `resolvedAt` | date | When it was resolved |
|
|
521
|
+
| `tenant` | relationship (optional) | Tenant scope (when multi-tenancy is enabled) |
|
|
522
|
+
|
|
523
|
+
---
|
|
524
|
+
|
|
525
|
+
## Exports Reference
|
|
526
|
+
|
|
527
|
+
| Import path | Exports |
|
|
528
|
+
| ---------------------------------------------------- | -------------------------------------------------------------------------------------------------- |
|
|
529
|
+
| `@focus-reactive/payload-plugin-comments` | `commentsPlugin`, `CommentsPluginConfig` (type), `CommentsTranslations` (type), `setPayloadConfig` |
|
|
530
|
+
| `@focus-reactive/payload-plugin-comments/styles.css` | Plugin stylesheet (Tailwind-compiled CSS) |
|
|
531
|
+
|
|
532
|
+
---
|
|
533
|
+
|
|
534
|
+
## Available Scripts
|
|
535
|
+
|
|
536
|
+
Run these from the project root with `pnpm`:
|
|
537
|
+
|
|
538
|
+
| Command | Description |
|
|
539
|
+
| ------------------- | -------------------------------------------------------------- |
|
|
540
|
+
| `pnpm build` | Build the plugin to `dist/` (tsup + Tailwind CSS minification) |
|
|
541
|
+
| `pnpm dev` | Build in watch mode — rebuilds on file changes |
|
|
542
|
+
| `pnpm lint` | Run ESLint on `src/` |
|
|
543
|
+
| `pnpm lint:fix` | Run ESLint with auto-fix |
|
|
544
|
+
| `pnpm format` | Format `src/` with Prettier |
|
|
545
|
+
| `pnpm format:check` | Check formatting without writing |
|
|
546
|
+
|
|
547
|
+
---
|
|
548
|
+
|
|
549
|
+
## Contributing
|
|
550
|
+
|
|
551
|
+
1. Fork the repository and create a feature branch.
|
|
552
|
+
2. Install dependencies: `pnpm install`
|
|
553
|
+
3. Start the build watcher: `pnpm dev`
|
|
554
|
+
4. Make your changes in `src/`.
|
|
555
|
+
5. Run `pnpm lint` and `pnpm format:check` before submitting.
|
|
556
|
+
6. Open a pull request against `main`.
|
|
557
|
+
|
|
558
|
+
---
|
|
559
|
+
|
|
560
|
+
## License
|
|
561
|
+
|
|
562
|
+
MIT © [Focus Reactive](https://focusreactive.com/)
|
|
@@ -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 @@
|
|
|
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 @@
|
|
|
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 @@
|
|
|
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 @@
|
|
|
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"}
|