+
@@ -213,7 +226,8 @@ onBeforeUnmount(() => {
/* Right sidebar drawer */
.right-sidebar {
width: 320px;
- padding: 10px;
+ padding: 0 10px;
+ min-height: 100%;
position: relative;
}
@@ -244,7 +258,6 @@ onBeforeUnmount(() => {
}
.layers {
position: relative;
- display: inline-block;
}
/* Document Styles */
@@ -298,4 +311,15 @@ onBeforeUnmount(() => {
background-color: #DBDBDB;
}
+@media (max-width: 768px) {
+ .sub-document {
+ max-width: 100%;
+ overflow: hidden;
+ }
+ .right-sidebar {
+ padding: 10px;
+ width: 55px;
+ position: relative;
+ }
+}
diff --git a/packages/superdoc/src/assets/test-data.js b/packages/superdoc/src/assets/test-data.js
index c99c5725d5..18f2e25e8a 100644
--- a/packages/superdoc/src/assets/test-data.js
+++ b/packages/superdoc/src/assets/test-data.js
@@ -540,8 +540,9 @@ export const fields = [
}
]
-export const conversations = [{
- "conversationId": "384db7b4-d95c-478e-bd3e-03bacaed6fc5",
+export const conversations = [
+ {
+ "conversationId": "convo-1",
"documentId": "456",
"creatorEmail": "nick@harbourshare.com",
"creatorName": "Nick Bernal",
@@ -567,8 +568,45 @@ export const conversations = [{
},
"markedDone": null,
"isFocused": true
-},{
- "conversationId": "384db7b4-d95c-478e-bd3e-ABC",
+},
+{
+ "conversationId": "convo-2",
+ "documentId": "456",
+ "creatorEmail": "nick@harbourshare.com",
+ "creatorName": "Nick Bernal",
+ "comments": [
+ {
+ "comment": "initial top COMMENT",
+ "user": {
+ "name": "Nick Bernal",
+ "email": "nick@harbourshare.com"
+ },
+ "timestamp": "2024-05-31T19:18:25.522Z"
+ },
+ {
+ "comment": "comment in thread",
+ "user": {
+ "name": "Nick Bernal",
+ "email": "nick@harbourshare.com"
+ },
+ "timestamp": "2024-05-31T19:20:25.522Z"
+ }
+ ],
+ "selection": {
+ "documentId": "456",
+ "page": "1",
+ "selectionBounds": {
+ "top": 0.296875,
+ "left": 500.91461181640625,
+ "bottom": 200.296875,
+ "right": 550.99163818359375
+ }
+ },
+ "markedDone": null,
+ "isFocused": true
+ },
+ {
+ "conversationId": "convo-3",
"documentId": "456",
"creatorEmail": "nick@harbourshare.com",
"creatorName": "Nick Bernal",
@@ -594,7 +632,36 @@ export const conversations = [{
},
"markedDone": null,
"isFocused": true
- }]
+ },
+ {
+ "conversationId": "convo-4-page2",
+ "documentId": "456",
+ "creatorEmail": "nick@harbourshare.com",
+ "creatorName": "Nick Bernal",
+ "comments": [
+ {
+ "comment": "pg1 - 1",
+ "user": {
+ "name": "Nick Bernal",
+ "email": "nick@harbourshare.com"
+ },
+ "timestamp": "2024-05-31T19:18:25.522Z"
+ }
+ ],
+ "selection": {
+ "documentId": "456",
+ "page": "2",
+ "selectionBounds": {
+ "top": 105.296875,
+ "left": 413.91461181640625,
+ "bottom": 125.296875,
+ "right": 487.99163818359375
+ }
+ },
+ "markedDone": null,
+ "isFocused": true
+ },
+]
export const annotations = [
diff --git a/packages/superdoc/src/components/CommentsLayer/CommentDialog.vue b/packages/superdoc/src/components/CommentsLayer/CommentDialog.vue
index b0c551b7f3..ea1574854f 100644
--- a/packages/superdoc/src/components/CommentsLayer/CommentDialog.vue
+++ b/packages/superdoc/src/components/CommentsLayer/CommentDialog.vue
@@ -3,17 +3,18 @@ import { computed, toRefs, ref, getCurrentInstance, onMounted } from 'vue';
import { storeToRefs } from 'pinia';
import { useCommentsStore } from '@/stores/comments-store';
import { useSuperdocStore } from '@/stores/superdoc-store';
+import useSelection from '@/helpers/use-selection';
import useComment from '@/components/CommentsLayer/use-comment';
import Avatar from '@/components/general/Avatar.vue';
const superdocStore = useSuperdocStore();
const commentsStore = useCommentsStore();
-const { COMMENT_EVENTS, getCommentLocation, checkOverlaps } = commentsStore;
-const { getConfig, activeComment, overlappingComments } = storeToRefs(commentsStore);
+const { COMMENT_EVENTS } = commentsStore;
+const { getConfig, activeComment, pendingComment, floatingCommentsOffset } = storeToRefs(commentsStore);
const { areDocumentsReady } = superdocStore;
+const { selectionPosition } = storeToRefs(superdocStore);
const { proxy } = getCurrentInstance();
-const emit = defineEmits(['click-outside']);
const props = defineProps({
user: {
type: Object,
@@ -31,19 +32,16 @@ const props = defineProps({
type: Object,
required: true,
},
- showGrouped: {
- type: Boolean,
- required: false,
- default: false,
- },
});
+const emit = defineEmits(['click-outside', 'ready', 'dialog-exit']);
const currentElement = ref(null);
const inputIsFocused = ref(false);
const input = ref(null);
const addComment = () => {
if (!input.value?.value) return;
+ // create the new comment for the conversation
const comment = useComment({
user: {
email: props.user.email,
@@ -53,10 +51,38 @@ const addComment = () => {
comment: input.value.value,
});
- props.data.comments.push(comment);
+ // If this conversation is pending addition, add to the document first
+ if (pendingComment.value && pendingComment.value.conversationId === props.data.conversationId) {
+ const newConversation = { ...pendingComment.value }
+
+ const selection = pendingComment.value.selection.getValues();
+ const bounds = selection.selectionBounds;
+ if (bounds.top > bounds.bottom) {
+ const temp = bounds.top;
+ bounds.top = bounds.bottom;
+ bounds.bottom = temp;
+ }
+ if (bounds.left > bounds.right) {
+ const temp = bounds.left;
+ bounds.left = bounds.right;
+ bounds.right = temp;
+ }
+ newConversation.selection = useSelection(selection)
+
+ // Remove the pending comment
+ pendingComment.value = null;
+
+ // Reset the original selection
+ selectionPosition.value = null;
+ newConversation.comments.push(comment);
+ props.currentDocument.conversations.push(newConversation);
+ proxy.$superdoc.broadcastComments(COMMENT_EVENTS.ADD, props.data.getValues());
+ } else {
+ props.data.comments.push(comment);
+ proxy.$superdoc.broadcastComments(COMMENT_EVENTS.ADD, props.data.getValues());
+ }
+
input.value.value = '';
- proxy.$superdoc.broadcastComments(COMMENT_EVENTS.ADD, props.data.getValues());
- checkOverlaps(currentElement.value, props.data, props.currentDocument);
}
function formatDate(timestamp) {
@@ -78,36 +104,42 @@ const handleKeyUp = () => {
}
const getSidebarCommentStyle = computed(() => {
- const style = {}
+ const style = {};
if (isActiveComment.value) {
style.backgroundColor = 'white';
style.zIndex = 10;
}
- if (!props.parent) {
- style.position = 'relative';
- return style;
+ if (!props.data.comments.length && currentElement.value) {
+ const selectionBounds = props.data.selection.getContainerLocation(props.parent)
+ const bounds = props.data.selection.selectionBounds;
+ const parentTop = props.parent.getBoundingClientRect().top;
+ const currentBounds = currentElement.value.getBoundingClientRect();
+ style.top = bounds.top + selectionBounds.top + 'px';
+ style.width = 300 + 'px';
}
- const topOffset = 10;
- const location = getCommentLocation(props.data.selection, props.parent);
- if (!location) return {};
-
- style.top = location.top - topOffset + 'px';
return style;
});
const cleanConversations = () => {
if (props.data.comments.length) return;
+ if (pendingComment.value) selectionPosition.value = null;
const id = props.data.conversationId;
+ pendingComment.value = null;
props.currentDocument.removeConversation(id);
proxy.$superdoc.broadcastComments(COMMENT_EVENTS.DELETED, id);
}
const handleClickOutside = (e) => {
- if (e.target.dataset.id) activeComment.value = e.target.dataset.id;
- else activeComment.value = null;
- cleanConversations();
+ if (activeComment.value === props.data.conversationId) {
+ floatingCommentsOffset.value = 0;
+
+ emit('dialog-exit');
+ if (e.target.dataset.id) activeComment.value = e.target.dataset.id;
+ else activeComment.value = null;
+ cleanConversations();
+ }
}
const setFocus = () => {
@@ -119,22 +151,11 @@ const markDone = () => {
convo.markDone(props.user.email, props.user.name);
props.currentDocument.removeConversation(convo.conversationId);
proxy.$superdoc.broadcastComments(COMMENT_EVENTS.RESOLVED, convo.getValues());
-
- const group = overlappingComments.value.find((g) => g.includes(props.data));
- if (!group) return;
- const index = group.findIndex((c) => c.conversationId === props.data.conversationId);
- if (index > -1) group.splice(index, 1);
- if (group.length === 1) {
- const conversation = group[0];
- const groupIndex = overlappingComments.value.findIndex((g) => g.includes(conversation));
-
- overlappingComments.value.splice(groupIndex, 1);
- conversation.group = false;
- }
}
const cancelComment = () => {
activeComment.value = null;
+ pendingComment.value = null;
if (!props.data.comments.length) {
cleanConversations();
}
@@ -144,28 +165,26 @@ const isActiveComment = computed(() => {
return activeComment.value === props.data.conversationId;
});
-const trackContainers = (e) => {
- currentElement.value = e;
- const conversations = props.currentDocument.conversations;
- const currentConversation = conversations.find((c) => c.conversationId === props.data.conversationId);
- if (!currentConversation) return;
- currentConversation.conversationElement = e;
-}
+
+onMounted(() => {
+ emit('ready', props.data.conversationId, currentElement);
+});