diff --git a/packages/superdoc/src/components/CommentsLayer/CommentDialog.vue b/packages/superdoc/src/components/CommentsLayer/CommentDialog.vue
index 9e8505d1ba..690df3dc79 100644
--- a/packages/superdoc/src/components/CommentsLayer/CommentDialog.vue
+++ b/packages/superdoc/src/components/CommentsLayer/CommentDialog.vue
@@ -101,28 +101,6 @@ const isInternalDropdownDisabled = computed(() => {
return getConfig.value.readOnly;
});
-const overflowOptions = [
- { label: 'Edit', key: 'edit' },
- { label: 'Delete', key: 'delete' },
-];
-
-const showOverflow = computed(() => (comment) => {
- if (!!props.comment.resolvedTime) return [];
- if (getConfig.value.readOnly) return [];
- if (!getConfig.value.overflow) return [];
- if (comment.trackedChange) return [];
-
- const isOwnComment = comment.creatorEmail === superdocStore.user.email;
- if (isOwnComment) return isAllowed(PERMISSIONS.COMMENTS_OVERFLOW_OWN, role, isInternal);
- return isAllowed(PERMISSIONS.COMMENTS_OVERFLOW_OTHER, role, isInternal);
-});
-
-const getOverflowOptions = (comment) => {
- const isOwnComment = comment.creatorEmail === superdocStore.user.email;
- if (!isOwnComment) return overflowOptions.filter((o) => o.key !== 'delete');
- return overflowOptions;
-};
-
const isEditingThisComment = computed(() => (comment) => {
return isEditing.value === comment.commentId;
});
@@ -308,12 +286,10 @@ onMounted(() => {
{
if (!props.comment) return false;
if (props.comment.resolvedTime) return false;
if (commentsStore.pendingComment) return false;
- if (props.comment.parentCommentId) return false;
if (props.isPendingInput) return false;
return true;
});
@@ -69,8 +69,8 @@ const allowReject = computed(() => {
const allowOverflow = computed(() => {
if (!generallyAllowed.value) return false;
if (props.comment.trackedChange) return false;
- if (!props.overflowOptions || !props.overflowOptions.length) return false;
if (props.isPendingInput) return false;
+ if (getOverflowOptions.value.length === 0) return false;
return true;
});
@@ -78,10 +78,24 @@ const allowOverflow = computed(() => {
const getOverflowOptions = computed(() => {
if (!generallyAllowed.value) return false;
- if (!props.comment.creatorEmail !== proxy.$superdoc.config.user.email) {
- return props.overflowOptions.filter((option) => option.key !== 'edit');
- }
- return props.overflowOptions;
+ const allowedOptions = [];
+ const options = new Set();
+
+ // Only the comment creator can edit
+ if (props.comment.creatorEmail === proxy.$superdoc.config.user.email) {
+ options.add('edit');
+ };
+
+ const isOwnComment = props.comment.creatorEmail === proxy.$superdoc.config.user.email;
+
+ if (isOwnComment && isAllowed(PERMISSIONS.COMMENTS_DELETE_OWN, role, isInternal)) {
+ options.add('delete');
+ } else if (!isOwnComment && isAllowed(PERMISSIONS.COMMENTS_DELETE_OTHER, role, isInternal)) {
+ options.add('delete');
+ };
+
+ options.forEach((option) => allowedOptions.push(OVERFLOW_OPTIONS[option]));
+ return allowedOptions;
});
const handleResolve = () => emit('resolve');
diff --git a/packages/superdoc/src/core/collaboration/helpers.js b/packages/superdoc/src/core/collaboration/helpers.js
index f4895bccc1..a711f704e0 100644
--- a/packages/superdoc/src/core/collaboration/helpers.js
+++ b/packages/superdoc/src/core/collaboration/helpers.js
@@ -27,9 +27,20 @@ export const initCollaborationComments = (superdoc) => {
if (currentUser.name === user.name && currentUser.email === user.email) return;
+ if (__IS_DEBUG__) console.debug('[initCollaborationComments] commentsArray.observe', commentsArray.toJSON());
+
// Update conversations
const comments = commentsArray.toJSON();
- superdoc.commentsStore.commentsList = comments.map((c) => useComment(c));
+
+ const seen = new Set();
+ const filtered = [];
+ comments.forEach((c) =>{
+ if (!seen.has(c.commentId)) {
+ seen.add(c.commentId);
+ filtered.push(c);
+ };
+ });
+ superdoc.commentsStore.commentsList = filtered.map((c) => useComment(c));
});
};
diff --git a/packages/superdoc/src/core/collaboration/permissions.js b/packages/superdoc/src/core/collaboration/permissions.js
index 4a3db24395..d541103d7b 100644
--- a/packages/superdoc/src/core/collaboration/permissions.js
+++ b/packages/superdoc/src/core/collaboration/permissions.js
@@ -5,6 +5,8 @@ export const PERMISSIONS = Object.freeze({
REJECT_OTHER: 'REJECT_OTHER',
COMMENTS_OVERFLOW_OWN: 'COMMENTS_OVERFLOW',
COMMENTS_OVERFLOW_OTHER: 'COMMENTS_OVERFLOW_OTHER',
+ COMMENTS_DELETE_OWN: 'COMMENTS_DELETE_OWN',
+ COMMENTS_DELETE_OTHER: 'COMMENTS_DELETE_OTHER',
UPLOAD_VERSION: 'UPLOAD_VERSION',
VERSION_HISTORY: 'VERSION_HISTORY',
});
@@ -17,8 +19,8 @@ const ROLES = Object.freeze({
const permissions = Object.freeze({
[PERMISSIONS.RESOLVE_OWN]: {
- internal: [ROLES.EDITOR, ROLES.SUGGESTER],
- external: [ROLES.EDITOR, ROLES.SUGGESTER],
+ internal: [ROLES.EDITOR],
+ external: [ROLES.EDITOR],
},
[PERMISSIONS.RESOLVE_OTHER]: {
internal: [ROLES.EDITOR],
@@ -40,6 +42,14 @@ const permissions = Object.freeze({
internal: [ROLES.EDITOR],
external: [],
},
+ [PERMISSIONS.COMMENTS_DELETE_OWN]: {
+ internal: [ROLES.EDITOR, ROLES.SUGGESTER],
+ external: [ROLES.EDITOR, ROLES.SUGGESTER],
+ },
+ [PERMISSIONS.COMMENTS_DELETE_OTHER]: {
+ internal: [ROLES.EDITOR],
+ external: [],
+ },
[PERMISSIONS.UPLOAD_VERSION]: {
internal: [ROLES.EDITOR],
external: [],
diff --git a/packages/superdoc/src/stores/comments-store.js b/packages/superdoc/src/stores/comments-store.js
index a9e3e8b859..b113ba36f2 100644
--- a/packages/superdoc/src/stores/comments-store.js
+++ b/packages/superdoc/src/stores/comments-store.js
@@ -423,6 +423,7 @@ export const useCommentsStore = defineStore('comments', () => {
};
if (__IS_DEBUG__) console.debug('[deleteComment] emitting...', event);
+ superdoc.emit('comments-update', event);
syncCommentsToClients(superdoc, event);
}
@@ -449,6 +450,8 @@ export const useCommentsStore = defineStore('comments', () => {
const processLoadedDocxComments = ({ superdoc, comments, documentId }) => {
const document = superdocStore.getDocument(documentId);
+ if (__IS_DEBUG__) console.debug('[processLoadedDocxComments] processing comments...', comments);
+
comments.forEach((comment) => {
const importedName = `${comment.creatorName.replace('(imported)', '')} (imported)`
const newComment = useComment({