Skip to content

Commit e84d568

Browse files
committed
fix(comment): enforce document and sheet permissions
1 parent 4d38c5e commit e84d568

9 files changed

Lines changed: 71 additions & 30 deletions

File tree

packages/docs-thread-comment-ui/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,7 @@
8181
"@univerjs/drawing": "workspace:*",
8282
"@univerjs/engine-render": "workspace:*",
8383
"@univerjs/icons": "1.38.0",
84+
"@univerjs/protocol": "workspace:*",
8485
"@univerjs/thread-comment": "workspace:*",
8586
"@univerjs/thread-comment-ui": "workspace:*",
8687
"@univerjs/ui": "workspace:*"

packages/docs-thread-comment-ui/src/menu/menu.ts

Lines changed: 46 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -14,38 +14,64 @@
1414
* limitations under the License.
1515
*/
1616

17-
import type { IAccessor } from '@univerjs/core';
18-
import type { IMenuButtonItem } from '@univerjs/ui';
19-
import type { LocaleKey } from '../locale/types';
20-
import { IUniverInstanceService, SHEET_EDITOR_UNITS, UniverInstanceType } from '@univerjs/core';
21-
import { DocSelectionManagerService, DocSkeletonManagerService } from '@univerjs/docs';
17+
import { IPermissionService, IUniverInstanceService, SHEET_EDITOR_UNITS, UniverInstanceType } from '@univerjs/core';
18+
import { DocSelectionManagerService, DocSkeletonManagerService, getDocumentPermissionValue } from '@univerjs/docs';
2219
import { DocumentEditArea, IRenderManagerService, withCurrentTypeOfRenderer } from '@univerjs/engine-render';
20+
import { UnitAction } from '@univerjs/protocol';
2321
import { getMenuHiddenObservable, MenuItemType } from '@univerjs/ui';
24-
import { debounceTime, Observable } from 'rxjs';
22+
import { combineLatest, debounceTime, map, startWith } from 'rxjs';
2523
import {
2624
AddDocDrawingCommentOperation,
2725
StartAddCommentOperation,
2826
ToggleCommentPanelOperation,
2927
} from '../commands/operations/show-comment-panel.operation';
3028

31-
export function AddDocDrawingCommentMenuItemFactory(accessor: IAccessor): IMenuButtonItem<LocaleKey> {
29+
type MenuAccessor = Parameters<typeof getMenuHiddenObservable>[0];
30+
31+
function getCommentPermissionDisabled$(accessor: MenuAccessor) {
32+
const instanceService = accessor.get(IUniverInstanceService);
33+
const permissionService = accessor.get(IPermissionService);
34+
return combineLatest([
35+
instanceService.getCurrentTypeOfUnit$(UniverInstanceType.UNIVER_DOC),
36+
permissionService.permissionPointUpdate$.pipe(startWith(undefined)),
37+
]).pipe(map(([document]) => !document || !getDocumentPermissionValue(
38+
permissionService,
39+
document.getUnitId(),
40+
document.getUnitId(),
41+
UnitAction.Comment
42+
)));
43+
}
44+
45+
export function AddDocDrawingCommentMenuItemFactory(accessor: MenuAccessor) {
3246
return {
3347
id: AddDocDrawingCommentOperation.id,
3448
type: MenuItemType.BUTTON,
3549
icon: 'InsertCommentDoubleIcon',
3650
title: 'docs-thread-comment-ui.panel.addComment',
3751
tooltip: 'docs-thread-comment-ui.panel.addComment',
3852
hidden$: getMenuHiddenObservable(accessor, UniverInstanceType.UNIVER_DOC),
53+
disabled$: getCommentPermissionDisabled$(accessor),
3954
};
4055
}
4156

42-
export const shouldDisableAddComment = (accessor: IAccessor) => {
57+
export const shouldDisableAddComment = (accessor: MenuAccessor) => {
4358
const renderManagerService = accessor.get(IRenderManagerService);
4459
const docSelectionManagerService = accessor.get(DocSelectionManagerService);
60+
const instanceService = accessor.get(IUniverInstanceService);
61+
const permissionService = accessor.get(IPermissionService);
62+
const document = instanceService.getCurrentUnitOfType(UniverInstanceType.UNIVER_DOC);
63+
if (!document || !getDocumentPermissionValue(
64+
permissionService,
65+
document.getUnitId(),
66+
document.getUnitId(),
67+
UnitAction.Comment
68+
)) {
69+
return true;
70+
}
4571
const skeleton = withCurrentTypeOfRenderer(
4672
UniverInstanceType.UNIVER_DOC,
4773
DocSkeletonManagerService,
48-
accessor.get(IUniverInstanceService),
74+
instanceService,
4975
renderManagerService
5076
)?.getSkeleton();
5177

@@ -63,28 +89,27 @@ export const shouldDisableAddComment = (accessor: IAccessor) => {
6389
return false;
6490
};
6591

66-
export function AddDocCommentMenuItemFactory(accessor: IAccessor): IMenuButtonItem<LocaleKey> {
92+
export function AddDocCommentMenuItemFactory(accessor: MenuAccessor) {
6793
return {
6894
id: StartAddCommentOperation.id,
6995
type: MenuItemType.BUTTON,
7096
icon: 'InsertCommentDoubleIcon',
7197
title: 'docs-thread-comment-ui.panel.addComment',
7298
tooltip: 'docs-thread-comment-ui.panel.addComment',
7399
hidden$: getMenuHiddenObservable(accessor, UniverInstanceType.UNIVER_DOC, undefined, SHEET_EDITOR_UNITS),
74-
disabled$: new Observable(function (subscribe) {
75-
const textSelectionService = accessor.get(DocSelectionManagerService);
76-
const observer = textSelectionService.textSelection$.pipe(debounceTime(16)).subscribe(() => {
77-
subscribe.next(shouldDisableAddComment(accessor));
78-
});
79-
80-
return () => {
81-
observer.unsubscribe();
82-
};
83-
}),
100+
disabled$: combineLatest([
101+
accessor.get(DocSelectionManagerService).textSelection$.pipe(
102+
debounceTime(16),
103+
map(() => shouldDisableAddComment(accessor)),
104+
startWith(shouldDisableAddComment(accessor))
105+
),
106+
getCommentPermissionDisabled$(accessor),
107+
]).pipe(map(([selectionDisabled, permissionDisabled]) =>
108+
selectionDisabled || permissionDisabled)),
84109
};
85110
}
86111

87-
export function ToolbarDocCommentMenuItemFactory(accessor: IAccessor): IMenuButtonItem<LocaleKey> {
112+
export function ToolbarDocCommentMenuItemFactory(accessor: MenuAccessor) {
88113
return {
89114
id: ToggleCommentPanelOperation.id,
90115
type: MenuItemType.BUTTON,

packages/docs-thread-comment-ui/src/views/DocThreadCommentPanel.tsx

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,14 +17,14 @@
1717
import type { DocumentDataModel } from '@univerjs/core';
1818
import type { IAddDocCommentComment } from '../commands/commands/add-doc-comment.command';
1919
import type { IDeleteDocCommentComment } from '../commands/commands/delete-doc-comment.command';
20-
import { ICommandService, Injector, isInternalEditorID, IUniverInstanceService, UniverInstanceType, UserManagerService } from '@univerjs/core';
20+
import { ICommandService, Injector, IPermissionService, isInternalEditorID, IUniverInstanceService, UniverInstanceType, UserManagerService } from '@univerjs/core';
2121
import { DocSelectionManagerService, RichTextEditingMutation } from '@univerjs/docs';
2222
import { DEFAULT_DOC_SUBUNIT_ID } from '@univerjs/docs-thread-comment';
2323
import { deserializeThreadCommentAnchor, serializeThreadCommentAnchor, ThreadCommentAnchorKind, ThreadCommentModel } from '@univerjs/thread-comment';
2424
import { ThreadCommentDraftService, ThreadCommentPanel } from '@univerjs/thread-comment-ui';
2525
import { useDependency, useObservable } from '@univerjs/ui';
2626
import { useEffect, useMemo, useState } from 'react';
27-
import { debounceTime, filter, map, Observable } from 'rxjs';
27+
import { debounceTime, filter, map, merge, Observable } from 'rxjs';
2828
import { AddDocCommentComment } from '../commands/commands/add-doc-comment.command';
2929
import { DeleteDocCommentComment } from '../commands/commands/delete-doc-comment.command';
3030
import { StartAddCommentOperation } from '../commands/operations/show-comment-panel.operation';
@@ -51,11 +51,16 @@ export const DocThreadCommentPanel = () => {
5151
() => docSelectionManagerService.textSelection$.pipe(debounceTime(16)),
5252
[docSelectionManagerService.textSelection$]
5353
);
54+
const permissionService = useDependency(IPermissionService);
55+
const disableAddChange$ = useMemo(
56+
() => merge(selectionChange$, permissionService.permissionPointUpdate$),
57+
[permissionService.permissionPointUpdate$, selectionChange$]
58+
);
5459
const disableAdd = useObservable(
55-
() => selectionChange$.pipe(map(() => shouldDisableAddComment(injector))),
60+
() => disableAddChange$.pipe(map(() => shouldDisableAddComment(injector))),
5661
shouldDisableAddComment(injector),
5762
false,
58-
[injector, selectionChange$]
63+
[disableAddChange$, injector]
5964
);
6065
const commandService = useDependency(ICommandService);
6166
const threadCommentModel = useDependency(ThreadCommentModel);

packages/docs/src/controllers/__tests__/doc-permission.controller.spec.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -307,6 +307,7 @@ describe('DocPermissionController', () => {
307307
[UnitAction.Print, 'docs.operation.print'],
308308
[UnitAction.Export, 'docs-exchange-client.operation.export-doc'],
309309
[UnitAction.Comment, 'docs.command.add-comment'],
310+
[UnitAction.Comment, 'docs.operation.add-drawing-comment'],
310311
] as const)('enforces unit action %s on its existing command surface', async (point, commandId) => {
311312
const commandService = get(ICommandService);
312313
commandService.registerCommand({ id: commandId, type: CommandType.OPERATION, handler: () => true });

packages/docs/src/controllers/doc-permission.controller.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -270,6 +270,7 @@ function getDocumentUnitAction(commandId: string): UnitAction | undefined {
270270
if (commandId === 'docs.operation.print') return UnitAction.Print;
271271
if (commandId === 'docs-exchange-client.operation.export-doc') return UnitAction.Export;
272272
if (commandId === 'docs.operation.start-add-comment' ||
273+
commandId === 'docs.operation.add-drawing-comment' ||
273274
(commandId.startsWith('docs.command.') && commandId.includes('comment')) ||
274275
commandId.startsWith('thread-comment.command.') ||
275276
commandId.startsWith('thread-comment.mutation.')) {

packages/sheets-thread-comment-ui/src/controllers/__tests__/sheets-thread-comment-permission.controller.spec.ts

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ import {
2525
UpdateCommentCommand,
2626
} from '@univerjs/thread-comment';
2727
import { describe, expect, it, vi } from 'vitest';
28-
import { ShowAddSheetCommentModalOperation } from '../../commands/operations/comment.operation';
28+
import { AddSheetDrawingCommentOperation, ShowAddSheetCommentModalOperation } from '../../commands/operations/comment.operation';
2929
import { SheetsThreadCommentPermissionController } from '../sheets-thread-comment-permission.controller';
3030

3131
type BeforeCommandHandler = (command: { id: string; params?: unknown }) => void;
@@ -67,6 +67,7 @@ describe('SheetsThreadCommentPermissionController', () => {
6767
const beforeCommandHandler = getBeforeCommandHandler();
6868

6969
beforeCommandHandler?.({ id: ShowAddSheetCommentModalOperation.id });
70+
beforeCommandHandler?.({ id: AddSheetDrawingCommentOperation.id });
7071
beforeCommandHandler?.({
7172
id: AddCommentCommand.id,
7273
params: {
@@ -92,7 +93,7 @@ describe('SheetsThreadCommentPermissionController', () => {
9293
},
9394
});
9495

95-
expect(permissionCheck.permissionCheckWithoutRange).toHaveBeenCalledTimes(1);
96+
expect(permissionCheck.permissionCheckWithoutRange).toHaveBeenCalledTimes(2);
9697
expect(permissionCheck.permissionCheckWithRanges).toHaveBeenCalledWith(expect.any(Object), [{
9798
startRow: 1,
9899
startColumn: 1,
@@ -105,7 +106,7 @@ describe('SheetsThreadCommentPermissionController', () => {
105106
endRow: 3,
106107
endColumn: 2,
107108
}], 'unit-1', 'sheet-1');
108-
expect(permissionCheck.blockExecuteWithoutPermission).toHaveBeenCalledTimes(4);
109+
expect(permissionCheck.blockExecuteWithoutPermission).toHaveBeenCalledTimes(5);
109110
expect(permissionCheck.blockExecuteWithoutPermission).toHaveBeenLastCalledWith('sheets-thread-comment-ui.permission.commentErr');
110111

111112
controller.dispose();

packages/sheets-thread-comment-ui/src/controllers/sheets-thread-comment-permission.controller.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ import {
4141
ThreadCommentAnchorKind,
4242
UpdateCommentCommand,
4343
} from '@univerjs/thread-comment';
44-
import { ShowAddSheetCommentModalOperation, ToggleSheetCommentPanelOperation } from '../commands/operations/comment.operation';
44+
import { AddSheetDrawingCommentOperation, ShowAddSheetCommentModalOperation, ToggleSheetCommentPanelOperation } from '../commands/operations/comment.operation';
4545

4646
export class SheetsThreadCommentPermissionController extends Disposable {
4747
constructor(
@@ -60,7 +60,7 @@ export class SheetsThreadCommentPermissionController extends Disposable {
6060
this._commandService.beforeCommandExecuted((command: ICommandInfo) => {
6161
const { id } = command;
6262

63-
if (id === ShowAddSheetCommentModalOperation.id || id === ToggleSheetCommentPanelOperation.id) {
63+
if (id === AddSheetDrawingCommentOperation.id || id === ShowAddSheetCommentModalOperation.id || id === ToggleSheetCommentPanelOperation.id) {
6464
const permission = this._sheetPermissionCheckController.permissionCheckWithoutRange({
6565
workbookTypes: [WorkbookCommentPermission],
6666
worksheetTypes: [WorksheetViewPermission],

packages/sheets-thread-comment-ui/src/menu/menu.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,10 @@ export const drawingCommentMenuFactory = (accessor: IAccessor) => ({
2929
title: 'sheets-thread-comment-ui.menu.addComment',
3030
tooltip: 'sheets-thread-comment-ui.menu.addComment',
3131
hidden$: getMenuHiddenObservable(accessor, UniverInstanceType.UNIVER_SHEET),
32+
disabled$: getCurrentRangeDisable$(accessor, {
33+
workbookTypes: [WorkbookCommentPermission],
34+
worksheetTypes: [WorksheetViewPermission],
35+
}),
3236
});
3337

3438
export const threadCommentMenuFactory = (accessor: IAccessor) => {

pnpm-lock.yaml

Lines changed: 3 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)