Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -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;
});
Expand Down Expand Up @@ -308,12 +286,10 @@ onMounted(() => {
<!-- Comments and their threaded (sub) comments are rendered here -->
<div v-for="(comment, index) in comments" :key="index" class="conversation-item">
<CommentHeader
v-if="showOverflow(comment)"
:user="getCommentUser(comment)"
:config="getConfig"
:timestamp="getProcessedDate(comment.createdTime)"
:comment="comment"
:overflow-options="getOverflowOptions(comment)"
@resolve="handleResolve"
@reject="handleReject"
@overflow-select="handleOverflowSelect($event, comment)"
Expand Down
34 changes: 24 additions & 10 deletions packages/superdoc/src/components/CommentsLayer/CommentHeader.vue
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,6 @@ const props = defineProps({
type: Object,
required: true,
},
overflowOptions: {
type: Array,
required: false,
},
comment: {
type: Object,
required: false,
Expand All @@ -42,11 +38,15 @@ const role = proxy.$superdoc.config.role;
const isInternal = proxy.$superdoc.config.isInternal;
const isOwnComment = props.comment.creatorEmail === proxy.$superdoc.config.user.email;

const OVERFLOW_OPTIONS = Object.freeze({
edit: { label: 'Edit', key: 'edit' },
delete: { label: 'Delete', key: 'delete' },
});

const generallyAllowed = computed(() => {
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;
});
Expand All @@ -69,19 +69,33 @@ 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;
});

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');
Expand Down
13 changes: 12 additions & 1 deletion packages/superdoc/src/core/collaboration/helpers.js
Original file line number Diff line number Diff line change
Expand Up @@ -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));
});
};

Expand Down
14 changes: 12 additions & 2 deletions packages/superdoc/src/core/collaboration/permissions.js
Original file line number Diff line number Diff line change
Expand Up @@ -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',
});
Expand All @@ -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],
Expand All @@ -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: [],
Expand Down
3 changes: 3 additions & 0 deletions packages/superdoc/src/stores/comments-store.js
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}

Expand All @@ -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({
Expand Down