[web] open comments and changes via url (#36546)

* [web] open a comment from a URL

* [web] add "View comment" button to digest email

* [web] open a tracked change from a URL

* [web] add "View suggestion" button to digest email

* [web] open the review panel from an open=review-panel URL

* [web] drop the digest email CTA and collapse the deep links to t=review

* [web] add an Open project button to the section overflow row and plain-text view links

* [web] validate the comment and change deep-link ids as object ids

* [web] collapse the deep-link resolvers into a single DeepLink component

* fix: scrolling into view when below the fold

* fix: address claude review

* fix: style adjustments

* fix: updating types to accomodate accepted/rejected changes

---------

Co-authored-by: Jimmy Domagala-Tang <jimmy.domagala-tang@overleaf.com>
GitOrigin-RevId: dab535591a93e1c3849a6b2a0dcc3e3934354385
This commit is contained in:
Kristina
2026-09-17 12:07:22 +00:00
committed by Copybot
co-authored by Jimmy Domagala-Tang
parent 5dc8c2b0c3
commit 44910202f3
15 changed files with 977 additions and 91 deletions
@@ -39,6 +39,7 @@ import { convertFileRefToBinaryFile } from '@/features/ide-react/util/file-view'
import { useEditorOpenDocContext } from '@/features/ide-react/context/editor-open-doc-context'
import { useEditorPropertiesContext } from '@/features/ide-react/context/editor-properties-context'
import { showConnectionRestoredToast } from '@/features/ide-react/components/connection-restored-toast'
import { useDeepLinkContext } from '@/features/ide-react/context/deep-link-context'
export interface GotoOffsetOptions {
gotoOffset: number
@@ -119,6 +120,12 @@ export const EditorManagerProvider: FC<React.PropsWithChildren> = ({
wantTrackChangesRef.current = wantTrackChanges
}, [wantTrackChanges])
const {
deepLinkedDocId,
deepLinkedThreadId,
reportDeepLinkedThreadNotFound,
} = useDeepLinkContext()
const { fileTreeData } = useFileTreeData()
const fileTreeDataRef = useRef(fileTreeData)
useEffect(() => {
@@ -527,13 +534,34 @@ export const EditorManagerProvider: FC<React.PropsWithChildren> = ({
const openInitialDoc = useCallback(
async (fallbackDocId?: string) => {
if (deepLinkedDocId) {
const deepLinkedDoc = findDocEntityById(fileTreeData, deepLinkedDocId)
if (deepLinkedDoc) {
return await openDoc(deepLinkedDoc)
}
// the deep link points at a doc that is no longer in the project, so
// any comment it referenced is unreachable
if (deepLinkedThreadId) {
reportDeepLinkedThreadNotFound()
}
}
const docId =
customLocalStorage.getItem(currentDocumentIdStorageKey) || fallbackDocId
if (docId) {
return await openDocWithId(docId)
}
},
[currentDocumentIdStorageKey, openDocWithId]
[
currentDocumentIdStorageKey,
deepLinkedDocId,
deepLinkedThreadId,
fileTreeData,
openDoc,
openDocWithId,
reportDeepLinkedThreadNotFound,
]
)
useEffect(() => {