Skip to content

Commit

Permalink
chore: update permission facade (#4557)
Browse files Browse the repository at this point in the history
  • Loading branch information
ybzky authored Jan 23, 2025
1 parent 5b7cc47 commit bfd9ba4
Show file tree
Hide file tree
Showing 5 changed files with 306 additions and 25 deletions.
18 changes: 10 additions & 8 deletions packages/facade/src/apis/sheets/__tests__/f-permission.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -80,13 +80,15 @@ describe('Test FPermission', () => {

it('set range protection point false', async () => {
const permission = univerAPI.getPermission();
const unitId = univerAPI.getActiveWorkbook()?.getId();
const subUnitId = univerAPI.getActiveWorkbook()?.getActiveSheet().getSheetId();
const ranges = [{ startRow: 0, endRow: 1, startColumn: 0, endColumn: 1 }];
const newRanges = [{ startRow: 0, endRow: 2, startColumn: 0, endColumn: 2 }];
const workbook = univerAPI.getActiveWorkbook();
const worksheet = workbook?.getActiveSheet();
const unitId = workbook?.getId();
const subUnitId = worksheet?.getSheetId();
const rangeFirst = worksheet?.getRange(0, 0, 2, 2);
const rangeSecond = worksheet?.getRange(0, 0, 3, 3);

if (unitId && subUnitId) {
const res = await permission.addRangeBaseProtection(unitId, subUnitId, ranges);
if (unitId && subUnitId && rangeFirst && rangeSecond) {
const res = await permission.addRangeBaseProtection(unitId, subUnitId, [rangeFirst]);
if (!res?.permissionId || !res?.ruleId) {
return;
}
Expand All @@ -103,9 +105,9 @@ describe('Test FPermission', () => {
catchErr = true;
}
expect(catchErr).toBe(true);
permission.setRangeProtectionRanges(unitId, subUnitId, res.ruleId, newRanges);
permission.setRangeProtectionRanges(unitId, subUnitId, res.ruleId, [rangeSecond]);
let rule = rangeProtectionRuleModel.getRule(unitId, subUnitId, res.ruleId);
expect(rule?.ranges).toStrictEqual(newRanges);
expect(rule?.ranges).toStrictEqual([rangeSecond].map((range) => range.getRange()));
permission.removeRangeProtection(unitId, subUnitId, [res.ruleId]);
rule = rangeProtectionRuleModel.getRule(unitId, subUnitId, res.ruleId);
expect(rule).toBeUndefined();
Expand Down
153 changes: 142 additions & 11 deletions packages/sheets/src/facade/f-permission.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,18 +14,29 @@
* limitations under the License.
*/

import type { IRange, RangePermissionPointConstructor, WorkbookPermissionPointConstructor, WorkSheetPermissionPointConstructor } from '@univerjs/core';
import type { RangePermissionPointConstructor, WorkbookPermissionPointConstructor, WorkSheetPermissionPointConstructor } from '@univerjs/core';
import type { Observable } from 'rxjs';
import type { FRange } from './f-range';
import { FBase, generateRandomId, IAuthzIoService, ICommandService, Inject, Injector, IPermissionService, Rectangle } from '@univerjs/core';
import { AddRangeProtectionMutation, AddWorksheetProtectionMutation, DeleteRangeProtectionMutation, DeleteWorksheetProtectionMutation, getAllWorksheetPermissionPoint, getAllWorksheetPermissionPointByPointPanel, PermissionPointsDefinitions, RangeProtectionRuleModel, SetRangeProtectionMutation, SetWorksheetPermissionPointsMutation, UnitObject, WorkbookEditablePermission, WorksheetEditPermission, WorksheetProtectionPointModel, WorksheetProtectionRuleModel, WorksheetViewPermission } from '@univerjs/sheets';

/**
* @description Used to generate permission instances to control permissions for the entire workbook
* @hideconstructor
*/
export class FPermission extends FBase {
/**
* Permission point definition, can read the point constructor want to modify from here
*/
public permissionPointsDefinition = PermissionPointsDefinitions;
public rangeRuleChangedAfterAuth$: Observable<unknown>;
public sheetRuleChangedAfterAuth$: Observable<unknown>;
/**
* An observable object used to monitor permission change events within a range, thereby triggering corresponding subsequent processing.
*/
public rangeRuleChangedAfterAuth$: Observable<string>;
/**
* An observable object used to monitor permission change events within a worksheet, thereby triggering corresponding subsequent processing.
*/
public sheetRuleChangedAfterAuth$: Observable<string>;

constructor(
@Inject(Injector) protected readonly _injector: Injector,
Expand All @@ -43,12 +54,19 @@ export class FPermission extends FBase {

/**
* Configures a specific permission point for a workbook.
*
* This function sets or updates a permission point for a workbook identified by `unitId`.
* It creates a new permission point if it does not already exist, and updates the point with the provided value.
* @param {string} unitId - The unique identifier of the workbook for which the permission is being set.
* @param {WorkbookPermissionPointConstructor} FPointClass - The constructor function for creating a permission point instance. Other point constructors can See the [permission-point documentation](https://github.com/dream-num/univer/tree/dev/packages/sheets/src/services/permission/permission-point) for more details.
* @param {boolean} value - The boolean value to determine whether the permission point is enabled or disabled.
*
* @example
* ```typescript
* const workbook = univerAPI.getActiveWorkbook();
* const permission = workbook.getPermission();
* const unitId = workbook.getId();
* permission.setWorkbookPermissionPoint(unitId, permission.permissionPointsDefinition.WorkbookEditablePermission, false)
* ```
*/
setWorkbookPermissionPoint(unitId: string, FPointClass: WorkbookPermissionPointConstructor, value: boolean): void {
const instance = new FPointClass(unitId);
Expand All @@ -63,16 +81,40 @@ export class FPermission extends FBase {
* This function is used to set whether the workbook can be edited
* @param {string} unitId - The unique identifier of the workbook for which the permission is being set.
* @param {boolean} value - A value that controls whether the workbook can be edited
*
* @example
* ```typescript
* const workbook = univerAPI.getActiveWorkbook();
* const permission = workbook.getPermission();
* const unitId = workbook.getId();
* permission.setWorkbookEditPermission(unitId, false);
* ```
*/
setWorkbookEditPermission(unitId: string, value: boolean): void {
this.setWorkbookPermissionPoint(unitId, WorkbookEditablePermission, value);
}

/**
* This function is used to add a base permission for a worksheet.
* Note that after adding, only the background mask of the permission module will be rendered. If you want to modify the function permissions,
* you need to modify the permission points with the permissionId returned by this function.
* @param {string} unitId - The unique identifier of the workbook for which the permission is being set.
* @param {string} subUnitId - The unique identifier of the worksheet for which the permission is being set.
* @returns {Promise<string | undefined>} - Returns the `permissionId` if the permission is successfully added. If the operation fails or no result is returned, it resolves to `undefined`.
*
* @example
* ```typescript
* const workbook = univerAPI.getActiveWorkbook();
* const permission = workbook.getPermission();
* const unitId = workbook.getId();
* const worksheet = workbook.getActiveSheet();
* const subUnitId = worksheet.getSheetId();
* // Note that there will be no permission changes after this step is completed. It only returns an ID for subsequent permission changes.
* // For details, please see the example of the **`setWorksheetPermissionPoint`** API.
* const permissionId = await permission.addWorksheetBasePermission(unitId, subUnitId)
* // Can still edit and read it.
* console.log('debugger', permissionId)
* ```
*/
async addWorksheetBasePermission(unitId: string, subUnitId: string): Promise<string | undefined> {
const hasRangeProtection = this._rangeProtectionRuleModel.getSubunitRuleList(unitId, subUnitId).length > 0;
Expand Down Expand Up @@ -107,6 +149,16 @@ export class FPermission extends FBase {
* Delete the entire table protection set for the worksheet and reset the point permissions of the worksheet to true
* @param {string} unitId - The unique identifier of the workbook for which the permission is being set.
* @param {string} subUnitId - The unique identifier of the worksheet for which the permission is being set.
*
* @example
* ```typescript
* const workbook = univerAPI.getActiveWorkbook();
* const permission = workbook.getPermission();
* const unitId = workbook.getId();
* const worksheet = workbook.getActiveSheet();
* const subUnitId = worksheet.getSheetId();
* permission.removeWorksheetPermission(unitId, subUnitId);
* ```
*/
removeWorksheetPermission(unitId: string, subUnitId: string): void {
this._commandService.syncExecuteCommand(DeleteWorksheetProtectionMutation.id, {
Expand All @@ -130,6 +182,17 @@ export class FPermission extends FBase {
* See the [permission-point documentation](https://github.com/dream-num/univer/tree/dev/packages/sheets/src/services/permission/permission-point) for more details.
* @param {boolean} value - The new permission value to be set for the worksheet.
* @returns {Promise<string | undefined>} - Returns the `permissionId` if the permission point is successfully set or created. If no permission is set, it resolves to `undefined`.
*
* @example
* ```typescript
* const workbook = univerAPI.getActiveWorkbook();
* const permission = workbook.getPermission();
* const unitId = workbook.getId();
* const worksheet = workbook.getActiveSheet();
* const subUnitId = worksheet.getSheetId();
* const permissionId = await permission.addWorksheetBasePermission(unitId, subUnitId)
* // After this line of code , the worksheet will no longer be editable
* permission.setWorksheetPermissionPoint(unitId, subUnitId, permission.permissionPointsDefinition.WorksheetEditPermission, false);
*/
async setWorksheetPermissionPoint(unitId: string, subUnitId: string, FPointClass: WorkSheetPermissionPointConstructor, value: boolean): Promise<string | undefined> {
const hasBasePermission = this._worksheetProtectionRuleModel.getRule(unitId, subUnitId);
Expand Down Expand Up @@ -175,12 +238,31 @@ export class FPermission extends FBase {

/**
* Adds a range protection to the worksheet.
* Note that after adding, only the background mask of the permission module will be rendered. If you want to modify the function permissions,
* you need to modify the permission points with the permissionId returned by this function.
* @param {string} unitId - The unique identifier of the workbook.
* @param {string} subUnitId - The unique identifier of the worksheet.
* @param {IRange[]} ranges - The ranges to be protected.
* @param {FRange[]} ranges - The ranges to be protected.
* @returns {Promise<{ permissionId: string, ruleId: string } | undefined>} - Returns an object containing the `permissionId` and `ruleId` if the range protection is successfully added. If the operation fails or no result is returned, it resolves to `undefined`. permissionId is used to stitch permission point ID,ruleId is used to store permission rules
*
* @example
* ```typescript
*const workbook = univerAPI.getActiveWorkbook();
* const permission = workbook.getPermission();
* const unitId = workbook.getId();
* const worksheet = workbook.getActiveSheet();
* const subUnitId = worksheet.getSheetId();
* const range = worksheet.getRange(0,0,2,2);
* const ranges = [];
* ranges.push(range);
* // Note that there will be no permission changes after this step is completed. It only returns an ID for subsequent permission changes.
* // For details, please see the example of the **`setRangeProtectionPermissionPoint`** API.
* const res = await permission.addRangeBaseProtection(unitId, subUnitId, ranges);
* const {permissionId, ruleId} = res;
* console.log('debugger', permissionId, ruleId);
* ```
*/
async addRangeBaseProtection(unitId: string, subUnitId: string, ranges: IRange[]): Promise<{
async addRangeBaseProtection(unitId: string, subUnitId: string, ranges: FRange[]): Promise<{
permissionId: string;
ruleId: string;
} | undefined> {
Expand All @@ -202,7 +284,7 @@ export class FPermission extends FBase {
const overlap = subunitRuleList.some((rule) => {
return rule.ranges.some((range) => {
return ranges.some((newRange) => {
return Rectangle.intersects(newRange, range);
return Rectangle.intersects(newRange.getRange(), range);
});
});
});
Expand All @@ -217,7 +299,7 @@ export class FPermission extends FBase {
unitType: UnitObject.SelectRange,
unitId,
subUnitId,
ranges,
ranges: ranges.map((range) => range.getRange()),
id: ruleId,
}],
});
Expand All @@ -234,6 +316,21 @@ export class FPermission extends FBase {
* @param {string} unitId - The unique identifier of the workbook.
* @param {string} subUnitId - The unique identifier of the worksheet.
* @param {string[]} ruleIds - The rule IDs of the range protection to be removed.
*
* @example
* ```typescript
* const workbook = univerAPI.getActiveWorkbook();
* const permission = workbook.getPermission();
* const unitId = workbook.getId();
* const worksheet = workbook.getActiveSheet();
* const subUnitId = worksheet.getSheetId();
* const range = worksheet.getRange(0,0,2,2);
* const ranges = [];
* ranges.push(range);
* const res = await permission.addRangeBaseProtection(unitId, subUnitId, ranges);
* const ruleId = res.ruleId;
* permission.removeRangeProtection(unitId, subUnitId, [ruleId]);
* ```
*/
removeRangeProtection(unitId: string, subUnitId: string, ruleIds: string[]): void {
const res = this._commandService.syncExecuteCommand(DeleteRangeProtectionMutation.id, {
Expand Down Expand Up @@ -262,6 +359,24 @@ export class FPermission extends FBase {
* @param {RangePermissionPointConstructor} FPointClass - The constructor for the range permission point class.
* See the [permission-point documentation](https://github.com/dream-num/univer/tree/dev/packages/sheets/src/services/permission/permission-point) for more details.
* @param {boolean} value - The new permission value to be set for the range (e.g., true for allowing access, false for restricting access).
*
* @example
* ```typescript
* const workbook = univerAPI.getActiveWorkbook();
* const permission = workbook.getPermission();
* const unitId = workbook.getId();
* const worksheet = workbook.getActiveSheet();
* const subUnitId = worksheet.getSheetId();
* const range = worksheet.getRange(0, 0, 2, 2);
* const ranges = [];
* ranges.push(range);
* // Note that there will be no permission changes after this step is completed. It only returns an ID for subsequent permission changes.
* // For details, please see the example of the **`setRangeProtectionPermissionPoint`** API.
* const res = await permission.addRangeBaseProtection(unitId, subUnitId, ranges);
* const {permissionId, ruleId} = res;
* // After passing the following line of code, the range set above will become uneditable
* permission.setRangeProtectionPermissionPoint(unitId,subUnitId,permissionId, permission.permissionPointsDefinition.RangeProtectionPermissionEditPoint, false);
* ```
*/
setRangeProtectionPermissionPoint(unitId: string, subUnitId: string, permissionId: string, FPointClass: RangePermissionPointConstructor, value: boolean): void {
const instance = new FPointClass(unitId, subUnitId, permissionId);
Expand All @@ -282,15 +397,31 @@ export class FPermission extends FBase {
* @param {string} subUnitId - The unique identifier of the worksheet within the workbook.
* @param {string} ruleId - The ruleId of the range protection rule that is being updated.
* @param {IRange[]} ranges - The array of new ranges to be set for the range protection rule.
*
* @example
* ```typescript
* const workbook = univerAPI.getActiveWorkbook();
* const permission = workbook.getPermission();
* const unitId = workbook.getId();
* const worksheet = workbook.getActiveSheet();
* const subUnitId = worksheet.getSheetId();
* const range = worksheet.getRange(0, 0, 2, 2);
* const ranges = [];
* ranges.push(range);
* const res = await permission.addRangeBaseProtection(unitId, subUnitId, ranges);
* const {permissionId, ruleId} = res;
* const newRange = worksheet.getRange(3, 3, 2, 2);
* permission.setRangeProtectionRanges(unitId, subUnitId, ruleId, [newRange]);
* ```
*/
setRangeProtectionRanges(unitId: string, subUnitId: string, ruleId: string, ranges: IRange[]): void {
setRangeProtectionRanges(unitId: string, subUnitId: string, ruleId: string, ranges: FRange[]): void {
const rule = this._rangeProtectionRuleModel.getRule(unitId, subUnitId, ruleId);
if (rule) {
const subunitRuleList = this._rangeProtectionRuleModel.getSubunitRuleList(unitId, subUnitId).filter((r) => r.id !== ruleId);
const overlap = subunitRuleList.some((rule) => {
return rule.ranges.some((range) => {
return ranges.some((newRange) => {
return Rectangle.intersects(newRange, range);
return Rectangle.intersects(newRange.getRange(), range);
});
});
});
Expand All @@ -303,7 +434,7 @@ export class FPermission extends FBase {
ruleId,
rule: {
...rule,
ranges,
ranges: ranges.map((range) => range.getRange()),
},
});
}
Expand Down
2 changes: 1 addition & 1 deletion packages/sheets/src/model/range-protection-rule.model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ export class RangeProtectionRuleModel {

ruleChange$ = this._ruleChange.asObservable();

private _ruleRefresh = new Subject();
private _ruleRefresh = new Subject<string>();
ruleRefresh$ = this._ruleRefresh.asObservable();

ruleRefresh(id: string) {
Expand Down
Loading

0 comments on commit bfd9ba4

Please sign in to comment.