# Управление разрешениями

- Human documentation: [https://docs.univer.ai/ru-RU/guides/sheets/features/core/permission](https://docs.univer.ai/ru-RU/guides/sheets/features/core/permission)

- Agent Markdown: [https://docs.univer.ai/ru-RU/guides/sheets/features/core/permission.md](https://docs.univer.ai/ru-RU/guides/sheets/features/core/permission.md)

- Requested language: `ru-RU`

- Content language: `ru-RU`

- Documentation version: `1.2.0`

- Source: [sheets/features/core/permission.ru-RU.mdx](https://github.com/dream-num/documentation/blob/dev/content/guides/sheets/features/core/permission.ru-RU.mdx)

---

Univer позволяет управлять разрешениями и ограничивать действия пользователей с книгами, листами и диапазонами. Если пользователь пытается выполнить действие без необходимого разрешения, операция прерывается, а пользователь получает уведомление. Например, можно защитить диапазон и определить, смогут ли участники редактировать, просматривать, копировать или фильтровать данные в нём.

> [!WARNING]
> Сервис должен сохранять правила защиты и изменения участников, возвращать права текущего пользователя и передавать ошибки запросов вызывающему коду. Пустые списки в заглушке не обеспечивают сохранение данных. При совместной работе сервер отдельно проверяет чтение, JOIN и изменение; см. [Идентификация и авторизация](https://docs.univer.ai/ru-RU/server/collaboration/identity-and-authorization.md). Защита интерфейса и скрытие затенения не заменяют серверную авторизацию.
> 
> [Интеграция сервиса авторизации](#authorization-service)

> Interactive example: [Open the playground](/playground/sheets/permission)

Перейдите к разделу по своей задаче. Базовые операции, расширенные примеры, настройки и устранение проблем остаются на этой странице; полные контракты API поддерживаются в Reference.

* [Типовые задачи](#permission-tasks)
* [Настройка интерфейса прав](#permission-ui)
* [Интеграция сервиса авторизации](#permission-integration)
* [Reference](#reference)

## Основные понятия

* Область действия: разрешения применяются на трёх уровнях — книга, лист и диапазон.
* Точки разрешений: каждой функции соответствует точка разрешения. Изменяя её, можно управлять доступностью функции.
* Правила защиты: прежде чем настраивать точки разрешений для листов и диапазонов, необходимо создать правило защиты.

> [!INFO]
> Локальные права без сохранения изменяются через точки прав. Для сохранения см. [Интеграция сервиса авторизации](#authorization-service)
> 
> При совместном редактировании обновление точки разрешения синхронизирует состояние сервера:
> 
> * `false`: для точки разрешения требуется роль не ниже `owner`
> * `true`: для точки разрешения требуется роль не ниже `reader`

## Базовый пример

Перед использованием примеров `allowedUsers` замените `user1` и `user2` реальными идентификаторами участников, возвращаемыми вашим сервисом авторизации.

Ниже показаны наиболее распространённые способы настройки разрешений на трёх уровнях: книги, листа и диапазона.

### Пример разрешений для книги

Разрешения на уровне книги можно настроить напрямую через [Facade API](https://docs.univer.ai/ru-RU/guides/sheets/getting-started/facade.md).

В следующем примере редактирование отключается для всей книги. Для управления другими функциями замените точку разрешения на соответствующую (см. [список точек разрешений книги](#workbook-point)):

```typescript
const fWorkbook = univerAPI.getActiveWorkbook()
if (!fWorkbook) throw new Error('No active workbook')
const workbookPermission = fWorkbook.getWorkbookPermission()

// Set the workbook to be non-editable
await workbookPermission.setPoint(univerAPI.Enum.WorkbookPermissionPoint.Edit, false)
```

Важно:

* точки разрешений книги можно настраивать напрямую, не создавая правил защиты.

### Пример разрешений для листа

Разрешения листа и диапазона можно настраивать через Facade API или команды. В следующем примере задаётся разрешение на редактирование листа. Для других функций замените точку разрешения на соответствующую (см. [список точек разрешений листа](#worksheet-point)):

```typescript
const fWorkbook = univerAPI.getActiveWorkbook()
if (!fWorkbook) throw new Error('No active workbook')
const fWorksheet = fWorkbook.getActiveSheet()
const worksheetPermission = fWorksheet.getWorksheetPermission()

// Create worksheet protection, allow specified users to edit
const permissionId = await worksheetPermission.protect({
  allowedUsers: ['user1', 'user2'],
  name: 'My Worksheet Protection',
})

// To set permission points, you must first protect the worksheet
await worksheetPermission.setPoint(univerAPI.Enum.WorksheetPermissionPoint.Edit, false)
```

#### Удаление разрешений листа

```typescript
const fWorkbook = univerAPI.getActiveWorkbook()
if (!fWorkbook) throw new Error('No active workbook')
const fWorksheet = fWorkbook.getActiveSheet()
const worksheetPermission = fWorksheet.getWorksheetPermission()

// Remove worksheet protection
await worksheetPermission.unprotect()
```

### Пример пользовательских разрешений диапазона

Разрешения диапазона также можно настраивать через API и команды. Здесь в качестве примера используется разрешение на редактирование диапазона. Для других функций диапазона замените точки разрешений; подробности см. в [списке точек разрешений диапазона](#range-point).

```typescript
const fWorkbook = univerAPI.getActiveWorkbook()
if (!fWorkbook) throw new Error('No active workbook')
const fWorksheet = fWorkbook.getActiveSheet()
const fRange = fWorksheet.getRange('A1:B2')
const rangePermission = fRange.getRangePermission()

// Set range protection permission, allow specified users to edit but not allow others to view
const rule = await rangePermission.protect({
  name: 'My protected range',
  allowViewByOthers: false,
  allowedUsers: ['user1', 'user2'],
})
console.log(rule)

// To set permission points, you must first create a range protection rule.
await rule.setPoint(univerAPI.Enum.RangePermissionPoint.Edit, false)
await rule.setPoint(univerAPI.Enum.RangePermissionPoint.View, true)
```

#### Удаление разрешений защиты диапазона

```typescript
const fWorkbook = univerAPI.getActiveWorkbook()
if (!fWorkbook) throw new Error('No active workbook')
const fWorksheet = fWorkbook.getActiveSheet()
const fRange = fWorksheet.getRange('A1:B2')
const rangePermission = fRange.getRangePermission()

// delete all rules within the range
await rangePermission.unprotect()

// Or delete specific rules within the range
const rules = await rangePermission.listRules()
if (rules.length > 0) {
  await rules[0].remove()
}
```

## Типовые задачи

### Перевести книгу в режим чтения

```typescript
const fWorkbook = univerAPI.getActiveWorkbook()
if (!fWorkbook) throw new Error('No active workbook')
const permission = fWorkbook.getWorkbookPermission()
await permission.setMode('viewer')
console.log(permission.getSnapshot())
```

### Управлять защищёнными диапазонами

```typescript
const fWorkbook = univerAPI.getActiveWorkbook()
if (!fWorkbook) throw new Error('No active workbook')
const fWorksheet = fWorkbook.getActiveSheet()
const permission = fWorksheet.getWorksheetPermission()

const createdRules = await permission.protectRanges([
  {
    ranges: [fWorksheet.getRange('A1:B2')],
    options: { name: 'Public area', allowViewByOthers: true },
  },
  {
    ranges: [fWorksheet.getRange('C3:D4')],
    options: { name: 'Private area', allowViewByOthers: false, allowedUsers: ['user1'] },
  },
])
console.log(createdRules)

const rules = await permission.listRangeProtectionRules()
const firstRule = rules[0]
if (firstRule) {
  await firstRule.updateRanges([fWorksheet.getRange('A1:B3')])
}
```

### Проверить права ячейки

```typescript
const fWorkbook = univerAPI.getActiveWorkbook()
if (!fWorkbook) throw new Error('No active workbook')
const permission = fWorkbook.getActiveSheet().getWorksheetPermission()
console.log(permission.debugCellPermission(0, 0))
```

## Список точек разрешений

Исходный код всех точек разрешений доступен [здесь](https://github.com/dream-num/univer/tree/dev/packages/sheets/src/services/permission/permission-point).

Если разрешения книги пересекаются с разрешениями листа или диапазона, для использования функции **все** соответствующие разрешения должны иметь значение `true`.

### Разрешения книги

| Перечисление API                                          | Соответствующий класс точки разрешения | Описание                  |
| --------------------------------------------------------- | -------------------------------------- | ------------------------- |
| univerAPI.Enum.WorkbookPermissionPoint.Edit               | WorkbookEditablePermission             | Редактирование            |
| univerAPI.Enum.WorkbookPermissionPoint.View               | WorkbookViewPermission                 | Просмотр                  |
| univerAPI.Enum.WorkbookPermissionPoint.Print              | WorkbookPrintPermission                | Печать                    |
| univerAPI.Enum.WorkbookPermissionPoint.Export             | WorkbookExportPermission               | Экспорт                   |
| univerAPI.Enum.WorkbookPermissionPoint.Share              | WorkbookSharePermission                | Общий доступ              |
| univerAPI.Enum.WorkbookPermissionPoint.CopyContent        | WorkbookCopyPermission                 | Копирование               |
| univerAPI.Enum.WorkbookPermissionPoint.DuplicateFile      | WorkbookDuplicatePermission            | Создание дубликатов       |
| univerAPI.Enum.WorkbookPermissionPoint.Comment            | WorkbookCommentPermission              | Комментирование           |
| univerAPI.Enum.WorkbookPermissionPoint.ManageCollaborator | WorkbookManageCollaboratorPermission   | Управление участниками    |
| univerAPI.Enum.WorkbookPermissionPoint.CreateSheet        | WorkbookCreateSheetPermission          | Создание листов           |
| univerAPI.Enum.WorkbookPermissionPoint.DeleteSheet        | WorkbookDeleteSheetPermission          | Удаление листов           |
| univerAPI.Enum.WorkbookPermissionPoint.RenameSheet        | WorkbookRenameSheetPermission          | Переименование листов     |
| univerAPI.Enum.WorkbookPermissionPoint.MoveSheet          | WorkbookMoveSheetPermission            | Перемещение листов        |
| univerAPI.Enum.WorkbookPermissionPoint.HideSheet          | WorkbookHideSheetPermission            | Скрытие листов            |
| univerAPI.Enum.WorkbookPermissionPoint.CopySheet          | WorkbookCopySheetPermission            | Копирование листов        |
| univerAPI.Enum.WorkbookPermissionPoint.ViewHistory        | WorkbookViewHistoryPermission          | Просмотр истории          |
| univerAPI.Enum.WorkbookPermissionPoint.RecoverHistory     | WorkbookRecoverHistoryPermission       | Восстановление из истории |
| univerAPI.Enum.WorkbookPermissionPoint.CreateProtection   | WorkbookCreateProtectPermission        | Создание защиты           |
| univerAPI.Enum.WorkbookPermissionPoint.InsertRow          | WorkbookInsertRowPermission            | Вставка строк             |
| univerAPI.Enum.WorkbookPermissionPoint.InsertColumn       | WorkbookInsertColumnPermission         | Вставка столбцов          |
| univerAPI.Enum.WorkbookPermissionPoint.DeleteRow          | WorkbookDeleteRowPermission            | Удаление строк            |
| univerAPI.Enum.WorkbookPermissionPoint.DeleteColumn       | WorkbookDeleteColumnPermission         | Удаление столбцов         |

### Разрешения листа

| Перечисление API                                               | Соответствующий класс точки разрешения    | Описание                               |
| -------------------------------------------------------------- | ----------------------------------------- | -------------------------------------- |
| univerAPI.Enum.WorksheetPermissionPoint.Edit                   | WorksheetEditPermission                   | Редактирование                         |
| univerAPI.Enum.WorksheetPermissionPoint.View                   | WorksheetViewPermission                   | Просмотр                               |
| univerAPI.Enum.WorksheetPermissionPoint.Copy                   | WorksheetCopyPermission                   | Копирование                            |
| univerAPI.Enum.WorksheetPermissionPoint.SetCellValue           | WorksheetSetCellValuePermission           | Изменение значений ячеек               |
| univerAPI.Enum.WorksheetPermissionPoint.SetCellStyle           | WorksheetSetCellStylePermission           | Изменение стилей ячеек                 |
| univerAPI.Enum.WorksheetPermissionPoint.SetRowStyle            | WorksheetSetRowStylePermission            | Настройка стилей строк                 |
| univerAPI.Enum.WorksheetPermissionPoint.SetColumnStyle         | WorksheetSetColumnStylePermission         | Настройка стилей столбцов              |
| univerAPI.Enum.WorksheetPermissionPoint.InsertRow              | WorksheetInsertRowPermission              | Вставка строк                          |
| univerAPI.Enum.WorksheetPermissionPoint.InsertColumn           | WorksheetInsertColumnPermission           | Вставка столбцов                       |
| univerAPI.Enum.WorksheetPermissionPoint.DeleteRow              | WorksheetDeleteRowPermission              | Удаление строк                         |
| univerAPI.Enum.WorksheetPermissionPoint.DeleteColumn           | WorksheetDeleteColumnPermission           | Удаление столбцов                      |
| univerAPI.Enum.WorksheetPermissionPoint.Sort                   | WorksheetSortPermission                   | Сортировка                             |
| univerAPI.Enum.WorksheetPermissionPoint.Filter                 | WorksheetFilterPermission                 | Фильтрация                             |
| univerAPI.Enum.WorksheetPermissionPoint.PivotTable             | WorksheetPivotTablePermission             | Использование сводных таблиц           |
| univerAPI.Enum.WorksheetPermissionPoint.InsertHyperlink        | WorksheetInsertHyperlinkPermission        | Использование гиперссылок              |
| univerAPI.Enum.WorksheetPermissionPoint.ManageCollaborator     | WorksheetManageCollaboratorPermission     | Управление участниками                 |
| univerAPI.Enum.WorksheetPermissionPoint.DeleteProtection       | WorksheetDeleteProtectionPermission       | Удаление защиты                        |
| univerAPI.Enum.WorksheetPermissionPoint.EditExtraObject        | WorksheetEditExtraObjectPermission        | Редактирование дополнительных объектов |
| univerAPI.Enum.WorksheetPermissionPoint.SelectProtectedCells   | WorksheetSelectProtectedCellsPermission   | Выделение защищённых ячеек             |
| univerAPI.Enum.WorksheetPermissionPoint.SelectUnProtectedCells | WorksheetSelectUnProtectedCellsPermission | Выделение незащищённых ячеек           |

### Защита диапазона

| Перечисление API                                       | Соответствующий класс точки разрешения         | Описание                                         |
| ------------------------------------------------------ | ---------------------------------------------- | ------------------------------------------------ |
| univerAPI.Enum.RangePermissionPoint.Edit               | RangeProtectionPermissionEditPoint             | Редактирование защищённых диапазонов             |
| univerAPI.Enum.RangePermissionPoint.View               | RangeProtectionPermissionViewPoint             | Просмотр содержимого защищённых диапазонов       |
| univerAPI.Enum.RangePermissionPoint.Delete             | RangeProtectionPermissionDeleteProtectionPoint | Удаление защищённых диапазонов                   |
| univerAPI.Enum.RangePermissionPoint.ManageCollaborator | RangeProtectionPermissionManageCollaPoint      | Управление участниками для защищённых диапазонов |

## Настройка интерфейса прав

### Стратегия затенения защищённого диапазона

Чтобы различать защищённые области, которые текущий пользователь может и не может редактировать, используйте `non-editable`. Затенение скрывается для доступных для редактирования защищённых областей и сохраняется там, где право редактирования отключено. Защищённые диапазоны, недоступные для просмотра, остаются замаскированными.

Эта настройка управляет отображением защиты диапазонов и листов. Она не создаёт правила защиты, не меняет права редактирования или просмотра и не добавляет затенение к незащищённым областям. Сначала настройте правила и права текущего пользователя, как показано выше.

| Стратегия           | Отображение                                                                               |
| ------------------- | ----------------------------------------------------------------------------------------- |
| `true` / `'always'` | Показывать затенение всех защищённых областей (по умолчанию).                             |
| `'non-editable'`    | Скрывать затенение редактируемых защищённых областей и сохранять его для нередактируемых. |
| `'non-viewable'`    | Показывать затенение только для защищённых областей, недоступных для просмотра.           |
| `false` / `'none'`  | Скрывать всё затенение защиты; проверки прав продолжают действовать.                      |



Задайте стратегию при инициализации:

#### Режим плагина

```typescript
univer.registerPlugin(UniverSheetsUIPlugin, {
  protectedRangeShadow: 'non-editable',
})
```

#### Режим предустановки

```typescript
createUniver({
  presets: [
    UniverSheetsCorePreset({
      sheets: {
        protectedRangeShadow: 'non-editable',
      },
    }),
  ],
})
```

Также эту настройку можно изменять динамически через API:

Приведённый ниже Facade API обновляет существующие книги в текущем экземпляре Univer. В режиме плагинов сначала импортируйте `@univerjs/sheets-ui/facade`; пресет Sheets Core уже включает этот импорт.

```typescript
// Set to only show shadows for non-editable ranges
univerAPI.setProtectedRangeShadowStrategy('non-editable')

// Get the current protected range shadow display strategy
console.log(univerAPI.getProtectedRangeShadowStrategy())

// Subscribe to changes in the protected range shadow strategy
const subscription = univerAPI.getProtectedRangeShadowStrategy$().subscribe((strategy) => {
  console.log('Global strategy changed to:', strategy)
  // Update UI or perform other actions
})

// Later, unsubscribe to clean up
subscription.unsubscribe()
```

### Пользовательский компонент выбора пользователей

Встроенный в Univer компонент выбора пользователей имеет ограниченные возможности настройки. Для более сложных сценариев можно предоставить собственный компонент, как показано ниже.

> [!NOTE]
> Инструкции по созданию собственных компонентов см. в разделе [Пользовательские компоненты](https://docs.univer.ai/ru-RU/guides/sheets/ui/components.md).

#### Режим плагина

```typescript
univer.registerPlugin(UniverSheetsUIPlugin, {
  protectedRangeUserSelector: {
    /**
     * Custom component; must implement the `IPermissionDetailUserPartProps` interface.
     */
    component: CustomPermissionDetailUserPart,
    /**
     * The framework of the component. Must be passed correctly.
     */
    framework: 'react',
  },
})
```

#### Режим предустановки

```typescript
const { univer } = createUniver({
  presets: [
    UniverSheetsCorePreset({
      sheets: {
        protectedRangeUserSelector: {
        /**
         * Custom component; must implement the `IPermissionDetailUserPartProps` interface.
         */
          component: CustomPermissionDetailUserPart,
          /**
           * The framework of the component. Must be passed correctly.
           */
          framework: 'react',
        },
      },
    }),
  ],
})
```

Вызывайте `setSelectUserList()` из обработчика изменения выбора. Этот минимальный пример React очищает выбор: `useDependency` вызывается внутри компонента, а сервис обновляется только после нажатия. Остальную часть выбора реализуйте по `IPermissionDetailUserPartProps`.

#### Режим плагинов

```tsx
import type { IPermissionDetailUserPartProps } from '@univerjs/sheets-ui'
import type { FC } from 'react'
import { SheetPermissionUserManagerService } from '@univerjs/sheets-ui'
import { useDependency } from '@univerjs/ui'

export const CustomPermissionDetailUserPart: FC<IPermissionDetailUserPartProps> = () => {
  const service = useDependency(SheetPermissionUserManagerService)
  const clearSelection = () => service.setSelectUserList([])

  return <button type="button" onClick={clearSelection}>Очистить выбранных пользователей</button>
}
```

#### Режим предустановок

```tsx
import type { IPermissionDetailUserPartProps } from '@univerjs/preset-sheets-core'
import type { FC } from 'react'
import { SheetPermissionUserManagerService, useDependency } from '@univerjs/preset-sheets-core'

export const CustomPermissionDetailUserPart: FC<IPermissionDetailUserPartProps> = () => {
  const service = useDependency(SheetPermissionUserManagerService)
  const clearSelection = () => service.setSelectUserList([])

  return <button type="button" onClick={clearSelection}>Очистить выбранных пользователей</button>
}
```

### Скрытие диалогового окна разрешений

```typescript
univerAPI.setPermissionDialogVisible(false)
```

## Интеграция сервиса авторизации

### Расширенное использование

Если в собственном плагине требуется проверять разрешения, можно работать с точками разрешений напрямую.

В следующем примере на основе `WorkbookEditablePermission` показано, как проверять разрешения в собственном плагине. Другие точки разрешений работают аналогично.

```typescript
import { IPermissionService } from '@univerjs/core'
import { WorkbookEditablePermission } from '@univerjs/sheets'

class YourService {
  constructor(@IPermissionService private _permissionService: IPermissionService) {
  }

  setWorkbookNotEditable() {
    this._permissionService.updatePermissionPoint(new WorkbookEditablePermission('unitId').id, false)
  }

  setWorkbookEditable() {
    this._permissionService.updatePermissionPoint(new WorkbookEditablePermission('unitId').id, true)
  }
}
```

[Список точек разрешений](#point-list)

### Расширение точек разрешений

Чтобы настроить собственную точку разрешения, реализуйте `IPermissionPoint` и зарегистрируйте её в службе разрешений:

```typescript
import type { IPermissionPoint } from '@univerjs/core'
import { IPermissionService, PermissionStatus } from '@univerjs/core'
import { UnitAction, UnitObject } from '@univerjs/protocol'

export class CustomPermissionPoint implements IPermissionPoint {
  type = UnitObject.Unkonwn // your type
  subType = UnitAction.View // your subType
  status = PermissionStatus.INIT
  value = true // Default value
  id: string
  constructor(unitId: string, subUnitId: string, customId: string) {
    // The id must be unique within `IPermissionService`.
    this.id = `${unitId}.${subUnitId}.${customId}`
  }
}

class YourService {
  constructor(@IPermissionService private _permissionService: IPermissionService) {
    this._init()
  }

  _init() {
    this._permissionService.addPermissionPoint(new CustomPermissionPoint('unitId', 'subUnitId', 'my-id'))
  }
}

// How to use it elsewhere
class ConsumeService {
  constructor(@IPermissionService private _permissionService: IPermissionService) {
  }

  doSomething() {
    const point = this._permissionService.getPermissionPoint(new CustomPermissionPoint('unitId', 'subUnitId', 'my-id').id)
    console.log(point?.value)
  }

  bindEvent() {
    // This returns an RxJS observable that lets you listen for permission changes
    const point$ = this._permissionService.getPermissionPoint$(new CustomPermissionPoint('unitId', 'subUnitId', 'my-id').id)
    console.log(point$)
  }
}
```

### Интеграция со сторонней службой авторизации (для опытных пользователей)

Реализуйте [IAuthzIoService](https://github.com/dream-num/univer/blob/dev/packages/core/src/services/authz-io/type.ts) в приложении и свяжите методы прав, ролей и участников с сервером. В примере предполагается, что `./authorization-service` экспортирует эту реализацию как `YourAuthzService`. Зарегистрируйте её до создания книг, сохранив остальные параметры и плагины.

```typescript
import { IAuthzIoService, Univer } from '@univerjs/core'
import { YourAuthzService } from './authorization-service'

const univer = new Univer({
  override: [[IAuthzIoService, { useClass: YourAuthzService }]],
})
```

Сервис должен сохранять правила защиты и изменения участников, возвращать права текущего пользователя и передавать ошибки запросов вызывающему коду. Пустые списки в заглушке не обеспечивают сохранение данных. При совместной работе сервер отдельно проверяет чтение, JOIN и изменение; см. [Идентификация и авторизация](https://docs.univer.ai/ru-RU/server/collaboration/identity-and-authorization.md). Защита интерфейса и скрытие затенения не заменяют серверную авторизацию.

![Разрешения](https://raw.githubusercontent.com/dream-num/documentation/dev/content/guides/sheets/features/core/permission/permission-en.png)

### Управление участниками

> [!NOTE]
> Управление участниками реализуется через пользователей, ACL и сервис прав вашего приложения. Защитите чтение, JOIN и изменения согласно [Identity and authorization](https://docs.univer.ai/ru-RU/server/collaboration/identity-and-authorization.md). Для API ниже требуется соответствующая реализация сервиса прав.

* Получение списка участников

```typescript
const fWorkbook = univerAPI.getActiveWorkbook()
if (!fWorkbook) throw new Error('No active workbook')
const workbookPermission = fWorkbook.getWorkbookPermission()

const collaborators = await workbookPermission.listCollaborators()
console.log(collaborators)
```

* Добавление участников

```typescript
const fWorkbook = univerAPI.getActiveWorkbook()
if (!fWorkbook) throw new Error('No active workbook')
const workbookPermission = fWorkbook.getWorkbookPermission()

// Add multiple collaborators at once
await workbookPermission.setCollaborators([
  {
    user: { userID: 'user1', name: 'John Doe', avatar: 'https://...' },
    role: univerAPI.Enum.UnitRole.Editor,
  },
  {
    user: { userID: 'user2', name: 'Jane Smith', avatar: '' },
    role: univerAPI.Enum.UnitRole.Reader,
  },
])

// Add a single collaborator
await workbookPermission.addCollaborator(
  { userID: 'user1', name: 'John Doe', avatar: 'https://...' },
  univerAPI.Enum.UnitRole.Editor,
)
```

* Изменение роли участника

```typescript
const fWorkbook = univerAPI.getActiveWorkbook()
if (!fWorkbook) throw new Error('No active workbook')
const workbookPermission = fWorkbook.getWorkbookPermission()

await workbookPermission.updateCollaborator(
  { userID: 'user1', name: 'John Doe Updated', avatar: 'https://...' },
  univerAPI.Enum.UnitRole.Reader,
)
```

* Удаление участников

```typescript
const fWorkbook = univerAPI.getActiveWorkbook()
if (!fWorkbook) throw new Error('No active workbook')
const workbookPermission = fWorkbook.getWorkbookPermission()

// Remove multiple collaborators
await workbookPermission.removeCollaborators(['user1', 'user2'])

// Remove a single collaborator
await workbookPermission.removeCollaborator('user1')
```

## Reference

* [FWorkbookPermission](https://docs.univer.ai/ru-RU/reference/facade/workbook-permission.md)
* [FWorksheetPermission](https://docs.univer.ai/ru-RU/reference/facade/worksheet-permission.md)
* [FRangePermission](https://docs.univer.ai/ru-RU/reference/facade/range-permission.md)
* [FRangeProtectionRule](https://docs.univer.ai/ru-RU/reference/facade/range-protection-rule.md)
