# Overview

Source: https://docs.interop.io/manager/capabilities/layouts/overview/index.html

## Overview

**io.Manager** stores the Layouts of the connected io.Connect platforms (Global and Workspace Layouts) and provides them to the users of **io.Connect Desktop** and **io.Connect Browser**.

> ℹ️ *For more details on using Layouts in the io.Connect platforms, see the [Capabilities > Windows > Layouts](https://docs.interop.io/desktop/capabilities/windows/layouts/overview/index.md) section of the **io.Connect Desktop** documentation and the [Capabilities > Windows > Layouts](https://docs.interop.io/browser/capabilities/windows/layouts/setup/index.md) section of the **io.Connect Browser** documentation.*

The **io.Manager** Server stores Layouts in one of two models - [advanced Layouts](#advanced_layouts) or [legacy Layouts](#legacy_layouts).

You can [configure](#advanced_layouts-enabling_advanced_layouts) which model the **io.Manager** Server provides to the io.Connect platforms, and each connected io.Connect platform must use the same model.

To manage the stored Layouts, use the **io.Manager** [Admin UI](https://docs.interop.io/manager/capabilities/layouts/admin-ui/index.md) or the **io.Manager** Server [REST API](#rest_api).

## Advanced Layouts

Available since io.Manager 4.0 & io.Connect Desktop 10.5

Advanced Layouts enable users to share Global and Workspace Layouts directly from **io.Connect Desktop**. A user can share a Layout they own with specific users and groups, granting each of them view or edit access, or make the Layout public, unlike [legacy Layouts](#legacy_layouts), where only an administrator can make a Layout available to other users.

An advanced Layout is identified by its `id` and carries its own [access information](https://docs.interop.io/manager/capabilities/layouts/sharing/index.md), which determines the users that can see and edit the Layout.

The following table describes how advanced Layouts differ from legacy Layouts:

| Feature | Advanced Layouts | Legacy Layouts |
|---------|------------------|----------------|
| Identity | The `id` of the Layout. | The `name`, `type`, and `owner` of the Layout. |
| Owner | A user. | A user, or `*` for a common Layout that isn't owned by a specific user. |
| Visibility | Set by the [access level](https://docs.interop.io/manager/capabilities/layouts/sharing/index.md#access_levels) of the Layout - `"private"`, `"public"`, or `"shared"`. | A Layout owned by a user is private. A common Layout is visible to all users, or to specific groups. |
| Editing | The owner and the users and groups with `"edit"` access can update, rename, and delete the Layout, and change its access information. | Users can't change a common Layout. |
| Saving changes without edit access | Rejected with an HTTP 403 status code. No private copy is created. | Saved as a private copy owned by the user. The common Layout stays unchanged. |
| Name uniqueness | Unique per `type` and owner while the Layout is private, and unique per `type` across all owners once the Layout is shared or public. | Unique per `type` and owner. |
| Default Global Layout | There is no default Global Layout common to all users. Each user sets their own default Global Layout from the io.Connect platform. | A Layout marked as `default` is the default Global Layout for every user that can see it, unless the user has a default Global Layout of their own. |
| Supported platforms | **io.Connect Desktop** 10.5 or later. | **io.Connect Desktop** and **io.Connect Browser**. |

### Enabling Advanced Layouts

> ⚠️ *Note that the **io.Manager** Server and all connected io.Connect platforms must use the same Layout model - advanced Layouts must be either enabled in all of them, or disabled in all of them.*

> ⚠️ *Note that **io.Connect Browser** doesn't support advanced Layouts. If any **io.Connect Browser** clients connect to the **io.Manager** Server, the server must keep providing legacy Layouts.*

To switch from legacy Layouts to advanced Layouts:

1. Set the `enabled` property of the [`advancedLayouts`](https://docs.interop.io/manager/configuration/server/index.md#configuration_object-advancedlayoutsconfig) top-level key in the configuration object for initializing the **io.Manager** Server to `true`, or set the `API_ADVANCED_LAYOUTS_ENABLED` environment variable to `true`, depending on your [deployment](https://docs.interop.io/manager/deployment/index.md) approach.

The following example demonstrates how to enable advanced Layouts when initializing the **io.Manager** Server:

```javascript
import { start } from "@interopio/manager";

const config = {
    advancedLayouts: {
        // Provide advanced Layouts to the io.Connect platforms.
        enabled: true
    }
};

const server = await start(config);
```

The following example demonstrates how to enable advanced Layouts via an environment variable:

```cmd
API_ADVANCED_LAYOUTS_ENABLED=true
```

2. [Enable advanced Layouts](https://docs.interop.io/desktop/capabilities/windows/layouts/overview/index.md#layout_sharing-configuration) in each connected **io.Connect Desktop** platform instance by setting the `"enabled"` property of the `"advancedLayouts"` object under the `"server"` top-level key in the `system.json` [system configuration](https://docs.interop.io/desktop/developers/configuration/system/index.md) file of **io.Connect Desktop** to `true`. Using advanced Layouts requires **io.Connect Desktop** 10.5 or later.

3. If the **io.Manager** Server already holds legacy Layouts, run the one-time [migration](https://docs.interop.io/manager/capabilities/layouts/migration/index.md) of legacy Layouts to advanced Layouts. Until the migration runs, the io.Connect platforms will see only the advanced Layouts created after advanced Layouts were enabled.

4. Optionally, [restrict](https://docs.interop.io/manager/capabilities/layouts/sharing/index.md#restricting_sharing) the users that can share Layouts or make them public.

While advanced Layouts are enabled, the [REST API](#rest_api) endpoints for legacy Layouts reject writes with an HTTP 400 status code. While advanced Layouts are disabled, the endpoints for advanced Layouts reject writes in the same way.

> ⚠️ *Note that you can use the `advancedLayoutsEnabled` field in the response of the `GET /v2/server/info` endpoint to determine which Layout model the **io.Manager** Server uses.*

### Reverting to Legacy Layouts

To return to legacy Layouts, set to `false` the settings described in [Enabling Advanced Layouts](#advanced_layouts-enabling_advanced_layouts) on the **io.Manager** Server and in each connected io.Connect platform instance.

Changes made to advanced Layouts while they were enabled aren't reflected in the legacy Layouts. Changes made to legacy Layouts after they were migrated aren't carried over by a later migration run, and once the migration has [completed without failures](https://docs.interop.io/manager/capabilities/layouts/migration/index.md#status__reruns), it can't be run again.

## Legacy Layouts

Legacy Layouts are the default Layout model of the **io.Manager** Server. A legacy Layout is identified by its `name`, `type`, and `owner`. The following fields describe the visibility of a legacy Layout and whether it is a default Global Layout:

| Field | Description |
|-------|-------------|
| `accessList` | Groups that can see a common Layout. |
| `default` | If `true`, the Layout is the default Global Layout for every user that can see it, unless the user has a default Global Layout of their own. |
| `owner` | The user that owns the Layout, or `*` for a common Layout that isn't owned by a specific user - e.g., a public Layout or a Layout shared with groups via `accessList`. |
| `public` | If `true`, a common Layout is visible to all users. |

Users can't change a common Layout. When a user saves a public or shared Layout, **io.Manager** creates a private copy of it for that user, and the common Layout stays unchanged.

## REST API

The **io.Manager** Server REST API manages Layouts via the following endpoints. Each endpoint requires the listed [permission group](https://docs.interop.io/manager/authorization/index.md).

> ℹ️ *For more details on the request and response shapes of the endpoints, see the [Swagger UI](https://docs.interop.io/manager/open-api-support/index.md) provided by the **io.Manager** Server.*

The [`@interopio/manager-api`](https://www.npmjs.com/package/@interopio/manager-api) library exposes the operations for advanced Layouts and Layout migration via the `advancedLayouts` property of an `AdminAPI` instance.

### Advanced Layouts

Available since io.Manager 4.0

Use the following endpoints to manage [advanced Layouts](#advanced_layouts):

| Endpoint | Permission | Description |
|----------|------------|-------------|
| `DELETE /advancedLayouts` | `IO_MANAGER:LAYOUTS:WRITE` | Deletes all advanced Layouts. |
| `DELETE /advancedLayouts/{id}` | `IO_MANAGER:LAYOUTS:WRITE` | Deletes the advanced Layout with the given `id`. |
| `GET /advancedLayouts` | `IO_MANAGER:LAYOUTS:READ` | Lists advanced Layouts. Use the optional `params` query parameter to filter, group, sort, and page the results. |
| `GET /advancedLayouts/{id}` | `IO_MANAGER:LAYOUTS:READ` | Returns the advanced Layout with the given `id`. |
| `POST /advancedLayouts` | `IO_MANAGER:LAYOUTS:WRITE` | Creates an advanced Layout, or updates it if one with the same `id` already exists. |
| `POST /advancedLayouts/add` | `IO_MANAGER:LAYOUTS:WRITE` | Creates an advanced Layout. Returns `400` when the Layout would break the [name uniqueness](https://docs.interop.io/manager/capabilities/layouts/sharing/index.md#name_conflicts) rule, so an existing Layout is never overwritten. |
| `POST /advancedLayouts/check-conflict` | `IO_MANAGER:LAYOUTS:READ` | Checks whether saving a Layout with the given `name`, `type`, owner, and access level would [conflict](https://docs.interop.io/manager/capabilities/layouts/sharing/index.md#name_conflicts) with an existing advanced Layout. |
| `POST /advancedLayouts/update` | `IO_MANAGER:LAYOUTS:WRITE` | Updates the advanced Layout with the given `id`. Returns `404` when no Layout with that `id` exists. |

### Layout Migration

Available since io.Manager 4.0

Use the following endpoints to review and run the [migration](https://docs.interop.io/manager/capabilities/layouts/migration/index.md) of legacy Layouts to advanced Layouts:

| Endpoint | Permission | Description |
|----------|------------|-------------|
| `GET /advancedLayouts/migration/layouts` | `IO_MANAGER:LAYOUTS:WRITE` | Lists the legacy Layouts a migration run would migrate, each with the access information it will receive. Use the optional `params` query parameter to filter, sort, and page the results. |
| `GET /advancedLayouts/migration/status` | `IO_MANAGER:LAYOUTS:WRITE` | Returns the migration status, the number of legacy Layouts a run would migrate, and the outcome of the last run. |
| `POST /advancedLayouts/migration/run` | `IO_MANAGER:LAYOUTS:WRITE` | Runs the migration and returns its outcome. |

### Legacy Layouts

Use the following endpoints to manage [legacy Layouts](#legacy_layouts):

| Endpoint | Permission | Description |
|----------|------------|-------------|
| `DELETE /layouts` | `IO_MANAGER:LAYOUTS:WRITE` | Deletes all legacy Layouts. |
| `DELETE /layouts/{id}` | `IO_MANAGER:LAYOUTS:WRITE` | Deletes the legacy Layout with the given `id`. |
| `DELETE /layouts/{type}/{name}` | `IO_MANAGER:LAYOUTS:WRITE` | Deletes the public or shared legacy Layout with the given `type` and `name`. |
| `GET /layouts` | `IO_MANAGER:LAYOUTS:READ` | Lists legacy Layouts. Use the optional `params` query parameter to filter, group, sort, and page the results. |
| `GET /layouts/{id}` | `IO_MANAGER:LAYOUTS:READ` | Returns the legacy Layout with the given `id`. |
| `GET /layouts/{type}/{name}` | `IO_MANAGER:LAYOUTS:READ` | Returns the public or shared legacy Layout with the given `type` and `name`. |
| `POST /v2/layouts/add` | `IO_MANAGER:LAYOUTS:WRITE` | Creates a legacy Layout. Returns `400` when a Layout with the same `name`, `type`, and `owner` already exists. |
| `POST /v2/layouts/add-or-update` | `IO_MANAGER:LAYOUTS:WRITE` | Creates a legacy Layout, or updates it if it already exists. |
| `POST /v2/layouts/update` | `IO_MANAGER:LAYOUTS:WRITE` | Updates an existing legacy Layout. Returns `404` when no Layout with the given `id`, or with the given `name`, `type`, and `owner`, exists. |
