# Permissions

## Content

SpreadJS Sheets Coollaboration provides two document modes: **View Mode** and **Edit Mode**. Through the Permissions feature, users can configure specific operational permissions in **View Mode**, striking a balance between flexibility and security in a collaborative environment.

## Functionality Description

The following is a detailed introduction to the two document modes ([User - BrowsingMode](/spreadjs/docs/v18/spreadjs-collaboration-server/spreadjs-sheets-collaboration/user)):

### View Mode

* Users can only view the workbook content.
* Certain UI operations (e.g., hiding rows, adjusting column width) can be enabled via permissions, but these operations only **take effect locally and are not synchronized.**
* In **View Mode**, by default, all reversible commands are disabled. However, users can customize the following permissions to allow specific operations, optimizing the viewing experience without compromising data integrity:
    * `allowNonDataModifyingOperations`: Allows viewer could execute non-data modifying operations.
    * `allowHideRowsOrColumns`: Allows hiding or showing rows or columns.
    * `allowResizeRowsOrColumns`: Allows resizing rows or columns.
    * `allowFilter`: Allows filtering data.
    * `allowSort`: Allows sorting data.

### Edit Mode

* Users have unrestricted editing permissions.
* All modifications are synchronized in real-time with other collaborators.
* This is the **default mode** for workbook.

### Policy Points

* In View Mode, all Command operations (including built-in commands and custom Commands) are restricted, but APIs are not limited.
* In View Mode, any data changes resulting from permission-enabled operations take effect only locally and are not synchronized.

### Application Scenarios

* **Data Viewing:** Users in **View Mode** can configure executable actions (such as hiding rows or filtering data) based on business requirements to analyze data.
* **Security**: Fine-grained permission controls prevent unauthorized modifications, protecting data in the collaborative environment.
* **Team Collaboration**: Combined with status tracking, users can see others’ operations while retaining control over their own capabilities.

## Methods

Users can bind user information to the workbook using the [setUser ](/spreadjs/api/v18/classes/GC.Spread.Sheets.Collaboration.Collaboration#setuser)method or simultaneously bind presence and user information to the workbook using the [bindPresence ](/spreadjs/api/v18/collaboration/spread-sheets-collaboration-client/README#bindpresence)method.

## Usage

The following example demonstrates how to set a user to View Mode and allow them to hide/show rows/columns, resize rows/columns, and filter data:

1. Initialize workbook and user information.

    ```typescript
    const workbook = new GC.Spread.Sheets.Workbook(document.getElementById("ss"), { sheetCount: 2 });
    // Simulate user data (usually obtained from the server)
    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
        }
    };
    ```
2. Bind user information to the workbook; this approach does not require presence information. If you need to bind both presence and user information, use the method in Step 3.

    ```typescript
    workbook.collaboration.setUser(user);
    ```
3. Bind both presence and user information to the workbook.

    ```typescript
    const presence = new Presence<IPresence>(conn);
    bindPresence(workbook, presence, user);
    ```

### Complete Example

```typescript
import { Presence } from "js-collaboration-presence-client";
import { bindPresence, IPresence } from "spread-sheets-collaboration-client";

// init workbook
const workbook = new GC.Spread.Sheets.Workbook(document.getElementById("ss"), { sheetCount: 2 });

// Simulate user data (usually obtained from the server)
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
    }
};

// Binding workbook with user, no presence info.
workbook.collaboration.setUser(user);
```

## API

* `spread-sheets-collaboration-client`

    ```typescript
    /**
     * Defines the BrowsingMode
     * @enum {number}
     */
    export enum BrowsingMode {
        /** Specifies that the user could edit the document.
         * @type {number}
         */
        edit,
        /** Specifies that the user could only view the document.
         * @type {number}
         */
        view,
    }
    /**
     * Defines the PermissionTypes
     * @enum {number}
     */
    export enum PermissionTypes {
        /** Specifies that viewer could execute non-data modifying operations.
         * @type {number}
         */
        allowNonDataModifyingOperations,
        /** Specifies that viewer could hide/unhide rows/columns.
         * @type {number}
         */
        allowHideRowsOrColumns,
        /** Specifies that viewer could resize rows/columns.
         * @type {number}
         */
        allowResizeRowsOrColumns,
        /** Specifies that viewer could filter range.
         * @type {number}
         */
        allowFilter,
        /** Specifies that viewer could sort.
         * @type {number}
         */
        allowSort,
    }
    export interface IPermission {
        mode: BrowsingMode;
        viewModePermissions?: PermissionTypes;
    }
    export interface IUser {
        id: string;
        name: string;
        color?: string;
        permission?: IPermission;
    }
    ```
* `GC.Spread.Sheets.ContextMenu`

    ```typescript
    interface GC.Spread.Sheets.ContextMenu.IMenuItemData {
      ...
      metaData?:  GC.Spread.Sheets.ICommandMetaData; // metaData is an Object used to attach some information to the menuItemData. 
    }
    export interface ICommandMetaData{
        viewModePermissions: GC.Spread.Sheets.Collaboration.PermissionTypes; // whether the menuItem is available when browsingMode is in viewMode. 
    }
    ```