Merge pull request #26814 from overleaf/mj-review-panel-comment-collapse

[web] Fix review panel check for comments in active document

GitOrigin-RevId: fc0c35bc1d2f253c133dec5dcea7f81f68d723a9
This commit is contained in:
Mathias Jakobsen
2025-07-07 12:12:35 +01:00
committed by Copybot
parent 56232b48a7
commit b89951cf5d
2 changed files with 185 additions and 15 deletions

View File

@@ -15,8 +15,9 @@ export const hasActiveRange = (
return true
}
for (const thread of Object.values(threads)) {
if (!thread.resolved) {
for (const comment of ranges.comments) {
const thread = threads[comment.op.t]
if (thread && !thread.resolved) {
return true
}
}

View File

@@ -8,6 +8,19 @@ import { mockScope } from '../source-editor/helpers/mock-scope'
import { TestContainer } from '../source-editor/helpers/test-container'
import { docId } from '../source-editor/helpers/mock-doc'
const userData = {
avatar_text: 'User',
email: USER_EMAIL,
hue: 180,
id: USER_ID,
isSelf: true,
first_name: 'Test',
last_name: 'User',
}
const resolvedThreadId = 'resolved-thread-id'
const unresolvedThreadId = 'unresolved-thread-id'
describe('<ReviewPanel />', function () {
beforeEach(function () {
window.metaAttributesCache.set('ol-preventCompileOnLoad', true)
@@ -23,19 +36,6 @@ describe('<ReviewPanel />', function () {
},
])
const userData = {
avatar_text: 'User',
email: USER_EMAIL,
hue: 180,
id: USER_ID,
isSelf: true,
first_name: 'Test',
last_name: 'User',
}
const resolvedThreadId = 'resolved-thread-id'
const unresolvedThreadId = 'unresolved-thread-id'
cy.intercept('GET', '/project/*/threads', {
// Resolved comment thread
[resolvedThreadId]: {
@@ -623,6 +623,175 @@ describe('<ReviewPanel />', function () {
})
})
describe('<ReviewPanel /> in mini mode', function () {
function render({ comments = [], changes = [], threads = {} }: any) {
window.metaAttributesCache.set('ol-preventCompileOnLoad', true)
cy.interceptEvents()
cy.intercept('GET', '/project/*/changes/users', [
{
id: USER_ID,
email: USER_EMAIL,
first_name: 'Test',
last_name: 'User',
},
])
const getChanges = cy.stub().as('getChanges').returns([])
const removeChangeIds = cy.stub().as('removeChangeIds')
const scope = mockScope(undefined, {
docOptions: {
rangesOptions: {
comments,
changes,
getChanges,
removeChangeIds,
},
},
projectFeatures: { trackChangesVisible: true },
})
cy.intercept('GET', '/project/*/ranges', [
{
id: docId,
ranges: {
changes,
comments,
docId,
},
},
])
cy.intercept('GET', '/project/*/threads', threads)
cy.intercept('POST', `/project/*/doc/${docId}/metadata`, {})
cy.wrap(scope).as('scope')
cy.mount(
<TestContainer>
<EditorProviders scope={scope}>
<CodeMirrorEditor />
</EditorProviders>
</TestContainer>
)
// Wait for editor
cy.get('.cm-content').should('have.css', 'opacity', '1')
// Toggle the review panel twice to ensure data is loaded
cy.findByText('contentLine 0').type('{command}jj', {
scrollBehavior: false,
})
cy.findByText('contentLine 1').type('{ctrl}jj', { scrollBehavior: false })
}
it("doesn't render mini when no comments or changes are present in project", function () {
render({
comments: [],
changes: [],
threads: {},
})
cy.get('.review-panel-mini').should('not.exist')
})
it("doesn't render mini when no comments or changes are present in document", function () {
render({
comments: [],
changes: [],
threads: {
'random-unrelated-thread': {
messages: [
{
content: 'a comment',
id: 'random-unrelated-thread-1',
timestamp: new Date('2025-01-01T01:00:00.000Z'),
user: userData,
user_id: USER_ID,
},
],
},
},
})
cy.get('.review-panel-mini').should('not.exist')
})
it("doesn't render mini when a resolved comments is present in document", function () {
render({
comments: [
{
id: resolvedThreadId,
op: { p: 161, c: 'Your introduction', t: resolvedThreadId },
},
],
changes: [],
threads: {
[resolvedThreadId]: {
resolved: true,
resolved_at: new Date('2025-01-02T00:00:00.000Z').toISOString(),
resolved_by_user_id: USER_ID,
resolved_by_user: userData,
messages: [
{
content: 'a comment',
id: `${resolvedThreadId}-1`,
timestamp: new Date('2025-01-01T01:00:00.000Z'),
user: userData,
user_id: USER_ID,
},
],
},
},
})
cy.get('.review-panel-mini').should('not.exist')
})
it('renders mini when a unresolved comments is present in document', function () {
render({
comments: [
{
id: unresolvedThreadId,
op: { p: 161, c: 'Your introduction', t: unresolvedThreadId },
},
],
changes: [],
threads: {
[unresolvedThreadId]: {
messages: [
{
content: 'a comment',
id: `${unresolvedThreadId}-1`,
timestamp: new Date('2025-01-01T01:00:00.000Z'),
user: userData,
user_id: USER_ID,
},
],
},
},
})
cy.get('.review-panel-mini').should('exist')
})
it('renders mini when a tracked change is present in document', function () {
render({
comments: [],
changes: [
{
metadata: {
user_id: USER_ID,
ts: new Date('2025-01-01T00:00:00.000Z'),
},
id: 'inserted-op-id',
op: { p: 166, t: 'inserted-op-id', i: 'introduction' },
},
],
threads: {},
})
cy.get('.review-panel-mini').should('exist')
})
})
describe('<ReviewPanel /> for free users', function () {
function mountEditor(ownerId = USER_ID) {
const scope = mockScope(undefined, {