diff --git a/e2e/disposing/disposing.spec.ts b/e2e/disposing/disposing.spec.ts index eee4bb19e18..501e83ed694 100644 --- a/e2e/disposing/disposing.spec.ts +++ b/e2e/disposing/disposing.spec.ts @@ -43,10 +43,30 @@ test('no error on constructing and disposing', async ({ page }) => { await page.waitForTimeout(2000); await page.evaluate(() => window.E2EControllerAPI.loadDefaultSheet()); - await page.waitForTimeout(2000); // wait for long enough to let the GC do its job + await page.waitForTimeout(2000); await page.evaluate(() => window.E2EControllerAPI.disposeUniver()); - await page.waitForTimeout(2000); // wait for long enough to let the GC do its job + await page.waitForTimeout(2000); + + expect(errored).toBeFalsy(); +}); + +test('no error when dispose a unit', async ({ page }) => { + let errored = false; + + page.on('pageerror', (error) => { + console.error('Page error:', error); + errored = true; + }); + + await page.goto('http://localhost:3000/sheets/'); + await page.waitForTimeout(2000); + + await page.evaluate(() => window.E2EControllerAPI.loadAndRelease(1)); + await page.waitForTimeout(2000); + + await page.evaluate(() => window.E2EControllerAPI.loadAndRelease(2)); + await page.waitForTimeout(2000); expect(errored).toBeFalsy(); }); diff --git a/e2e/memory/memory.spec.ts b/e2e/memory/memory.spec.ts index c4acbbe88c8..32786c02afd 100644 --- a/e2e/memory/memory.spec.ts +++ b/e2e/memory/memory.spec.ts @@ -23,6 +23,7 @@ import { expect, test } from '@playwright/test'; // examples/src/plugins/debugger/controllers/e2e/e2e-memory.controller.ts export interface IE2EControllerAPI { loadAndRelease(id: number): Promise; + loadDefaultSheet(): Promise; disposeUniver(): Promise; } @@ -33,6 +34,8 @@ declare global { } } +const MAX_MEMORY_OVERFLOW = 2_500_000; + test('memory', async ({ page }) => { await page.goto('http://localhost:3000/sheets/'); await page.waitForTimeout(2000); @@ -49,9 +52,8 @@ test('memory', async ({ page }) => { const memoryAfterSecondLoad = (await getMetrics(page)).JSHeapUsedSize; console.log('Memory after second load:', memoryAfterSecondLoad); - // max overflow for 3MB const notLeaking = (memoryAfterSecondLoad <= memoryAfterFirstLoad) - || (memoryAfterSecondLoad - memoryAfterFirstLoad <= 2_500_000); + || (memoryAfterSecondLoad - memoryAfterFirstLoad <= MAX_MEMORY_OVERFLOW); expect(notLeaking).toBeTruthy(); }); diff --git a/packages/core/src/services/instance/instance.service.ts b/packages/core/src/services/instance/instance.service.ts index 04232ac3cca..8613bcb93d5 100644 --- a/packages/core/src/services/instance/instance.service.ts +++ b/packages/core/src/services/instance/instance.service.ts @@ -119,21 +119,28 @@ export class UniverInstanceService extends Disposable implements IUniverInstance }; } - private readonly _currentUnits$ = new BehaviorSubject<{ [type: UnitType]: Nullable }>({}); + private _currentUnits = new Map>(); + private readonly _currentUnits$ = new BehaviorSubject>>(this._currentUnits); readonly currentUnits$ = this._currentUnits$.asObservable(); getCurrentTypeOfUnit$(type: number): Observable> { - return this.currentUnits$.pipe(map((units) => units[type] ?? null), distinctUntilChanged()) as Observable>; + return this.currentUnits$.pipe(map((units) => units.get(type) ?? null), distinctUntilChanged()) as Observable>; } getCurrentUnitForType(type: UnitType): Nullable { - return this._currentUnits$.getValue()[type] as Nullable; + return this._currentUnits.get(type) as Nullable; } setCurrentUnitForType(unitId: string): void { const result = this._getUnitById(unitId); if (!result) throw new Error(`[UniverInstanceService]: no document with unitId ${unitId}!`); - this._currentUnits$.next({ ...this._currentUnits$.getValue(), [result[1]]: result[0] }); + this._currentUnits.set(result[1], result[0]); + this._currentUnits$.next(this._currentUnits); + } + + private _removeCurrentUnitForType(type: UnitType): void { + this._currentUnits.set(type, null); + this._currentUnits$.next(this._currentUnits); } private readonly _unitAdded$ = new Subject(); @@ -142,21 +149,28 @@ export class UniverInstanceService extends Disposable implements IUniverInstance return this._unitAdded$.pipe(filter((unit) => unit.type === type)) as Observable; } + /** + * Add a unit into Univer. + * + * @ignore + * + * @param unit The unit to be added. + */ __addUnit(unit: UnitModel): void { const type = unit.type; if (!this._unitsByType.has(type)) { this._unitsByType.set(type, []); } - this._unitsByType.get(type)!.push(unit); - this._currentUnits$.next({ ...this._currentUnits$.getValue(), [type]: unit }); this._unitAdded$.next(unit); + + this.setCurrentUnitForType(unit.getUnitId()); } private _unitDisposed$ = new Subject(); - unitDisposed$ = this._unitDisposed$.asObservable(); + readonly unitDisposed$ = this._unitDisposed$.asObservable(); getTypeOfUnitDisposed$>(type: UniverInstanceType): Observable { return this.unitDisposed$.pipe(filter((unit) => unit.type === type)) as Observable; } @@ -242,10 +256,13 @@ export class UniverInstanceService extends Disposable implements IUniverInstance const index = units.indexOf(unit); units.splice(index, 1); - this._unitDisposed$.next(unit); - this._currentUnits$.next({ ...this._currentUnits$.getValue(), [type]: null }); + // Firstly un-mark the unit as "current". + this._removeCurrentUnitForType(type); this._focused$.next(null); + // Then dispose the unit. + this._unitDisposed$.next(unit); + return true; } diff --git a/packages/core/src/services/permission/permission.service.ts b/packages/core/src/services/permission/permission.service.ts index ace881f7fd1..2bb490dfe78 100644 --- a/packages/core/src/services/permission/permission.service.ts +++ b/packages/core/src/services/permission/permission.service.ts @@ -25,7 +25,6 @@ export class PermissionService extends Disposable implements IPermissionService private _permissionPointMap: Map>> = new Map(); private _permissionPointUpdate$ = new Subject>(); - public permissionPointUpdate$ = this._permissionPointUpdate$.asObservable(); deletePermissionPoint(permissionId: string) { diff --git a/packages/facade/src/apis/__tests__/create-test-bed.ts b/packages/facade/src/apis/__tests__/create-test-bed.ts index 74402ec3af5..dcc133e3bda 100644 --- a/packages/facade/src/apis/__tests__/create-test-bed.ts +++ b/packages/facade/src/apis/__tests__/create-test-bed.ts @@ -32,7 +32,7 @@ import { } from '@univerjs/core'; import { FormulaDataModel, FunctionService, IFunctionService, LexerTreeBuilder } from '@univerjs/engine-formula'; import { ISocketService, WebSocketService } from '@univerjs/network'; -import { SelectionManagerService, SheetInterceptorService, WorkbookPermissionService, WorksheetPermissionService, WorksheetProtectionPointModel, WorksheetProtectionRuleModel } from '@univerjs/sheets'; +import { RangeProtectionRuleModel, SelectionManagerService, SheetInterceptorService, WorkbookPermissionService, WorksheetPermissionService, WorksheetProtectionPointModel, WorksheetProtectionRuleModel } from '@univerjs/sheets'; import { DescriptionService, FormulaCustomFunctionService, @@ -151,6 +151,7 @@ export function createFacadeTestBed(workbookData?: IWorkbookData, dependencies?: injector.add([WorksheetPermissionService]); injector.add([WorkbookPermissionService]); injector.add([WorksheetProtectionPointModel]); + injector.add([RangeProtectionRuleModel]); injector.add([IAuthzIoService, { useClass: AuthzIoLocalService }]); injector.add([WorksheetProtectionRuleModel]); diff --git a/packages/sheets-formula/src/commands/operations/__tests__/create-command-test-bed.ts b/packages/sheets-formula/src/commands/operations/__tests__/create-command-test-bed.ts index 7740d6e9fd4..0d989b19dfc 100644 --- a/packages/sheets-formula/src/commands/operations/__tests__/create-command-test-bed.ts +++ b/packages/sheets-formula/src/commands/operations/__tests__/create-command-test-bed.ts @@ -17,7 +17,7 @@ import type { IWorkbookData } from '@univerjs/core'; import { AuthzIoLocalService, IAuthzIoService, ILogService, IUniverInstanceService, LocaleType, LogLevel, Plugin, Univer, UniverInstanceType } from '@univerjs/core'; import { LexerTreeBuilder } from '@univerjs/engine-formula'; -import { SelectionManagerService, SheetInterceptorService, WorkbookPermissionService, WorksheetPermissionService, WorksheetProtectionPointModel, WorksheetProtectionRuleModel } from '@univerjs/sheets'; +import { RangeProtectionRuleModel, SelectionManagerService, SheetInterceptorService, WorkbookPermissionService, WorksheetPermissionService, WorksheetProtectionPointModel, WorksheetProtectionRuleModel } from '@univerjs/sheets'; import type { Dependency } from '@wendellhu/redi'; import { Inject, Injector } from '@wendellhu/redi'; import { EditorService, IEditorService } from '@univerjs/ui'; @@ -80,6 +80,7 @@ export function createCommandTestBed(workbookData?: IWorkbookData, dependencies? injector.add([WorksheetPermissionService]); injector.add([WorksheetProtectionPointModel]); injector.add([WorkbookPermissionService]); + injector.add([RangeProtectionRuleModel]); injector.add([IAuthzIoService, { useClass: AuthzIoLocalService }]); injector.add([WorksheetProtectionRuleModel]); diff --git a/packages/sheets-formula/src/controllers/menu.ts b/packages/sheets-formula/src/controllers/menu.ts index 31d43f0d8ef..ffb4511fea5 100644 --- a/packages/sheets-formula/src/controllers/menu.ts +++ b/packages/sheets-formula/src/controllers/menu.ts @@ -14,12 +14,13 @@ * limitations under the License. */ -import { UniverInstanceType } from '@univerjs/core'; +import type { Workbook } from '@univerjs/core'; +import { IUniverInstanceService, UniverInstanceType } from '@univerjs/core'; import { getCurrentRangeDisable$, PASTE_SPECIAL_MENU_ID } from '@univerjs/sheets-ui'; import type { IMenuItem } from '@univerjs/ui'; import { getMenuHiddenObservable, IClipboardInterfaceService, MenuGroup, MenuItemType, MenuPosition } from '@univerjs/ui'; import type { IAccessor } from '@wendellhu/redi'; -import { combineLatestWith, map, Observable } from 'rxjs'; +import { combineLatestWith, map, Observable, of, switchMap } from 'rxjs'; import { RangeProtectionPermissionEditPoint, WorkbookEditablePermission, WorksheetEditPermission, WorksheetSetCellValuePermission } from '@univerjs/sheets'; import { SheetOnlyPasteFormulaCommand } from '../commands/commands/formula-clipboard.command'; @@ -76,8 +77,20 @@ export function MoreFunctionsMenuItemFactory(accessor: IAccessor): IMenuItem { } function menuClipboardDisabledObservable(injector: IAccessor): Observable { - const clipboardDisabled$: Observable = new Observable((subscriber) => subscriber.next(!injector.get(IClipboardInterfaceService).supportClipboard)); - return clipboardDisabled$; + const univerInstanceService = injector.get(IUniverInstanceService); + const workbook$ = univerInstanceService.getCurrentTypeOfUnit$(UniverInstanceType.UNIVER_SHEET); + return workbook$.pipe( + switchMap((workbook) => { + if (!workbook) { + return of(true); + } + const clipboardInterfaceService = injector.get(IClipboardInterfaceService); + if (clipboardInterfaceService) { + return new Observable((subscriber) => subscriber.next(!injector.get(IClipboardInterfaceService).supportClipboard)) as Observable; + } + return of(true); + }) + ); } export function PasteFormulaMenuItemFactory(accessor: IAccessor): IMenuItem { diff --git a/packages/sheets-thread-comment/src/types/const.ts b/packages/sheets-thread-comment/src/types/const.ts index 1159ad97eb9..51726d6665d 100644 --- a/packages/sheets-thread-comment/src/types/const.ts +++ b/packages/sheets-thread-comment/src/types/const.ts @@ -16,4 +16,4 @@ export const SHEETS_THREAD_COMMENT_MODAL = 'univer.sheet.thread-comment-modal'; export const COMMENT_SINGLE_ICON = 'comment-single'; -export const SHEETS_THREAD_COMMENT = 'univer.sheet.thread-comment'; +export const SHEETS_THREAD_COMMENT = 'SHEET_THREAD_COMMENT'; diff --git a/packages/sheets-ui/src/controllers/menu/__tests__/menu.spec.ts b/packages/sheets-ui/src/controllers/menu/__tests__/menu.spec.ts index 6e5d9e632c5..b5d4b8b0c42 100644 --- a/packages/sheets-ui/src/controllers/menu/__tests__/menu.spec.ts +++ b/packages/sheets-ui/src/controllers/menu/__tests__/menu.spec.ts @@ -93,10 +93,10 @@ describe('test menu items', () => { disposableCollection.add(menuItem.activated$!.subscribe((v: boolean) => (activated = v))); disposableCollection.add(menuItem.disabled$!.subscribe((v: boolean) => (disabled = v))); expect(activated).toBeFalsy(); - expect(disabled).toBeFalsy(); select({ startRow: 0, startColumn: 0, endRow: 0, endColumn: 0 }); expect(await commandService.executeCommand(SetBoldCommand.id)).toBeTruthy(); expect(activated).toBe(true); + expect(disabled).toBeFalsy(); }); }); diff --git a/packages/sheets-ui/src/controllers/menu/menu-util.ts b/packages/sheets-ui/src/controllers/menu/menu-util.ts index 7e39e5766a4..6393a790f26 100644 --- a/packages/sheets-ui/src/controllers/menu/menu-util.ts +++ b/packages/sheets-ui/src/controllers/menu/menu-util.ts @@ -48,140 +48,79 @@ export function deriveStateFromActiveSheet$(univerInstanceService: IUniverIns export function getCurrentRangeDisable$(accessor: IAccessor, permissionTypes: IPermissionTypes = {}) { const univerInstanceService = accessor.get(IUniverInstanceService); - const selectionManagerService = accessor.get(SelectionManagerService); - const rangeProtectionRuleModel = accessor.get(RangeProtectionRuleModel); - const worksheetRuleModel = accessor.get(WorksheetProtectionRuleModel); - const workbook = univerInstanceService.getCurrentUnitForType(UniverInstanceType.UNIVER_SHEET)!; + const workbook$ = univerInstanceService.getCurrentTypeOfUnit$(UniverInstanceType.UNIVER_SHEET); const userManagerService = accessor.get(UserManagerService); - const contextService = accessor.get(IContextService); - const focusedOnDrawing$ = contextService.subscribeContextValue$(FOCUSING_COMMON_DRAWINGS).pipe(startWith(false)); - if (!workbook) { - return of(true); - } - - return combineLatest([userManagerService.currentUser$, workbook.activeSheet$, selectionManagerService.selectionMoveEnd$, focusedOnDrawing$]).pipe( - switchMap(([_, __, selection, focusOnDrawings]) => { - if (focusOnDrawings) { - return of(true); - } - const worksheet = workbook.getActiveSheet(); - if (!worksheet) { + return combineLatest([userManagerService.currentUser$, workbook$]).pipe( + switchMap(([_, workbook]) => { + if (!workbook) { return of(true); } - const unitId = workbook.getUnitId(); - const subUnitId = worksheet.getSheetId(); - - const permissionService = accessor.get(IPermissionService); - - const { workbookTypes = [WorkbookEditablePermission], worksheetTypes, rangeTypes } = permissionTypes; - - const permissionIds: string[] = []; - - workbookTypes?.forEach((F) => { - permissionIds.push(new F(unitId).id); - }); - - worksheetTypes?.forEach((F) => { - permissionIds.push(new F(unitId, subUnitId).id); - }); - - const worksheetRule = worksheetRuleModel.getRule(unitId, subUnitId); - - if (worksheetRule) { - return permissionService.composePermission$(permissionIds).pipe(map((list) => { - return list.some((item) => item.value === false); - })); - } - - const selectionRanges = selection?.map((selection) => selection.range); - const rules = rangeProtectionRuleModel.getSubunitRuleList(unitId, subUnitId).filter((rule) => { - return selectionRanges?.some((range) => { - return rule.ranges.some((ruleRange) => Rectangle.intersects(range, ruleRange)); - }); - }); - - rangeTypes?.forEach((F) => { - rules.forEach((rule) => { - permissionIds.push(new F(unitId, subUnitId, rule.permissionId).id); - }); - }); - - return permissionService.composePermission$(permissionIds).pipe(map((list) => { - return list.some((item) => item.value === false); - })); - }) - ); -} - -export function getCommentDisable$(accessor: IAccessor, permissionTypes: IPermissionTypes = {}) { - const univerInstanceService = accessor.get(IUniverInstanceService); - const selectionManagerService = accessor.get(SelectionManagerService); - const rangeProtectionRuleModel = accessor.get(RangeProtectionRuleModel); - const worksheetRuleModel = accessor.get(WorksheetProtectionRuleModel); - const userManagerService = accessor.get(UserManagerService); + return workbook.activeSheet$.pipe( + switchMap((worksheet) => { + if (!worksheet) { + return of(true); + } - const contextService = accessor.get(IContextService); - const focusedOnDrawing$ = contextService.subscribeContextValue$(FOCUSING_COMMON_DRAWINGS); + const selectionManagerService = accessor.get(SelectionManagerService); + const rangeProtectionRuleModel = accessor.get(RangeProtectionRuleModel); + const worksheetRuleModel = accessor.get(WorksheetProtectionRuleModel); - return combineLatest([userManagerService.currentUser$, selectionManagerService.selectionMoveEnd$, focusedOnDrawing$]).pipe( - switchMap(([_, __, focusOnDrawing]) => { - const workbook = univerInstanceService.getCurrentUnitForType(UniverInstanceType.UNIVER_SHEET); - if (!workbook) { - return of(true); - } + const contextService = accessor.get(IContextService); + const focusedOnDrawing$ = contextService.subscribeContextValue$(FOCUSING_COMMON_DRAWINGS).pipe(startWith(false)); - if (focusOnDrawing) { - return of(true); - } + return combineLatest([selectionManagerService.selectionMoveEnd$, focusedOnDrawing$]).pipe( + switchMap(([selection, focusOnDrawings]) => { + if (focusOnDrawings) { + return of(true); + } - const worksheet = workbook.getActiveSheet(); - if (!worksheet) { - return of(true); - } + const unitId = workbook.getUnitId(); + const subUnitId = worksheet.getSheetId(); - const unitId = workbook.getUnitId(); - const subUnitId = worksheet.getSheetId(); + const permissionService = accessor.get(IPermissionService); - const permissionService = accessor.get(IPermissionService); + const { workbookTypes = [WorkbookEditablePermission], worksheetTypes, rangeTypes } = permissionTypes; - const { workbookTypes = [WorkbookEditablePermission], worksheetTypes, rangeTypes } = permissionTypes; + const permissionIds: string[] = []; - const permissionIds: string[] = []; + workbookTypes?.forEach((F) => { + permissionIds.push(new F(unitId).id); + }); - workbookTypes?.forEach((F) => { - permissionIds.push(new F(unitId).id); - }); + worksheetTypes?.forEach((F) => { + permissionIds.push(new F(unitId, subUnitId).id); + }); - worksheetTypes?.forEach((F) => { - permissionIds.push(new F(unitId, subUnitId).id); - }); + const worksheetRule = worksheetRuleModel.getRule(unitId, subUnitId); - const worksheetRule = worksheetRuleModel.getRule(unitId, subUnitId); + if (worksheetRule) { + return permissionService.composePermission$(permissionIds).pipe(map((list) => { + return list.some((item) => item.value === false); + })); + } - if (worksheetRule) { - return permissionService.composePermission$(permissionIds).pipe(map((list) => { - return list.some((item) => item.value === false); - })); - } + const selectionRanges = selection?.map((selection) => selection.range); + const rules = rangeProtectionRuleModel.getSubunitRuleList(unitId, subUnitId).filter((rule) => { + return selectionRanges?.some((range) => { + return rule.ranges.some((ruleRange) => Rectangle.intersects(range, ruleRange)); + }); + }); - const selectionRanges = selectionManagerService.getSelections()?.map((selection) => selection.range); - const rules = rangeProtectionRuleModel.getSubunitRuleList(unitId, subUnitId).filter((rule) => { - return selectionRanges?.some((range) => { - return rule.ranges.some((ruleRange) => Rectangle.intersects(range, ruleRange)); - }); - }); - - rangeTypes?.forEach((F) => { - rules.forEach((rule) => { - permissionIds.push(new F(unitId, subUnitId, rule.permissionId).id); - }); - }); + rangeTypes?.forEach((F) => { + rules.forEach((rule) => { + permissionIds.push(new F(unitId, subUnitId, rule.permissionId).id); + }); + }); - return permissionService.composePermission$(permissionIds).pipe(map((list) => { - return list.some((item) => item.value === false); - })); + return permissionService.composePermission$(permissionIds).pipe(map((list) => { + return list.some((item) => item.value === false); + })); + }) + ); + }) + ); }) ); } @@ -416,39 +355,43 @@ export function getCellMenuHidden$(accessor: IAccessor, type: 'row' | 'col') { export function getWorkbookPermissionDisable$(accessor: IAccessor, workbookPermissionTypes: WorkbookPermissionPointConstructor[]) { const univerInstanceService = accessor.get(IUniverInstanceService); - const workbook = univerInstanceService.getCurrentUnitForType(UniverInstanceType.UNIVER_SHEET)!; + const workbook$ = univerInstanceService.getCurrentTypeOfUnit$(UniverInstanceType.UNIVER_SHEET)!; const worksheetRuleModel = accessor.get(WorksheetProtectionRuleModel); const selectionRuleModel = accessor.get(RangeProtectionRuleModel); const permissionService = accessor.get(IPermissionService); - const unitId = workbook.getUnitId(); - - const activeSheet$ = workbook.activeSheet$; - const userManagerService = accessor.get(UserManagerService); - return combineLatest([userManagerService.currentUser$, activeSheet$]).pipe( - switchMap(([_user, activeSheet]) => { - if (!activeSheet) { + return combineLatest([userManagerService.currentUser$, workbook$]).pipe( + switchMap(([_user, workbook]) => { + if (!workbook) { return of(true); } - const workbookPermissionIds: string[] = []; - workbookPermissionTypes.forEach((F) => workbookPermissionIds.push(new F(unitId).id)); - const workbookPermission$ = permissionService.composePermission$(workbookPermissionIds).pipe(map((list) => list.every((item) => item.value === true))); - const workbookManageCollaboratorPermission$ = permissionService.getPermissionPoint$(new WorkbookManageCollaboratorPermission(unitId).id)?.pipe(map((permission) => permission.value)) ?? of(false); - - return combineLatest([workbookPermission$, workbookManageCollaboratorPermission$]).pipe( - map(([basePermission, manageable]) => { - if (!basePermission) { - return true; - } - - const subUnitId = activeSheet.getSheetId(); - const worksheetRule = worksheetRuleModel.getRule(unitId, subUnitId); - const worksheetRuleList = selectionRuleModel.getSubunitRuleList(unitId, subUnitId); - if (worksheetRule || worksheetRuleList.length) { - return !manageable; + return workbook.activeSheet$.pipe( + switchMap((activeSheet) => { + if (!activeSheet) { + return of(true); } - return false; + const unitId = workbook.getUnitId(); + const workbookPermissionIds: string[] = []; + workbookPermissionTypes.forEach((F) => workbookPermissionIds.push(new F(unitId).id)); + const workbookPermission$ = permissionService.composePermission$(workbookPermissionIds).pipe(map((list) => list.every((item) => item.value === true))); + const workbookManageCollaboratorPermission$ = permissionService.getPermissionPoint$(new WorkbookManageCollaboratorPermission(unitId).id)?.pipe(map((permission) => permission.value)) ?? of(false); + + return combineLatest([workbookPermission$, workbookManageCollaboratorPermission$]).pipe( + map(([basePermission, manageable]) => { + if (!basePermission) { + return true; + } + + const subUnitId = activeSheet.getSheetId(); + const worksheetRule = worksheetRuleModel.getRule(unitId, subUnitId); + const worksheetRuleList = selectionRuleModel.getSubunitRuleList(unitId, subUnitId); + if (worksheetRule || worksheetRuleList.length) { + return !manageable; + } + return false; + }) + ); }) ); }) diff --git a/packages/sheets-ui/src/controllers/menu/permission-menu-util.ts b/packages/sheets-ui/src/controllers/menu/permission-menu-util.ts index cd6870f937f..226ed9b2041 100644 --- a/packages/sheets-ui/src/controllers/menu/permission-menu-util.ts +++ b/packages/sheets-ui/src/controllers/menu/permission-menu-util.ts @@ -22,132 +22,160 @@ import { combineLatest, map, merge, of, startWith, switchMap } from 'rxjs'; export function getAddPermissionHidden$(accessor: IAccessor) { const univerInstanceService = accessor.get(IUniverInstanceService); - const selectionManagerService = accessor.get(SelectionManagerService); - const workbook = univerInstanceService.getCurrentUnitForType(UniverInstanceType.UNIVER_SHEET)!; - - const rangeProtectionRuleModel = accessor.get(RangeProtectionRuleModel); - const worksheetRuleModel = accessor.get(WorksheetProtectionRuleModel); - - return merge( - selectionManagerService.selectionMoveEnd$, - rangeProtectionRuleModel.ruleChange$, - worksheetRuleModel.ruleChange$ - ).pipe( - map(() => { - const worksheet = workbook.getActiveSheet(); - if (!worksheet) { - return false; - } + const workbook$ = univerInstanceService.getCurrentTypeOfUnit$(UniverInstanceType.UNIVER_SHEET); + const userManagerService = accessor.get(UserManagerService); - const unitId = workbook.getUnitId(); - const subUnitId = worksheet.getSheetId(); - const subUnitRuleList = rangeProtectionRuleModel.getSubunitRuleList(unitId, subUnitId); - const selections = selectionManagerService.getSelections(); - const selectionsRanges = selections?.map((selection) => selection.range); - const ruleRanges = subUnitRuleList.map((rule) => rule.ranges).flat(); - if (!selectionsRanges) { - return false; - } - const worksheetRule = worksheetRuleModel.getRule(unitId, subUnitId); - if (worksheetRule?.permissionId && worksheetRule?.name) { - return true; + return combineLatest([workbook$, userManagerService.currentUser$]).pipe( + switchMap(([workbook, _]) => { + if (!workbook) { + return of(true); } - return selectionsRanges?.some((selectionRange) => { - return ruleRanges.some((ruleRange) => { - return Rectangle.intersects(selectionRange, ruleRange); - }); - }); + + return workbook.activeSheet$.pipe( + switchMap((worksheet) => { + if (!worksheet) { + return of(true); + } + const rangeProtectionRuleModel = accessor.get(RangeProtectionRuleModel); + const worksheetRuleModel = accessor.get(WorksheetProtectionRuleModel); + const selectionManagerService = accessor.get(SelectionManagerService); + return merge( + selectionManagerService.selectionMoveEnd$, + rangeProtectionRuleModel.ruleChange$, + worksheetRuleModel.ruleChange$ + ).pipe( + map(() => { + const unitId = workbook.getUnitId(); + const subUnitId = worksheet.getSheetId(); + const subUnitRuleList = rangeProtectionRuleModel.getSubunitRuleList(unitId, subUnitId); + const selections = selectionManagerService.getSelections(); + const selectionsRanges = selections?.map((selection) => selection.range); + const ruleRanges = subUnitRuleList.map((rule) => rule.ranges).flat(); + if (!selectionsRanges) { + return false; + } + const worksheetRule = worksheetRuleModel.getRule(unitId, subUnitId); + if (worksheetRule?.permissionId && worksheetRule?.name) { + return true; + } + return selectionsRanges?.some((selectionRange) => { + return ruleRanges.some((ruleRange) => { + return Rectangle.intersects(selectionRange, ruleRange); + }); + }); + }) + ); + }) + ); }) ); } export function getEditPermissionHidden$(accessor: IAccessor) { const univerInstanceService = accessor.get(IUniverInstanceService); - const selectionManagerService = accessor.get(SelectionManagerService); - const workbook = univerInstanceService.getCurrentUnitForType(UniverInstanceType.UNIVER_SHEET)!; - const rangeRuleModel = accessor.get(RangeProtectionRuleModel); - const worksheetRuleModel = accessor.get(WorksheetProtectionRuleModel); - - return merge( - selectionManagerService.selectionMoveEnd$, - rangeRuleModel.ruleChange$, - worksheetRuleModel.ruleChange$ - ).pipe( - map(() => { - const worksheet = workbook.getActiveSheet(); - if (!worksheet) { - return false; - } - - const unitId = workbook.getUnitId(); - const subUnitId = worksheet.getSheetId(); - const subUnitRuleList = rangeRuleModel.getSubunitRuleList(unitId, subUnitId); - const selectionRanges = selectionManagerService.getSelections()?.map((selection) => selection.range); - - const ruleRanges = subUnitRuleList.map((rule) => rule.ranges).flat(); - if (!selectionRanges?.length) { - return true; - } - - if (selectionRanges.length > 1) { - return true; - } - const selectedRange = selectionRanges[0]; + const workbook$ = univerInstanceService.getCurrentTypeOfUnit$(UniverInstanceType.UNIVER_SHEET); + const userManagerService = accessor.get(UserManagerService); - const worksheetRule = worksheetRuleModel.getRule(unitId, subUnitId); - if (worksheetRule?.permissionId && worksheetRule?.name) { - return false; + return combineLatest([workbook$, userManagerService.currentUser$]).pipe( + switchMap(([workbook, _]) => { + if (!workbook) { + return of(true); } - const lapRanges = ruleRanges.filter((ruleRange) => Rectangle.intersects(ruleRange, selectedRange)); - - return lapRanges.length !== 1; + return workbook.activeSheet$.pipe( + switchMap((worksheet) => { + if (!worksheet) { + return of(true); + } + const rangeProtectionRuleModel = accessor.get(RangeProtectionRuleModel); + const worksheetRuleModel = accessor.get(WorksheetProtectionRuleModel); + + const selectionManagerService = accessor.get(SelectionManagerService); + return merge( + selectionManagerService.selectionMoveEnd$, + rangeProtectionRuleModel.ruleChange$, + worksheetRuleModel.ruleChange$ + ).pipe( + map(() => { + const unitId = workbook.getUnitId(); + const subUnitId = worksheet.getSheetId(); + const subUnitRuleList = rangeRuleModel.getSubunitRuleList(unitId, subUnitId); + const selectionRanges = selectionManagerService.getSelections()?.map((selection) => selection.range); + + const ruleRanges = subUnitRuleList.map((rule) => rule.ranges).flat(); + if (!selectionRanges?.length) { + return true; + } + + if (selectionRanges.length > 1) { + return true; + } + + const selectedRange = selectionRanges[0]; + + const worksheetRule = worksheetRuleModel.getRule(unitId, subUnitId); + if (worksheetRule?.permissionId && worksheetRule?.name) { + return false; + } + + const lapRanges = ruleRanges.filter((ruleRange) => Rectangle.intersects(ruleRange, selectedRange)); + + return lapRanges.length !== 1; + }) + ); + }) + ); }) ); } export function getPermissionDisableBase$(accessor: IAccessor) { const univerInstanceService = accessor.get(IUniverInstanceService); - const workbook = univerInstanceService.getCurrentUnitForType(UniverInstanceType.UNIVER_SHEET)!; - const selectionProtectionRuleModel = accessor.get(RangeProtectionRuleModel); - const worksheetProtectionRuleModel = accessor.get(WorksheetProtectionRuleModel); - const unitId = workbook.getUnitId(); const permissionService = accessor.get(IPermissionService); - - const selectionManagerService = accessor.get(SelectionManagerService); + const workbook$ = univerInstanceService.getCurrentTypeOfUnit$(UniverInstanceType.UNIVER_SHEET); const userManagerService = accessor.get(UserManagerService); - return combineLatest([workbook.activeSheet$, userManagerService.currentUser$]).pipe( - switchMap(([sheet, _]) => { - if (!sheet) { + return combineLatest([workbook$, userManagerService.currentUser$]).pipe( + switchMap(([workbook, _]) => { + if (!workbook) { return of(true); } - const permission$ = permissionService.getPermissionPoint$(new WorkbookManageCollaboratorPermission(unitId).id)?.pipe(map((e) => !!e.value)) ?? of(false); - const ruleChange$ = merge( - selectionManagerService.selectionMoveEnd$, - selectionProtectionRuleModel.ruleChange$, - worksheetProtectionRuleModel.ruleChange$ - ).pipe( - startWith(null) - ); - - return combineLatest([permission$, ruleChange$]).pipe( - map(([permission, _]) => { - if (!permission) { - return true; - } - const selections = selectionManagerService.getSelections(); - const selectionRanges = selections?.map((selection) => selection.range); - if (!selectionRanges?.length) { - return false; - } - if (selectionRanges.length > 1) { - return true; + return workbook.activeSheet$.pipe( + switchMap((worksheet) => { + if (!worksheet) { + return of(true); } - return false; + const unitId = workbook.getUnitId(); + const selectionManagerService = accessor.get(SelectionManagerService); + const selectionProtectionRuleModel = accessor.get(RangeProtectionRuleModel); + const worksheetProtectionRuleModel = accessor.get(WorksheetProtectionRuleModel); + const permission$ = permissionService.getPermissionPoint$(new WorkbookManageCollaboratorPermission(unitId).id)?.pipe(map((e) => !!e.value)) ?? of(false); + const ruleChange$ = merge( + selectionProtectionRuleModel.ruleChange$, + worksheetProtectionRuleModel.ruleChange$ + ).pipe( + startWith(null) + ); + return combineLatest([permission$, ruleChange$, selectionManagerService.selectionMoveEnd$]).pipe( + map(([permission, _, __]) => { + if (!permission) { + return true; + } + const selections = selectionManagerService.getSelections(); + const selectionRanges = selections?.map((selection) => selection.range); + if (!selectionRanges?.length) { + return false; + } + + if (selectionRanges.length > 1) { + return true; + } + return false; + }) + ); }) ); }) @@ -156,57 +184,62 @@ export function getPermissionDisableBase$(accessor: IAccessor) { export function getAddPermissionDisableBase$(accessor: IAccessor) { const univerInstanceService = accessor.get(IUniverInstanceService); - const workbook = univerInstanceService.getCurrentUnitForType(UniverInstanceType.UNIVER_SHEET)!; - const selectionProtectionRuleModel = accessor.get(RangeProtectionRuleModel); - const worksheetProtectionRuleModel = accessor.get(WorksheetProtectionRuleModel); - const unitId = workbook.getUnitId(); - const selectionManagerService = accessor.get(SelectionManagerService); - const userManagerService = accessor.get(UserManagerService); const permissionService = accessor.get(IPermissionService); - const contextService = accessor.get(IContextService); - const focusingDrawing$ = contextService.subscribeContextValue$(FOCUSING_COMMON_DRAWINGS).pipe(startWith(false)); + const workbook$ = univerInstanceService.getCurrentTypeOfUnit$(UniverInstanceType.UNIVER_SHEET); + const userManagerService = accessor.get(UserManagerService); - return combineLatest([workbook.activeSheet$, userManagerService.currentUser$, focusingDrawing$]).pipe( - switchMap(([sheet, _, focusOnDrawing]) => { - if (!sheet || focusOnDrawing) { + return combineLatest([workbook$, userManagerService.currentUser$]).pipe( + switchMap(([workbook, _]) => { + if (!workbook) { return of(true); } - const subUnitId = sheet.getSheetId(); - const permission$ = permissionService.getPermissionPoint$(new WorkbookManageCollaboratorPermission(unitId).id)?.pipe(map((e) => !!e.value)) ?? of(false); - const ruleChange$ = merge( - selectionManagerService.selectionMoveEnd$, - selectionProtectionRuleModel.ruleChange$, - worksheetProtectionRuleModel.ruleChange$ - ).pipe( - startWith(null) - ); - - return combineLatest([permission$, ruleChange$]).pipe( - map(([permission, _]) => { - if (!permission) { - return true; - } - const selections = selectionManagerService.getSelections(); - const selectionRanges = selections?.map((selection) => selection.range); - if (!selectionRanges?.length) { - return true; - } - - const worksheetRule = worksheetProtectionRuleModel.getRule(unitId, subUnitId); - if (worksheetRule?.permissionId && worksheetRule?.name) { - return true; + return workbook.activeSheet$.pipe( + switchMap((worksheet) => { + if (!worksheet) { + return of(true); } - - const subunitRuleList = selectionProtectionRuleModel.getSubunitRuleList(unitId, subUnitId); - const hasLap = selectionRanges?.some((selectionRange) => { - return subunitRuleList.some((rule) => { - return rule.ranges.some((ruleRange) => { - return Rectangle.intersects(selectionRange, ruleRange); + const contextService = accessor.get(IContextService); + const focusingDrawing$ = contextService.subscribeContextValue$(FOCUSING_COMMON_DRAWINGS).pipe(startWith(false)); + const unitId = workbook.getUnitId(); + const subUnitId = worksheet.getSheetId(); + const selectionProtectionRuleModel = accessor.get(RangeProtectionRuleModel); + const worksheetProtectionRuleModel = accessor.get(WorksheetProtectionRuleModel); + const selectionManagerService = accessor.get(SelectionManagerService); + const permission$ = permissionService.getPermissionPoint$(new WorkbookManageCollaboratorPermission(unitId).id)?.pipe(map((e) => !!e.value)) ?? of(false); + const ruleChange$ = merge( + selectionProtectionRuleModel.ruleChange$, + worksheetProtectionRuleModel.ruleChange$ + ).pipe( + startWith(null) + ); + return combineLatest([permission$, ruleChange$, selectionManagerService.selectionMoveEnd$, focusingDrawing$]).pipe( + map(([permission, _, __, focus]) => { + if (!permission || focus) { + return true; + } + const selections = selectionManagerService.getSelections(); + const selectionRanges = selections?.map((selection) => selection.range); + if (!selectionRanges?.length) { + return true; + } + + const worksheetRule = worksheetProtectionRuleModel.getRule(unitId, subUnitId); + if (worksheetRule?.permissionId && worksheetRule?.name) { + return true; + } + + const subunitRuleList = selectionProtectionRuleModel.getSubunitRuleList(unitId, subUnitId); + const hasLap = selectionRanges?.some((selectionRange) => { + return subunitRuleList.some((rule) => { + return rule.ranges.some((ruleRange) => { + return Rectangle.intersects(selectionRange, ruleRange); + }); + }); }); - }); - }); - return hasLap; + return hasLap; + }) + ); }) ); }) @@ -215,38 +248,41 @@ export function getAddPermissionDisableBase$(accessor: IAccessor) { export function getAddPermissionFromSheetBarDisable$(accessor: IAccessor) { const univerInstanceService = accessor.get(IUniverInstanceService); - const workbook = univerInstanceService.getCurrentUnitForType(UniverInstanceType.UNIVER_SHEET)!; - const selectionProtectionRuleModel = accessor.get(RangeProtectionRuleModel); - const worksheetProtectionRuleModel = accessor.get(WorksheetProtectionRuleModel); const permissionService = accessor.get(IPermissionService); + const workbook$ = univerInstanceService.getCurrentTypeOfUnit$(UniverInstanceType.UNIVER_SHEET); const userManagerService = accessor.get(UserManagerService); - return combineLatest([workbook.activeSheet$, userManagerService.currentUser$]).pipe( - switchMap(([activeSheet, _]) => { - if (!activeSheet) { + return combineLatest([workbook$, userManagerService.currentUser$]).pipe( + switchMap(([workbook, _]) => { + if (!workbook) { return of(true); } - const unitId = workbook.getUnitId(); - const subUnitId = activeSheet.getSheetId(); - const permission$ = permissionService.getPermissionPoint$(new WorkbookManageCollaboratorPermission(unitId).id)?.pipe(map((e) => !!e.value)) ?? of(false); - - const ruleChange$ = merge( - worksheetProtectionRuleModel.ruleChange$, - selectionProtectionRuleModel.ruleChange$ - ).pipe( - startWith(null) - ); - return combineLatest([ - permission$, - ruleChange$, - ]).pipe( - map(([permission, _]) => { - if (!permission) return true; - const worksheetRule = worksheetProtectionRuleModel.getRule(unitId, subUnitId); - if (worksheetRule?.permissionId && worksheetRule?.name) return true; - const subUnitRuleList = selectionProtectionRuleModel.getSubunitRuleList(unitId, subUnitId)?.filter((item) => item?.permissionId && item?.name); - return subUnitRuleList.length > 0; + return workbook.activeSheet$.pipe( + switchMap((worksheet) => { + if (!worksheet) { + return of(true); + } + const unitId = workbook.getUnitId(); + const subUnitId = worksheet.getSheetId(); + const selectionProtectionRuleModel = accessor.get(RangeProtectionRuleModel); + const worksheetProtectionRuleModel = accessor.get(WorksheetProtectionRuleModel); + const permission$ = permissionService.getPermissionPoint$(new WorkbookManageCollaboratorPermission(unitId).id)?.pipe(map((e) => !!e.value)) ?? of(false); + const ruleChange$ = merge( + selectionProtectionRuleModel.ruleChange$, + worksheetProtectionRuleModel.ruleChange$ + ).pipe( + startWith(null) + ); + return combineLatest([permission$, ruleChange$]).pipe( + map(([permission, _]) => { + if (!permission) return true; + const worksheetRule = worksheetProtectionRuleModel.getRule(unitId, subUnitId); + if (worksheetRule?.permissionId && worksheetRule?.name) return true; + const subUnitRuleList = selectionProtectionRuleModel.getSubunitRuleList(unitId, subUnitId)?.filter((item) => item?.permissionId && item?.name); + return subUnitRuleList.length > 0; + }) + ); }) ); }) @@ -255,25 +291,32 @@ export function getAddPermissionFromSheetBarDisable$(accessor: IAccessor) { export function getRemovePermissionFromSheetBarDisable$(accessor: IAccessor) { const univerInstanceService = accessor.get(IUniverInstanceService); - const workbook = univerInstanceService.getCurrentUnitForType(UniverInstanceType.UNIVER_SHEET)!; - const worksheetProtectionRuleModel = accessor.get(WorksheetProtectionRuleModel); - const userManagerService = accessor.get(UserManagerService); const permissionService = accessor.get(IPermissionService); + const workbook$ = univerInstanceService.getCurrentTypeOfUnit$(UniverInstanceType.UNIVER_SHEET); + const userManagerService = accessor.get(UserManagerService); - return combineLatest([workbook.activeSheet$, userManagerService.currentUser$, worksheetProtectionRuleModel.ruleChange$.pipe(startWith(null))]).pipe( - switchMap(([activeSheet, _]) => { - if (!activeSheet) { + return combineLatest([workbook$, userManagerService.currentUser$]).pipe( + switchMap(([workbook, _]) => { + if (!workbook) { return of(true); } - const unitId = workbook.getUnitId(); - const subUnitId = activeSheet.getSheetId(); - const permission$ = permissionService.getPermissionPoint$(new WorkbookManageCollaboratorPermission(unitId).id)?.pipe(map((e) => !!e.value)) ?? of(false); - - return permission$.pipe( - map((permission) => { - if (!permission) return true; - const worksheetPermissionRule = worksheetProtectionRuleModel.getRule(unitId, subUnitId); - return !(worksheetPermissionRule?.permissionId && worksheetPermissionRule?.name); + + return workbook.activeSheet$.pipe( + switchMap((worksheet) => { + if (!worksheet) { + return of(true); + } + const unitId = workbook.getUnitId(); + const subUnitId = worksheet.getSheetId(); + const worksheetProtectionRuleModel = accessor.get(WorksheetProtectionRuleModel); + const permission$ = permissionService.getPermissionPoint$(new WorkbookManageCollaboratorPermission(unitId).id)?.pipe(map((e) => !!e.value)) ?? of(false); + return combineLatest([permission$, worksheetProtectionRuleModel.ruleChange$.pipe(startWith(null))]).pipe( + map(([permission, _]) => { + if (!permission) return true; + const worksheetPermissionRule = worksheetProtectionRuleModel.getRule(unitId, subUnitId); + return !(worksheetPermissionRule?.permissionId && worksheetPermissionRule?.name); + }) + ); }) ); }) @@ -282,33 +325,41 @@ export function getRemovePermissionFromSheetBarDisable$(accessor: IAccessor) { export function getSetPermissionFromSheetBarDisable$(accessor: IAccessor) { const univerInstanceService = accessor.get(IUniverInstanceService); - const workbook = univerInstanceService.getCurrentUnitForType(UniverInstanceType.UNIVER_SHEET)!; const permissionService = accessor.get(IPermissionService); - const unitId = workbook.getUnitId(); + const workbook$ = univerInstanceService.getCurrentTypeOfUnit$(UniverInstanceType.UNIVER_SHEET); const userManagerService = accessor.get(UserManagerService); - const worksheetRuleModel = accessor.get(WorksheetProtectionRuleModel); - const selectionProtectionRuleModel = accessor.get(RangeProtectionRuleModel); - return combineLatest([workbook.activeSheet$, userManagerService.currentUser$]).pipe( - switchMap(([activeSheet, _]) => { - if (!activeSheet) { + return combineLatest([workbook$, userManagerService.currentUser$]).pipe( + switchMap(([workbook, _]) => { + if (!workbook) { return of(true); } - const permission$ = permissionService.getPermissionPoint$(new WorkbookManageCollaboratorPermission(unitId).id)?.pipe(map((e) => !!e.value)) ?? of(false); - const worksheetRuleChange$ = worksheetRuleModel.ruleChange$.pipe(startWith(null)); - const selectionRuleChange$ = selectionProtectionRuleModel.ruleChange$.pipe(startWith(null)); - return combineLatest([permission$, worksheetRuleChange$, selectionRuleChange$]).pipe( - map(([permission, _, __]) => { - if (!permission) { - return true; - } - const subUnitId = activeSheet.getSheetId(); - const worksheetRule = worksheetRuleModel.getRule(unitId, subUnitId); - const selectionRuleList = selectionProtectionRuleModel.getSubunitRuleList(unitId, subUnitId); - if (worksheetRule || selectionRuleList.length) { - return false; + + return workbook.activeSheet$.pipe( + switchMap((worksheet) => { + if (!worksheet) { + return of(true); } - return true; + const unitId = workbook.getUnitId(); + const selectionProtectionRuleModel = accessor.get(RangeProtectionRuleModel); + const worksheetProtectionRuleModel = accessor.get(WorksheetProtectionRuleModel); + const permission$ = permissionService.getPermissionPoint$(new WorkbookManageCollaboratorPermission(unitId).id)?.pipe(map((e) => !!e.value)) ?? of(false); + const worksheetRuleChange$ = worksheetProtectionRuleModel.ruleChange$.pipe(startWith(null)); + const selectionRuleChange$ = selectionProtectionRuleModel.ruleChange$.pipe(startWith(null)); + return combineLatest([permission$, worksheetRuleChange$, selectionRuleChange$]).pipe( + map(([permission, _, __]) => { + if (!permission) { + return true; + } + const subUnitId = worksheet.getSheetId(); + const worksheetRule = worksheetProtectionRuleModel.getRule(unitId, subUnitId); + const selectionRuleList = selectionProtectionRuleModel.getSubunitRuleList(unitId, subUnitId); + if (worksheetRule || selectionRuleList.length) { + return false; + } + return true; + }) + ); }) ); }) @@ -317,55 +368,62 @@ export function getSetPermissionFromSheetBarDisable$(accessor: IAccessor) { export function getRemovePermissionDisable$(accessor: IAccessor) { const univerInstanceService = accessor.get(IUniverInstanceService); - const workbook = univerInstanceService.getCurrentUnitForType(UniverInstanceType.UNIVER_SHEET)!; - const selectionProtectionRuleModel = accessor.get(RangeProtectionRuleModel); - const worksheetProtectionRuleModel = accessor.get(WorksheetProtectionRuleModel); - const unitId = workbook.getUnitId(); const permissionService = accessor.get(IPermissionService); + const workbook$ = univerInstanceService.getCurrentTypeOfUnit$(UniverInstanceType.UNIVER_SHEET); const userManagerService = accessor.get(UserManagerService); - return combineLatest([workbook.activeSheet$, userManagerService.currentUser$]).pipe( - switchMap(([activeSheet, _]) => { - if (!activeSheet) { + return combineLatest([workbook$, userManagerService.currentUser$]).pipe( + switchMap(([workbook, _]) => { + if (!workbook) { return of(true); } - const subUnitId = activeSheet.getSheetId(); - const changes$ = merge( - accessor.get(SelectionManagerService).selectionMoveEnd$, - accessor.get(RangeProtectionRuleModel).ruleChange$, - accessor.get(WorksheetProtectionRuleModel).ruleChange$ - ); - const permission$ = permissionService.getPermissionPoint$(new WorkbookManageCollaboratorPermission(unitId).id)?.pipe(map((e) => !!e.value)) ?? of(false); - return combineLatest([changes$, permission$]).pipe( - map(([_, permission]) => { - if (!permission) { - return true; + return workbook.activeSheet$.pipe( + switchMap((worksheet) => { + if (!worksheet) { + return of(true); } - const selections = accessor.get(SelectionManagerService).getSelections(); - const selectionRanges = selections?.map((selection) => selection.range); - if (!selectionRanges?.length || selectionRanges.length > 1) { - return true; - } - - const selectionRange = selectionRanges[0]; - - const worksheetRule = worksheetProtectionRuleModel.getRule(unitId, subUnitId); - if (worksheetRule?.permissionId && worksheetRule?.name) { - return false; - } - - const subUnitRuleRanges = selectionProtectionRuleModel.getSubunitRuleList(unitId, subUnitId).map((rule) => rule.ranges).flat(); - - const hasLap = subUnitRuleRanges.some((ruleRange) => { - return Rectangle.intersects(selectionRange, ruleRange); - }); + const unitId = workbook.getUnitId(); + const subUnitId = worksheet.getSheetId(); + const selectionProtectionRuleModel = accessor.get(RangeProtectionRuleModel); + const worksheetProtectionRuleModel = accessor.get(WorksheetProtectionRuleModel); + const permission$ = permissionService.getPermissionPoint$(new WorkbookManageCollaboratorPermission(unitId).id)?.pipe(map((e) => !!e.value)) ?? of(false); + + const changes$ = merge( + selectionProtectionRuleModel.ruleChange$, + worksheetProtectionRuleModel.ruleChange$ + ).pipe(startWith(null)); + return combineLatest([changes$, permission$]).pipe( + map(([_, permission]) => { + if (!permission) { + return true; + } + const selections = accessor.get(SelectionManagerService).getSelections(); + const selectionRanges = selections?.map((selection) => selection.range); + if (!selectionRanges?.length || selectionRanges.length > 1) { + return true; + } + + const selectionRange = selectionRanges[0]; + + const worksheetRule = worksheetProtectionRuleModel.getRule(unitId, subUnitId); + if (worksheetRule?.permissionId && worksheetRule?.name) { + return false; + } + + const subUnitRuleRanges = selectionProtectionRuleModel.getSubunitRuleList(unitId, subUnitId).map((rule) => rule.ranges).flat(); + + const hasLap = subUnitRuleRanges.some((ruleRange) => { + return Rectangle.intersects(selectionRange, ruleRange); + }); - if (hasLap) { - return false; - } else { - return true; - } + if (hasLap) { + return false; + } else { + return true; + } + }) + ); }) ); }) @@ -374,19 +432,27 @@ export function getRemovePermissionDisable$(accessor: IAccessor) { export function getViewPermissionDisable$(accessor: IAccessor) { const univerInstanceService = accessor.get(IUniverInstanceService); - const workbook = univerInstanceService.getCurrentUnitForType(UniverInstanceType.UNIVER_SHEET)!; - const unitId = workbook.getUnitId(); - const userManagerService = accessor.get(UserManagerService); const permissionService = accessor.get(IPermissionService); + const workbook$ = univerInstanceService.getCurrentTypeOfUnit$(UniverInstanceType.UNIVER_SHEET); + const userManagerService = accessor.get(UserManagerService); - return combineLatest([workbook.activeSheet$, userManagerService.currentUser$]).pipe( - switchMap(([sheet, _]) => { - if (!sheet) { + return combineLatest([workbook$, userManagerService.currentUser$]).pipe( + switchMap(([workbook, _]) => { + if (!workbook) { return of(true); } - const permission$ = permissionService.getPermissionPoint$(new WorkbookEditablePermission(unitId).id)?.pipe(map((e) => !!e.value)) ?? of(false); - return permission$.pipe( - map((permission) => !permission) + + return workbook.activeSheet$.pipe( + switchMap((worksheet) => { + if (!worksheet) { + return of(true); + } + const unitId = workbook.getUnitId(); + const permission$ = permissionService.getPermissionPoint$(new WorkbookEditablePermission(unitId).id)?.pipe(map((e) => !!e.value)) ?? of(false); + return permission$.pipe( + map((permission) => !permission) + ); + }) ); }) ); diff --git a/packages/sheets-ui/src/index.ts b/packages/sheets-ui/src/index.ts index 2c812adadd2..76cbddff2bc 100644 --- a/packages/sheets-ui/src/index.ts +++ b/packages/sheets-ui/src/index.ts @@ -23,7 +23,7 @@ export { ExpandSelectionCommand, JumpOver, MoveSelectionCommand } from './comman export { SetCellEditVisibleArrowOperation, SetCellEditVisibleOperation } from './commands/operations/cell-edit.operation'; export { SetScrollOperation } from './commands/operations/scroll.operation'; export { SheetsScrollRenderController } from './controllers/render-controllers/scroll.render-controller'; -export { deriveStateFromActiveSheet$, getCurrentRangeDisable$, getCommentDisable$ } from './controllers/menu/menu-util'; +export { deriveStateFromActiveSheet$, getCurrentRangeDisable$ } from './controllers/menu/menu-util'; export { SheetsRenderService } from './services/sheets-render.service'; export { SetZoomRatioOperation } from './commands/operations/set-zoom-ratio.operation'; export { diff --git a/packages/sheets-ui/src/services/mark-selection/mark-selection.service.ts b/packages/sheets-ui/src/services/mark-selection/mark-selection.service.ts index 95dd6acd3fe..6b1c983bb19 100644 --- a/packages/sheets-ui/src/services/mark-selection/mark-selection.service.ts +++ b/packages/sheets-ui/src/services/mark-selection/mark-selection.service.ts @@ -69,13 +69,17 @@ export class MarkSelectionService extends Disposable implements IMarkSelectionSe control: null, exits, }); + this.refreshShapes(); return id; } refreshShapes() { - const currentUnitId = this._currentService.getCurrentUnitForType(UniverInstanceType.UNIVER_SHEET)!.getUnitId(); - const currentSubUnitId = this._currentService.getCurrentUnitForType(UniverInstanceType.UNIVER_SHEET)!.getActiveSheet()?.getSheetId(); + const currentSheet = this._currentService.getCurrentUnitForType(UniverInstanceType.UNIVER_SHEET); + if (!currentSheet) return; + + const currentUnitId = currentSheet.getUnitId(); + const currentSubUnitId = currentSheet.getActiveSheet()?.getSheetId(); this._shapeMap.forEach((shape) => { const { unitId, subUnitId, selection, control: oldControl, zIndex } = shape; diff --git a/packages/sheets/src/commands/commands/__tests__/create-command-test-bed.ts b/packages/sheets/src/commands/commands/__tests__/create-command-test-bed.ts index 84110ddee73..e8dc60c6252 100644 --- a/packages/sheets/src/commands/commands/__tests__/create-command-test-bed.ts +++ b/packages/sheets/src/commands/commands/__tests__/create-command-test-bed.ts @@ -36,6 +36,7 @@ import { BorderStyleManagerService } from '../../../services/border-style-manage import { SelectionManagerService } from '../../../services/selection-manager.service'; import { SheetInterceptorService } from '../../../services/sheet-interceptor/sheet-interceptor.service'; import { WorksheetProtectionPointModel, WorksheetProtectionRuleModel } from '../../../services/permission/worksheet-permission'; +import { RangeProtectionRuleModel } from '../../../model/range-protection-rule.model'; const TEST_WORKBOOK_DATA_DEMO: IWorkbookData = { id: 'test', @@ -98,6 +99,7 @@ export function createCommandTestBed(workbookData?: IWorkbookData, dependencies? override onStarting(injector: Injector): void { injector.add([WorksheetPermissionService]); injector.add([WorksheetProtectionPointModel]); + injector.add([RangeProtectionRuleModel]); injector.add([WorkbookPermissionService]); injector.add([WorksheetProtectionRuleModel]); injector.add([SelectionManagerService]); diff --git a/packages/sheets/src/controllers/calculate-result-apply.controller.ts b/packages/sheets/src/controllers/calculate-result-apply.controller.ts index 50b50b1d18e..29094ce2220 100644 --- a/packages/sheets/src/controllers/calculate-result-apply.controller.ts +++ b/packages/sheets/src/controllers/calculate-result-apply.controller.ts @@ -34,10 +34,6 @@ export class CalculateResultApplyController extends Disposable { } private _initialize(): void { - this._commandExecutedListener(); - } - - private _commandExecutedListener() { this.disposeWithMe( this._commandService.onCommandExecuted((command: ICommandInfo) => { if (command.id !== SetFormulaCalculationResultMutation.id) { diff --git a/packages/sheets/src/controllers/defined-name-data.controller.ts b/packages/sheets/src/controllers/defined-name-data.controller.ts index b61c9144afa..44a1e25d2c5 100644 --- a/packages/sheets/src/controllers/defined-name-data.controller.ts +++ b/packages/sheets/src/controllers/defined-name-data.controller.ts @@ -16,9 +16,7 @@ import { Disposable, - ICommandService, IResourceManagerService, - IUniverInstanceService, LifecycleStages, OnLifecycle, UniverInstanceType } from '@univerjs/core'; @@ -30,11 +28,8 @@ const SHEET_DEFINED_NAME_PLUGIN = 'SHEET_DEFINED_NAME_PLUGIN'; @OnLifecycle(LifecycleStages.Ready, DefinedNameDataController) export class DefinedNameDataController extends Disposable { constructor( - @ICommandService private readonly _commandService: ICommandService, - @IUniverInstanceService private readonly _univerInstanceService: IUniverInstanceService, @IDefinedNamesService private readonly _definedNamesService: IDefinedNamesService, @IResourceManagerService private _resourceManagerService: IResourceManagerService - ) { super(); diff --git a/packages/sheets/src/controllers/feature-calculation.controller.ts b/packages/sheets/src/controllers/feature-calculation.controller.ts deleted file mode 100644 index 4ad2ab555b3..00000000000 --- a/packages/sheets/src/controllers/feature-calculation.controller.ts +++ /dev/null @@ -1,105 +0,0 @@ -/** - * Copyright 2023-present DreamNum Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import { - Disposable, - ICommandService, - IUniverInstanceService, - LifecycleStages, - ObjectMatrix, - OnLifecycle, -} from '@univerjs/core'; -import { FormulaDataModel, IFeatureCalculationManagerService } from '@univerjs/engine-formula'; -import { Inject } from '@wendellhu/redi'; - -@OnLifecycle(LifecycleStages.Ready, FeatureCalculationController) -export class FeatureCalculationController extends Disposable { - constructor( - @ICommandService private readonly _commandService: ICommandService, - @IFeatureCalculationManagerService - private readonly _featureCalculationManagerService: IFeatureCalculationManagerService, - @IUniverInstanceService private readonly _univerInstanceService: IUniverInstanceService, - @Inject(FormulaDataModel) private readonly _formulaDataModel: FormulaDataModel - ) { - super(); - - // this._initialize(); - } - - /** - * Test function access to the formula system example , feature calculation , - * you can register a listening range and callback function , - * the range will be analyzed through the dependency after the callback function execution , - * the callback function to return to an execution result , - * you can continue to enter the formula dependency system , to get the final result . - */ - private _initialize(): void { - const featureId = 'test'; - - const unitId = 'workbook-01'; - - const subUnitId = 'sheet-0011'; - - const runtimeCellData = { - [unitId]: { - [subUnitId]: new ObjectMatrix({ - 4: { - 0: { - v: 10, - t: 2, - }, - }, - }), - }, - }; - - const dirtyRanges = { - [unitId]: { - [subUnitId]: [ - { - startRow: 4, - startColumn: 0, - endRow: 4, - endColumn: 0, - }, - ], - }, - }; - - this._featureCalculationManagerService.register(featureId, { - unitId, - subUnitId, - dependencyRanges: [ - { - unitId, - sheetId: subUnitId, - range: { - startRow: 0, - endRow: 3, - startColumn: 0, - endColumn: 3, - }, - }, - ], - getDirtyData: () => { - return { - runtimeCellData, - dirtyRanges, - }; - }, - }); - } -} diff --git a/packages/sheets/src/services/permission/workbook-permission/workbook-permission.service.ts b/packages/sheets/src/services/permission/workbook-permission/workbook-permission.service.ts index ad2f1c08f3f..d3c41368745 100644 --- a/packages/sheets/src/services/permission/workbook-permission/workbook-permission.service.ts +++ b/packages/sheets/src/services/permission/workbook-permission/workbook-permission.service.ts @@ -18,15 +18,20 @@ import { Inject } from '@wendellhu/redi'; import type { Workbook } from '@univerjs/core'; import { Disposable, IPermissionService, IUniverInstanceService, LifecycleStages, OnLifecycle, UniverInstanceType } from '@univerjs/core'; +import { getAllWorksheetPermissionPoint, getAllWorksheetPermissionPointByPointPanel } from '../worksheet-permission/utils'; +import { RangeProtectionRuleModel } from '../../../model/range-protection-rule.model'; +import { RangeProtectionPermissionEditPoint, RangeProtectionPermissionViewPoint } from '../permission-point'; import { getAllWorkbookPermissionPoint } from './util'; @OnLifecycle(LifecycleStages.Starting, WorkbookPermissionService) export class WorkbookPermissionService extends Disposable { constructor( @Inject(IPermissionService) private _permissionService: IPermissionService, - @Inject(IUniverInstanceService) private _univerInstanceService: IUniverInstanceService + @Inject(IUniverInstanceService) private _univerInstanceService: IUniverInstanceService, + @Inject(RangeProtectionRuleModel) private _rangeProtectionRuleModel: RangeProtectionRuleModel ) { super(); + this._init(); } @@ -49,6 +54,22 @@ export class WorkbookPermissionService extends Disposable { this.disposeWithMe(this._univerInstanceService.getTypeOfUnitDisposed$(UniverInstanceType.UNIVER_SHEET).subscribe((workbook) => { const unitId = workbook.getUnitId(); + workbook.getSheets().forEach((worksheet) => { + const subUnitId = worksheet.getSheetId(); + + const rangeRuleList = this._rangeProtectionRuleModel.getSubunitRuleList(unitId, subUnitId); + rangeRuleList.forEach((rule) => { + [RangeProtectionPermissionEditPoint, RangeProtectionPermissionViewPoint].forEach((F) => { + const instance = new F(unitId, subUnitId, rule.permissionId); + this._permissionService.deletePermissionPoint(instance.id); + }); + }); + + [...getAllWorksheetPermissionPoint(), ...getAllWorksheetPermissionPointByPointPanel()].forEach((F) => { + const instance = new F(unitId, subUnitId); + this._permissionService.deletePermissionPoint(instance.id); + }); + }); getAllWorkbookPermissionPoint().forEach((F) => { const instance = new F(unitId); this._permissionService.deletePermissionPoint(instance.id); diff --git a/packages/sheets/src/services/permission/worksheet-permission/worksheet-permission.service.ts b/packages/sheets/src/services/permission/worksheet-permission/worksheet-permission.service.ts index 8b83055e246..07692b27e8f 100644 --- a/packages/sheets/src/services/permission/worksheet-permission/worksheet-permission.service.ts +++ b/packages/sheets/src/services/permission/worksheet-permission/worksheet-permission.service.ts @@ -18,12 +18,11 @@ import type { Workbook, Worksheet } from '@univerjs/core'; import { IPermissionService, IResourceManagerService, IUniverInstanceService, LifecycleStages, OnLifecycle, RxDisposable, UniverInstanceType } from '@univerjs/core'; import { Inject, Injector } from '@wendellhu/redi'; import { takeUntil } from 'rxjs/operators'; - -// import type { UnitAction, UnitObject } from '@univerjs/protocol'; import { UniverType } from '@univerjs/protocol'; import type { IObjectModel, IObjectPointModel } from '../type'; -import { SheetInterceptorService } from '../../sheet-interceptor/sheet-interceptor.service'; +import { RangeProtectionPermissionEditPoint, RangeProtectionPermissionViewPoint } from '../permission-point'; +import { RangeProtectionRuleModel } from '../../../model/range-protection-rule.model'; import { WorksheetProtectionRuleModel } from './worksheet-permission-rule.model'; import { getAllWorksheetPermissionPoint, getAllWorksheetPermissionPointByPointPanel } from './utils'; import { WorksheetProtectionPointModel } from './worksheet-permission-point.model'; @@ -40,7 +39,7 @@ export class WorksheetPermissionService extends RxDisposable { @Inject(WorksheetProtectionRuleModel) private _worksheetProtectionRuleModel: WorksheetProtectionRuleModel, @Inject(WorksheetProtectionPointModel) private _worksheetProtectionPointRuleModel: WorksheetProtectionPointModel, @Inject(IResourceManagerService) private _resourceManagerService: IResourceManagerService, - @Inject(SheetInterceptorService) private _sheetInterceptorService: SheetInterceptorService + @Inject(RangeProtectionRuleModel) private _rangeProtectionRuleModel: RangeProtectionRuleModel ) { super(); this._init(); @@ -67,6 +66,15 @@ export class WorksheetPermissionService extends RxDisposable { }); workbook.sheetDisposed$.subscribe((worksheet) => { const subUnitId = worksheet.getSheetId(); + + const rangeRuleList = this._rangeProtectionRuleModel.getSubunitRuleList(unitId, subUnitId); + rangeRuleList.forEach((rule) => { + [RangeProtectionPermissionEditPoint, RangeProtectionPermissionViewPoint].forEach((F) => { + const instance = new F(unitId, subUnitId, rule.permissionId); + this._permissionService.deletePermissionPoint(instance.id); + }); + }); + [...getAllWorksheetPermissionPoint(), ...getAllWorksheetPermissionPointByPointPanel()].forEach((F) => { const instance = new F(unitId, subUnitId); this._permissionService.deletePermissionPoint(instance.id); diff --git a/packages/sheets/src/sheets-plugin.ts b/packages/sheets/src/sheets-plugin.ts index 75acb32d702..9570b063c76 100644 --- a/packages/sheets/src/sheets-plugin.ts +++ b/packages/sheets/src/sheets-plugin.ts @@ -22,7 +22,6 @@ import { Inject, Injector } from '@wendellhu/redi'; import { UniverFormulaEnginePlugin } from '@univerjs/engine-formula'; import { BasicWorksheetController } from './controllers/basic-worksheet.controller'; import { CalculateResultApplyController } from './controllers/calculate-result-apply.controller'; -import { FeatureCalculationController } from './controllers/feature-calculation.controller'; import { MergeCellController } from './controllers/merge-cell.controller'; import { BorderStyleManagerService } from './services/border-style-manager.service'; import { NumfmtService } from './services/numfmt/numfmt.service'; @@ -114,8 +113,7 @@ export class UniverSheetsPlugin extends Plugin { if (!this._config?.notExecuteFormula) { // Should execute formula. dependencies.push( - [CalculateResultApplyController], - [FeatureCalculationController] + [CalculateResultApplyController] ); }