+
+
+
+ {t('viewer.comments.title', 'Comments')}
+
+
+
+
+ {totalCount === 0 ? (
+
+ {t('viewer.comments.hint', 'Place comments with the Comment, Insert Text, or Replace Text tools. They will appear here by page.')}
+
+ ) : (
+ pageNumbers.map((pageIndex) => {
+ const entries = byPage[pageIndex] ?? [];
+ const pageNum = pageIndex + 1;
+ return (
+
+
+ {t('viewer.comments.pageLabel', 'Page {{page}}', { page: pageNum })}
+
+
+ {entries.length === 1
+ ? t('viewer.comments.oneComment', '1 comment')
+ : t('viewer.comments.nComments', '{{count}} comments', { count: entries.length })}
+
+
+
+ {entries.map((entry) => {
+ const ann = entry.annotation?.object;
+ const id = ann?.id;
+ if (!id) return null;
+ const key = `${pageIndex}_${id}`;
+ const replyKey = `${pageIndex}_${id}_reply`;
+ const displayContent = getCommentDisplayContent(entry);
+ const draft = draftContents[key] !== undefined ? draftContents[key] : displayContent;
+ const replyDraft = replyDrafts[replyKey] ?? '';
+ const authorName = getAuthorName(ann, displayName);
+ /** Only treat as "comment posted" when annotation actually has content (user clicked Send), not on every keystroke. */
+ const hasMainContent = (displayContent ?? '').trim().length > 0;
+ const isEditingMain = editingMainKey === key;
+
+ const mainTimestamp = formatCommentDate(ann);
+ const typeLabel = getAnnotationTypeLabel(ann, t);
+
+ return (
+
+
+
+
+
+
+ {authorName}
+
+
+ {typeLabel}{mainTimestamp ? ` · ${mainTimestamp}` : ''}
+
+
+
+
+
+ handleLocateAnnotation(pageIndex, ann)}
+ >
+
+
+
+
+
+
+
+ {!hasMainContent || isEditingMain ? (
+ <>
+
+ );
+ })}
+
+
+ );
+ })
+ )}
+
+
+
+ setDeleteModal(null)}
+ title={t('viewer.comments.deleteTitle', 'Remove annotation from comments?')}
+ centered
+ size="sm"
+ >
+
+ {t(
+ 'viewer.comments.deleteDescription',
+ 'This annotation has a comment attached. You can remove just the comment from the sidebar while keeping the annotation, or delete everything.'
+ )}
+
+
+
+
+
+
+
+ );
+}
diff --git a/frontend/src/core/components/viewer/EmbedPdfViewer.tsx b/frontend/src/core/components/viewer/EmbedPdfViewer.tsx
index d88a4fb25f..745b0642b1 100644
--- a/frontend/src/core/components/viewer/EmbedPdfViewer.tsx
+++ b/frontend/src/core/components/viewer/EmbedPdfViewer.tsx
@@ -126,6 +126,7 @@ const EmbedPdfViewerContent = ({
toggleThumbnailSidebar,
isBookmarkSidebarVisible,
isAttachmentSidebarVisible,
+ isCommentsSidebarVisible,
isSearchInterfaceVisible,
searchInterfaceActions,
zoomActions,
@@ -201,8 +202,9 @@ const EmbedPdfViewerContent = ({
const isSignatureMode = isInAnnotationTool;
const isManualRedactMode = selectedTool === 'redact';
- // Enable annotations only when annotation tool is selected
- const shouldEnableAnnotations = selectedTool === 'annotate' || isSignatureMode;
+ // Enable annotations when annotation tool is selected OR when annotations are visible
+ // (so users can interact with existing comment annotations in reader/viewer mode)
+ const shouldEnableAnnotations = selectedTool === 'annotate' || isSignatureMode || isAnnotationsVisible;
// Enable redaction only when redaction tool is selected
const shouldEnableRedaction = selectedTool === 'redact';
@@ -910,10 +912,12 @@ const EmbedPdfViewerContent = ({
}, [isFormFillToolActive, currentFile, currentFileId, fetchFormFields]);
const sidebarWidthRem = 15;
+ const commentsSidebarWidthRem = 18;
const totalRightMargin =
(isThumbnailSidebarVisible ? sidebarWidthRem : 0) +
(isBookmarkSidebarVisible ? sidebarWidthRem : 0) +
- (isAttachmentSidebarVisible ? sidebarWidthRem : 0);
+ (isAttachmentSidebarVisible ? sidebarWidthRem : 0) +
+ (isCommentsSidebarVisible ? commentsSidebarWidthRem : 0);
return (