mirror of
https://github.com/dream-num/univer.git
synced 2026-08-28 14:56:51 +08:00
fix(sheets-thread-comment): preserve cell thread selection (#7571)
This commit is contained in:
@@ -27,11 +27,25 @@ export const SheetsThreadCommentCell = () => {
|
||||
const sheetsThreadCommentPopupService = useDependency(SheetsThreadCommentPopupService);
|
||||
const activePopup = useObservable(sheetsThreadCommentPopupService.activePopup$);
|
||||
const sheetThreadCommentModel = useDependency(SheetsThreadCommentModel);
|
||||
const getRootId = () => {
|
||||
if (!activePopup) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const { unitId, subUnitId, row, col, commentId } = activePopup;
|
||||
const activeComment = commentId
|
||||
? sheetThreadCommentModel.getAllByLocation(unitId, subUnitId, row, col).find((comment) => comment.id === commentId)
|
||||
: undefined;
|
||||
|
||||
return activeComment && !activeComment.resolved
|
||||
? activeComment.id
|
||||
: sheetThreadCommentModel.getByLocation(unitId, subUnitId, row, col);
|
||||
};
|
||||
const rootId = useObservable(
|
||||
activePopup
|
||||
? () => sheetThreadCommentModel.commentUpdate$.pipe(
|
||||
map(() => sheetThreadCommentModel.getByLocation(activePopup.unitId, activePopup.subUnitId, activePopup.row, activePopup.col)),
|
||||
startWith(sheetThreadCommentModel.getByLocation(activePopup.unitId, activePopup.subUnitId, activePopup.row, activePopup.col))
|
||||
map(() => getRootId()),
|
||||
startWith(getRootId())
|
||||
)
|
||||
: null,
|
||||
undefined,
|
||||
|
||||
+36
@@ -1047,6 +1047,42 @@ describe('SheetsThreadCommentPanel', () => {
|
||||
}));
|
||||
});
|
||||
|
||||
it('switches the cell thread when the active popup selects another thread at the same location', () => {
|
||||
const testBed = createTestBed();
|
||||
univer = testBed.univer;
|
||||
testBed.threadCommentModel.addComment(unitId, sheet1, createComment('first-thread', sheet1, 'B2', 'First B2 thread'));
|
||||
testBed.threadCommentModel.addComment(unitId, sheet1, createComment('second-thread', sheet1, 'B2', 'Second B2 thread'));
|
||||
testBed.popupService.showPopup({
|
||||
unitId,
|
||||
subUnitId: sheet1,
|
||||
row: 1,
|
||||
col: 1,
|
||||
commentId: 'first-thread',
|
||||
});
|
||||
|
||||
const rendered = renderCell(testBed.injector);
|
||||
root = rendered.root;
|
||||
container = rendered.container;
|
||||
|
||||
expect(container.querySelector(`#CELL-${unitId}-${sheet1}-first-thread`)).toBeInstanceOf(HTMLElement);
|
||||
expect(container.textContent).toContain('First B2 thread');
|
||||
expect(container.textContent).not.toContain('Second B2 thread');
|
||||
|
||||
act(() => {
|
||||
testBed.popupService.showPopup({
|
||||
unitId,
|
||||
subUnitId: sheet1,
|
||||
row: 1,
|
||||
col: 1,
|
||||
commentId: 'second-thread',
|
||||
});
|
||||
});
|
||||
|
||||
expect(container.querySelector(`#CELL-${unitId}-${sheet1}-second-thread`)).toBeInstanceOf(HTMLElement);
|
||||
expect(container.textContent).toContain('Second B2 thread');
|
||||
expect(container.textContent).not.toContain('First B2 thread');
|
||||
});
|
||||
|
||||
it('updates an open cell popup when a thread is added at that cell location', () => {
|
||||
const testBed = createTestBed();
|
||||
univer = testBed.univer;
|
||||
|
||||
+36
@@ -36,6 +36,42 @@ function createComment(overrides: Record<string, unknown> = {}) {
|
||||
}
|
||||
|
||||
describe('SheetsThreadCommentModel', () => {
|
||||
it('keeps the newer unresolved thread as the default when an older thread is reopened', () => {
|
||||
const olderComment = createComment({ id: 'older-comment', threadId: 'older-thread', resolved: true });
|
||||
const newerComment = createComment({ id: 'newer-comment', threadId: 'newer-thread' });
|
||||
const comments = new Map([
|
||||
[olderComment.id, olderComment],
|
||||
[newerComment.id, newerComment],
|
||||
]);
|
||||
const updates$ = new Subject<unknown>();
|
||||
const threadCommentModel = {
|
||||
getAll: () => [{ threads: [
|
||||
{ unitId: 'unit-1', subUnitId: 'sheet-1', root: olderComment },
|
||||
{ unitId: 'unit-1', subUnitId: 'sheet-1', root: newerComment },
|
||||
] }],
|
||||
commentUpdate$: updates$,
|
||||
getComment: (_unitId: string, _subUnitId: string, commentId: string) => comments.get(commentId),
|
||||
};
|
||||
const univerInstanceService = {
|
||||
getUnitType: () => UniverInstanceType.UNIVER_SHEET,
|
||||
};
|
||||
const model = new SheetsThreadCommentModel(threadCommentModel as never, univerInstanceService as never);
|
||||
|
||||
expect(model.getByLocation('unit-1', 'sheet-1', 0, 0)).toBe(newerComment.id);
|
||||
|
||||
olderComment.resolved = false;
|
||||
updates$.next({
|
||||
type: 'resolve',
|
||||
unitId: 'unit-1',
|
||||
subUnitId: 'sheet-1',
|
||||
payload: { commentId: olderComment.id, resolved: false },
|
||||
});
|
||||
|
||||
expect(model.getByLocation('unit-1', 'sheet-1', 0, 0)).toBe(newerComment.id);
|
||||
|
||||
model.dispose();
|
||||
});
|
||||
|
||||
it('should build location indexes from existing root comments and expose thread data', () => {
|
||||
const root = createComment();
|
||||
const reply = createComment({ id: 'reply-1', parentId: root.id, ref: '', resolved: false });
|
||||
|
||||
@@ -230,7 +230,7 @@ export class SheetsThreadCommentModel extends Disposable {
|
||||
getByLocation(unitId: string, subUnitId: string, row: number, column: number): string | undefined {
|
||||
const comments = this.getAllByLocation(unitId, subUnitId, row, column);
|
||||
const activeComments = comments.filter((comment) => !comment.resolved);
|
||||
return activeComments[0]?.id;
|
||||
return activeComments[activeComments.length - 1]?.id;
|
||||
}
|
||||
|
||||
getAllByLocation(unitId: string, subUnitId: string, row: number, column: number): IThreadComment[] {
|
||||
|
||||
Reference in New Issue
Block a user