# 권한

## Content

SpreadJS Sheets 동시 작업은 **보기 모드(View Mode)**와 **편집 모드(Edit Mode)**의 두 가지 문서 모드를 제공합니다. 권한(Permissions) 기능을 통해 동시 작업 환경에서 유연성과 보안을 균형 있게 유지하면서 **보기 모드**에서 특정 작업 권한을 워크북에 설정할 수 있습니다.

## 기능 설명

### IPermission

**[IPermission](/spreadjs/api/v19/collaboration/spread-sheets-collaboration-client/interfaces/IPermission)**[ ](/spreadjs/api/v19/collaboration/spread-sheets-collaboration-client/interfaces/IPermission) 인터페이스는 워크북의 구체적인 권한을 정의하며, 다음 속성을 포함합니다.

* **mode: BrowsingMode**
    워크북 접근 모드를 지정하며 **BrowsingMode** 열거형 값을 사용합니다.
    * **BrowsingMode.edit**: 워크북을 편집할 수 있습니다.
    * **BrowsingMode.view**: 워크북은 읽기 전용이지만 추가 권한을 가질 수 있습니다.
* **viewModePermissions: PermissionTypes (선택 사항)**
    워크북이 **view** 모드일 때의 추가 권한을 지정합니다. 이 속성은 비트 필드로, 비트 연산을 사용해 여러 **PermissionTypes** 값을 조합할 수 있습니다.

```typescript
export type IPermission {
    mode: GC.Spread.Sheets.Collaboration.BrowsingMode;
    viewModePermissions?: GC.Spread.Sheets.Collaboration.PermissionTypes;
}
```

### 열거형 타입

#### [BrowsingMode](/spreadjs/api/v19/collaboration/spread-sheets-collaboration-client/enums/BrowsingMode)

워크북의 탐색 모드를 정의합니다.

* **edit = 0**: 편집 모드, 워크북을 수정할 수 있습니다.
* **view = 1**: 보기 모드, 워크북은 읽기 전용입니다.

```typescript
/**
 * 문서 상호 작용을 위한 탐색 모드를 열거합니다.
 * @enum {number}
 */
export enum BrowsingMode {
    /** 워크북을 편집할 수 있습니다.
     * @type {number}
     */
    edit,
    /** 워크북을 보기 전용으로 표시합니다.
     * @type {number}
     */
    view,
}
```

### 편집 모드

* 워크북에 대한 편집 권한에 제한이 없습니다.
* 모든 변경 사항이 다른 동시 작업 사용자와 실시간으로 동기화됩니다.
* 워크북의 **기본 모드**입니다.

### 보기 모드

* 워크북은 읽기 전용입니다.
* 행 숨기기, 열 너비 조정과 같은 특정 UI 작업은 권한을 통해 허용할 수 있지만, 이러한 작업은 **로컬에만 적용되며 동기화되지 않습니다.**
* **보기 모드**에서는 기본적으로 모든 되돌릴 수 있는 명령(Command)이 비활성화됩니다. 단, 데이터 무결성을 유지하면서 보기 환경을 최적화하기 위해 다음 권한을 선택적으로 허용할 수 있습니다.
    * `allowNonDataModifyingOperations`: 데이터 변경이 없는 작업 허용
    * `allowHideRowsOrColumns`: 행 또는 열 숨기기/표시 허용
    * `allowResizeRowsOrColumns`: 행 또는 열 크기 조정 허용
    * `allowFilter`: 필터 적용 허용
    * `allowSort`: 정렬 허용

### 정책 포인트

* 보기 모드에서는 모든 Command 작업(기본 명령 및 사용자 정의 Command 포함)이 제한되지만, API 호출은 제한되지 않습니다.
* 보기 모드에서 권한으로 허용된 작업으로 인한 데이터 변경은 로컬에만 적용되며 동기화되지 않습니다.

### 적용 시나리오

* **데이터 조회**: **보기 모드**의 워크북에서 행 숨기기, 필터 적용 등 UI를 조정하여 다른 사용자의 워크북에 영향을 주지 않고 데이터를 분석할 수 있습니다.
* **보안**: 세분화된 권한 제어를 통해 무단 수정을 방지하고 동시 작업 환경에서 데이터를 보호합니다.
* **팀 동시 작업**: 상태 추적과 결합하여 사용자는 다른 사용자의 작업을 확인하면서도 자신의 작업 권한은 제어할 수 있습니다.

## 메서드

사용자는 **UserManager.current** 및 **setPermission** 메서드를 사용하여 사용자 정보를 워크북에 바인딩할 수 있으며, 또는 [bindPresence ](/spreadjs/api/v19/collaboration/spread-sheets-collaboration-client/README#bindpresence) 메서드를 사용해 Presence와 사용자 정보를 동시에 워크북에 바인딩할 수 있습니다.

## 사용 방법

다음 예제는 활성 사용자를 설정하고 워크북 권한을 보기 모드로 설정한 뒤, 행/열 숨기기·표시, 행/열 크기 조정, 필터 기능을 허용하는 방법을 보여줍니다.

* 워크북 및 사용자 정보 초기화

```typescript
// 현재 사용자 설정
GC.Spread.Common.UserManager.current("896736#B1WZd2yQ");

const workbook = new GC.Spread.Sheets.Workbook("ss");
// 워크북 권한 설정
workbook.collaboration.setPermission({
  mode: GC.Spread.Sheets.Collaboration.BrowsingMode.view,
  viewModePermissions: GC.Spread.Sheets.Collaboration.PermissionTypes.allowHideRowsOrColumns
    | GC.Spread.Sheets.Collaboration.PermissionTypes.allowResizeRowsOrColumns
    | GC.Spread.Sheets.Collaboration.PermissionTypes.allowFilter
});
```

* Presence 및 권한이 포함된 사용자 정보를 워크북에 바인딩

```typescript
const presence = new Presence<IPresence>(conn);
const workbook = new GC.Spread.Sheets.Workbook(document.getElementById("ss"), { sheetCount: 2 });
const user = {
    id: "896736#B1WZd2yQ",
    name: "chris",
    color: "#FF0000",
    permission: {
      mode: GC.Spread.Sheets.Collaboration.BrowsingMode.view,
      viewModePermissions: GC.Spread.Sheets.Collaboration.PermissionTypes.allowHideRowsOrColumns
      | GC.Spread.Sheets.Collaboration.PermissionTypes.allowResizeRowsOrColumns
      | GC.Spread.Sheets.Collaboration.PermissionTypes.allowFilter
    }
};
bindPresence(workbook, presence, user);
```

## API

* `spread-sheets-collaboration-client`

```typescript
/**
 * BrowsingMode 정의
 * @enum {number}
 */
export enum BrowsingMode {
    /** 사용자가 문서를 편집할 수 있음을 지정합니다.
     * @type {number}
     */
    edit,
    /** 사용자가 문서를 보기만 할 수 있음을 지정합니다.
     * @type {number}
     */
    view,
}
/**
 * PermissionTypes 정의
 * @enum {number}
 */
export enum PermissionTypes {
    /** 데이터 변경이 없는 작업 실행 허용
     * @type {number}
     */
    allowNonDataModifyingOperations,
    /** 행/열 숨기기 또는 표시 허용
     * @type {number}
     */
    allowHideRowsOrColumns,
    /** 행/열 크기 조정 허용
     * @type {number}
     */
    allowResizeRowsOrColumns,
    /** 범위 필터 허용
     * @type {number}
     */
    allowFilter,
    /** 정렬 허용
     * @type {number}
     */
    allowSort,
}
export interface IPermission {
    mode: BrowsingMode;
    viewModePermissions?: PermissionTypes;
}
```

* `GC.Spread.Sheets.Collaboration.Collaboration`

```typescript
///* function setPermission(permission: GC.Spread.Sheets.Collaboration.IPermission): void
/**
  * 권한 정보를 설정합니다.
  * @param {GC.Spread.Sheets.Collaboration.IPermission} permission - 권한 정보
  * @example
  * // 현재 권한을 업데이트합니다.
  * let permission = {
  *     mode: GC.Spread.Sheets.Collaboration.BrowsingMode.view,
  * };
  * spread.collaboration.setPermission(permission);
  */
setPermission (permission: IPermission): void;

///* function getPermission(): GC.Spread.Sheets.Collaboration.IPermission
/**
  * 워크북의 권한을 가져옵니다.
  * @returns {GC.Spread.Sheets.Collaboration.IPermission} permission - 권한 정보
  * @example
  * ```typescript
  * // 권한을 가져옵니다.
  * const permission = spread.collaboration.getPermission();
  */
getPermission (): GC.Spread.Sheets.Collaboration.IPermission;
```

* `GC.Spread.Sheets.Events`

```typescript
///* field static PermissionChanged: string
/**
 * 워크북 권한이 변경될 때 발생합니다.
 * @name GC.Spread.Sheets.Workbook#PermissionChanged
 * @event
 * @param {GC.Spread.Sheets.Collaboration.IPermission} permission 이벤트를 발생시킨 권한 정보
 * @example
 * ```javascript
 * // PermissionChanged 이벤트를 사용합니다.
 * spread.bind(GC.Spread.Sheets.Events.PermissionChanged, function (e, info) {
 *     console.log(info.permission);
 * });
 * ```
 */
static PermissionChanged = 'PermissionChanged';
```

* `GC.Spread.Sheets.ContextMenu`

```typescript
interface GC.Spread.Sheets.ContextMenu.IMenuItemData {
  ...
  metaData?:  GC.Spread.Sheets.ICommandMetaData; // menuItemData에 정보를 부가하기 위한 객체
}
export interface ICommandMetaData{
    viewModePermissions: GC.Spread.Sheets.Collaboration.PermissionTypes; // browsingMode가 viewMode일 때 메뉴 항목 사용 가능 여부
}
```